DPC++ Runtime
Runtime libraries for oneAPI DPC++
config.cpp
Go to the documentation of this file.
1 //==---------------- config.cpp ---------------------------------*- 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 
12 #include <detail/config.hpp>
13 
14 #include <cstring>
15 #include <fstream>
16 #include <iostream>
17 #include <limits>
18 
20 namespace sycl {
21 namespace detail {
22 
23 #ifndef SYCL_CONFIG_FILE_NAME
24 #define SYCL_CONFIG_FILE_NAME "sycl.conf"
25 #endif // SYCL_CONFIG_FILE_NAME
26 
27 #define CONFIG(Name, MaxSize, CompileTimeDef) \
28  const char *SYCLConfigBase<Name>::MValueFromFile = nullptr; \
29  char SYCLConfigBase<Name>::MStorage[MaxSize + 1]; \
30  const char *const SYCLConfigBase<Name>::MCompileTimeDef = \
31  getStrOrNullptr(__SYCL_STRINGIFY(CompileTimeDef)); \
32  const char *const SYCLConfigBase<Name>::MConfigName = __SYCL_STRINGIFY(Name);
33 #include "detail/config.def"
34 #undef CONFIG
35 
36 static void initValue(const char *Key, const char *Value) {
37 #define CONFIG(Name, MaxSize, CompileTimeDef) \
38  if (0 == strncmp(Key, SYCLConfigBase<Name>::MConfigName, MAX_CONFIG_NAME)) { \
39  strncpy(SYCLConfigBase<Name>::MStorage, Value, MaxSize); \
40  SYCLConfigBase<Name>::MStorage[MaxSize] = '\0'; \
41  SYCLConfigBase<Name>::MValueFromFile = SYCLConfigBase<Name>::MStorage; \
42  return; \
43  }
44 #include "detail/config.def"
45 #undef CONFIG
46 }
47 
48 void readConfig(bool ForceInitialization) {
49  static bool Initialized = false;
50  if (!ForceInitialization && Initialized) {
51  return;
52  }
53 
54  std::fstream File;
55  if (const char *ConfigFile = getenv("SYCL_CONFIG_FILE_NAME"))
56  File.open(ConfigFile, std::ios::in);
57  else {
58  const std::string LibSYCLDir = sycl::detail::OSUtil::getCurrentDSODir();
59  File.open(LibSYCLDir + sycl::detail::OSUtil::DirSep + SYCL_CONFIG_FILE_NAME,
60  std::ios::in);
61  }
62 
63  if (File.is_open()) {
64  char Key[MAX_CONFIG_NAME] = {0}, Value[MAX_CONFIG_VALUE] = {0};
65  std::string BufString;
66  std::size_t Position = std::string::npos;
67  while (!File.eof()) {
68  // Expected format:
69  // ConfigName=Value\r
70  // ConfigName=Value #comment
71  // ConfigName=Value
72  // TODO: Skip spaces before and after '='
73  std::getline(File, BufString);
74  if (File.fail() && !File.eof()) {
75  // Fail to process the line.
76  File.clear(File.rdstate() & ~std::ios_base::failbit);
77  File.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
78  throw sycl::exception(
79  make_error_code(errc::runtime),
80  "An error occurred while attempting to read a line");
81  }
82  // Handle '\r'
83  if ((BufString.length() > 0) &&
84  (BufString[BufString.length() - 1] == '\r')) {
85  BufString.pop_back();
86  }
87  // Handle comments
88  if (BufString.find("#") != std::string::npos) {
89  BufString.erase(BufString.find("#"));
90  while ((BufString.length() > 0) &&
91  (BufString[BufString.length() - 1] == ' ')) {
92  BufString.pop_back();
93  }
94  }
95  // Skip lines with a length = 0 or which don't have "="
96  if ((BufString.length() == 0) ||
97  (BufString.find("=") == std::string::npos)) {
98  continue;
99  }
100  // Finding the position of '='
101  Position = BufString.find("=");
102  // Checking that the variable name is less than MAX_CONFIG_NAME and more
103  // than zero character
104  if ((Position <= MAX_CONFIG_NAME) && (Position > 0)) {
105  // Checking that the value is less than MAX_CONFIG_VALUE and
106  // more than zero character
107  if ((BufString.length() - (Position + 1) <= MAX_CONFIG_VALUE) &&
108  (BufString.length() != Position + 1)) {
109  // Checking for spaces at the beginning and end of the line,
110  // before and after '='
111  if ((BufString[0] == ' ') ||
112  (BufString[BufString.length() - 1] == ' ') ||
113  (BufString[Position - 1] == ' ') ||
114  (BufString[Position + 1] == ' ')) {
115  throw sycl::exception(
116  make_error_code(errc::runtime),
117  "SPACE found at the beginning/end of the line "
118  "or before/after '='");
119  }
120  // Creating pairs of (key, value)
121  BufString.copy(Key, Position, 0);
122  Key[Position] = '\0';
123  BufString.copy(Value, BufString.length() - (Position + 1),
124  Position + 1);
125  Value[BufString.length() - (Position + 1)] = '\0';
126  } else {
127  throw sycl::exception(
128  make_error_code(errc::runtime),
129  "The value contains more than " +
130  std::to_string(MAX_CONFIG_VALUE) +
131  " characters or does not contain them at all");
132  }
133  } else {
134  throw sycl::exception(make_error_code(errc::runtime),
135  "Variable name is more than " +
136  std::to_string(MAX_CONFIG_NAME) +
137  " or less than one character");
138  }
139 
140  initValue(Key, Value);
141  }
142  File.close();
143  }
144  Initialized = true;
145 }
146 
147 // Prints configs name with their value
148 void dumpConfig() {
149 #define CONFIG(Name, MaxSize, CompileTimeDef) \
150  { \
151  const char *Val = SYCLConfigBase<Name>::getRawValue(); \
152  std::cerr << SYCLConfigBase<Name>::MConfigName << " : " \
153  << (Val ? Val : "unset") << std::endl; \
154  }
155 #include "detail/config.def"
156 #undef CONFIG
157 }
158 
159 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
160 const std::array<std::pair<std::string, info::device_type>, 5> &
162  static const std::array<std::pair<std::string, info::device_type>, 5>
163  SyclDeviceTypeMap = {{{"host", info::device_type::host},
164  {"cpu", info::device_type::cpu},
165  {"gpu", info::device_type::gpu},
166  {"acc", info::device_type::accelerator},
167  {"*", info::device_type::all}}};
168  return SyclDeviceTypeMap;
169 }
170 
171 // Array is used by SYCL_DEVICE_FILTER and SYCL_DEVICE_ALLOWLIST
172 const std::array<std::pair<std::string, backend>, 7> &getSyclBeMap() {
173  static const std::array<std::pair<std::string, backend>, 7> SyclBeMap = {
174  {{"host", backend::host},
175  {"opencl", backend::opencl},
176  {"level_zero", backend::ext_oneapi_level_zero},
177  {"cuda", backend::ext_oneapi_cuda},
178  {"hip", backend::ext_oneapi_hip},
179  {"esimd_emulator", backend::ext_intel_esimd_emulator},
180  {"*", backend::all}}};
181  return SyclBeMap;
182 }
183 
184 } // namespace detail
185 } // namespace sycl
186 } // __SYCL_INLINE_NAMESPACE(cl)
cl::sycl::detail::MAX_CONFIG_VALUE
constexpr int MAX_CONFIG_VALUE
Definition: config.hpp:48
cl::sycl::detail::MAX_CONFIG_NAME
constexpr int MAX_CONFIG_NAME
Definition: config.hpp:47
defines_elementary.hpp
config.hpp
SYCL_CONFIG_FILE_NAME
#define SYCL_CONFIG_FILE_NAME
Definition: config.cpp:24
os_util.hpp
cl::sycl::make_error_code
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:121
sycl
Definition: invoke_simd.hpp:68
max
simd< _Tp, _Abi > max(const simd< _Tp, _Abi > &, const simd< _Tp, _Abi > &) noexcept
cl::sycl::detail::dumpConfig
void dumpConfig()
Definition: config.cpp:148
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
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::detail::getSyclDeviceTypeMap
const std::array< std::pair< std::string, info::device_type >, 5 > & getSyclDeviceTypeMap()
Definition: config.cpp:161
cl::sycl::detail::initValue
static void initValue(const char *Key, const char *Value)
Definition: config.cpp:36
cl::sycl::all
detail::enable_if_t< detail::is_sigeninteger< T >::value, int > all(T x) __NOEXC
Definition: builtins.hpp:1297
common.hpp
cl::sycl::exception
Definition: exception.hpp:63
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12