-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lanuch function for unifying CPU and GPU code. [Reopen] #3643
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/*! | ||
* Copyright 2015 by Contributors | ||
* Copyright 2015-2018 by Contributors | ||
* \file common.h | ||
* \brief Common utilities | ||
*/ | ||
|
@@ -19,6 +19,13 @@ | |
#if defined(__CUDACC__) | ||
#include <thrust/system/cuda/error.h> | ||
#include <thrust/system_error.h> | ||
|
||
#define WITH_CUDA() true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't there a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you mean |
||
|
||
#else | ||
|
||
#define WITH_CUDA() false | ||
|
||
#endif | ||
|
||
namespace dh { | ||
|
@@ -29,11 +36,11 @@ namespace dh { | |
#define safe_cuda(ans) ThrowOnCudaError((ans), __FILE__, __LINE__) | ||
|
||
inline cudaError_t ThrowOnCudaError(cudaError_t code, const char *file, | ||
int line) { | ||
int line) { | ||
if (code != cudaSuccess) { | ||
throw thrust::system_error(code, thrust::cuda_category(), | ||
std::string{file} + "(" + // NOLINT | ||
std::to_string(line) + ")"); | ||
LOG(FATAL) << thrust::system_error(code, thrust::cuda_category(), | ||
std::string{file} + ": " + // NOLINT | ||
std::to_string(line)).what(); | ||
} | ||
return code; | ||
} | ||
|
@@ -70,13 +77,13 @@ inline std::string ToString(const T& data) { | |
*/ | ||
class Range { | ||
public: | ||
using DifferenceType = int64_t; | ||
|
||
class Iterator { | ||
friend class Range; | ||
|
||
public: | ||
using DifferenceType = int64_t; | ||
|
||
XGBOOST_DEVICE int64_t operator*() const { return i_; } | ||
XGBOOST_DEVICE DifferenceType operator*() const { return i_; } | ||
XGBOOST_DEVICE const Iterator &operator++() { | ||
i_ += step_; | ||
return *this; | ||
|
@@ -97,8 +104,8 @@ class Range { | |
XGBOOST_DEVICE void Step(DifferenceType s) { step_ = s; } | ||
|
||
protected: | ||
XGBOOST_DEVICE explicit Iterator(int64_t start) : i_(start) {} | ||
XGBOOST_DEVICE explicit Iterator(int64_t start, int step) : | ||
XGBOOST_DEVICE explicit Iterator(DifferenceType start) : i_(start) {} | ||
XGBOOST_DEVICE explicit Iterator(DifferenceType start, DifferenceType step) : | ||
i_{start}, step_{step} {} | ||
|
||
public: | ||
|
@@ -109,9 +116,10 @@ class Range { | |
XGBOOST_DEVICE Iterator begin() const { return begin_; } // NOLINT | ||
XGBOOST_DEVICE Iterator end() const { return end_; } // NOLINT | ||
|
||
XGBOOST_DEVICE Range(int64_t begin, int64_t end) | ||
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end) | ||
: begin_(begin), end_(end) {} | ||
XGBOOST_DEVICE Range(int64_t begin, int64_t end, Iterator::DifferenceType step) | ||
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end, | ||
DifferenceType step) | ||
: begin_(begin, step), end_(end) {} | ||
|
||
XGBOOST_DEVICE bool operator==(const Range& other) const { | ||
|
@@ -121,9 +129,7 @@ class Range { | |
return !(*this == other); | ||
} | ||
|
||
XGBOOST_DEVICE void Step(Iterator::DifferenceType s) { begin_.Step(s); } | ||
|
||
XGBOOST_DEVICE Iterator::DifferenceType GetStep() const { return begin_.step_; } | ||
XGBOOST_DEVICE void Step(DifferenceType s) { begin_.Step(s); } | ||
|
||
private: | ||
Iterator begin_; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
#include <vector> | ||
#include <cmath> | ||
#include <algorithm> | ||
#include <utility> | ||
#include "avx_helpers.h" | ||
|
||
namespace xgboost { | ||
|
@@ -29,22 +30,31 @@ inline avx::Float8 Sigmoid(avx::Float8 x) { | |
} | ||
|
||
/*! | ||
* \brief do inplace softmax transformaton on p_rec | ||
* \param p_rec the input/output vector of the values. | ||
* \brief Do inplace softmax transformaton on start to end | ||
* | ||
* \tparam Iterator Input iterator type | ||
* | ||
* \param start Start iterator of input | ||
* \param end end iterator of input | ||
*/ | ||
inline void Softmax(std::vector<float>* p_rec) { | ||
std::vector<float> &rec = *p_rec; | ||
float wmax = rec[0]; | ||
for (size_t i = 1; i < rec.size(); ++i) { | ||
wmax = std::max(rec[i], wmax); | ||
template <typename Iterator> | ||
XGBOOST_DEVICE inline void Softmax(Iterator start, Iterator end) { | ||
static_assert(std::is_same<bst_float, | ||
typename std::remove_reference< | ||
decltype(std::declval<Iterator>().operator*())>::type | ||
>::value, | ||
"Values should be of type bst_float"); | ||
bst_float wmax = *start; | ||
for (Iterator i = start+1; i != end; ++i) { | ||
wmax = fmaxf(*i, wmax); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw, this is a single-precision intrinsic, as is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, let me try a |
||
} | ||
double wsum = 0.0f; | ||
for (float & elem : rec) { | ||
elem = std::exp(elem - wmax); | ||
wsum += elem; | ||
for (Iterator i = start; i != end; ++i) { | ||
*i = expf(*i - wmax); | ||
wsum += *i; | ||
} | ||
for (float & elem : rec) { | ||
elem /= static_cast<float>(wsum); | ||
for (Iterator i = start; i != end; ++i) { | ||
*i /= static_cast<float>(wsum); | ||
} | ||
} | ||
|
||
|
@@ -56,7 +66,7 @@ inline void Softmax(std::vector<float>* p_rec) { | |
* \tparam Iterator The type of the iterator. | ||
*/ | ||
template<typename Iterator> | ||
inline Iterator FindMaxIndex(Iterator begin, Iterator end) { | ||
XGBOOST_DEVICE inline Iterator FindMaxIndex(Iterator begin, Iterator end) { | ||
Iterator maxit = begin; | ||
for (Iterator it = begin; it != end; ++it) { | ||
if (*it > *maxit) maxit = it; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you check the return value of
cudaGetDeviceCount()
instead of catching all exceptions?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try/catch is for XGBoost compiled with CUDA but running on CPU, in which case the cudaGetDeviceCount will fail and we return 0 as default.
I will make some note about that.