Skip to content

Commit 48f6bc9

Browse files
authored
[SYCL] Disable persistent device code caching by default. (#3891)
* [SYCL] Disable persistent device code caching by default. Also introduce boolean config variable SYCL_CACHE_PERSISTENT for finer grained control - to force on/off. Signed-off-by: kbobrovs <[email protected]>
1 parent 508dbfe commit 48f6bc9

File tree

5 files changed

+96
-9
lines changed

5 files changed

+96
-9
lines changed

sycl/doc/EnvironmentVariables.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ subject to change. Do not rely on these variables in production code.
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. |
4040
| `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`. |
41-
| `SYCL_CACHE_TRACE` | Any(\*) | If the variable is set, messages are sent to std::cerr when non-blocking failures happen (e.g. unable to access cache item file). |
42-
| `SYCL_CACHE_DISABLE_PERSISTENT` | Any(\*) | Switches persistent cache switch off when the variable is set. |
41+
| `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). |
42+
| `SYCL_CACHE_DISABLE_PERSISTENT (deprecated)` | Any(\*) | Has no effect. |
43+
| `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. |
4344
| `SYCL_CACHE_EVICTION_DISABLE` | Any(\*) | Switches cache eviction off when the variable is set. |
4445
| `SYCL_CACHE_MAX_SIZE` | Positive integer | Cache eviction is triggered once total size of cached images exceeds the value in megabytes (default - 8 192 for 8 GB). Set to 0 to disable size-based cache eviction. |
4546
| `SYCL_CACHE_THRESHOLD` | Positive integer | Cache eviction threshold in days (default value is 7 for 1 week). Set to 0 for disabling time-based cache eviction. |

sycl/source/detail/config.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CONFIG(SYCL_HOST_UNIFIED_MEMORY, 1, __SYCL_HOST_UNIFIED_MEMORY)
2424
CONFIG(SYCL_CACHE_DIR, 164, __SYCL_CACHE_DIR)
2525
CONFIG(SYCL_CACHE_TRACE, 1, __SYCL_CACHE_TRACE)
2626
CONFIG(SYCL_CACHE_DISABLE_PERSISTENT, 1, __SYCL_CACHE_DISABLE_PERSISTENT)
27+
CONFIG(SYCL_CACHE_PERSISTENT, 1, __SYCL_CACHE_PERSISTENT)
2728
CONFIG(SYCL_CACHE_EVICTION_DISABLE, 1, __SYCL_CACHE_EVICTION_DISABLE)
2829
CONFIG(SYCL_CACHE_MAX_SIZE, 16, __SYCL_CACHE_MAX_SIZE)
2930
CONFIG(SYCL_CACHE_THRESHOLD, 16, __SYCL_CACHE_THRESHOLD)

sycl/source/detail/config.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ template <ConfigID Config> class SYCLConfig {
106106

107107
static void reset() { (void)getCachedValue(/*ResetCache=*/true); }
108108

109+
static const char *getName() { return BaseT::MConfigName; }
110+
109111
private:
110112
static const char *getCachedValue(bool ResetCache = false) {
111113
static const char *ValStr = BaseT::getRawValue();

sycl/source/detail/persistent_device_code_cache.cpp

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ void PersistentDeviceCodeCache::putItemToDisc(
117117
OSUtil::makeDir(DirName.c_str());
118118
LockCacheItem Lock{FileName};
119119
if (Lock.isOwned()) {
120-
writeBinaryDataToFile(FileName + ".bin", Result);
120+
std::string FullFileName = FileName + ".bin";
121+
writeBinaryDataToFile(FullFileName, Result);
122+
trace("device binary has been cached: " + FullFileName);
121123
writeSourceItem(FileName + ".src", Device, Img, SpecConsts,
122124
BuildOptionsString);
123125
}
@@ -153,7 +155,11 @@ std::vector<std::vector<char>> PersistentDeviceCodeCache::getItemFromDisc(
153155
isCacheItemSrcEqual(FileName + ".src", Device, Img, SpecConsts,
154156
BuildOptionsString)) {
155157
try {
156-
return readBinaryDataFromFile(FileName + ".bin");
158+
std::string FullFileName = FileName + ".bin";
159+
std::vector<std::vector<char>> res =
160+
readBinaryDataFromFile(FullFileName);
161+
trace("using cached device binary: " + FullFileName);
162+
return res; // subject for NRVO
157163
} catch (...) {
158164
// If read was unsuccessfull try the next item
159165
}
@@ -323,13 +329,53 @@ std::string PersistentDeviceCodeCache::getCacheItemPath(
323329
std::to_string(StringHasher(BuildOptionsString));
324330
}
325331

326-
/* Returns true if persistent cache enabled. The cache can be disabled by
327-
* setting SYCL_CACHE_EVICTION_DISABLE environmnet variable.
332+
// TODO Currently parsing configuration variables and error reporting is not
333+
// centralized, and is basically re-implemented (with different level of
334+
// reliability) for each particular variable. As a variant, this can go into
335+
// the SYCLConfigBase class, which can be templated by value type, default value
336+
// and value parser (combined with error checker). It can also have typed get()
337+
// function returning one-time parsed and error-checked value.
338+
339+
// Parses persistent cache configuration and checks it for errors.
340+
// Returns true if it is enabled, false otherwise.
341+
static bool parsePersistentCacheConfig() {
342+
constexpr bool Default = false; // default is disabled
343+
344+
// Check if deprecated opt-out env var is used, then warn.
345+
if (SYCLConfig<SYCL_CACHE_DISABLE_PERSISTENT>::get()) {
346+
std::cerr
347+
<< "WARNING: " << SYCLConfig<SYCL_CACHE_DISABLE_PERSISTENT>::getName()
348+
<< " environment variable is deprecated "
349+
<< "and has no effect. By default, persistent device code caching is "
350+
<< (Default ? "enabled." : "disabled.") << " Use "
351+
<< SYCLConfig<SYCL_CACHE_PERSISTENT>::getName()
352+
<< "=1/0 to enable/disable.\n";
353+
}
354+
bool Ret = Default;
355+
const char *RawVal = SYCLConfig<SYCL_CACHE_PERSISTENT>::get();
356+
357+
if (RawVal) {
358+
if (!std::strcmp(RawVal, "0")) {
359+
Ret = false;
360+
} else if (!std::strcmp(RawVal, "1")) {
361+
Ret = true;
362+
} else {
363+
std::string Msg =
364+
std::string{"Invalid value for bool configuration variable "} +
365+
SYCLConfig<SYCL_CACHE_PERSISTENT>::getName() + std::string{": "} +
366+
RawVal;
367+
throw runtime_error(Msg, PI_INVALID_OPERATION);
368+
}
369+
}
370+
PersistentDeviceCodeCache::trace(Ret ? "enabled" : "disabled");
371+
return Ret;
372+
}
373+
374+
/* Returns true if persistent cache is enabled.
328375
*/
329376
bool PersistentDeviceCodeCache::isEnabled() {
330-
static const char *PersistenCacheDisabled =
331-
SYCLConfig<SYCL_CACHE_DISABLE_PERSISTENT>::get();
332-
return !PersistenCacheDisabled;
377+
static bool Val = parsePersistentCacheConfig();
378+
return Val;
333379
}
334380

335381
/* Returns path for device code cache root directory

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@
1818
#include <llvm/Support/FileSystem.h>
1919
#include <vector>
2020

21+
// TODO: Introduce common unit tests header and move it there
22+
static void set_env(const char *name, const char *value) {
23+
#ifdef _WIN32
24+
(void)_putenv_s(name, value);
25+
#else
26+
(void)setenv(name, value, /*overwrite*/ 1);
27+
#endif
28+
}
29+
30+
static void unset_env(const char *name) {
31+
#ifdef _WIN32
32+
(void)_putenv_s(name, "");
33+
#else
34+
unsetenv(name);
35+
#endif
36+
}
37+
2138
namespace {
2239
constexpr auto sycl_read_write = cl::sycl::access::mode::read_write;
2340
using namespace cl::sycl;
@@ -98,6 +115,10 @@ class PersistenDeviceCodeCache : public ::testing::Test {
98115
if (Plt.is_host() || Plt.get_backend() != backend::opencl) {
99116
return;
100117
}
118+
119+
set_env("SYCL_CACHE_PERSISTENT", "1");
120+
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_PERSISTENT>::reset();
121+
101122
std::string BuildOptions{"--concurrent-access=" +
102123
std::to_string(ThreadCount)};
103124
DeviceCodeID = ProgramID;
@@ -151,6 +172,10 @@ TEST_F(PersistenDeviceCodeCache, KeysWithNullTermSymbol) {
151172
if (Plt.is_host() || Plt.get_backend() != backend::opencl) {
152173
return;
153174
}
175+
176+
set_env("SYCL_CACHE_PERSISTENT", "1");
177+
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_PERSISTENT>::reset();
178+
154179
std::string Key{'1', '\0', '3', '4', '\0'};
155180
std::vector<unsigned char> SpecConst(Key.begin(), Key.end());
156181
std::string ItemDir = detail::PersistentDeviceCodeCache::getCacheItemPath(
@@ -204,6 +229,10 @@ TEST_F(PersistenDeviceCodeCache, CorruptedCacheFiles) {
204229
if (Plt.is_host() || Plt.get_backend() != backend::opencl) {
205230
return;
206231
}
232+
233+
set_env("SYCL_CACHE_PERSISTENT", "1");
234+
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_PERSISTENT>::reset();
235+
207236
std::string BuildOptions{"--corrupted-file"};
208237
std::string ItemDir = detail::PersistentDeviceCodeCache::getCacheItemPath(
209238
Dev, Img, {}, BuildOptions);
@@ -267,6 +296,10 @@ TEST_F(PersistenDeviceCodeCache, LockFile) {
267296
if (Plt.is_host() || Plt.get_backend() != backend::opencl) {
268297
return;
269298
}
299+
300+
set_env("SYCL_CACHE_PERSISTENT", "1");
301+
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_PERSISTENT>::reset();
302+
270303
std::string BuildOptions{"--obsolete-lock"};
271304
std::string ItemDir = detail::PersistentDeviceCodeCache::getCacheItemPath(
272305
Dev, Img, {}, BuildOptions);
@@ -318,6 +351,10 @@ TEST_F(PersistenDeviceCodeCache, AccessDeniedForCacheDir) {
318351
if (Plt.is_host() || Plt.get_backend() != backend::opencl) {
319352
return;
320353
}
354+
355+
set_env("SYCL_CACHE_PERSISTENT", "1");
356+
sycl::detail::SYCLConfig<sycl::detail::SYCL_CACHE_PERSISTENT>::reset();
357+
321358
std::string BuildOptions{"--build-options"};
322359
std::string ItemDir = detail::PersistentDeviceCodeCache::getCacheItemPath(
323360
Dev, Img, {}, BuildOptions);

0 commit comments

Comments
 (0)