@@ -50,6 +50,8 @@ class device_image_impl {
50
50
unsigned int CompositeOffset = 0 ;
51
51
unsigned int Size = 0 ;
52
52
unsigned int BlobOffset = 0 ;
53
+ // Indicates if the specialization constant was set to a value which is
54
+ // different from the default value.
53
55
bool IsSet = false ;
54
56
};
55
57
@@ -61,7 +63,8 @@ class device_image_impl {
61
63
sycl::detail::pi ::PiProgram Program)
62
64
: MBinImage(BinImage), MContext(std::move(Context)),
63
65
MDevices (std::move(Devices)), MState(State), MProgram(Program),
64
- MKernelIDs(std::move(KernelIDs)) {
66
+ MKernelIDs(std::move(KernelIDs)),
67
+ MSpecConstsDefValBlob(getSpecConstsDefValBlob()) {
65
68
updateSpecConstSymMap ();
66
69
}
67
70
@@ -74,6 +77,7 @@ class device_image_impl {
74
77
: MBinImage(BinImage), MContext(std::move(Context)),
75
78
MDevices(std::move(Devices)), MState(State), MProgram(Program),
76
79
MKernelIDs(std::move(KernelIDs)), MSpecConstsBlob(SpecConstsBlob),
80
+ MSpecConstsDefValBlob(getSpecConstsDefValBlob()),
77
81
MSpecConstSymMap(SpecConstMap) {}
78
82
79
83
bool has_kernel (const kernel_id &KernelIDCand) const noexcept {
@@ -152,6 +156,21 @@ class device_image_impl {
152
156
std::vector<SpecConstDescT> &Descs =
153
157
MSpecConstSymMap[std::string{SpecName}];
154
158
for (SpecConstDescT &Desc : Descs) {
159
+ // If there is a default value of the specialization constant and it is
160
+ // the same as the value which is being set then do nothing, runtime is
161
+ // going to handle this case just like if only the default value of the
162
+ // specialization constant was provided.
163
+ if (MSpecConstsDefValBlob.size () &&
164
+ (std::memcmp (MSpecConstsDefValBlob.begin () + Desc.BlobOffset ,
165
+ static_cast <const char *>(Value) + Desc.CompositeOffset ,
166
+ Desc.Size ) == 0 )) {
167
+ // Now we have default value, so reset to false.
168
+ Desc.IsSet = false ;
169
+ continue ;
170
+ }
171
+
172
+ // Value of the specialization constant is set to a value which is
173
+ // different from the default value.
155
174
Desc.IsSet = true ;
156
175
std::memcpy (MSpecConstsBlob.data () + Desc.BlobOffset ,
157
176
static_cast <const char *>(Value) + Desc.CompositeOffset ,
@@ -161,19 +180,20 @@ class device_image_impl {
161
180
162
181
void get_specialization_constant_raw_value (const char *SpecName,
163
182
void *ValueRet) const noexcept {
164
- assert ( is_specialization_constant_set (SpecName) );
183
+ bool IsSet = is_specialization_constant_set (SpecName);
165
184
// Lock the mutex to prevent when one thread in the middle of writing a
166
185
// new value while another thread is reading the value to pass it to
167
186
// JIT compiler.
168
187
const std::lock_guard<std::mutex> SpecConstLock (MSpecConstAccessMtx);
169
-
188
+ assert (IsSet || MSpecConstsDefValBlob. size ());
170
189
// operator[] can't be used here, since it's not marked as const
171
190
const std::vector<SpecConstDescT> &Descs =
172
191
MSpecConstSymMap.at (std::string{SpecName});
173
192
for (const SpecConstDescT &Desc : Descs) {
174
-
193
+ auto Blob =
194
+ IsSet ? MSpecConstsBlob.data () : MSpecConstsDefValBlob.begin ();
175
195
std::memcpy (static_cast <char *>(ValueRet) + Desc.CompositeOffset ,
176
- MSpecConstsBlob. data () + Desc.BlobOffset , Desc.Size );
196
+ Blob + Desc.BlobOffset , Desc.Size );
177
197
}
178
198
}
179
199
@@ -293,16 +313,30 @@ class device_image_impl {
293
313
}
294
314
295
315
private:
316
+ // Get the specialization constant default value blob.
317
+ ByteArray getSpecConstsDefValBlob () const {
318
+ if (!MBinImage)
319
+ return ByteArray (nullptr , 0 );
320
+
321
+ // Get default values for specialization constants.
322
+ const RTDeviceBinaryImage::PropertyRange &SCDefValRange =
323
+ MBinImage->getSpecConstantsDefaultValues ();
324
+ if (!SCDefValRange.size ())
325
+ return ByteArray (nullptr , 0 );
326
+
327
+ ByteArray DefValDescriptors =
328
+ DeviceBinaryProperty (*SCDefValRange.begin ()).asByteArray ();
329
+ // First 8 bytes are consumed by the size of the property.
330
+ DefValDescriptors.dropBytes (8 );
331
+ return DefValDescriptors;
332
+ }
333
+
296
334
void updateSpecConstSymMap () {
297
335
if (MBinImage) {
298
336
const RTDeviceBinaryImage::PropertyRange &SCRange =
299
337
MBinImage->getSpecConstants ();
300
338
using SCItTy = RTDeviceBinaryImage::PropertyRange::ConstIterator;
301
339
302
- // get default values for specialization constants
303
- const RTDeviceBinaryImage::PropertyRange &SCDefValRange =
304
- MBinImage->getSpecConstantsDefaultValues ();
305
-
306
340
// This variable is used to calculate spec constant value offset in a
307
341
// flat byte array.
308
342
unsigned BlobOffset = 0 ;
@@ -341,16 +375,13 @@ class device_image_impl {
341
375
}
342
376
MSpecConstsBlob.resize (BlobOffset);
343
377
344
- bool HasDefaultValues = SCDefValRange.begin () != SCDefValRange.end ();
345
-
346
- if (HasDefaultValues) {
347
- ByteArray DefValDescriptors =
348
- DeviceBinaryProperty (*SCDefValRange.begin ()).asByteArray ();
349
- assert (DefValDescriptors.size () - 8 == MSpecConstsBlob.size () &&
378
+ if (MSpecConstsDefValBlob.size ()) {
379
+ assert (MSpecConstsDefValBlob.size () == MSpecConstsBlob.size () &&
350
380
" Specialization constant default value blob do not have the "
351
381
" expected size." );
352
- std::uninitialized_copy (&DefValDescriptors[8 ],
353
- &DefValDescriptors[8 ] + MSpecConstsBlob.size (),
382
+ std::uninitialized_copy (MSpecConstsDefValBlob.begin (),
383
+ MSpecConstsDefValBlob.begin () +
384
+ MSpecConstsBlob.size (),
354
385
MSpecConstsBlob.data ());
355
386
}
356
387
}
@@ -372,6 +403,9 @@ class device_image_impl {
372
403
// Binary blob which can have values of all specialization constants in the
373
404
// image
374
405
std::vector<unsigned char > MSpecConstsBlob;
406
+ // Binary blob which can have default values of all specialization constants
407
+ // in the image.
408
+ const ByteArray MSpecConstsDefValBlob;
375
409
// Buffer containing binary blob which can have values of all specialization
376
410
// constants in the image, it is using for storing non-native specialization
377
411
// constants
0 commit comments