@@ -109,62 +109,49 @@ class UrOffloadEntry {
109
109
NativeType MNative;
110
110
};
111
111
112
- // / Generic array of UR entries.
113
- template <typename T> class UrArray {
112
+ namespace internal {
113
+ // Content from this namespace shouldn't be used anywhere outside of this file
114
+
115
+ // / "native" data structures used by SYCL RT do not hold the data, but only
116
+ // / point to it. The data itself is embedded into the binary data sections in
117
+ // / real applications.
118
+ // / In unit-tests we mock those data structures and therefore we need to ensure
119
+ // / that the lifetime of the underlying data is correct and we won't perform
120
+ // / any illegal memory accesses in unit-tests.
121
+ template <typename T> class LifetimeExtender {
114
122
public:
115
- explicit UrArray (std::vector<T> Entries) : MMockEntries(std::move(Entries)) {
116
- updateEntries ();
117
- }
118
-
119
- UrArray (std::initializer_list<T> Entries) : MMockEntries( std::move(Entries)) {
120
- updateEntries ( );
123
+ explicit LifetimeExtender (std::vector<T> Entries)
124
+ : MMockEntries(std::move(Entries)) {
125
+ MEntries. clear ();
126
+ std::transform (MMockEntries. begin (), MMockEntries. end (),
127
+ std::back_inserter (MEntries),
128
+ []( const T &Entry) { return Entry. convertToNativeType (); } );
121
129
}
122
130
123
- UrArray () = default ;
124
-
125
- void push_back (const T &Entry) {
126
- MMockEntries.push_back (Entry);
127
- MEntriesNeedUpdate = true ;
128
- }
131
+ LifetimeExtender () = default ;
129
132
130
133
typename T::NativeType *begin () {
131
- if (MEntriesNeedUpdate) {
132
- updateEntries ();
133
- }
134
-
135
134
if (MEntries.empty ())
136
135
return nullptr ;
137
136
138
137
return &*MEntries.begin ();
139
138
}
140
139
typename T::NativeType *end () {
141
- if (MEntriesNeedUpdate) {
142
- updateEntries ();
143
- }
144
-
145
140
if (MEntries.empty ())
146
141
return nullptr ;
147
142
148
143
return &*MEntries.rbegin () + 1 ;
149
144
}
150
145
151
146
private:
152
- void updateEntries () {
153
- MEntries.clear ();
154
- std::transform (MMockEntries.begin (), MMockEntries.end (),
155
- std::back_inserter (MEntries),
156
- [](const T &Entry) { return Entry.convertToNativeType (); });
157
- }
158
147
std::vector<T> MMockEntries;
159
148
std::vector<typename T::NativeType> MEntries;
160
- bool MEntriesNeedUpdate = false ;
161
149
};
162
150
163
151
#ifdef __cpp_deduction_guides
164
- template <typename T> UrArray (std::vector<T>) -> UrArray<T>;
165
-
166
- template <typename T> UrArray (std::initializer_list<T>) -> UrArray<T>;
152
+ template <typename T> LifetimeExtender (std::vector<T>) -> LifetimeExtender<T>;
167
153
#endif // __cpp_deduction_guides
154
+ } // namespace internal
168
155
169
156
// / Convenience wrapper for sycl_device_binary_property_set.
170
157
class UrPropertySet {
@@ -187,19 +174,23 @@ class UrPropertySet {
187
174
// Value must be an all-zero 32-bit mask, which would mean that no fallback
188
175
// libraries are needed to be loaded.
189
176
UrProperty DeviceLibReqMask (" " , Data, SYCL_PROPERTY_TYPE_UINT32);
190
- insert (__SYCL_PROPERTY_SET_DEVICELIB_REQ_MASK, UrArray{DeviceLibReqMask});
177
+ insert (__SYCL_PROPERTY_SET_DEVICELIB_REQ_MASK, std::move (DeviceLibReqMask));
178
+ }
179
+
180
+ // / Adds a new property to the set.
181
+ // /
182
+ // / \param Name is a property name. See ur.hpp for list of known names.
183
+ // / \param Prop is a property value.
184
+ void insert (const std::string &Name, UrProperty &&Props) {
185
+ insert (Name, internal::LifetimeExtender{std::vector{std::move (Props)}});
191
186
}
192
187
193
188
// / Adds a new array of properties to the set.
194
189
// /
195
190
// / \param Name is a property array name. See ur.hpp for list of known names.
196
191
// / \param Props is an array of property values.
197
- void insert (const std::string &Name, UrArray<UrProperty> Props) {
198
- MNames.push_back (Name);
199
- MMockProperties.push_back (std::move (Props));
200
- MProperties.push_back (_sycl_device_binary_property_set_struct{
201
- MNames.back ().data (), MMockProperties.back ().begin (),
202
- MMockProperties.back ().end ()});
192
+ void insert (const std::string &Name, std::vector<UrProperty> &&Props) {
193
+ insert (Name, internal::LifetimeExtender{std::move (Props)});
203
194
}
204
195
205
196
_sycl_device_binary_property_set_struct *begin () {
@@ -215,36 +206,65 @@ class UrPropertySet {
215
206
}
216
207
217
208
private:
209
+ // / Adds a new array of properties to the set.
210
+ // /
211
+ // / \param Name is a property array name. See ur.hpp for list of known names.
212
+ // / \param Props is an array of property values.
213
+ void insert (const std::string &Name,
214
+ internal::LifetimeExtender<UrProperty> Props) {
215
+ MNames.push_back (Name);
216
+ MMockProperties.push_back (std::move (Props));
217
+ MProperties.push_back (_sycl_device_binary_property_set_struct{
218
+ MNames.back ().data (), MMockProperties.back ().begin (),
219
+ MMockProperties.back ().end ()});
220
+ }
221
+
218
222
std::vector<std::string> MNames;
219
- std::vector<UrArray <UrProperty>> MMockProperties;
223
+ std::vector<internal::LifetimeExtender <UrProperty>> MMockProperties;
220
224
std::vector<_sycl_device_binary_property_set_struct> MProperties;
221
225
};
222
226
223
227
// / Convenience wrapper around UR internal structures, that manages UR binary
224
228
// / image data lifecycle.
225
229
class UrImage {
226
- public :
230
+ private :
227
231
// / Constructs an arbitrary device image.
228
232
UrImage (uint16_t Version, uint8_t Kind, uint8_t Format,
229
233
const std::string &DeviceTargetSpec,
230
234
const std::string &CompileOptions, const std::string &LinkOptions,
231
- std::vector<char > Manifest, std::vector<unsigned char > Binary,
232
- UrArray<UrOffloadEntry> OffloadEntries, UrPropertySet PropertySet)
235
+ std::vector<char > &&Manifest, std::vector<unsigned char > &&Binary,
236
+ internal::LifetimeExtender<UrOffloadEntry> OffloadEntries,
237
+ UrPropertySet PropertySet)
233
238
: MVersion(Version), MKind(Kind), MFormat(Format),
234
239
MDeviceTargetSpec (DeviceTargetSpec), MCompileOptions(CompileOptions),
235
240
MLinkOptions(LinkOptions), MManifest(std::move(Manifest)),
236
241
MBinary(std::move(Binary)), MOffloadEntries(std::move(OffloadEntries)),
237
242
MPropertySet(std::move(PropertySet)) {}
238
243
244
+ public:
245
+ // / Constructs an arbitrary device image.
246
+ UrImage (uint16_t Version, uint8_t Kind, uint8_t Format,
247
+ const std::string &DeviceTargetSpec,
248
+ const std::string &CompileOptions, const std::string &LinkOptions,
249
+ std::vector<char > &&Manifest, std::vector<unsigned char > &&Binary,
250
+ std::vector<UrOffloadEntry> &&OffloadEntries,
251
+ UrPropertySet PropertySet)
252
+ : UrImage(Version, Kind, Format, DeviceTargetSpec, CompileOptions,
253
+ LinkOptions, std::move(Manifest), std::move(Binary),
254
+ internal::LifetimeExtender(std::move(OffloadEntries)),
255
+ std::move(PropertySet)) {}
256
+
239
257
// / Constructs a SYCL device image of the latest version.
240
258
UrImage (uint8_t Format, const std::string &DeviceTargetSpec,
241
259
const std::string &CompileOptions, const std::string &LinkOptions,
242
- std::vector<unsigned char > Binary,
243
- UrArray<UrOffloadEntry> OffloadEntries, UrPropertySet PropertySet)
260
+ std::vector<unsigned char > &&Binary,
261
+ std::vector<UrOffloadEntry> &&OffloadEntries,
262
+ UrPropertySet PropertySet)
244
263
: UrImage(SYCL_DEVICE_BINARY_VERSION,
245
264
SYCL_DEVICE_BINARY_OFFLOAD_KIND_SYCL, Format, DeviceTargetSpec,
246
265
CompileOptions, LinkOptions, {}, std::move(Binary),
247
- std::move(OffloadEntries), std::move(PropertySet)) {}
266
+ internal::LifetimeExtender(std::move(OffloadEntries)),
267
+ std::move(PropertySet)) {}
248
268
249
269
sycl_device_binary_struct convertToNativeType () {
250
270
return sycl_device_binary_struct{
@@ -275,7 +295,7 @@ class UrImage {
275
295
std::string MLinkOptions;
276
296
std::vector<char > MManifest;
277
297
std::vector<unsigned char > MBinary;
278
- UrArray <UrOffloadEntry> MOffloadEntries;
298
+ internal::LifetimeExtender <UrOffloadEntry> MOffloadEntries;
279
299
UrPropertySet MPropertySet;
280
300
};
281
301
@@ -392,7 +412,7 @@ inline UrProperty makeSpecConstant(std::vector<char> &ValData,
392
412
// / Utility function to mark kernel as the one using assert
393
413
inline void setKernelUsesAssert (const std::vector<std::string> &Names,
394
414
UrPropertySet &Set) {
395
- UrArray <UrProperty> Value;
415
+ std::vector <UrProperty> Value;
396
416
for (const std::string &N : Names)
397
417
Value.push_back ({N, {0 , 0 , 0 , 0 }, SYCL_PROPERTY_TYPE_UINT32});
398
418
Set.insert (__SYCL_PROPERTY_SET_SYCL_ASSERT_USED, std::move (Value));
@@ -401,16 +421,14 @@ inline void setKernelUsesAssert(const std::vector<std::string> &Names,
401
421
// / Utility function to add specialization constants to property set.
402
422
// /
403
423
// / This function overrides the default spec constant values.
404
- inline void addSpecConstants (UrArray <UrProperty> SpecConstants,
424
+ inline void addSpecConstants (std::vector <UrProperty> && SpecConstants,
405
425
std::vector<char > ValData, UrPropertySet &Props) {
406
426
Props.insert (__SYCL_PROPERTY_SET_SPEC_CONST_MAP, std::move (SpecConstants));
407
427
408
428
UrProperty Prop{" all" , std::move (ValData), SYCL_PROPERTY_TYPE_BYTE_ARRAY};
409
429
410
- UrArray<UrProperty> DefaultValues{std::move (Prop)};
411
-
412
430
Props.insert (__SYCL_PROPERTY_SET_SPEC_CONST_DEFAULT_VALUES_MAP,
413
- std::move (DefaultValues ));
431
+ std::move (Prop ));
414
432
}
415
433
416
434
// / Utility function to add ESIMD kernel flag to property set.
@@ -419,15 +437,13 @@ inline void addESIMDFlag(UrPropertySet &Props) {
419
437
ValData[0 ] = 1 ;
420
438
UrProperty Prop{" isEsimdImage" , ValData, SYCL_PROPERTY_TYPE_UINT32};
421
439
422
- UrArray<UrProperty> Value{std::move (Prop)};
423
-
424
- Props.insert (__SYCL_PROPERTY_SET_SYCL_MISC_PROP, std::move (Value));
440
+ Props.insert (__SYCL_PROPERTY_SET_SYCL_MISC_PROP, std::move (Prop));
425
441
}
426
442
427
443
// / Utility function to generate offload entries for kernels without arguments.
428
- inline UrArray <UrOffloadEntry>
444
+ inline std::vector <UrOffloadEntry>
429
445
makeEmptyKernels (std::initializer_list<std::string> KernelNames) {
430
- UrArray <UrOffloadEntry> Entries;
446
+ std::vector <UrOffloadEntry> Entries;
431
447
432
448
for (const auto &Name : KernelNames) {
433
449
UrOffloadEntry E{Name, {}, 0 };
@@ -531,7 +547,7 @@ inline void
531
547
addDeviceRequirementsProps (UrPropertySet &Props,
532
548
const std::vector<sycl::aspect> &Aspects,
533
549
const std::vector<int > &ReqdWGSize = {}) {
534
- UrArray <UrProperty> Value{makeAspectsProp (Aspects)};
550
+ std::vector <UrProperty> Value{makeAspectsProp (Aspects)};
535
551
if (!ReqdWGSize.empty ())
536
552
Value.push_back (makeReqdWGSizeProp (ReqdWGSize));
537
553
Props.insert (__SYCL_PROPERTY_SET_SYCL_DEVICE_REQUIREMENTS, std::move (Value));
@@ -550,7 +566,7 @@ generateDefaultImage(std::initializer_list<std::string> KernelNames) {
550
566
std::vector<unsigned char > Bin (Combined.begin (), Combined.end ());
551
567
Bin.push_back (0 );
552
568
553
- UrArray <UrOffloadEntry> Entries = makeEmptyKernels (KernelNames);
569
+ std::vector <UrOffloadEntry> Entries = makeEmptyKernels (KernelNames);
554
570
555
571
UrImage Img{SYCL_DEVICE_BINARY_TYPE_SPIRV, // Format
556
572
__SYCL_DEVICE_BINARY_TARGET_SPIRV64, // DeviceTargetSpec
0 commit comments