DPC++ Runtime
Runtime libraries for oneAPI DPC++
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 = 1024;
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_RT_WARNING_LEVEL> {
188 
189 public:
190  static unsigned int get() { return getCachedValue(); }
191 
192  static void reset() { (void)getCachedValue(true); }
193 
194 private:
195  static unsigned int getCachedValue(bool ResetCache = false) {
196  const auto Parser = []() {
197  const char *ValStr = BaseT::getRawValue();
198  int SignedLevel = ValStr ? std::atoi(ValStr) : 0;
199  return SignedLevel >= 0 ? SignedLevel : 0;
200  };
201 
202  static unsigned int Level = Parser();
203  if (ResetCache)
204  Level = Parser();
205 
206  return Level;
207  }
208 };
209 
210 template <> class SYCLConfig<SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE> {
212 
213 public:
214  static bool get() {
215  static const char *ValStr = BaseT::getRawValue();
216  return ValStr != nullptr;
217  }
218 };
219 
220 template <> class SYCLConfig<SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING> {
222 
223 public:
224  static bool get() {
225  static const char *ValStr = BaseT::getRawValue();
226  return ValStr != nullptr;
227  }
228 };
229 
230 template <> class SYCLConfig<SYCL_PARALLEL_FOR_RANGE_ROUNDING_PARAMS> {
232 
233 private:
234 public:
235  static void GetSettings(size_t &MinFactor, size_t &GoodFactor,
236  size_t &MinRange) {
237  static const char *RoundParams = BaseT::getRawValue();
238  if (RoundParams == nullptr)
239  return;
240 
241  static bool ProcessedFactors = false;
242  static size_t MF;
243  static size_t GF;
244  static size_t MR;
245  if (!ProcessedFactors) {
246  // Parse optional parameters of this form (all values required):
247  // MinRound:PreferredRound:MinRange
248  std::string Params(RoundParams);
249  size_t Pos = Params.find(':');
250  if (Pos != std::string::npos) {
251  MF = std::stoi(Params.substr(0, Pos));
252  Params.erase(0, Pos + 1);
253  Pos = Params.find(':');
254  if (Pos != std::string::npos) {
255  GF = std::stoi(Params.substr(0, Pos));
256  Params.erase(0, Pos + 1);
257  MR = std::stoi(Params);
258  }
259  }
260  ProcessedFactors = true;
261  }
262  MinFactor = MF;
263  GoodFactor = GF;
264  MinRange = MR;
265  }
266 };
267 
268 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
269 const std::array<std::pair<std::string, info::device_type>, 5> &
271 
272 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
273 const std::array<std::pair<std::string, backend>, 7> &getSyclBeMap();
274 
275 template <> class SYCLConfig<SYCL_DEVICE_FILTER> {
277 
278 public:
280  static bool Initialized = false;
281  static device_filter_list *FilterList = nullptr;
282 
283  // Configuration parameters are processed only once, like reading a string
284  // from environment and converting it into a typed object.
285  if (Initialized) {
286  return FilterList;
287  }
288 
289  const char *ValStr = BaseT::getRawValue();
290  if (ValStr) {
291  FilterList = &GlobalHandler::instance().getDeviceFilterList(ValStr);
292  }
293 
294  // TODO: remove the following code when we remove the support for legacy
295  // env vars.
296  // Emit the deprecation warning message if SYCL_BE or SYCL_DEVICE_TYPE is
297  // set.
298  if (SYCLConfig<SYCL_BE>::get() || getenv("SYCL_DEVICE_TYPE")) {
299  std::cerr << "\nWARNING: The legacy environment variables SYCL_BE and "
300  "SYCL_DEVICE_TYPE are deprecated. Please use "
301  "SYCL_DEVICE_FILTER instead. For details, please refer to "
302  "https://github.com/intel/llvm/blob/sycl/sycl/doc/"
303  "EnvironmentVariables.md\n\n";
304  }
305 
306  // As mentioned above, configuration parameters are processed only once.
307  // If multiple threads are checking this env var at the same time,
308  // they will end up setting the configration to the same value.
309  // If other threads check after one thread already set configration,
310  // the threads will get the same value as the first thread.
311  Initialized = true;
312  return FilterList;
313  }
314 };
315 
316 template <> class SYCLConfig<SYCL_ENABLE_DEFAULT_CONTEXTS> {
318 
319 public:
320  static bool get() {
321 #ifdef WIN32
322  constexpr bool DefaultValue = false;
323 #else
324  constexpr bool DefaultValue = true;
325 #endif
326 
327  const char *ValStr = getCachedValue();
328 
329  if (!ValStr)
330  return DefaultValue;
331 
332  return ValStr[0] == '1';
333  }
334 
335  static void reset() { (void)getCachedValue(/*ResetCache=*/true); }
336 
337  static const char *getName() { return BaseT::MConfigName; }
338 
339 private:
340  static const char *getCachedValue(bool ResetCache = false) {
341  static const char *ValStr = BaseT::getRawValue();
342  if (ResetCache)
343  ValStr = BaseT::getRawValue();
344  return ValStr;
345  }
346 };
347 
348 template <> class SYCLConfig<SYCL_QUEUE_THREAD_POOL_SIZE> {
350 
351 public:
352  static int get() {
353  static int Value = [] {
354  const char *ValueStr = BaseT::getRawValue();
355 
356  int Result = 1;
357 
358  if (ValueStr)
359  try {
360  Result = std::stoi(ValueStr);
361  } catch (...) {
362  throw invalid_parameter_error(
363  "Invalid value for SYCL_QUEUE_THREAD_POOL_SIZE environment "
364  "variable: value should be a number",
366  }
367 
368  if (Result < 1)
369  throw invalid_parameter_error(
370  "Invalid value for SYCL_QUEUE_THREAD_POOL_SIZE environment "
371  "variable: value should be larger than zero",
373 
374  return Result;
375  }();
376 
377  return Value;
378  }
379 };
380 
381 } // namespace detail
382 } // namespace sycl
383 } // __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:279
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:235
sycl
Definition: invoke_simd.hpp:68
cl::sycl::detail::SYCLConfig< SYCL_RT_WARNING_LEVEL >::reset
static void reset()
Definition: config.hpp:192
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:224
cl::sycl::detail::SYCLConfig< SYCL_QUEUE_THREAD_POOL_SIZE >::get
static int get()
Definition: config.hpp:352
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:320
cl::sycl::detail::SYCLConfig< SYCL_RT_WARNING_LEVEL >::get
static unsigned int get()
Definition: config.hpp:190
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:335
PI_INVALID_VALUE
@ PI_INVALID_VALUE
Definition: pi.h:91
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:214
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:337
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12