DPC++ Runtime
Runtime libraries for oneAPI Data Parallel C++
config.hpp
Go to the documentation of this file.
1 //==---------------- config.hpp - SYCL config -------------------*- C++-*---==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
14 #include <CL/sycl/detail/pi.hpp>
17 
18 #include <algorithm>
19 #include <array>
20 #include <cstdlib>
21 #include <mutex>
22 #include <string>
23 #include <utility>
24 
26 namespace sycl {
27 namespace detail {
28 
29 #ifdef DISABLE_CONFIG_FROM_ENV
30 constexpr bool ConfigFromEnvEnabled = false;
31 #else
32 constexpr bool ConfigFromEnvEnabled = true;
33 #endif // DISABLE_CONFIG_FROM_ENV
34 
35 #ifdef DISABLE_CONFIG_FROM_CONFIG_FILE
36 constexpr bool ConfigFromFileEnabled = false;
37 #else
38 constexpr bool ConfigFromFileEnabled = true;
39 #endif // DISABLE_CONFIG_FROM_CONFIG_FILE
40 
41 #ifdef DISABLE_CONFIG_FROM_COMPILE_TIME
42 constexpr bool ConfigFromCompileDefEnabled = false;
43 #else
44 constexpr bool ConfigFromCompileDefEnabled = true;
45 #endif // DISABLE_CONFIG_FROM_COMPILE_TIME
46 
47 constexpr int MAX_CONFIG_NAME = 256;
48 constexpr int MAX_CONFIG_VALUE = 256;
49 
50 // Enum of config IDs for accessing other arrays
51 enum ConfigID {
52  START = 0,
53 #define CONFIG(name, ...) name,
54 #include "config.def"
55 #undef CONFIG
57 };
58 
59 // Consider strings starting with __ as unset
60 constexpr const char *getStrOrNullptr(const char *Str) {
61  return (Str[0] == '_' && Str[1] == '_') ? nullptr : Str;
62 }
63 
64 // Intializes configs from the configuration file
65 void readConfig(bool ForceInitialization = false);
66 
67 template <ConfigID Config> class SYCLConfigBase;
68 
69 #define CONFIG(Name, MaxSize, CompileTimeDef) \
70  template <> class SYCLConfigBase<Name> { \
71  public: \
72  /*Preallocated storage for config value which is extracted from a config \
73  * file*/ \
74  static char MStorage[MaxSize + 1]; \
75  /*Points to the storage if config is set in the file, nullptr otherwise*/ \
76  static const char *MValueFromFile; \
77  /*The name of the config*/ \
78  static const char *const MConfigName; \
79  /*Points to the value which is set during compilation, nullptr otherwise. \
80  * Detection of whether a value is set or not is based on checking the \
81  * beginning of the string, if it starts with double underscore(__) the \
82  * value is not set.*/ \
83  static const char *const MCompileTimeDef; \
84  \
85  static const char *getRawValue() { \
86  if (ConfigFromEnvEnabled) \
87  if (const char *ValStr = getenv(MConfigName)) \
88  return ValStr; \
89  \
90  if (ConfigFromFileEnabled) { \
91  readConfig(); \
92  if (MValueFromFile) \
93  return MValueFromFile; \
94  } \
95  \
96  if (ConfigFromCompileDefEnabled && MCompileTimeDef) \
97  return MCompileTimeDef; \
98  \
99  return nullptr; \
100  } \
101  };
102 #include "config.def"
103 #undef CONFIG
104 
105 template <ConfigID Config> class SYCLConfig {
107 
108 public:
109  static const char *get() { return getCachedValue(); }
110 
111  static void reset() { (void)getCachedValue(/*ResetCache=*/true); }
112 
113  static const char *getName() { return BaseT::MConfigName; }
114 
115 private:
116  static const char *getCachedValue(bool ResetCache = false) {
117  static const char *ValStr = BaseT::getRawValue();
118  if (ResetCache)
119  ValStr = BaseT::getRawValue();
120  return ValStr;
121  }
122 };
123 
124 template <> class SYCLConfig<SYCL_BE> {
126 
127 public:
128  static backend *get() {
129  static bool Initialized = false;
130  static backend *BackendPtr = nullptr;
131 
132  // Configuration parameters are processed only once, like reading a string
133  // from environment and converting it into a typed object.
134  if (Initialized)
135  return BackendPtr;
136 
137  const char *ValStr = BaseT::getRawValue();
138  const std::array<std::pair<std::string, backend>, 6> SyclBeMap = {
139  {{"PI_OPENCL", backend::opencl},
140  {"PI_LEVEL_ZERO", backend::ext_oneapi_level_zero},
141  {"PI_LEVEL0", backend::ext_oneapi_level_zero}, // for backward
142  // compatibility
143  {"PI_CUDA", backend::ext_oneapi_cuda},
144  {"PI_ESIMD_EMULATOR", backend::ext_intel_esimd_emulator},
145  {"PI_HIP", backend::ext_oneapi_hip}}};
146  if (ValStr) {
147  auto It = std::find_if(
148  std::begin(SyclBeMap), std::end(SyclBeMap),
149  [&ValStr](const std::pair<std::string, backend> &element) {
150  return element.first == ValStr;
151  });
152  if (It == SyclBeMap.end())
153  pi::die("Invalid backend. "
154  "Valid values are "
155  "PI_OPENCL/PI_LEVEL_ZERO/PI_CUDA/PI_ESIMD_EMULATOR/PI_HIP");
156  static backend Backend = It->second;
157  BackendPtr = &Backend;
158  }
159  Initialized = true;
160  return BackendPtr;
161  }
162 };
163 
164 template <> class SYCLConfig<SYCL_PI_TRACE> {
166 
167 public:
168  static int get() {
169  static bool Initialized = false;
170  // We don't use TraceLevel enum here because user can provide any bitmask
171  // which can correspond to several enum values.
172  static int Level = 0; // No tracing by default
173 
174  // Configuration parameters are processed only once, like reading a string
175  // from environment and converting it into a typed object.
176  if (Initialized)
177  return Level;
178 
179  const char *ValStr = BaseT::getRawValue();
180  Level = (ValStr ? std::atoi(ValStr) : 0);
181  Initialized = true;
182  return Level;
183  }
184 };
185 
186 template <> class SYCLConfig<SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE> {
188 
189 public:
190  static bool get() {
191  static const char *ValStr = BaseT::getRawValue();
192  return ValStr != nullptr;
193  }
194 };
195 
196 template <> class SYCLConfig<SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING> {
198 
199 public:
200  static bool get() {
201  static const char *ValStr = BaseT::getRawValue();
202  return ValStr != nullptr;
203  }
204 };
205 
206 template <> class SYCLConfig<SYCL_PARALLEL_FOR_RANGE_ROUNDING_PARAMS> {
208 
209 private:
210 public:
211  static void GetSettings(size_t &MinFactor, size_t &GoodFactor,
212  size_t &MinRange) {
213  static const char *RoundParams = BaseT::getRawValue();
214  if (RoundParams == nullptr)
215  return;
216 
217  static bool ProcessedFactors = false;
218  static size_t MF;
219  static size_t GF;
220  static size_t MR;
221  if (!ProcessedFactors) {
222  // Parse optional parameters of this form (all values required):
223  // MinRound:PreferredRound:MinRange
224  std::string Params(RoundParams);
225  size_t Pos = Params.find(':');
226  if (Pos != std::string::npos) {
227  MF = std::stoi(Params.substr(0, Pos));
228  Params.erase(0, Pos + 1);
229  Pos = Params.find(':');
230  if (Pos != std::string::npos) {
231  GF = std::stoi(Params.substr(0, Pos));
232  Params.erase(0, Pos + 1);
233  MR = std::stoi(Params);
234  }
235  }
236  ProcessedFactors = true;
237  }
238  MinFactor = MF;
239  GoodFactor = GF;
240  MinRange = MR;
241  }
242 };
243 
244 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
245 const std::array<std::pair<std::string, info::device_type>, 5> &
247 
248 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
249 const std::array<std::pair<std::string, backend>, 7> &getSyclBeMap();
250 
251 template <> class SYCLConfig<SYCL_DEVICE_FILTER> {
253 
254 public:
256  static bool Initialized = false;
257  static device_filter_list *FilterList = nullptr;
258 
259  // Configuration parameters are processed only once, like reading a string
260  // from environment and converting it into a typed object.
261  if (Initialized) {
262  return FilterList;
263  }
264 
265  const char *ValStr = BaseT::getRawValue();
266  if (ValStr) {
267  FilterList = &GlobalHandler::instance().getDeviceFilterList(ValStr);
268  }
269 
270  // TODO: remove the following code when we remove the support for legacy
271  // env vars.
272  // Emit the deprecation warning message if SYCL_BE or SYCL_DEVICE_TYPE is
273  // set.
274  if (SYCLConfig<SYCL_BE>::get() || getenv("SYCL_DEVICE_TYPE")) {
275  std::cerr << "\nWARNING: The legacy environment variables SYCL_BE and "
276  "SYCL_DEVICE_TYPE are deprecated. Please use "
277  "SYCL_DEVICE_FILTER instead. For details, please refer to "
278  "https://github.com/intel/llvm/blob/sycl/sycl/doc/"
279  "EnvironmentVariables.md\n\n";
280  }
281 
282  // As mentioned above, configuration parameters are processed only once.
283  // If multiple threads are checking this env var at the same time,
284  // they will end up setting the configration to the same value.
285  // If other threads check after one thread already set configration,
286  // the threads will get the same value as the first thread.
287  Initialized = true;
288  return FilterList;
289  }
290 };
291 
292 template <> class SYCLConfig<SYCL_ENABLE_DEFAULT_CONTEXTS> {
294 
295 public:
296  static bool get() {
297 #ifdef WIN32
298  constexpr bool DefaultValue = false;
299 #else
300  constexpr bool DefaultValue = true;
301 #endif
302 
303  const char *ValStr = getCachedValue();
304 
305  if (!ValStr)
306  return DefaultValue;
307 
308  return ValStr[0] == '1';
309  }
310 
311  static void reset() { (void)getCachedValue(/*ResetCache=*/true); }
312 
313  static const char *getName() { return BaseT::MConfigName; }
314 
315 private:
316  static const char *getCachedValue(bool ResetCache = false) {
317  static const char *ValStr = BaseT::getRawValue();
318  if (ResetCache)
319  ValStr = BaseT::getRawValue();
320  return ValStr;
321  }
322 };
323 
324 template <> class SYCLConfig<SYCL_QUEUE_THREAD_POOL_SIZE> {
326 
327 public:
328  static int get() {
329  static int Value = [] {
330  const char *ValueStr = BaseT::getRawValue();
331 
332  int Result = 1;
333 
334  if (ValueStr)
335  try {
336  Result = std::stoi(ValueStr);
337  } catch (...) {
338  throw invalid_parameter_error(
339  "Invalid value for SYCL_QUEUE_THREAD_POOL_SIZE environment "
340  "variable: value should be a number",
342  }
343 
344  if (Result < 1)
345  throw invalid_parameter_error(
346  "Invalid value for SYCL_QUEUE_THREAD_POOL_SIZE environment "
347  "variable: value should be larger than zero",
349 
350  return Result;
351  }();
352 
353  return Value;
354  }
355 };
356 
357 } // namespace detail
358 } // namespace sycl
359 } // __SYCL_INLINE_NAMESPACE(cl)
cl::sycl::detail::MAX_CONFIG_VALUE
constexpr int MAX_CONFIG_VALUE
Definition: config.hpp:48
cl::sycl::backend
backend
Definition: backend_types.hpp:21
cl::sycl::detail::MAX_CONFIG_NAME
constexpr int MAX_CONFIG_NAME
Definition: config.hpp:47
cl::sycl::detail::SYCLConfig::get
static const char * get()
Definition: config.hpp:109
cl::sycl::detail::SYCLConfig< SYCL_BE >::get
static backend * get()
Definition: config.hpp:128
device_filter.hpp
cl::sycl::detail::START
@ START
Definition: config.hpp:52
cl::sycl::detail::SYCLConfig
Definition: config.hpp:105
cl::sycl::detail::getStrOrNullptr
constexpr const char * getStrOrNullptr(const char *Str)
Definition: config.hpp:60
cl::sycl::detail::SYCLConfig< SYCL_DEVICE_FILTER >::get
static device_filter_list * get()
Definition: config.hpp:255
cl::sycl::detail::SYCLConfig< SYCL_PARALLEL_FOR_RANGE_ROUNDING_PARAMS >::GetSettings
static void GetSettings(size_t &MinFactor, size_t &GoodFactor, size_t &MinRange)
Definition: config.hpp:211
cl::sycl::detail::SYCLConfig::getName
static const char * getName()
Definition: config.hpp:113
pi.hpp
cl::sycl::detail::SYCLConfig< SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING >::get
static bool get()
Definition: config.hpp:200
cl::sycl::detail::SYCLConfig< SYCL_QUEUE_THREAD_POOL_SIZE >::get
static int get()
Definition: config.hpp:328
cl::sycl::detail::SYCLConfigBase
Definition: config.hpp:67
cl::sycl::detail::getSyclBeMap
const std::array< std::pair< std::string, backend >, 7 > & getSyclBeMap()
Definition: config.cpp:172
cl::sycl::detail::readConfig
void readConfig(bool ForceInitialization)
Definition: config.cpp:48
cl::sycl::detail::ConfigID
ConfigID
Definition: config.hpp:51
cl::sycl::detail::pi::die
void die(const char *Message)
Definition: pi.cpp:537
cl::sycl::detail::ConfigFromEnvEnabled
constexpr bool ConfigFromEnvEnabled
Definition: config.hpp:32
cl::sycl::detail::device_filter_list
Definition: device_filter.hpp:37
defines.hpp
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
global_handler.hpp
cl::sycl::detail::getSyclDeviceTypeMap
const std::array< std::pair< std::string, info::device_type >, 5 > & getSyclDeviceTypeMap()
Definition: config.cpp:161
cl::sycl::detail::SYCLConfig< SYCL_ENABLE_DEFAULT_CONTEXTS >::get
static bool get()
Definition: config.hpp:296
cl::sycl::detail::SYCLConfig< SYCL_PI_TRACE >::get
static int get()
Definition: config.hpp:168
cl::sycl::detail::SYCLConfig::reset
static void reset()
Definition: config.hpp:111
cl::sycl::detail::SYCLConfig< SYCL_ENABLE_DEFAULT_CONTEXTS >::reset
static void reset()
Definition: config.hpp:311
PI_INVALID_VALUE
@ PI_INVALID_VALUE
Definition: pi.h:87
backend_types.hpp
cl::sycl::detail::ConfigFromFileEnabled
constexpr bool ConfigFromFileEnabled
Definition: config.hpp:38
cl::sycl::detail::SYCLConfig< SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE >::get
static bool get()
Definition: config.hpp:190
cl::sycl::detail::END
@ END
Definition: config.hpp:56
cl::sycl::detail::ConfigFromCompileDefEnabled
constexpr bool ConfigFromCompileDefEnabled
Definition: config.hpp:44
info_desc.hpp
cl::sycl::detail::SYCLConfig< SYCL_ENABLE_DEFAULT_CONTEXTS >::getName
static const char * getName()
Definition: config.hpp:313
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12