xgboost

common.h
Go to the documentation of this file.
1
6 #ifndef XGBOOST_COMMON_COMMON_H_
7 #define XGBOOST_COMMON_COMMON_H_
8
9 #include <xgboost/base.h>
10 #include <xgboost/logging.h>
11 #include <xgboost/span.h>
12
13 #include <algorithm>
14 #include <exception>
15 #include <functional>
16 #include <limits>
17 #include <type_traits>
18 #include <vector>
19 #include <string>
20 #include <sstream>
21 #include <numeric>
22 #include <utility>
23
24 #if defined(__CUDACC__)
25 #include <thrust/system/cuda/error.h>
26 #include <thrust/system_error.h>
27
28 #define WITH_CUDA() true
29
30 #else
31
32 #define WITH_CUDA() false
33
34 #endif // defined(__CUDACC__)
35
36 namespace dh {
37 #if defined(__CUDACC__)
38 /*
39 * Error handling functions
40 */
41 #define safe_cuda(ans) ThrowOnCudaError((ans), __FILE__, __LINE__)
42
43 inline cudaError_t ThrowOnCudaError(cudaError_t code, const char *file,
44 int line) {
45 if (code != cudaSuccess) {
46 LOG(FATAL) << thrust::system_error(code, thrust::cuda_category(),
47 std::string{file} + ": " + // NOLINT
48 std::to_string(line)).what();
49 }
50 return code;
51 }
52 #endif // defined(__CUDACC__)
53 } // namespace dh
54
55 namespace xgboost {
56 namespace common {
62 inline std::vector<std::string> Split(const std::string& s, char delim) {
63 std::string item;
64 std::istringstream is(s);
65 std::vector<std::string> ret;
66 while (std::getline(is, item, delim)) {
67 ret.push_back(item);
68 }
69 return ret;
70 }
71
72 template <typename T>
73 XGBOOST_DEVICE T Max(T a, T b) {
74 return a < b ? b : a;
75 }
76
77 // simple routine to convert any data to string
78 template<typename T>
79 inline std::string ToString(const T& data) {
80 std::ostringstream os;
81 os << data;
82 return os.str();
83 }
84
85 template <typename T1, typename T2>
86 XGBOOST_DEVICE T1 DivRoundUp(const T1 a, const T2 b) {
87 return static_cast<T1>(std::ceil(static_cast<double>(a) / b));
88 }
89
90 namespace detail {
91 template <class T, std::size_t N, std::size_t... Idx>
92 constexpr auto UnpackArr(std::array<T, N> &&arr, std::index_sequence<Idx...>) {
93 return std::make_tuple(std::forward<std::array<T, N>>(arr)[Idx]...);
94 }
95 } // namespace detail
96
97 template <class T, std::size_t N>
98 constexpr auto UnpackArr(std::array<T, N> &&arr) {
99 return detail::UnpackArr(std::forward<std::array<T, N>>(arr),
100 std::make_index_sequence<N>{});
101 }
102
103 /*
104 * Range iterator
105 */
106 class Range {
107 public:
108 using DifferenceType = int64_t;
109
110 class Iterator {
111 friend class Range;
112
113 public:
114 XGBOOST_DEVICE DifferenceType operator*() const { return i_; }
115 XGBOOST_DEVICE const Iterator &operator++() {
116 i_ += step_;
117 return *this;
118 }
119 XGBOOST_DEVICE Iterator operator++(int) {
120 Iterator res {*this};
121 i_ += step_;
122 return res;
123 }
124
125 XGBOOST_DEVICE bool operator==(const Iterator &other) const {
126 return i_ >= other.i_;
127 }
128 XGBOOST_DEVICE bool operator!=(const Iterator &other) const {
129 return i_ < other.i_;
130 }
131
132 XGBOOST_DEVICE void Step(DifferenceType s) { step_ = s; }
133
134 protected:
135 XGBOOST_DEVICE explicit Iterator(DifferenceType start) : i_(start) {}
136 XGBOOST_DEVICE explicit Iterator(DifferenceType start, DifferenceType step) :
137 i_{start}, step_{step} {}
138
139 private:
140 int64_t i_;
141 DifferenceType step_ = 1;
142 };
143
144 XGBOOST_DEVICE Iterator begin() const { return begin_; } // NOLINT
145 XGBOOST_DEVICE Iterator end() const { return end_; } // NOLINT
146
147 XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end)
148 : begin_(begin), end_(end) {}
149 XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end,
150 DifferenceType step)
151 : begin_(begin, step), end_(end) {}
152
153 XGBOOST_DEVICE bool operator==(const Range& other) const {
154 return *begin_ == *other.begin_ && *end_ == *other.end_;
155 }
156 XGBOOST_DEVICE bool operator!=(const Range& other) const {
157 return !(*this == other);
158 }
159
160 XGBOOST_DEVICE void Step(DifferenceType s) { begin_.Step(s); }
161
162 private:
163 Iterator begin_;
164 Iterator end_;
165 };
166
173 template <typename Fn>
174 class IndexTransformIter {
175 size_t iter_{0};
176 Fn fn_;
177
178 public:
179 using iterator_category = std::random_access_iterator_tag; // NOLINT
180 using value_type = std::result_of_t<Fn(size_t)>; // NOLINT
181 using difference_type = detail::ptrdiff_t; // NOLINT
182 using reference = std::add_lvalue_reference_t<value_type>; // NOLINT
183 using pointer = std::add_pointer_t<value_type>; // NOLINT
184
185 public:
189 explicit IndexTransformIter(Fn &&op) : fn_{op} {}
190 IndexTransformIter(IndexTransformIter const &) = default;
191 IndexTransformIter& operator=(IndexTransformIter&&) = default;
192 IndexTransformIter& operator=(IndexTransformIter const& that) {
193 iter_ = that.iter_;
194 return *this;
195 }
196
197 value_type operator*() const { return fn_(iter_); }
198
199 auto operator-(IndexTransformIter const &that) const { return iter_ - that.iter_; }
200 bool operator==(IndexTransformIter const &that) const { return iter_ == that.iter_; }
201 bool operator!=(IndexTransformIter const &that) const { return !(*this == that); }
202
203 IndexTransformIter &operator++() {
204 iter_++;
205 return *this;
206 }
207 IndexTransformIter operator++(int) {
208 auto ret = *this;
209 ++(*this);
210 return ret;
211 }
212 IndexTransformIter &operator+=(difference_type n) {
213 iter_ += n;
214 return *this;
215 }
216 IndexTransformIter &operator-=(difference_type n) {
217 (*this) += -n;
218 return *this;
219 }
220 IndexTransformIter operator+(difference_type n) const {
221 auto ret = *this;
222 return ret += n;
223 }
224 IndexTransformIter operator-(difference_type n) const {
225 auto ret = *this;
226 return ret -= n;
227 }
228 };
229
230 template <typename Fn>
231 auto MakeIndexTransformIter(Fn&& fn) {
232 return IndexTransformIter<Fn>(std::forward<Fn>(fn));
233 }
234
235 int AllVisibleGPUs();
236
237 inline void AssertGPUSupport() {
238 #ifndef XGBOOST_USE_CUDA
239 LOG(FATAL) << "XGBoost version not compiled with GPU support.";
240 #endif // XGBOOST_USE_CUDA
241 }
242
243 inline void AssertOneAPISupport() {
244 #ifndef XGBOOST_USE_ONEAPI
245 LOG(FATAL) << "XGBoost version not compiled with OneAPI support.";
246 #endif // XGBOOST_USE_ONEAPI
247 }
248
249 template <typename Idx, typename Container,
250 typename V = typename Container::value_type,
251 typename Comp = std::less<V>>
252 std::vector<Idx> ArgSort(Container const &array, Comp comp = std::less<V>{}) {
253 std::vector<Idx> result(array.size());
254 std::iota(result.begin(), result.end(), 0);
255 auto op = [&array, comp](Idx const &l, Idx const &r) { return comp(array[l], array[r]); };
256 XGBOOST_PARALLEL_STABLE_SORT(result.begin(), result.end(), op);
257 return result;
258 }
259
260 struct OptionalWeights {
261 Span<float const> weights;
262 float dft{1.0f};
263
264 explicit OptionalWeights(Span<float const> w) : weights{w} {}
265 explicit OptionalWeights(float w) : dft{w} {}
266
267 XGBOOST_DEVICE float operator[](size_t i) const { return weights.empty() ? dft : weights[i]; }
268 };
269 } // namespace common
270 } // namespace xgboost
271 #endif // XGBOOST_COMMON_COMMON_H_
xgboost::common::IndexTransformIter::operator=
IndexTransformIter & operator=(IndexTransformIter &&)=default
xgboost::common::IndexTransformIter::operator+=
IndexTransformIter & operator+=(difference_type n)
Definition: common.h:212
xgboost::common::detail::ptrdiff_t
typename std::conditional< std::is_same< std::ptrdiff_t, std::int64_t >::value, std::ptrdiff_t, std::int64_t >::type ptrdiff_t
Definition: span.h:135
xgboost::common::IndexTransformIter
Transform iterator that takes an index and calls transform operator.
Definition: common.h:174
xgboost::common::UnpackArr
constexpr auto UnpackArr(std::array< T, N > &&arr)
Definition: common.h:98
xgboost::common::Range::begin
XGBOOST_DEVICE Iterator begin() const
Definition: common.h:144
xgboost::common::Range::Iterator::operator==
XGBOOST_DEVICE bool operator==(const Iterator &other) const
Definition: common.h:125
xgboost::common::IndexTransformIter::operator!=
bool operator!=(IndexTransformIter const &that) const
Definition: common.h:201
dh
Definition: common.h:36
xgboost::common::Max
XGBOOST_DEVICE T Max(T a, T b)
Definition: common.h:73
xgboost::common::IndexTransformIter::operator-
IndexTransformIter operator-(difference_type n) const
Definition: common.h:224
xgboost::common::IndexTransformIter::IndexTransformIter
IndexTransformIter(Fn &&op)
Definition: common.h:189
xgboost::common::Range::operator==
XGBOOST_DEVICE bool operator==(const Range &other) const
Definition: common.h:153
xgboost::common::Range::Iterator::Iterator
XGBOOST_DEVICE Iterator(DifferenceType start)
Definition: common.h:135
xgboost::common::Range::Iterator::operator*
XGBOOST_DEVICE DifferenceType operator*() const
Definition: common.h:114
xgboost::common::IndexTransformIter::value_type
std::result_of_t< Fn(size_t)> value_type
Definition: common.h:180
xgboost::common::IndexTransformIter::operator*
value_type operator*() const
Definition: common.h:197
XGBOOST_PARALLEL_STABLE_SORT
#define XGBOOST_PARALLEL_STABLE_SORT(X, Y, Z)
Definition: base.h:69
base.h
defines configuration macros of xgboost.
xgboost::common::Range::Iterator::operator++
XGBOOST_DEVICE Iterator operator++(int)
Definition: common.h:119
xgboost::common::Range::Iterator::operator++
const XGBOOST_DEVICE Iterator & operator++()
Definition: common.h:115
xgboost::common::IndexTransformIter::operator-=
IndexTransformIter & operator-=(difference_type n)
Definition: common.h:216
xgboost::common::MakeIndexTransformIter
auto MakeIndexTransformIter(Fn &&fn)
Definition: common.h:231
xgboost::common::Span::empty
constexpr XGBOOST_DEVICE bool empty() const __span_noexcept
Definition: span.h:560
xgboost::common::IndexTransformIter::operator+
IndexTransformIter operator+(difference_type n) const
Definition: common.h:220
xgboost::common::Range::end
XGBOOST_DEVICE Iterator end() const
Definition: common.h:145
span.h
xgboost::common::Range::DifferenceType
int64_t DifferenceType
Definition: common.h:108
xgboost::common::Range::Iterator::Step
XGBOOST_DEVICE void Step(DifferenceType s)
Definition: common.h:132
xgboost::common::IndexTransformIter::operator++
IndexTransformIter operator++(int)
Definition: common.h:207
xgboost::common::AssertGPUSupport
void AssertGPUSupport()
Definition: common.h:237
xgboost::common::IndexTransformIter::operator=
IndexTransformIter & operator=(IndexTransformIter const &that)
Definition: common.h:192
xgboost::common::ArgSort
std::vector< Idx > ArgSort(Container const &array, Comp comp=std::less< V >{})
Definition: common.h:252
xgboost::common::Range::Range
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end)
Definition: common.h:147
xgboost::common::IndexTransformIter::operator==
bool operator==(IndexTransformIter const &that) const
Definition: common.h:200
xgboost::common::Range
Definition: common.h:106
xgboost::common::Range::Range
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end, DifferenceType step)
Definition: common.h:149
xgboost::common::DivRoundUp
XGBOOST_DEVICE T1 DivRoundUp(const T1 a, const T2 b)
Definition: common.h:86
xgboost::common::ToString
std::string ToString(const T &data)
Definition: common.h:79
xgboost::common::IndexTransformIter::difference_type
detail::ptrdiff_t difference_type
Definition: common.h:181
xgboost::common::IndexTransformIter::operator++
IndexTransformIter & operator++()
Definition: common.h:203
xgboost::common::IndexTransformIter::pointer
std::add_pointer_t< value_type > pointer
Definition: common.h:183
xgboost::common::AllVisibleGPUs
int AllVisibleGPUs()
xgboost::common::Range::operator!=
XGBOOST_DEVICE bool operator!=(const Range &other) const
Definition: common.h:156
xgboost::common::OptionalWeights::OptionalWeights
OptionalWeights(float w)
Definition: common.h:265
xgboost::common::OptionalWeights
Definition: common.h:260
xgboost::common::IndexTransformIter::reference
std::add_lvalue_reference_t< value_type > reference
Definition: common.h:182
xgboost::common::OptionalWeights::OptionalWeights
OptionalWeights(Span< float const > w)
Definition: common.h:264
xgboost::common::Span
span class implementation, based on ISO++20 span<T>. The interface should be the same.
Definition: span.h:148
xgboost::common::IndexTransformIter::operator-
auto operator-(IndexTransformIter const &that) const
Definition: common.h:199
xgboost::common::Range::Iterator::Iterator
XGBOOST_DEVICE Iterator(DifferenceType start, DifferenceType step)
Definition: common.h:136
xgboost::common::IndexTransformIter::iterator_category
std::random_access_iterator_tag iterator_category
Definition: common.h:179
xgboost::common::Range::Iterator::operator!=
XGBOOST_DEVICE bool operator!=(const Iterator &other) const
Definition: common.h:128
xgboost::common::Range::Step
XGBOOST_DEVICE void Step(DifferenceType s)
Definition: common.h:160
xgboost::common::Range::Iterator
Definition: common.h:110
xgboost::common::AssertOneAPISupport
void AssertOneAPISupport()
Definition: common.h:243
xgboost::common::detail::UnpackArr
constexpr auto UnpackArr(std::array< T, N > &&arr, std::index_sequence< Idx... >)
Definition: common.h:92
xgboost::common::OptionalWeights::dft
float dft
Definition: common.h:262
XGBOOST_DEVICE
#define XGBOOST_DEVICE
Tag function as usable by device.
Definition: base.h:84
xgboost::common::OptionalWeights::weights
Span< float const > weights
Definition: common.h:261
xgboost::common::OptionalWeights::operator[]
XGBOOST_DEVICE float operator[](size_t i) const
Definition: common.h:267
xgboost
namespace of xgboost
Definition: base.h:110
xgboost::common::Split
std::vector< std::string > Split(const std::string &s, char delim)
Split a string by delimiter.
Definition: common.h:62