@@ -65,144 +65,164 @@ AllowListParsedT parseAllowList(const std::string &AllowListRaw) {
65
65
size_t KeyStart = 0 , KeyEnd = 0 , ValueStart = 0 , ValueEnd = 0 ,
66
66
DeviceDescIndex = 0 ;
67
67
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)
71
76
break ;
72
77
const std::string &Key = AllowListRaw.substr (KeyStart, KeyEnd - KeyStart);
73
78
74
79
// check that provided key is supported
75
80
if (std::find (SupportedAllowListKeyNames.begin (),
76
81
SupportedAllowListKeyNames.end (),
77
82
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);
80
89
}
81
90
82
91
bool ShouldAllocateNewDeviceDescMap = false ;
83
92
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;
98
94
99
95
auto &DeviceDescMap = AllowListParsed[DeviceDescIndex];
100
96
101
97
// check if Key is not already defined in DeviceDescMap, e.g., caused by the
102
98
// following invalid syntax: Key1:Value1,Key2:Value2,Key1:Value3
103
99
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
144
101
if (std::find (SupportedKeyNamesHaveFixedValue.begin (),
145
102
SupportedKeyNamesHaveFixedValue.end (),
146
103
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 ;
164
112
}
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);
181
137
}
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
+
183
146
if (Key == DeviceVendorIdKeyName) {
184
147
// DeviceVendorId should have hex format
185
148
if (!std::regex_match (Value, std::regex (" 0[xX][0-9a-fA-F]+" ))) {
186
149
throw sycl::runtime_error (
187
150
" Value " + Value + " for key " + Key +
188
151
" 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 "
190
153
" details, please refer to "
191
154
" https://github.com/intel/llvm/blob/sycl/sycl/doc/"
192
155
" EnvironmentVariables.md" ,
193
156
PI_INVALID_VALUE);
194
157
}
195
158
}
196
159
}
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" );
197
218
198
219
// add key and value to the map
199
220
DeviceDescMap.emplace (Key, Value);
200
- } else {
221
+ } else
201
222
throw sycl::runtime_error (" Re-definition of key " + Key +
202
223
" is not allowed in "
203
224
" SYCL_DEVICE_ALLOWLIST" ,
204
225
PI_INVALID_VALUE);
205
- }
206
226
207
227
KeyStart = ValueEnd;
208
228
if (KeyStart != std::string::npos)
@@ -281,6 +301,7 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
281
301
for (const auto &SyclBe : SyclBeMap) {
282
302
if (SyclBe.second == Backend) {
283
303
DeviceDesc.emplace (BackendNameKeyName, SyclBe.first );
304
+ break ;
284
305
}
285
306
}
286
307
// get PlatformVersion value and put it to DeviceDesc
@@ -297,7 +318,6 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
297
318
298
319
int InsertIDx = 0 ;
299
320
for (RT::PiDevice Device : PiDevices) {
300
- bool IsInserted = false ;
301
321
// get DeviceType value and put it to DeviceDesc
302
322
RT::PiDeviceType PiDevType;
303
323
Plugin.call <PiApiKind::piDeviceGetInfo>(Device, PI_DEVICE_INFO_TYPE,
@@ -307,10 +327,7 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
307
327
for (const auto &SyclDeviceType : SyclDeviceTypeMap) {
308
328
if (SyclDeviceType.second == DeviceType) {
309
329
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;
314
331
break ;
315
332
}
316
333
}
@@ -321,25 +338,16 @@ void applyAllowList(std::vector<RT::PiDevice> &PiDevices,
321
338
std::stringstream DeviceVendorIdHexStringStream;
322
339
DeviceVendorIdHexStringStream << " 0x" << std::hex << DeviceVendorIdUInt;
323
340
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;
328
342
// get DriverVersion value and put it to DeviceDesc
329
343
const auto &DriverVersionValue = sycl::detail::get_device_info<
330
344
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;
335
346
// get DeviceName value and put it to DeviceDesc
336
347
const auto &DeviceNameValue =
337
348
sycl::detail::get_device_info<std::string, info::device::name>::get (
338
349
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;
343
351
344
352
// check if we can allow device with such device description DeviceDesc
345
353
if (deviceIsAllowed (DeviceDesc, AllowListParsed)) {
0 commit comments