@@ -59,11 +59,19 @@ IsSupportedImageFormat(sycl::detail::pi::PiDeviceBinaryType Format) {
59
59
Format == PI_DEVICE_BINARY_TYPE_NATIVE;
60
60
}
61
61
62
- /* Returns true if specified image should be cached on disk. It checks if
63
- * cache is enabled, image has supported format and matches thresholds. */
64
- bool PersistentDeviceCodeCache::isImageCached (const RTDeviceBinaryImage &Img) {
62
+ /* Returns true if specified images should be cached on disk. It checks if
63
+ * cache is enabled, images have supported format and match thresholds. */
64
+ bool PersistentDeviceCodeCache::areImagesCacheable (
65
+ const std::vector<const RTDeviceBinaryImage *> &Imgs) {
66
+ assert (!Imgs.empty ());
67
+ auto Format = Imgs[0 ]->getFormat ();
68
+ assert (std::all_of (Imgs.begin (), Imgs.end (),
69
+ [&Format](const RTDeviceBinaryImage *Img) {
70
+ return Img->getFormat () == Format;
71
+ }) &&
72
+ " All images are expected to have the same format" );
65
73
// Cache should be enabled and image type is one of the supported formats.
66
- if (!isEnabled () || !IsSupportedImageFormat (Img. getFormat () ))
74
+ if (!isEnabled () || !IsSupportedImageFormat (Format ))
67
75
return false ;
68
76
69
77
// Disable cache for ITT-profiled images.
@@ -79,25 +87,42 @@ bool PersistentDeviceCodeCache::isImageCached(const RTDeviceBinaryImage &Img) {
79
87
80
88
// Make sure that image size is between caching thresholds if they are set.
81
89
// Zero values for threshold is treated as disabled threshold.
82
- if ((MaxImgSize && (Img.getSize () > MaxImgSize)) ||
83
- (MinImgSize && (Img.getSize () < MinImgSize)))
90
+ size_t TotalSize = 0 ;
91
+ for (const RTDeviceBinaryImage *Img : Imgs)
92
+ TotalSize += Img->getSize ();
93
+ if ((MaxImgSize && (TotalSize > MaxImgSize)) ||
94
+ (MinImgSize && (TotalSize < MinImgSize)))
84
95
return false ;
85
96
86
97
return true ;
87
98
}
88
99
89
- /* Stores built program in persisten cache
100
+ static std::vector<const RTDeviceBinaryImage *>
101
+ getSortedImages (const std::vector<const RTDeviceBinaryImage *> &Imgs) {
102
+ std::vector<const RTDeviceBinaryImage *> SortedImgs = Imgs;
103
+ std::sort (SortedImgs.begin (), SortedImgs.end (),
104
+ [](const RTDeviceBinaryImage *A, const RTDeviceBinaryImage *B) {
105
+ // All entry names are unique among these images, so comparing the
106
+ // first ones is enough.
107
+ return std::strcmp (A->getRawData ().EntriesBegin ->name ,
108
+ B->getRawData ().EntriesBegin ->name ) < 0 ;
109
+ });
110
+ return SortedImgs;
111
+ }
112
+
113
+ /* Stores built program in persistent cache
90
114
*/
91
115
void PersistentDeviceCodeCache::putItemToDisc (
92
- const device &Device, const RTDeviceBinaryImage &Img ,
116
+ const device &Device, const std::vector< const RTDeviceBinaryImage *> &Imgs ,
93
117
const SerializedObj &SpecConsts, const std::string &BuildOptionsString,
94
118
const sycl::detail::pi::PiProgram &NativePrg) {
95
119
96
- if (!isImageCached (Img ))
120
+ if (!areImagesCacheable (Imgs ))
97
121
return ;
98
122
123
+ std::vector<const RTDeviceBinaryImage *> SortedImgs = getSortedImages (Imgs);
99
124
std::string DirName =
100
- getCacheItemPath (Device, Img , SpecConsts, BuildOptionsString);
125
+ getCacheItemPath (Device, SortedImgs , SpecConsts, BuildOptionsString);
101
126
102
127
if (DirName.empty ())
103
128
return ;
@@ -139,7 +164,7 @@ void PersistentDeviceCodeCache::putItemToDisc(
139
164
std::string FullFileName = FileName + " .bin" ;
140
165
writeBinaryDataToFile (FullFileName, Result);
141
166
trace (" device binary has been cached: " + FullFileName);
142
- writeSourceItem (FileName + " .src" , Device, Img , SpecConsts,
167
+ writeSourceItem (FileName + " .src" , Device, SortedImgs , SpecConsts,
143
168
BuildOptionsString);
144
169
} else {
145
170
PersistentDeviceCodeCache::trace (" cache lock not owned " + FileName);
@@ -160,14 +185,15 @@ void PersistentDeviceCodeCache::putItemToDisc(
160
185
* stored in vector of chars.
161
186
*/
162
187
std::vector<std::vector<char >> PersistentDeviceCodeCache::getItemFromDisc (
163
- const device &Device, const RTDeviceBinaryImage &Img ,
188
+ const device &Device, const std::vector< const RTDeviceBinaryImage *> &Imgs ,
164
189
const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
165
190
166
- if (!isImageCached (Img ))
191
+ if (!areImagesCacheable (Imgs ))
167
192
return {};
168
193
194
+ std::vector<const RTDeviceBinaryImage *> SortedImgs = getSortedImages (Imgs);
169
195
std::string Path =
170
- getCacheItemPath (Device, Img , SpecConsts, BuildOptionsString);
196
+ getCacheItemPath (Device, SortedImgs , SpecConsts, BuildOptionsString);
171
197
172
198
if (Path.empty () || !OSUtil::isPathPresent (Path))
173
199
return {};
@@ -179,7 +205,7 @@ std::vector<std::vector<char>> PersistentDeviceCodeCache::getItemFromDisc(
179
205
OSUtil::isPathPresent (FileName + " .src" )) {
180
206
181
207
if (!LockCacheItem::isLocked (FileName) &&
182
- isCacheItemSrcEqual (FileName + " .src" , Device, Img , SpecConsts,
208
+ isCacheItemSrcEqual (FileName + " .src" , Device, SortedImgs , SpecConsts,
183
209
BuildOptionsString)) {
184
210
try {
185
211
std::string FullFileName = FileName + " .bin" ;
@@ -256,12 +282,12 @@ PersistentDeviceCodeCache::readBinaryDataFromFile(const std::string &FileName) {
256
282
257
283
/* Writing cache item key sources to be used for reliable identification
258
284
* Format: Four pairs of [size, value] for device, build options, specialization
259
- * constant values, device code SPIR-V image .
285
+ * constant values, device code SPIR-V images .
260
286
*/
261
287
void PersistentDeviceCodeCache::writeSourceItem (
262
288
const std::string &FileName, const device &Device,
263
- const RTDeviceBinaryImage &Img, const SerializedObj &SpecConsts ,
264
- const std::string &BuildOptionsString) {
289
+ const std::vector< const RTDeviceBinaryImage *> &SortedImgs ,
290
+ const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
265
291
std::ofstream FileStream{FileName, std::ios::binary};
266
292
267
293
std::string DeviceString{getDeviceIDString (Device)};
@@ -277,9 +303,13 @@ void PersistentDeviceCodeCache::writeSourceItem(
277
303
FileStream.write ((char *)&Size, sizeof (Size));
278
304
FileStream.write ((const char *)SpecConsts.data (), Size);
279
305
280
- Size = Img.getSize ();
306
+ Size = 0 ;
307
+ for (const RTDeviceBinaryImage *Img : SortedImgs)
308
+ Size += Img->getSize ();
281
309
FileStream.write ((char *)&Size, sizeof (Size));
282
- FileStream.write ((const char *)Img.getRawData ().BinaryStart , Size);
310
+ for (const RTDeviceBinaryImage *Img : SortedImgs)
311
+ FileStream.write ((const char *)Img->getRawData ().BinaryStart ,
312
+ Img->getSize ());
283
313
FileStream.close ();
284
314
285
315
if (FileStream.fail ()) {
@@ -292,12 +322,14 @@ void PersistentDeviceCodeCache::writeSourceItem(
292
322
*/
293
323
bool PersistentDeviceCodeCache::isCacheItemSrcEqual (
294
324
const std::string &FileName, const device &Device,
295
- const RTDeviceBinaryImage &Img, const SerializedObj &SpecConsts ,
296
- const std::string &BuildOptionsString) {
325
+ const std::vector< const RTDeviceBinaryImage *> &SortedImgs ,
326
+ const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
297
327
std::ifstream FileStream{FileName, std::ios::binary};
298
328
299
- std::string ImgString{(const char *)Img.getRawData ().BinaryStart ,
300
- Img.getSize ()};
329
+ std::string ImgsString;
330
+ for (const RTDeviceBinaryImage *Img : SortedImgs)
331
+ ImgsString.append ((const char *)Img->getRawData ().BinaryStart ,
332
+ Img->getSize ());
301
333
std::string SpecConstsString{(const char *)SpecConsts.data (),
302
334
SpecConsts.size ()};
303
335
@@ -323,7 +355,7 @@ bool PersistentDeviceCodeCache::isCacheItemSrcEqual(
323
355
FileStream.read ((char *)&Size, sizeof (Size));
324
356
res.resize (Size);
325
357
FileStream.read (&res[0 ], Size);
326
- if (ImgString .compare (res))
358
+ if (ImgsString .compare (res))
327
359
return false ;
328
360
329
361
FileStream.close ();
@@ -335,29 +367,31 @@ bool PersistentDeviceCodeCache::isCacheItemSrcEqual(
335
367
return true ;
336
368
}
337
369
338
- /* Returns directory name to store specific kernel image for specified
370
+ /* Returns directory name to store specific kernel images for specified
339
371
* device, build options and specialization constants values.
340
372
*/
341
373
std::string PersistentDeviceCodeCache::getCacheItemPath (
342
- const device &Device, const RTDeviceBinaryImage &Img ,
374
+ const device &Device, const std::vector< const RTDeviceBinaryImage *> &Imgs ,
343
375
const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
344
376
std::string cache_root{getRootDir ()};
345
377
if (cache_root.empty ()) {
346
378
trace (" Disable persistent cache due to unconfigured cache root." );
347
379
return {};
348
380
}
349
381
350
- std::string ImgString = " " ;
351
- if (Img.getRawData ().BinaryStart )
352
- ImgString.assign ((const char *)Img.getRawData ().BinaryStart , Img.getSize ());
382
+ std::string ImgsString;
383
+ for (const RTDeviceBinaryImage *Img : Imgs)
384
+ if (Img->getRawData ().BinaryStart )
385
+ ImgsString.append ((const char *)Img->getRawData ().BinaryStart ,
386
+ Img->getSize ());
353
387
354
388
std::string DeviceString{getDeviceIDString (Device)};
355
389
std::string SpecConstsString{(const char *)SpecConsts.data (),
356
390
SpecConsts.size ()};
357
391
std::hash<std::string> StringHasher{};
358
392
359
393
return cache_root + " /" + std::to_string (StringHasher (DeviceString)) + " /" +
360
- std::to_string (StringHasher (ImgString )) + " /" +
394
+ std::to_string (StringHasher (ImgsString )) + " /" +
361
395
std::to_string (StringHasher (SpecConstsString)) + " /" +
362
396
std::to_string (StringHasher (BuildOptionsString));
363
397
}
0 commit comments