Skip to content

Commit 4c26d6c

Browse files
committed
Fix CR comments
1 parent 9a3dcf9 commit 4c26d6c

File tree

3 files changed

+237
-141
lines changed

3 files changed

+237
-141
lines changed

sycl/doc/EnvironmentVariables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ subject to change. Do not rely on these variables in production code.
2323
| `SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP` | Any(\*) | Disable cleanup of finished command nodes at host-device synchronization points. |
2424
| `SYCL_THROW_ON_BLOCK` | Any(\*) | Throw an exception on attempt to wait for a blocked command. |
2525
| `SYCL_DEVICELIB_INHIBIT_NATIVE` | String of device library extensions (separated by a whitespace) | Do not rely on device native support for devicelib extensions listed in this option. |
26-
| `SYCL_DEVICE_ALLOWLIST` | A list of devices and their driver version following the pattern: BackendName:XXX,DeviceType:YYY,DeviceVendorId:0xXYZW,DriverVersion:{{X.Y.Z.W}}. Also may contain PlatformVersion, DeviceName and PlatformName. There is no fixed order of properties in the pattern. | Filter out devices that do not match the pattern specified. BackendName accepts `host`, `opencl`, `level_zero` or `cuda`. DeviceType accepts `host`, `cpu`, `gpu` or `acc`. DeviceVendorId accepts uint32_t in hex form (0xXYZW). DriverVersion, PlatformVersion, DeviceName and PlatformName accept regular expression. Special characters, such as parenthesis, must be escaped. DPC++ runtime will select only those devices which satisfy provided values above and regex. More than one device can be specified using the piping symbol "\|".|
26+
| `SYCL_DEVICE_ALLOWLIST` | A list of devices and their driver version following the pattern: `BackendName:XXX,DeviceType:YYY,DeviceVendorId:0xXYZW,DriverVersion:{{X.Y.Z.W}}`. Also may contain `PlatformVersion`, `DeviceName` and `PlatformName`. There is no fixed order of properties in the pattern. | Filter out devices that do not match the pattern specified. `BackendName` accepts `host`, `opencl`, `level_zero` or `cuda`. `DeviceType` accepts `host`, `cpu`, `gpu` or `acc`. `DeviceVendorId` accepts uint32_t in hex form (`0xXYZW`). `DriverVersion`, `PlatformVersion`, `DeviceName` and `PlatformName` accept regular expression. Special characters, such as parenthesis, must be escaped. DPC++ runtime will select only those devices which satisfy provided values above and regex. More than one device can be specified using the piping symbol "\|".|
2727
| `SYCL_QUEUE_THREAD_POOL_SIZE` | Positive integer | Number of threads in thread pool of queue. |
2828
| `SYCL_DEVICELIB_NO_FALLBACK` | Any(\*) | Disable loading and linking of device library images |
2929
| `SYCL_PI_LEVEL_ZERO_MAX_COMMAND_LIST_CACHE` | Positive integer | Maximum number of oneAPI Level Zero Command lists that can be allocated with no reuse before throwing an "out of resources" error. Default is 20000, threshold may be increased based on resource availabilty and workload demand. |

sycl/source/detail/allowlist.cpp

Lines changed: 121 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -65,144 +65,164 @@ AllowListParsedT parseAllowList(const std::string &AllowListRaw) {
6565
size_t KeyStart = 0, KeyEnd = 0, ValueStart = 0, ValueEnd = 0,
6666
DeviceDescIndex = 0;
6767

68-
while ((KeyEnd = AllowListRaw.find(':', KeyStart)) != std::string::npos) {
69-
if ((ValueStart = AllowListRaw.find_first_not_of(":", KeyEnd)) ==
70-
std::string::npos)
68+
const char DelimeterBtwKeyAndValue = ':';
69+
const char DelimeterBtwItemsInDeviceDesc = ',';
70+
const char DelimeterBtwDeviceDescs = '|';
71+
72+
while ((KeyEnd = AllowListRaw.find(DelimeterBtwKeyAndValue, KeyStart)) !=
73+
std::string::npos) {
74+
if ((ValueStart = AllowListRaw.find_first_not_of(
75+
DelimeterBtwKeyAndValue, KeyEnd)) == std::string::npos)
7176
break;
7277
const std::string &Key = AllowListRaw.substr(KeyStart, KeyEnd - KeyStart);
7378

7479
// check that provided key is supported
7580
if (std::find(SupportedAllowListKeyNames.begin(),
7681
SupportedAllowListKeyNames.end(),
7782
Key) == SupportedAllowListKeyNames.end()) {
78-
throw sycl::runtime_error("Unrecognized key in SYCL_DEVICE_ALLOWLIST",
79-
PI_INVALID_VALUE);
83+
throw sycl::runtime_error(
84+
"Unrecognized key in SYCL_DEVICE_ALLOWLIST. For details, please "
85+
"refer to "
86+
"https://github.com/intel/llvm/blob/sycl/sycl/doc/"
87+
"EnvironmentVariables.md",
88+
PI_INVALID_VALUE);
8089
}
8190

8291
bool ShouldAllocateNewDeviceDescMap = false;
8392

84-
ValueEnd = AllowListRaw.find(',', ValueStart);
85-
if (ValueEnd == std::string::npos) {
86-
ValueEnd = AllowListRaw.length();
87-
}
88-
for (const auto &SupportedKeyName : SupportedAllowListKeyNames) {
89-
// check if it is the last Key:Value pair in the device description, and
90-
// correct end position of that value
91-
if (size_t ValueEndCand = AllowListRaw.find(
92-
"|" + std::string(SupportedKeyName), ValueStart);
93-
(ValueEndCand != std::string::npos) && (ValueEndCand < ValueEnd)) {
94-
ValueEnd = ValueEndCand;
95-
ShouldAllocateNewDeviceDescMap = true;
96-
}
97-
}
93+
std::string Value;
9894

9995
auto &DeviceDescMap = AllowListParsed[DeviceDescIndex];
10096

10197
// check if Key is not already defined in DeviceDescMap, e.g., caused by the
10298
// following invalid syntax: Key1:Value1,Key2:Value2,Key1:Value3
10399
if (DeviceDescMap.find(Key) == DeviceDescMap.end()) {
104-
// check that regex values have double curly braces at the beginning and
105-
// at the end
106-
size_t CurlyBracesStartSize = 0, CurlyBracesEndSize = 0;
107-
if (std::find(SupportedKeyNamesRequireRegexValue.begin(),
108-
SupportedKeyNamesRequireRegexValue.end(),
109-
Key) != SupportedKeyNamesRequireRegexValue.end()) {
110-
const std::string &ValueRaw =
111-
AllowListRaw.substr(ValueStart, ValueEnd - ValueStart);
112-
std::string Prefix("{{");
113-
// can be changed to string_view::starts_with after switching DPC++ RT
114-
// to C++20
115-
if (Prefix != ValueRaw.substr(0, Prefix.length())) {
116-
throw sycl::runtime_error("Key " + Key +
117-
" of SYCL_DEVICE_ALLOWLIST should have "
118-
"value which starts with {{",
119-
PI_INVALID_VALUE);
120-
}
121-
std::string Postfix("}}");
122-
// can be changed to string_view::ends_with after switching DPC++ RT to
123-
// C++20
124-
if (Postfix != ValueRaw.substr(ValueRaw.length() - Postfix.length(),
125-
ValueRaw.length())) {
126-
throw sycl::runtime_error("Key " + Key +
127-
" of SYCL_DEVICE_ALLOWLIST should have "
128-
"value which ends with }}",
129-
PI_INVALID_VALUE);
130-
}
131-
CurlyBracesStartSize = Prefix.length();
132-
CurlyBracesEndSize = Postfix.length();
133-
}
134-
// if value has curly braces {{ and }} at the beginning and at the end,
135-
// CurlyBracesStartSize and CurlyBracesEndSize != 0, so we move boundaries
136-
// to remove these braces
137-
const std::string &Value =
138-
AllowListRaw.substr(ValueStart + CurlyBracesStartSize,
139-
(ValueEnd - CurlyBracesEndSize) -
140-
(ValueStart + CurlyBracesStartSize));
141-
// check that values of keys, which should have some fixed format, are
142-
// valid. E.g., for BackendName key, the allowed values are only ones
143-
// described in SyclBeMap
100+
// calculate and validate value which has fixed format
144101
if (std::find(SupportedKeyNamesHaveFixedValue.begin(),
145102
SupportedKeyNamesHaveFixedValue.end(),
146103
Key) != SupportedKeyNamesHaveFixedValue.end()) {
147-
if (Key == BackendNameKeyName) {
148-
bool ValueForBackendNameIsValid = false;
149-
for (const auto &SyclBe : SyclBeMap) {
150-
if (Value == SyclBe.first) {
151-
ValueForBackendNameIsValid = true;
152-
break;
153-
}
154-
}
155-
if (!ValueForBackendNameIsValid) {
156-
throw sycl::runtime_error(
157-
"Value " + Value + " for key " + Key +
158-
" is not valid in "
159-
"SYCL_DEVICE_ALLOWLIST. For details, please refer to "
160-
"https://github.com/intel/llvm/blob/sycl/sycl/doc/"
161-
"EnvironmentVariables.md",
162-
PI_INVALID_VALUE);
163-
}
104+
ValueEnd = AllowListRaw.find(DelimeterBtwItemsInDeviceDesc, ValueStart);
105+
// check if it is the last Key:Value pair in the device description, and
106+
// correct end position of that value
107+
if (size_t ValueEndCand =
108+
AllowListRaw.find(DelimeterBtwDeviceDescs, ValueStart);
109+
(ValueEndCand != std::string::npos) && (ValueEndCand < ValueEnd)) {
110+
ValueEnd = ValueEndCand;
111+
ShouldAllocateNewDeviceDescMap = true;
164112
}
165-
if (Key == DeviceTypeKeyName) {
166-
bool ValueForDeviceTypeIsValid = false;
167-
for (const auto &SyclDeviceType : SyclDeviceTypeMap) {
168-
if (Value == SyclDeviceType.first) {
169-
ValueForDeviceTypeIsValid = true;
170-
break;
171-
}
172-
}
173-
if (!ValueForDeviceTypeIsValid) {
174-
throw sycl::runtime_error(
175-
"Value " + Value + " for key " + Key +
176-
" is not valid in "
177-
"SYCL_DEVICE_ALLOWLIST. For details, please refer to "
178-
"https://github.com/intel/llvm/blob/sycl/sycl/doc/"
179-
"EnvironmentVariables.md",
180-
PI_INVALID_VALUE);
113+
if (ValueEnd == std::string::npos)
114+
ValueEnd = AllowListRaw.length();
115+
116+
Value = AllowListRaw.substr(ValueStart, ValueEnd - ValueStart);
117+
118+
// post-processing checks for some values
119+
120+
auto ValidateEnumValues = [&](std::string CheckingKeyName,
121+
auto SourceOfSupportedValues) {
122+
if (Key == CheckingKeyName) {
123+
bool ValueIsValid = false;
124+
for (const auto &Item : SourceOfSupportedValues)
125+
if (Value == Item.first) {
126+
ValueIsValid = true;
127+
break;
128+
}
129+
if (!ValueIsValid)
130+
throw sycl::runtime_error(
131+
"Value " + Value + " for key " + Key +
132+
" is not valid in "
133+
"SYCL_DEVICE_ALLOWLIST. For details, please refer to "
134+
"https://github.com/intel/llvm/blob/sycl/sycl/doc/"
135+
"EnvironmentVariables.md",
136+
PI_INVALID_VALUE);
181137
}
182-
}
138+
};
139+
140+
// check that values of keys, which should have some fixed format, are
141+
// valid. E.g., for BackendName key, the allowed values are only ones
142+
// described in SyclBeMap
143+
ValidateEnumValues(BackendNameKeyName, SyclBeMap);
144+
ValidateEnumValues(DeviceTypeKeyName, SyclDeviceTypeMap);
145+
183146
if (Key == DeviceVendorIdKeyName) {
184147
// DeviceVendorId should have hex format
185148
if (!std::regex_match(Value, std::regex("0[xX][0-9a-fA-F]+"))) {
186149
throw sycl::runtime_error(
187150
"Value " + Value + " for key " + Key +
188151
" is not valid in "
189-
"SYCL_DEVICE_ALLOWLIST. It should have hex format. For "
152+
"SYCL_DEVICE_ALLOWLIST. It should have the hex format. For "
190153
"details, please refer to "
191154
"https://github.com/intel/llvm/blob/sycl/sycl/doc/"
192155
"EnvironmentVariables.md",
193156
PI_INVALID_VALUE);
194157
}
195158
}
196159
}
160+
// calculate and validate value which has regex format
161+
else if (std::find(SupportedKeyNamesRequireRegexValue.begin(),
162+
SupportedKeyNamesRequireRegexValue.end(),
163+
Key) != SupportedKeyNamesRequireRegexValue.end()) {
164+
const std::string Prefix("{{");
165+
// TODO: can be changed to string_view::starts_with after switching
166+
// DPC++ RT to C++20
167+
if (Prefix != AllowListRaw.substr(ValueStart, Prefix.length())) {
168+
throw sycl::runtime_error("Key " + Key +
169+
" of SYCL_DEVICE_ALLOWLIST should have "
170+
"value which starts with " +
171+
Prefix,
172+
PI_INVALID_VALUE);
173+
}
174+
// cut off prefix from the value
175+
ValueStart += Prefix.length();
176+
177+
ValueEnd = ValueStart;
178+
const std::string Postfix("}}");
179+
for (; ValueEnd < AllowListRaw.length() - Postfix.length() + 1;
180+
++ValueEnd) {
181+
if (Postfix == AllowListRaw.substr(ValueEnd, Postfix.length()))
182+
break;
183+
// if it is the last iteration and next 2 symbols are not a postfix,
184+
// throw exception
185+
if (ValueEnd == AllowListRaw.length() - Postfix.length())
186+
throw sycl::runtime_error(
187+
"Key " + Key +
188+
" of SYCL_DEVICE_ALLOWLIST should have "
189+
"value which ends with " +
190+
Postfix,
191+
PI_INVALID_VALUE);
192+
}
193+
size_t NextExpectedDelimeterPos = ValueEnd + Postfix.length();
194+
// if it is not the end of the string, check that symbol next to a
195+
// postfix is a delimeter (, or ;)
196+
if ((AllowListRaw.length() != NextExpectedDelimeterPos) &&
197+
(AllowListRaw[NextExpectedDelimeterPos] !=
198+
DelimeterBtwItemsInDeviceDesc) &&
199+
(AllowListRaw[NextExpectedDelimeterPos] != DelimeterBtwDeviceDescs))
200+
throw sycl::runtime_error(
201+
"Unexpected symbol on position " +
202+
std::to_string(NextExpectedDelimeterPos) + ": " +
203+
AllowListRaw[NextExpectedDelimeterPos] +
204+
". Should be either " + DelimeterBtwItemsInDeviceDesc +
205+
" or " + DelimeterBtwDeviceDescs,
206+
PI_INVALID_VALUE);
207+
208+
if (AllowListRaw[NextExpectedDelimeterPos] == DelimeterBtwDeviceDescs)
209+
ShouldAllocateNewDeviceDescMap = true;
210+
211+
Value = AllowListRaw.substr(ValueStart, ValueEnd - ValueStart);
212+
213+
ValueEnd += Postfix.length();
214+
} else
215+
assert(false &&
216+
"Key should be either in SupportedKeyNamesHaveFixedValue "
217+
"or SupportedKeyNamesRequireRegexValue");
197218

198219
// add key and value to the map
199220
DeviceDescMap.emplace(Key, Value);
200-
} else {
221+
} else
201222
throw sycl::runtime_error("Re-definition of key " + Key +
202223
" is not allowed in "
203224
"SYCL_DEVICE_ALLOWLIST",
204225
PI_INVALID_VALUE);
205-
}
206226

207227
KeyStart = ValueEnd;
208228
if (KeyStart != std::string::npos)
@@ -281,6 +301,7 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
281301
for (const auto &SyclBe : SyclBeMap) {
282302
if (SyclBe.second == Backend) {
283303
DeviceDesc.emplace(BackendNameKeyName, SyclBe.first);
304+
break;
284305
}
285306
}
286307
// get PlatformVersion value and put it to DeviceDesc
@@ -297,7 +318,6 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
297318

298319
int InsertIDx = 0;
299320
for (RT::PiDevice Device : PiDevices) {
300-
bool IsInserted = false;
301321
// get DeviceType value and put it to DeviceDesc
302322
RT::PiDeviceType PiDevType;
303323
Plugin.call<PiApiKind::piDeviceGetInfo>(Device, PI_DEVICE_INFO_TYPE,
@@ -307,10 +327,7 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
307327
for (const auto &SyclDeviceType : SyclDeviceTypeMap) {
308328
if (SyclDeviceType.second == DeviceType) {
309329
const auto &DeviceTypeValue = SyclDeviceType.first;
310-
std::tie(std::ignore, IsInserted) =
311-
DeviceDesc.emplace(DeviceTypeKeyName, DeviceTypeValue);
312-
if (!IsInserted)
313-
DeviceDesc.at(DeviceTypeKeyName) = DeviceTypeValue;
330+
DeviceDesc[DeviceTypeKeyName] = DeviceTypeValue;
314331
break;
315332
}
316333
}
@@ -321,25 +338,16 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
321338
std::stringstream DeviceVendorIdHexStringStream;
322339
DeviceVendorIdHexStringStream << "0x" << std::hex << DeviceVendorIdUInt;
323340
const auto &DeviceVendorIdValue = DeviceVendorIdHexStringStream.str();
324-
std::tie(std::ignore, IsInserted) = DeviceDesc.emplace(
325-
DeviceVendorIdKeyName, DeviceVendorIdHexStringStream.str());
326-
if (!IsInserted)
327-
DeviceDesc.at(DeviceVendorIdKeyName) = DeviceVendorIdValue;
341+
DeviceDesc[DeviceVendorIdKeyName] = DeviceVendorIdValue;
328342
// get DriverVersion value and put it to DeviceDesc
329343
const auto &DriverVersionValue = sycl::detail::get_device_info<
330344
std::string, info::device::driver_version>::get(Device, Plugin);
331-
std::tie(std::ignore, IsInserted) =
332-
DeviceDesc.emplace(DriverVersionKeyName, DriverVersionValue);
333-
if (!IsInserted)
334-
DeviceDesc.at(DriverVersionKeyName) = DriverVersionValue;
345+
DeviceDesc[DriverVersionKeyName] = DriverVersionValue;
335346
// get DeviceName value and put it to DeviceDesc
336347
const auto &DeviceNameValue =
337348
sycl::detail::get_device_info<std::string, info::device::name>::get(
338349
Device, Plugin);
339-
std::tie(std::ignore, IsInserted) =
340-
DeviceDesc.emplace(DeviceNameKeyName, DeviceNameValue);
341-
if (!IsInserted)
342-
DeviceDesc.at(DeviceNameKeyName) = DeviceNameValue;
350+
DeviceDesc[DeviceNameKeyName] = DeviceNameValue;
343351

344352
// check if we can allow device with such device description DeviceDesc
345353
if (deviceIsAllowed(DeviceDesc, AllowListParsed)) {

0 commit comments

Comments
 (0)