xgboost
context.h
前往此文件文档。
1 
5 #ifndef XGBOOST_CONTEXT_H_
6 #define XGBOOST_CONTEXT_H_
7 
8 #include <xgboost/base.h> // 对于 bst_d_ordinal_t
9 #include <xgboost/logging.h> // 对于 CHECK_GE
10 #include <xgboost/parameter.h> // 对于 XGBoostParameter
11 
12 #include <cstdint> // 对于 int16_t, int32_t, int64_t
13 #include <memory> // 对于 shared_ptr
14 #include <string> // 对于 string, to_string
15 #include <type_traits> // 对于 invoke_result_t, is_same_v, underlying_type_t
16 
17 namespace xgboost {
18 
19 struct CUDAContext;
20 
21 // 符号名称
22 struct DeviceSym {
23  static auto constexpr CPU() { return "cpu"; }
24  static auto constexpr CUDA() { return "cuda"; }
25  static auto constexpr SyclDefault() { return "sycl"; }
26  static auto constexpr SyclCPU() { return "sycl:cpu"; }
27  static auto constexpr SyclGPU() { return "sycl:gpu"; }
28 };
29 
34 struct DeviceOrd {
35  // 代表 CPU 设备 ID 的常量。
36  static bst_d_ordinal_t constexpr CPUOrdinal() { return -1; }
37  static bst_d_ordinal_t constexpr InvalidOrdinal() { return -2; }
38 
39  enum Type : std::int16_t { kCPU = 0, kCUDA = 1,
40  kSyclDefault = 2, kSyclCPU = 3, kSyclGPU = 4} device{kCPU};
41  // CUDA 或 Sycl 设备序号。
43 
44  [[nodiscard]] bool IsCUDA() const { return device == kCUDA; }
45  [[nodiscard]] bool IsCPU() const { return device == kCPU; }
46  [[nodiscard]] bool IsSyclDefault() const { return device == kSyclDefault; }
47  [[nodiscard]] bool IsSyclCPU() const { return device == kSyclCPU; }
48  [[nodiscard]] bool IsSyclGPU() const { return device == kSyclGPU; }
49  [[nodiscard]] bool IsSycl() const { return (IsSyclDefault() ||
50  IsSyclCPU() ||
51  IsSyclGPU()); }
52 
53  constexpr DeviceOrd() = default;
54  constexpr DeviceOrd(Type type, bst_d_ordinal_t ord) : device{type}, ordinal{ord} {}
55 
56  constexpr DeviceOrd(DeviceOrd const& that) = default;
57  constexpr DeviceOrd& operator=(DeviceOrd const& that) = default;
58  constexpr DeviceOrd(DeviceOrd&& that) = default;
59  constexpr DeviceOrd& operator=(DeviceOrd&& that) = default;
60 
64  [[nodiscard]] constexpr static auto CPU() { return DeviceOrd{kCPU, CPUOrdinal()}; }
70  [[nodiscard]] static constexpr auto CUDA(bst_d_ordinal_t ordinal) {
71  return DeviceOrd{kCUDA, ordinal};
72  }
78  [[nodiscard]] constexpr static auto SyclDefault(bst_d_ordinal_t ordinal = -1) {
80  }
86  [[nodiscard]] constexpr static auto SyclCPU(bst_d_ordinal_t ordinal = -1) {
87  return DeviceOrd{kSyclCPU, ordinal};
88  }
89 
95  [[nodiscard]] constexpr static auto SyclGPU(bst_d_ordinal_t ordinal = -1) {
96  return DeviceOrd{kSyclGPU, ordinal};
97  }
98 
99  [[nodiscard]] bool operator==(DeviceOrd const& that) const {
100  return device == that.device && ordinal == that.ordinal;
101  }
102  [[nodiscard]] bool operator!=(DeviceOrd const& that) const { return !(*this == that); }
106  [[nodiscard]] std::string Name() const {
107  switch (device) {
108  case DeviceOrd::kCPU:
109  return DeviceSym::CPU();
110  case DeviceOrd::kCUDA:
111  return DeviceSym::CUDA() + (':' + std::to_string(ordinal));
113  return DeviceSym::SyclDefault() + (':' + std::to_string(ordinal));
114  case DeviceOrd::kSyclCPU:
115  return DeviceSym::SyclCPU() + (':' + std::to_string(ordinal));
116  case DeviceOrd::kSyclGPU:
117  return DeviceSym::SyclGPU() + (':' + std::to_string(ordinal));
118  default: {
119  LOG(FATAL) << "未知设备。";
120  return "";
121  }
122  }
123  }
124 };
125 
126 static_assert(sizeof(DeviceOrd) == sizeof(std::int32_t));
127 
128 std::ostream& operator<<(std::ostream& os, DeviceOrd ord);
129 
133 struct Context : public XGBoostParameter<Context> {
134  private
135  // 用户接口参数,用于设备序号
136  std::string device{DeviceSym::CPU()}; // NOLINT
137  // 用户设置的设备序号
138  DeviceOrd device_{DeviceOrd::CPU()};
139 
140  public
141  static std::int64_t constexpr kDefaultSeed = 0;
142 
143  public
145 
146  void Init(Args const& kwargs);
147 
148  template <typename Container>
149  Args UpdateAllowUnknown(Container const& kwargs) {
151  this->SetDeviceOrdinal(kwargs);
152  return args;
153  }
154 
155  // 如果启用 OpenMP,则使用的线程数。如果等于 0,则使用系统默认值。
156  std::int32_t nthread{0}; // NOLINT
157  // 存储的随机种子
158  std::int64_t seed{kDefaultSeed};
159  // 是否每次迭代都为 PRNG 播种
160  bool seed_per_iteration{false};
161  // 当 gpu_id 无效时失败
163  bool validate_parameters{false};
164 
169  [[nodiscard]] std::int32_t Threads() const;
173  [[nodiscard]] bool IsCPU() const { return Device().IsCPU(); }
177  [[nodiscard]] bool IsCUDA() const { return Device().IsCUDA(); }
181  [[nodiscard]] bool IsSyclDefault() const { return Device().IsSyclDefault(); }
185  [[nodiscard]] bool IsSyclCPU() const { return Device().IsSyclCPU(); }
189  [[nodiscard]] bool IsSyclGPU() const { return Device().IsSyclGPU(); }
193  [[nodiscard]] bool IsSycl() const { return IsSyclDefault()
194  || IsSyclCPU()
195  || IsSyclGPU(); }
196 
200  [[nodiscard]] DeviceOrd Device() const { return device_; }
201 
206  [[nodiscard]] DeviceOrd DeviceFP64() const;
207 
211  [[nodiscard]] bst_d_ordinal_t Ordinal() const { return Device().ordinal; }
215  [[nodiscard]] std::string DeviceName() const { return Device().Name(); }
219  [[nodiscard]] CUDAContext const* CUDACtx() const;
220 
226  [[nodiscard]] Context MakeCUDA(bst_d_ordinal_t ordinal = 0) const {
227  Context ctx = *this;
228  return ctx.SetDevice(DeviceOrd::CUDA(ordinal));
229  }
233  [[nodiscard]] Context MakeCPU() const {
234  Context ctx = *this;
235  return ctx.SetDevice(DeviceOrd::CPU());
236  }
237 
241  template <typename CPUFn, typename CUDAFn>
242  decltype(auto) DispatchDevice(CPUFn&& cpu_fn, CUDAFn&& cuda_fn) const {
243  static_assert(std::is_same_v<std::invoke_result_t<CPUFn>, std::invoke_result_t<CUDAFn>>);
244  switch (this->Device().device) {
245  case DeviceOrd::kCPU:
246  return cpu_fn();
247  case DeviceOrd::kCUDA:
248  return cuda_fn();
249  default:
250  // 不要使用设备名称,因为这很可能是一个内部错误,该名称
251  // 将无效。
252  if (this->Device().IsSycl()) {
253  LOG(WARNING) << "所请求的功能尚无 SYCL 特定的实现。 "
254  << "正在使用 CPU 实现";
255  return cpu_fn();
256  } else {
257  LOG(FATAL) << "未知设备类型:"
258  << static_cast<std::underlying_type_t<DeviceOrd::Type>>(this->Device().device);
259  break;
260  }
261  }
262  return std::invoke_result_t<CPUFn>();
263  }
264 
268  template <typename CPUFn, typename CUDAFn, typename SYCLFn>
269  decltype(auto) DispatchDevice(CPUFn&& cpu_fn, CUDAFn&& cuda_fn, SYCLFn&& sycl_fn) const {
270  static_assert(std::is_same_v<std::invoke_result_t<CPUFn>, std::invoke_result_t<SYCLFn>>);
271  if (this->Device().IsSycl()) {
272  return sycl_fn();
273  } else {
274  return DispatchDevice(cpu_fn, cuda_fn);
275  }
276  }
277 
278  // 声明参数
280  DMLC_DECLARE_FIELD(seed)
281  .set_default(kDefaultSeed)
282  .describe("训练期间的随机数种子。");
283  DMLC_DECLARE_ALIAS(seed, random_state);
284  DMLC_DECLARE_FIELD(seed_per_iteration)
285  .set_default(false)
286  .describe("通过迭代器编号确定性地为 PRNG 播种。");
287  DMLC_DECLARE_FIELD(device).set_default(DeviceSym::CPU()).describe("设备序号。");
288  DMLC_DECLARE_FIELD(nthread).set_default(0).describe("要使用的线程数。");
289  DMLC_DECLARE_ALIAS(nthread, n_jobs);
290  DMLC_DECLARE_FIELD(fail_on_invalid_gpu_id)
291  .set_default(false)
292  .describe("当 gpu_id 无效时,报错失败。");
293  DMLC_DECLARE_FIELD(validate_parameters)
294  .set_default(false)
295  .describe("启用检查参数是否使用。");
296  }
297 
298  private
299  void SetDeviceOrdinal(Args const& kwargs);
300  Context& SetDevice(DeviceOrd d) {
301  this->device = (this->device_ = d).Name();
302  return *this;
303  }
304 
305  // 可变用于惰性 CUDA 上下文初始化。这避免了在加载时初始化 CUDA。
306  // 使用 shared_ptr 而不是 unique_ptr,因为使用 unique_ptr 很难在尝试隐藏 CUDA 代码时定义 p_impl。
307  // p_impl,同时尝试从主机编译器中隐藏 CUDA 代码。
308  mutable std::shared_ptr<CUDAContext> cuctx_;
309  // CFS CPU 限制的缓存值。(在容器化环境中使用)
310  std::int32_t cfs_cpu_count_; // NOLINT
311 };
312 } // namespace xgboost
313 
314 #endif // XGBOOST_CONTEXT_H_
为 xgboost 定义配置宏和基本类型。
集成目标、gbm和评估的学习器接口。这是用户面临的XGB...
Definition: base.h:97
std::vector< std::pair< std::string, std::string > > Args
定义: base.h:324
std::ostream & operator<<(std::ostream &os, DeviceOrd ord)
std::int16_t bst_d_ordinal_t
CUDA 设备的序号。
定义: base.h:139
使用 C++11 枚举类作为 DMLC 参数的宏
XGBoost的运行时上下文。包含线程和设备等信息。
Definition: context.h:133
decltype(auto) DispatchDevice(CPUFn &&cpu_fn, CUDAFn &&cuda_fn) const
根据当前设备调用函数。
定义: context.h:242
bool fail_on_invalid_gpu_id
定义: context.h:162
DeviceOrd Device() const
获取当前设备和序号。
定义: context.h:200
bool IsSycl() const
XGBoost 是否在任何 SYCL 设备上运行?
定义: context.h:193
std::string DeviceName() const
当前设备的名称。
定义: context.h:215
DeviceOrd DeviceFP64() const
获取当前设备和序号,如果它支持 fp64,否则返回默认 CPU。
bool seed_per_iteration
定义: context.h:160
std::int32_t Threads() const
根据 nthread 参数和系统设置返回自动选择的线程数...
bool validate_parameters
定义: context.h:163
std::int64_t seed
定义: context.h:158
Context MakeCUDA(bst_d_ordinal_t ordinal=0) const
基于当前上下文创建一个 CUDA 上下文。
定义: context.h:226
bool IsCPU() const
XGBoost 是否在 CPU 上运行?
定义: context.h:173
CUDAContext const * CUDACtx() const
获取用于分配器和流的 CUDA 设备上下文。
static constexpr std::int64_t kDefaultSeed
定义: context.h:141
bool IsCUDA() const
XGBoost 是否在 CUDA 设备上运行?
定义: context.h:177
bool IsSyclCPU() const
XGBoost 是否在 SYCL CPU 上运行?
定义: context.h:185
std::int32_t nthread
定义: context.h:156
Context MakeCPU() const
基于当前上下文创建一个 CPU 上下文。
定义: context.h:233
bool IsSyclGPU() const
XGBoost 是否在 SYCL GPU 上运行?
定义: context.h:189
bool IsSyclDefault() const
XGBoost 是否在默认 SYCL 设备上运行?
定义: context.h:181
DMLC_DECLARE_PARAMETER(Context)
定义: context.h:279
bst_d_ordinal_t Ordinal() const
获取 CUDA 设备序号。如果 XGBoost 在 CPU 上运行,则为 -1。
定义: context.h:211
void Init(Args const &kwargs)
Args UpdateAllowUnknown(Container const &kwargs)
定义: context.h:149
设备序号的类型。该类型被打包成32位,以便在查看类型(如lin...)时高效使用
Definition: context.h:34
constexpr static auto SyclGPU(bst_d_ordinal_t ordinal=-1)
SYCL GPU 的构造函数。
定义: context.h:95
bool operator==(DeviceOrd const &that) const
定义: context.h:99
bool IsCUDA() const
定义: context.h:44
bool operator!=(DeviceOrd const &that) const
定义: context.h:102
bool IsSyclCPU() const
定义: context.h:47
std::string Name() const
获取设备和序号的字符串表示形式。
定义: context.h:106
enum xgboost::DeviceOrd::Type kCPU
bool IsSyclDefault() const
定义: context.h:46
constexpr DeviceOrd & operator=(DeviceOrd &&that)=default
constexpr DeviceOrd(DeviceOrd &&that)=default
constexpr DeviceOrd & operator=(DeviceOrd const &that)=default
Type
定义: context.h:39
@ kSyclGPU
定义: context.h:40
@ kSyclDefault
定义: context.h:40
@ kCUDA
定义: context.h:39
@ kSyclCPU
定义: context.h:40
bool IsSyclGPU() const
定义: context.h:48
bool IsCPU() const
定义: context.h:45
static constexpr bst_d_ordinal_t InvalidOrdinal()
定义: context.h:37
static constexpr bst_d_ordinal_t CPUOrdinal()
定义: context.h:36
constexpr DeviceOrd(Type type, bst_d_ordinal_t ord)
定义: context.h:54
constexpr static auto SyclCPU(bst_d_ordinal_t ordinal=-1)
SYCL CPU 的构造函数。
定义: context.h:86
constexpr DeviceOrd()=default
bool IsSycl() const
定义: context.h:49
static constexpr auto CUDA(bst_d_ordinal_t ordinal)
CUDA 设备的构造函数。
定义: context.h:70
constexpr DeviceOrd(DeviceOrd const &that)=default
constexpr static auto CPU()
CPU 的构造函数。
定义: context.h:64
constexpr static auto SyclDefault(bst_d_ordinal_t ordinal=-1)
SYCL 的构造函数。
定义: context.h:78
bst_d_ordinal_t ordinal
定义: context.h:42
定义: context.h:22
static constexpr auto CUDA()
定义: context.h:24
static constexpr auto CPU()
定义: context.h:23
static constexpr auto SyclDefault()
定义: context.h:25
static constexpr auto SyclGPU()
定义: context.h:27
static constexpr auto SyclCPU()
定义: context.h:26
定义: parameter.h:84
Args UpdateAllowUnknown(Container const &kwargs)
定义: parameter.h:90