@@ -356,16 +356,26 @@ RT::PiProgram ProgramManager::createPIProgram(const RTDeviceBinaryImage &Img,
356356 return Res;
357357}
358358
359- long GetFileSize (const char *FileName ) {
360- struct stat Stat;
361- if (! stat (FileName, &Stat))
362- return Stat. st_size ;
363- return - 1 ;
359+ std::string getDeviceString (const device &Device ) {
360+ return {Device. get_platform (). get_info <sycl::info::platform::name>() + " / " +
361+ Device. get_info <sycl::info::device::name>() + " / " +
362+ Device. get_info <sycl::info::device::version>() + " / " +
363+ Device. get_info <sycl::info::device::driver_version>()} ;
364364}
365365
366- inline bool IsFSEntryPresent (const char *Path) {
366+ std::string DumpBinData (const unsigned char *Data, size_t Size) {
367+ if (!Size)
368+ return " NONE" ;
369+ std::stringstream ss;
370+ for (size_t i = 0 ; i < Size; i++) {
371+ ss << std::hex << (int )Data[i];
372+ }
373+ return ss.str ();
374+ }
375+
376+ inline bool IsFSEntryPresent (std::string Path) {
367377 struct stat Stat;
368- return !stat (Path, &Stat);
378+ return !stat (Path. c_str () , &Stat);
369379}
370380
371381int MakePathRecur (const char *Dir, mode_t Mode) {
@@ -378,14 +388,14 @@ int MakePathRecur(const char *Dir, mode_t Mode) {
378388 char *CurDir = strdup (Dir);
379389 MakePathRecur (dirname (CurDir), Mode);
380390 if (DbgProgMgr > 1 )
381- std::cerr << " Created directory: " << CurDir << std::endl;
391+ std::cerr << " #### Created directory: " << CurDir << std::endl;
382392
383393 free (CurDir);
384394 return mkdir (Dir, Mode);
385395}
386396
387- void WriteCacheItem (const std::string &FileName,
388- const std::vector<std::vector<char >> &Data) {
397+ void WriteCacheItemBin (const std::string &FileName,
398+ const std::vector<std::vector<char >> &Data) {
389399 std::ofstream FileStream{FileName, std::ios::binary};
390400 if (DbgProgMgr > 1 ) {
391401 std::cerr << " ####Writing programs built for " << std::dec << Data.size ()
@@ -396,7 +406,7 @@ void WriteCacheItem(const std::string &FileName,
396406 FileStream.write ((char *)&Size, sizeof (Size));
397407 for (size_t i = 0 ; i < Data.size (); ++i) {
398408 if (DbgProgMgr > 1 ) {
399- std::cerr << " \t Write " << i << " -th image of size " << std::dec
409+ std::cerr << " #### \t Write " << i << " -th image of size " << std::dec
400410 << Data[i].size () << " \n " ;
401411 }
402412 Size = Data[i].size ();
@@ -406,6 +416,36 @@ void WriteCacheItem(const std::string &FileName,
406416 FileStream.close ();
407417}
408418
419+ void WriteCacheItemSrc (const std::string &FileName, const device &Device,
420+ const RTDeviceBinaryImage &Img,
421+ const SerializedObj &SpecConsts,
422+ const std::string &BuildOptionsString) {
423+ std::ofstream FileStream{FileName, std::ios::binary};
424+ std::string ImgString{
425+ DumpBinData (Img.getRawData ().BinaryStart , Img.getSize ())};
426+ std::string DeviceString{getDeviceString (Device)};
427+ std::string SpecConstsString{
428+ DumpBinData (SpecConsts.data (), SpecConsts.size ())};
429+ if (DbgProgMgr > 1 ) {
430+ std::cerr << " ####Writing source for cache item.\n " ;
431+ std::cerr << " ####'" <<DeviceString<<" '" <<std::endl;
432+ }
433+
434+ size_t Size = DeviceString.size ();
435+ FileStream.write ((char *)&Size, sizeof (Size));
436+ FileStream.write (DeviceString.data (), Size);
437+ Size = BuildOptionsString.size ();
438+ FileStream.write ((char *)&Size, sizeof (Size));
439+ FileStream.write (BuildOptionsString.data (), Size);
440+ Size = SpecConstsString.size ();
441+ FileStream.write ((char *)&Size, sizeof (Size));
442+ FileStream.write (SpecConstsString.data (), Size);
443+ Size = ImgString.size ();
444+ FileStream.write ((char *)&Size, sizeof (Size));
445+ FileStream.write (ImgString.data (), Size);
446+ FileStream.close ();
447+ }
448+
409449std::vector<std::vector<char >> ReadCacheItem (const std::string &FileName) {
410450 std::vector<std::vector<char >> Res;
411451 std::ifstream FileStream{FileName, std::ios::binary};
@@ -421,8 +461,8 @@ std::vector<std::vector<char>> ReadCacheItem(const std::string &FileName) {
421461 for (size_t i = 0 ; i < ImgNum; ++i) {
422462 FileStream.read ((char *)&ImgSize, sizeof (ImgSize));
423463 if (DbgProgMgr > 1 ) {
424- std::cerr << " \t Read " << i << " -th image of size " << std::dec << ImgSize
425- << " \n " ;
464+ std::cerr << " #### \t Read " << i << " -th image of size " << std::dec
465+ << ImgSize << " \n " ;
426466 }
427467
428468 Res[i].resize (ImgSize);
@@ -432,26 +472,88 @@ std::vector<std::vector<char>> ReadCacheItem(const std::string &FileName) {
432472 return Res;
433473}
434474
435- std::string getDeviceString (const device &Device) {
436- return {Device.get_platform ().get_info <sycl::info::platform::name>() +
437- Device.get_info <sycl::info::device::name>() +
438- Device.get_info <sycl::info::device::version>() +
439- Device.get_info <sycl::info::device::driver_version>()};
440- }
475+ bool IsCacheItemSrcEqual (const std::string &FileName, const device &Device,
476+ const RTDeviceBinaryImage &Img,
477+ const SerializedObj &SpecConsts,
478+ const std::string &BuildOptionsString) {
479+ std::ifstream FileStream{FileName, std::ios::binary};
480+ std::string ImgString{
481+ DumpBinData (Img.getRawData ().BinaryStart , Img.getSize ())};
482+ std::string DeviceString{getDeviceString (Device)};
483+ std::string SpecConstsString{
484+ DumpBinData (SpecConsts.data (), SpecConsts.size ())};
441485
442- std::string DumpBinData (const unsigned char *Data, size_t Size) {
443- if (!Size)
444- return " NONE" ;
445- std::stringstream ss;
446- for (size_t i = 0 ; i < Size; i++) {
447- ss << std::hex << (int )Data[i];
486+ size_t Size;
487+ std::string res;
488+
489+ FileStream.read ((char *)&Size, sizeof (Size));
490+ res.resize (Size);
491+ FileStream.read (&res[0 ], Size);
492+ if (DeviceString.compare (res)) {
493+ if (DbgProgMgr > 1 ) {
494+ std::cerr << " ####Devices differ:" <<DeviceString.compare (0 , Size-1 , res.data ())<<" \n " ;
495+ std::cerr << " ####'" <<DeviceString<<" '\n " ;
496+ std::cerr << " ####\t vs\n " ;
497+ std::cerr << " ####'" <<std::string (res.data (),Size)<<" '\n " ;
498+ std::cerr << " ####Cached size " << std::dec << Size << " vs current size " << DeviceString.size () << std::endl;
499+ for (unsigned int i=0 ; i< Size;i++){
500+ if (res[i]!=DeviceString[i])
501+ std::cerr << " ####First diff on " << i<<std::endl;
502+ }
503+ }
504+
505+ return false ;
448506 }
449- return ss.str ();
507+
508+ FileStream.read ((char *)&Size, sizeof (Size));
509+ res.resize (Size);
510+ FileStream.read (&res[0 ], Size);
511+ if (BuildOptionsString.compare (0 , Size, res.data ())) {
512+ if (DbgProgMgr > 1 ) {
513+ std::cerr << " ####Build options differ:\n " ;
514+ std::cerr << " ####'" <<BuildOptionsString<<" '\n " ;
515+ std::cerr << " ####\t vs\n " ;
516+ std::cerr << " ####'" <<std::string (res.data (), Size)<<" '\n " ;
517+ }
518+ return false ;
519+ }
520+
521+ FileStream.read ((char *)&Size, sizeof (Size));
522+ res.resize (Size);
523+ FileStream.read (&res[0 ], Size);
524+ if (SpecConstsString.compare (0 , Size, res.data ())) {
525+ if (DbgProgMgr > 1 ) {
526+ std::cerr << " ####Specialization constants differ\n " ;
527+ std::cerr << " ####'" <<SpecConstsString<<" '\n " ;
528+ std::cerr << " ####\t vs\n " ;
529+ std::cerr << " ####'" <<std::string (res.data (), Size)<<" '\n " ;
530+ }
531+ return false ;
532+ }
533+
534+ FileStream.read ((char *)&Size, sizeof (Size));
535+ res.resize (Size);
536+ FileStream.read (&res[0 ], Size);
537+ if (ImgString.compare (0 , Size, res.data ())) {
538+ if (DbgProgMgr > 1 ) {
539+ std::cerr << " ####Images differ\n " ;
540+ std::cerr << " ####'" <<ImgString<<" '\n " ;
541+ std::cerr << " ####\t vs\n " ;
542+ std::cerr << " ####'" <<std::string (res.data (), Size)<<" '\n " ;
543+
544+ }
545+ return false ;
546+ }
547+
548+ FileStream.close ();
549+ if (DbgProgMgr > 1 )
550+ std::cerr << " ####Cache item sources are equal\n " ;
551+ return true ;
450552}
451553
452554std::string GetCacheItemDirName (const device &Device,
453555 const RTDeviceBinaryImage &Img,
454- const SerializedObj SpecConsts,
556+ const SerializedObj & SpecConsts,
455557 const std::string &BuildOptionsString) {
456558 static std::string cache_root{detail::OSUtil::getCacheRoot ()};
457559
@@ -461,6 +563,7 @@ std::string GetCacheItemDirName(const device &Device,
461563 std::string SpecConstsString{
462564 DumpBinData (SpecConsts.data (), SpecConsts.size ())};
463565 std::hash<std::string> StringHasher{};
566+
464567 return {cache_root + " /" + std::to_string (StringHasher (DeviceString)) + " /" +
465568 std::to_string (StringHasher (ImgString)) + " /" +
466569 std::to_string (StringHasher (SpecConstsString)) + " /" +
@@ -472,7 +575,7 @@ bool IsPersistentCacheEnabled() {
472575 SYCLConfig<SYCL_CACHE_DISABLE_PERSISTENT>::get ();
473576
474577 if (DbgProgMgr > 0 )
475- std::cerr << " Persistent cache "
578+ std::cerr << " #### Persistent cache "
476579 << (PersistenCacheDisabled ? " disabled." : " enabled." )
477580 << std::endl;
478581 return !PersistenCacheDisabled;
@@ -481,26 +584,28 @@ bool IsPersistentCacheEnabled() {
481584void ProgramManager::putPIProgramToDisc (const detail::plugin &Plugin,
482585 const device &Device,
483586 const RTDeviceBinaryImage &Img,
484- const SerializedObj SpecConsts,
587+ const SerializedObj & SpecConsts,
485588 const std::string &BuildOptionsString,
486589 const RT::PiProgram &Program) {
487590 if (!IsPersistentCacheEnabled ()) {
488591 return ;
489592 }
490593
491- static std::string DirName =
594+ std::string DirName =
492595 GetCacheItemDirName (Device, Img, SpecConsts, BuildOptionsString);
493596
494597 size_t i = 0 ;
495598 std::string FileName;
496599 do {
497- FileName = DirName + " /" + std::to_string (i++) + " .bin" ;
498- } while (IsFSEntryPresent (FileName.c_str ()));
600+ FileName = DirName + " /" + std::to_string (i++);
601+ } while (IsFSEntryPresent (FileName + " .bin" ));
602+
603+ unsigned int DeviceNum=0 ;
499604
500- size_t DeviceNum;
501605 Plugin.call <PiApiKind::piProgramGetInfo>(Program, PI_PROGRAM_INFO_NUM_DEVICES,
502606 sizeof (DeviceNum), &DeviceNum,
503- nullptr );
607+ nullptr );
608+
504609 std::vector<size_t > BinarySizes (DeviceNum);
505610 Plugin.call <PiApiKind::piProgramGetInfo>(
506611 Program, PI_PROGRAM_INFO_BINARY_SIZES,
@@ -518,13 +623,15 @@ void ProgramManager::putPIProgramToDisc(const detail::plugin &Plugin,
518623 Pointers.data (), nullptr );
519624
520625 MakePathRecur (DirName.c_str (), 0777 );
521- WriteCacheItem (FileName, Result);
626+ WriteCacheItemBin (FileName + " .bin" , Result);
627+ WriteCacheItemSrc (FileName + " .src" , Device, Img, SpecConsts,
628+ BuildOptionsString);
522629}
523630
524631bool ProgramManager::getPIProgramFromDisc (ContextImplPtr ContextImpl,
525632 const device &Device,
526633 const RTDeviceBinaryImage &Img,
527- const SerializedObj SpecConsts,
634+ const SerializedObj & SpecConsts,
528635 const std::string &BuildOptionsString,
529636 RT::PiProgram &NativePrg) {
530637
@@ -538,17 +645,20 @@ bool ProgramManager::getPIProgramFromDisc(ContextImplPtr ContextImpl,
538645 return false ;
539646
540647 int i = 0 ;
541- std::string BinFileName{Path + " /" + std::to_string (i) + " .bin" };
542- while (IsFSEntryPresent (BinFileName.c_str ())) {
543- auto BinDataItem = ReadCacheItem (BinFileName);
544- if (BinDataItem.size ()) {
648+ std::string FileName{Path + " /" + std::to_string (i)};
649+ while (IsFSEntryPresent (FileName + " .bin" ) &&
650+ IsFSEntryPresent (FileName + " .src" )) {
651+ auto BinDataItem = ReadCacheItem (FileName + " .bin" );
652+ if (BinDataItem.size () &&
653+ IsCacheItemSrcEqual (FileName + " .src" , Device, Img, SpecConsts,
654+ BuildOptionsString)) {
545655 // TODO: Build for multiple devices once supported by program manager
546656 NativePrg = createBinaryProgram (
547657 ContextImpl, Device, (const unsigned char *)BinDataItem[0 ].data (),
548658 BinDataItem[0 ].size ());
549659 return true ;
550660 }
551- BinFileName = Path + " /" + std::to_string (++i) + " .bin " ;
661+ FileName = Path + " /" + std::to_string (++i);
552662 }
553663
554664 return false ;
0 commit comments