@@ -135,6 +135,12 @@ class PersistentDeviceCodeCache
135
135
SYCLCachePersistentChanged = true ;
136
136
}
137
137
138
+ // Set SYCL_CACHE_MAX_SIZE.
139
+ void SetDiskCacheEvictionEnv (const char *NewValue) {
140
+ set_env (" SYCL_CACHE_MAX_SIZE" , NewValue);
141
+ sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_MAX_SIZE>::reset ();
142
+ }
143
+
138
144
void AppendToSYCLCacheDirEnv (const char *SubDir) {
139
145
std::string NewSYCLCacheDirPath{RootSYCLCacheDir};
140
146
if (NewSYCLCacheDirPath.back () != ' \\ ' && NewSYCLCacheDirPath.back () != ' /' )
@@ -144,6 +150,24 @@ class PersistentDeviceCodeCache
144
150
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_DIR>::reset ();
145
151
}
146
152
153
+ // Get the list of binary files in the cache directory.
154
+ std::vector<std::string> getBinaryFileNames (std::string CachePath) {
155
+
156
+ std::vector<std::string> FileNames;
157
+ std::error_code EC;
158
+ for (llvm::sys::fs::directory_iterator DirIt (CachePath, EC);
159
+ DirIt != llvm::sys::fs::directory_iterator (); DirIt.increment (EC)) {
160
+ // Check if the file is a binary file.
161
+ std::string filename = DirIt->path ();
162
+ if (filename.find (" .bin" ) != std::string::npos) {
163
+ // Just return the file name without the path.
164
+ FileNames.push_back (filename.substr (filename.find_last_of (" /\\ " ) + 1 ));
165
+ }
166
+ }
167
+
168
+ return FileNames;
169
+ }
170
+
147
171
void ResetSYCLCacheDirEnv () {
148
172
set_env (" SYCL_CACHE_DIR" , RootSYCLCacheDir.c_str ());
149
173
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_DIR>::reset ();
@@ -169,6 +193,9 @@ class PersistentDeviceCodeCache
169
193
SetSYCLCachePersistentEnv (SYCLCachePersistentBefore
170
194
? SYCLCachePersistentBefore->c_str ()
171
195
: nullptr );
196
+
197
+ // Reset SYCL_CACHE_MAX_SIZE.
198
+ SetDiskCacheEvictionEnv (nullptr );
172
199
ResetSYCLCacheDirEnv ();
173
200
}
174
201
@@ -519,6 +546,99 @@ TEST_P(PersistentDeviceCodeCache, AccessDeniedForCacheDir) {
519
546
}
520
547
#endif // _WIN32
521
548
549
+ // Unit tests for testing eviction in persistent cache.
550
+ TEST_P (PersistentDeviceCodeCache, BasicEviction) {
551
+
552
+ // Cleanup the cache directory.
553
+ std::string CacheRoot = detail::PersistentDeviceCodeCache::getRootDir ();
554
+ ASSERT_NO_ERROR (llvm::sys::fs::remove_directories (CacheRoot));
555
+ ASSERT_NO_ERROR (llvm::sys::fs::create_directories (CacheRoot));
556
+
557
+ // Disable eviction for the time being.
558
+ SetDiskCacheEvictionEnv (" 0" );
559
+
560
+ std::string BuildOptions{" --eviction" };
561
+ // Put 3 items to the cache.
562
+ // Sleeping for 1 second between each put to ensure that the items are
563
+ // written to the cache with different timestamps. After that, we will
564
+ // have three binary files in the cache with different timestamps. This is
565
+ // required to keep this unit test deterministic.
566
+ detail::PersistentDeviceCodeCache::putItemToDisc ({Dev}, {&Img}, {},
567
+ BuildOptions, NativeProg);
568
+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
569
+
570
+ detail::PersistentDeviceCodeCache::putItemToDisc ({Dev}, {&Img}, {},
571
+ BuildOptions, NativeProg);
572
+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
573
+
574
+ detail::PersistentDeviceCodeCache::putItemToDisc ({Dev}, {&Img}, {},
575
+ BuildOptions, NativeProg);
576
+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
577
+
578
+ // Retrieve 0.bin from the cache.
579
+ auto Res = detail::PersistentDeviceCodeCache::getItemFromDisc (
580
+ {Dev}, {&Img}, {}, BuildOptions);
581
+
582
+ // Get the number of binary files in the cached item folder.
583
+ std::string ItemDir = detail::PersistentDeviceCodeCache::getCacheItemPath (
584
+ Dev, {&Img}, {}, BuildOptions);
585
+ auto BinFiles = getBinaryFileNames (ItemDir);
586
+
587
+ EXPECT_EQ (BinFiles.size (), static_cast <size_t >(3 ))
588
+ << " Missing binary files. Eviction should not have happened." ;
589
+
590
+ // Get Cache size and size of each entry. Set eviction threshold so that
591
+ // just one item is evicted.
592
+ size_t CurrentCacheSize = 0 ;
593
+ size_t SizeOfOneEntry =
594
+ (size_t )(detail::OSUtil::getDirectorySize (CacheRoot)) + 10 ;
595
+
596
+ // Set SYCL_CACHE_MAX_SIZE.
597
+ SetDiskCacheEvictionEnv (std::to_string (SizeOfOneEntry).c_str ());
598
+
599
+ // Put 4th item to the cache. This should trigger eviction. Only the first
600
+ // item should be evicted.
601
+ detail::PersistentDeviceCodeCache::putItemToDisc ({Dev}, {&Img}, {},
602
+ BuildOptions, NativeProg);
603
+
604
+ // We should have three binary files: 0.bin, 2.bin, 3.bin.
605
+ BinFiles = getBinaryFileNames (ItemDir);
606
+ EXPECT_EQ (BinFiles.size (), static_cast <size_t >(3 ))
607
+ << " Eviction failed. Wrong number of binary files in the cache." ;
608
+
609
+ // Check that 1.bin was evicted.
610
+ for (const auto &File : BinFiles) {
611
+ EXPECT_NE (File, " 1.bin" )
612
+ << " Eviction failed. 1.bin should have been evicted." ;
613
+ }
614
+
615
+ ASSERT_NO_ERROR (llvm::sys::fs::remove_directories (ItemDir));
616
+ }
617
+
618
+ // Unit test for testing size file creation and update, concurrently.
619
+ TEST_P (PersistentDeviceCodeCache, ConcurentReadWriteCacheFileSize) {
620
+ // Cleanup the cache directory.
621
+ std::string CacheRoot = detail::PersistentDeviceCodeCache::getRootDir ();
622
+ ASSERT_NO_ERROR (llvm::sys::fs::remove_directories (CacheRoot));
623
+ ASSERT_NO_ERROR (llvm::sys::fs::create_directories (CacheRoot));
624
+
625
+ // Insanely large value to not trigger eviction. This test just checks
626
+ // for deadlocks/crashes when updating the size file concurrently.
627
+ SetDiskCacheEvictionEnv (" 10000000" );
628
+ ConcurentReadWriteCache (1 , 50 );
629
+ }
630
+
631
+ // Unit test for adding and evicting cache, concurrently.
632
+ TEST_P (PersistentDeviceCodeCache, ConcurentReadWriteCacheEviction) {
633
+ // Cleanup the cache directory.
634
+ std::string CacheRoot = detail::PersistentDeviceCodeCache::getRootDir ();
635
+ ASSERT_NO_ERROR (llvm::sys::fs::remove_directories (CacheRoot));
636
+ ASSERT_NO_ERROR (llvm::sys::fs::create_directories (CacheRoot));
637
+
638
+ SetDiskCacheEvictionEnv (" 1000" );
639
+ ConcurentReadWriteCache (2 , 40 );
640
+ }
641
+
522
642
INSTANTIATE_TEST_SUITE_P (PersistentDeviceCodeCacheImpl,
523
643
PersistentDeviceCodeCache,
524
644
::testing::Values (SYCL_DEVICE_BINARY_TYPE_SPIRV,
0 commit comments