Skip to content

Commit 4011775

Browse files
authored
[SYCL] Do not use current directory for JIT cache (#4047)
Remove storing JIT cache files to current directory when corresponding environment variables are not set. Complementary test change: intel/llvm-test-suite#337
1 parent d1556e4 commit 4011775

File tree

5 files changed

+63
-42
lines changed

5 files changed

+63
-42
lines changed

sycl/doc/EnvironmentVariables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ subject to change. Do not rely on these variables in production code.
3737
| `SYCL_DISABLE_PARALLEL_FOR_RANGE_ROUNDING` | Any(\*) | Disables automatic rounding-up of `parallel_for` invocation ranges. |
3838
| `SYCL_ENABLE_PCI` | Integer | When set to 1, enables obtaining the GPU PCI address when using the Level Zero backend. The default is 0. |
3939
| `SYCL_HOST_UNIFIED_MEMORY` | Integer | Enforce host unified memory support or lack of it for the execution graph builder. If set to 0, it is enforced as not supported by all devices. If set to 1, it is enforced as supported by all devices. |
40-
| `SYCL_CACHE_DIR` | Path | Path to persistent cache root directory. Default values are `%AppData%\libsycl_cache` for Windows and `$XDG_CACHE_HOME/libsycl_cache` on Linux, if `XDG_CACHE_HOME` is not set then `$HOME/.cache/libsycl_cache`. |
40+
| `SYCL_CACHE_DIR` | Path | Path to persistent cache root directory. Default values are `%AppData%\libsycl_cache` for Windows and `$XDG_CACHE_HOME/libsycl_cache` on Linux, if `XDG_CACHE_HOME` is not set then `$HOME/.cache/libsycl_cache`. When none of the environment variables are set SYCL persistent cache is disabled. |
4141
| `SYCL_CACHE_TRACE` | Any(\*) | If the variable is set, messages are sent to std::cerr when caching events or non-blocking failures happen (e.g. unable to access cache item file). |
4242
| `SYCL_CACHE_DISABLE_PERSISTENT (deprecated)` | Any(\*) | Has no effect. |
4343
| `SYCL_CACHE_PERSISTENT` | Integer | Controls persistent device compiled code cache. Turns it on if set to '1' and turns it off if set to '0'. When cache is enabled SYCL runtime will try to cache and reuse JIT-compiled binaries. Default is off. |

sycl/doc/KernelProgramCache.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ The device code image are stored on file system using structure below:
341341
<n>.bin
342342
```
343343

344-
- `<cache_root>` - root directory storing cache files;
344+
- `<cache_root>` - root directory storing cache files, that depends on
345+
environment variables (see SYCL_CACHE_DIR description in the
346+
[EnvironmentVariables.md](EnvironmentVariables.md));
345347
- `<device_hash>` - hash out of device information used to identify target
346348
device;
347349
- `<device_image_hash>` - hash made out of device image used as input for the

sycl/source/detail/persistent_device_code_cache.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,13 @@ void PersistentDeviceCodeCache::putItemToDisc(
7878
const SerializedObj &SpecConsts, const std::string &BuildOptionsString,
7979
const RT::PiProgram &NativePrg) {
8080

81-
if (!isImageCached(Img))
81+
std::string DirName =
82+
getCacheItemPath(Device, Img, SpecConsts, BuildOptionsString);
83+
84+
if (!isImageCached(Img) || DirName.empty())
8285
return;
8386

8487
auto Plugin = detail::getSyclObjImpl(Device)->getPlugin();
85-
std::string DirName =
86-
getCacheItemPath(Device, Img, SpecConsts, BuildOptionsString);
8788

8889
size_t i = 0;
8990
std::string FileName;
@@ -136,13 +137,10 @@ std::vector<std::vector<char>> PersistentDeviceCodeCache::getItemFromDisc(
136137
const device &Device, const RTDeviceBinaryImage &Img,
137138
const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
138139

139-
if (!isImageCached(Img))
140-
return {};
141-
142140
std::string Path =
143141
getCacheItemPath(Device, Img, SpecConsts, BuildOptionsString);
144142

145-
if (!OSUtil::isPathPresent(Path))
143+
if (!isImageCached(Img) || Path.empty() || !OSUtil::isPathPresent(Path))
146144
return {};
147145

148146
int i = 0;
@@ -315,6 +313,10 @@ std::string PersistentDeviceCodeCache::getCacheItemPath(
315313
const device &Device, const RTDeviceBinaryImage &Img,
316314
const SerializedObj &SpecConsts, const std::string &BuildOptionsString) {
317315
static std::string cache_root{getRootDir()};
316+
if (cache_root.empty()) {
317+
trace("Disable persistent cache due to unconfigured cache root.");
318+
return {};
319+
}
318320

319321
std::string ImgString{(const char *)Img.getRawData().BinaryStart,
320322
Img.getSize()};
@@ -379,6 +381,8 @@ bool PersistentDeviceCodeCache::isEnabled() {
379381
}
380382

381383
/* Returns path for device code cache root directory
384+
* If environment variables are not available return an empty string to identify
385+
* that cache is not available.
382386
*/
383387
std::string PersistentDeviceCodeCache::getRootDir() {
384388
static const char *RootDir = SYCLConfig<SYCL_CACHE_DIR>::get();
@@ -391,15 +395,16 @@ std::string PersistentDeviceCodeCache::getRootDir() {
391395
#if defined(__SYCL_RT_OS_LINUX)
392396
static const char *CacheDir = std::getenv("XDG_CACHE_HOME");
393397
static const char *HomeDir = std::getenv("HOME");
398+
if (!CacheDir && !HomeDir)
399+
return {};
394400
static std::string Res{
395-
std::string(CacheDir
396-
? CacheDir
397-
: (HomeDir ? std::string(HomeDir) + "/.cache" : ".")) +
401+
std::string(CacheDir ? CacheDir : (std::string(HomeDir) + "/.cache")) +
398402
DeviceCodeCacheDir};
399403
#else
400404
static const char *AppDataDir = std::getenv("AppData");
401-
static std::string Res{std::string(AppDataDir ? AppDataDir : ".") +
402-
DeviceCodeCacheDir};
405+
if (!AppDataDir)
406+
return {};
407+
static std::string Res{std::string(AppDataDir) + DeviceCodeCacheDir};
403408
#endif
404409
return Res;
405410
}

sycl/test/Unit/lit.cfg.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,7 @@ def find_shlibpath_var():
7373
lit_config.warning("unable to inject shared library path on '{}'"
7474
.format(platform.system()))
7575

76+
config.environment['SYCL_CACHE_DIR'] = config.llvm_obj_root + "/sycl_cache"
7677
config.environment['SYCL_DEVICE_FILTER'] = lit_config.params.get('SYCL_PLUGIN', "opencl") + ",host"
7778
lit_config.note("Backend: {}".format(config.environment['SYCL_DEVICE_FILTER']))
79+
lit_config.note("SYCL cache directory: {}".format(config.environment['SYCL_CACHE_DIR']))

sycl/unittests/kernel-and-program/PersistentDeviceCodeCache.cpp

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ class PersistenDeviceCodeCache : public ::testing::Test {
8181
return _putenv_s(name, value);
8282
}
8383
#endif
84+
virtual void SetUp() {
85+
EXPECT_NE(getenv("SYCL_CACHE_DIR"), nullptr)
86+
<< "Please set SYCL_CACHE_DIR environment variable pointing to cache "
87+
"location.";
88+
}
8489

8590
PersistenDeviceCodeCache() : Plt{default_selector()} {
8691

@@ -134,8 +139,8 @@ class PersistenDeviceCodeCache : public ::testing::Test {
134139
BuildOptions);
135140
for (size_t i = 0; i < Res.size(); ++i) {
136141
for (size_t j = 0; j < Res[i].size(); ++j) {
137-
assert(Res[i][j] == static_cast<char>(i) &&
138-
"Corrupted image loaded from persistent cache");
142+
EXPECT_EQ(Res[i][j], static_cast<char>(i))
143+
<< "Corrupted image loaded from persistent cache";
139144
}
140145
}
141146
};
@@ -189,12 +194,13 @@ TEST_F(PersistenDeviceCodeCache, KeysWithNullTermSymbol) {
189194
NativeProg);
190195
auto Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img,
191196
SpecConst, Key);
192-
assert(Res.size() != 0 && "Failed to load cache item");
197+
EXPECT_NE(Res.size(), static_cast<size_t>(0)) << "Failed to load cache item";
193198
for (size_t i = 0; i < Res.size(); ++i) {
194-
assert(Res[i].size() != 0 && "Failed to device image");
199+
EXPECT_NE(Res[i].size(), static_cast<size_t>(0))
200+
<< "Failed to load device image";
195201
for (size_t j = 0; j < Res[i].size(); ++j) {
196-
assert(Res[i][j] == static_cast<char>(i) &&
197-
"Corrupted image loaded from persistent cache");
202+
EXPECT_EQ(Res[i][j], static_cast<unsigned char>(i))
203+
<< "Corrupted image loaded from persistent cache";
198204
}
199205
}
200206

@@ -245,21 +251,23 @@ TEST_F(PersistenDeviceCodeCache, CorruptedCacheFiles) {
245251
// Only source file is present
246252
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
247253
NativeProg);
248-
assert(!llvm::sys::fs::remove(ItemDir + "/0.bin") &&
249-
"Failed to remove binary file");
254+
EXPECT_FALSE(llvm::sys::fs::remove(ItemDir + "/0.bin"))
255+
<< "Failed to remove binary file";
250256
auto Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
251257
BuildOptions);
252-
assert(Res.size() == 0 && "Item with missed binary file was read");
258+
EXPECT_EQ(Res.size(), static_cast<size_t>(0))
259+
<< "Item with missed binary file was read";
253260
llvm::sys::fs::remove_directories(ItemDir);
254261

255262
// Only binary file is present
256263
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
257264
NativeProg);
258-
assert(!llvm::sys::fs::remove(ItemDir + "/0.src") &&
259-
"Failed to remove source file");
265+
EXPECT_FALSE(llvm::sys::fs::remove(ItemDir + "/0.src"))
266+
<< "Failed to remove source file";
260267
Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
261268
BuildOptions);
262-
assert(Res.size() == 0 && "Item with missed source file was read");
269+
EXPECT_EQ(Res.size(), static_cast<size_t>(0))
270+
<< "Item with missed source file was read";
263271
llvm::sys::fs::remove_directories(ItemDir);
264272

265273
// Binary file is corrupted
@@ -272,10 +280,11 @@ TEST_F(PersistenDeviceCodeCache, CorruptedCacheFiles) {
272280
*/
273281
FileStream << 2 << 12 << "123456789012" << 23 << "1234";
274282
FileStream.close();
275-
assert((!FileStream.fail()) && "Failed to create trancated binary file");
283+
EXPECT_FALSE(FileStream.fail()) << "Failed to create trancated binary file";
276284
Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
277285
BuildOptions);
278-
assert(Res.size() == 0 && "Item with corrupted binary file was read");
286+
EXPECT_EQ(Res.size(), static_cast<size_t>(0))
287+
<< "Item with corrupted binary file was read";
279288

280289
llvm::sys::fs::remove_directories(ItemDir);
281290

@@ -288,7 +297,8 @@ TEST_F(PersistenDeviceCodeCache, CorruptedCacheFiles) {
288297
}
289298
Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
290299
BuildOptions);
291-
assert(Res.size() == 0 && "Item with corrupted binary file was read");
300+
EXPECT_EQ(Res.size(), static_cast<size_t>(0))
301+
<< "Item with corrupted binary file was read";
292302
llvm::sys::fs::remove_directories(ItemDir);
293303
}
294304

@@ -312,37 +322,38 @@ TEST_F(PersistenDeviceCodeCache, LockFile) {
312322
// Create 1st cahe item
313323
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
314324
NativeProg);
315-
assert(llvm::sys::fs::exists(ItemDir + "/0.bin") && "No file created");
325+
EXPECT_TRUE(llvm::sys::fs::exists(ItemDir + "/0.bin")) << "No file created";
316326
std::string LockFile = ItemDir + "/0.lock";
317-
assert(!llvm::sys::fs::exists(LockFile) && "Cache item locked");
327+
EXPECT_FALSE(llvm::sys::fs::exists(LockFile)) << "Cache item locked";
318328

319329
// Create lock file for the 1st cache item
320330
{ std::ofstream File{LockFile}; }
321331

322332
// Cache item is locked, cache miss happens on read
323333
auto Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
324334
BuildOptions);
325-
assert(Res.size() == 0 && "Locked item was read");
335+
EXPECT_EQ(Res.size(), static_cast<size_t>(0)) << "Locked item was read";
326336

327337
// Cache item is locked - new cache item to be created
328338
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
329339
NativeProg);
330-
assert(llvm::sys::fs::exists(ItemDir + "/1.bin") && "No file created");
340+
EXPECT_TRUE(llvm::sys::fs::exists(ItemDir + "/1.bin")) << "No file created";
331341

332342
// Second cache item is locked, cache miss happens on read
333343
{ std::ofstream File{ItemDir + "/1.lock"}; }
334344
Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
335345
BuildOptions);
336-
assert(Res.size() == 0 && "Locked item was read");
346+
347+
EXPECT_EQ(Res.size(), static_cast<size_t>(0)) << "Locked item was read";
337348

338349
// First cache item was unlocked and successfully read
339350
std::remove(LockFile.c_str());
340351
Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
341352
BuildOptions);
342353
for (size_t i = 0; i < Res.size(); ++i) {
343354
for (size_t j = 0; j < Res[i].size(); ++j) {
344-
assert(Res[i][j] == static_cast<char>(i) &&
345-
"Corrupted image loaded from persistent cache");
355+
EXPECT_EQ(Res[i][j], static_cast<unsigned char>(i))
356+
<< "Corrupted image loaded from persistent cache";
346357
}
347358
}
348359
llvm::sys::fs::remove_directories(ItemDir);
@@ -366,19 +377,20 @@ TEST_F(PersistenDeviceCodeCache, AccessDeniedForCacheDir) {
366377
llvm::sys::fs::remove_directories(ItemDir);
367378
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
368379
NativeProg);
369-
assert(llvm::sys::fs::exists(ItemDir + "/0.bin") && "No file created");
380+
EXPECT_TRUE(llvm::sys::fs::exists(ItemDir + "/0.bin")) << "No file created";
370381
llvm::sys::fs::setPermissions(ItemDir + "/0.bin", llvm::sys::fs::no_perms);
371382
// No access to binary file new cache item to be created
372383
detail::PersistentDeviceCodeCache::putItemToDisc(Dev, Img, {}, BuildOptions,
373384
NativeProg);
374-
assert(llvm::sys::fs::exists(ItemDir + "/1.bin") && "No file created");
385+
EXPECT_TRUE(llvm::sys::fs::exists(ItemDir + "/1.bin")) << "No file created";
375386

376387
llvm::sys::fs::setPermissions(ItemDir + "/1.bin", llvm::sys::fs::no_perms);
377388
auto Res = detail::PersistentDeviceCodeCache::getItemFromDisc(Dev, Img, {},
378389
BuildOptions);
379390

380-
// No image to be read due to lack of permissions fro source file
381-
assert(Res.size() == 0);
391+
// No image to be read due to lack of permissions from source file
392+
EXPECT_EQ(Res.size(), static_cast<size_t>(0))
393+
<< "Read from the file without permissions.";
382394

383395
llvm::sys::fs::setPermissions(ItemDir + "/0.bin", llvm::sys::fs::all_perms);
384396
llvm::sys::fs::setPermissions(ItemDir + "/1.bin", llvm::sys::fs::all_perms);
@@ -388,8 +400,8 @@ TEST_F(PersistenDeviceCodeCache, AccessDeniedForCacheDir) {
388400
// Image should be successfully read
389401
for (size_t i = 0; i < Res.size(); ++i) {
390402
for (size_t j = 0; j < Res[i].size(); ++j) {
391-
assert(Res[i][j] == static_cast<char>(i) &&
392-
"Corrupted image loaded from persistent cache");
403+
EXPECT_EQ(Res[i][j], static_cast<unsigned char>(i))
404+
<< "Corrupted image loaded from persistent cache";
393405
}
394406
}
395407
llvm::sys::fs::remove_directories(ItemDir);

0 commit comments

Comments
 (0)