#ifndef XGBOOST_COMMON_COMMON_H_
#define XGBOOST_COMMON_COMMON_H_
#include <array>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "xgboost/base.h"
#include "xgboost/logging.h"
#if defined(__CUDACC__)
#define WITH_CUDA() true
#else
#define WITH_CUDA() false
#endif
#if defined(XGBOOST_USE_CUDA)
#include <cuda_runtime_api.h>
#endif
namespace dh {
#if defined(XGBOOST_USE_CUDA)
void ThrowOnCudaError(cudaError_t code, const char *file, int line);
#define safe_cuda(ans) ThrowOnCudaError((ans), __FILE__, __LINE__)
#endif }
namespace xgboost::common {
inline std::vector<std::string> Split(const std::string& s, char delim) {
std::string item;
std::istringstream is(s);
std::vector<std::string> ret;
while (std::getline(is, item, delim)) {
ret.push_back(item);
}
return ret;
}
void EscapeU8(std::string const &string, std::string *p_buffer);
inline std::string EscapeU8(std::string const &str) {
std::string buffer;
EscapeU8(str, &buffer);
return buffer;
}
template <typename T>
XGBOOST_DEVICE T Max(T a, T b) {
return a < b ? b : a;
}
template <typename T1, typename T2>
XGBOOST_DEVICE T1 DivRoundUp(const T1 a, const T2 b) {
return static_cast<T1>(std::ceil(static_cast<double>(a) / b));
}
namespace detail {
template <class T, std::size_t N, std::size_t... Idx>
constexpr auto UnpackArr(std::array<T, N> &&arr, std::index_sequence<Idx...>) {
return std::make_tuple(std::forward<std::array<T, N>>(arr)[Idx]...);
}
}
template <class T, std::size_t N>
constexpr auto UnpackArr(std::array<T, N> &&arr) {
return detail::UnpackArr(std::forward<std::array<T, N>>(arr),
std::make_index_sequence<N>{});
}
class Range {
public:
using DifferenceType = int64_t;
class Iterator {
friend class Range;
public:
XGBOOST_DEVICE DifferenceType operator*() const { return i_; }
XGBOOST_DEVICE const Iterator &operator++() {
i_ += step_;
return *this;
}
XGBOOST_DEVICE Iterator operator++(int) {
Iterator res {*this};
i_ += step_;
return res;
}
XGBOOST_DEVICE bool operator==(const Iterator &other) const {
return i_ >= other.i_;
}
XGBOOST_DEVICE bool operator!=(const Iterator &other) const {
return i_ < other.i_;
}
XGBOOST_DEVICE void Step(DifferenceType s) { step_ = s; }
protected:
XGBOOST_DEVICE explicit Iterator(DifferenceType start) : i_(start) {}
XGBOOST_DEVICE explicit Iterator(DifferenceType start, DifferenceType step) :
i_{start}, step_{step} {}
private:
int64_t i_;
DifferenceType step_ = 1;
};
XGBOOST_DEVICE Iterator begin() const { return begin_; } XGBOOST_DEVICE Iterator end() const { return end_; }
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end)
: begin_(begin), end_(end) {}
XGBOOST_DEVICE Range(DifferenceType begin, DifferenceType end,
DifferenceType step)
: begin_(begin, step), end_(end) {}
XGBOOST_DEVICE bool operator==(const Range& other) const {
return *begin_ == *other.begin_ && *end_ == *other.end_;
}
XGBOOST_DEVICE bool operator!=(const Range& other) const {
return !(*this == other);
}
XGBOOST_DEVICE void Step(DifferenceType s) { begin_.Step(s); }
private:
Iterator begin_;
Iterator end_;
};
inline void AssertGPUSupport() {
#ifndef XGBOOST_USE_CUDA
LOG(FATAL) << "XGBoost version not compiled with GPU support.";
#endif }
inline void AssertNCCLSupport() {
#if !defined(XGBOOST_USE_NCCL)
LOG(FATAL) << "XGBoost version not compiled with NCCL support.";
#endif }
inline void AssertSYCLSupport() {
#ifndef XGBOOST_USE_SYCL
LOG(FATAL) << "XGBoost version not compiled with SYCL support.";
#endif }
template <typename Indexable>
XGBOOST_DEVICE size_t LastOf(size_t group, Indexable const &indptr) {
return indptr[group + 1] - 1;
}
std::string HumanMemUnit(std::size_t n_bytes);
} #endif