Skip to content

Commit 051fa68

Browse files
committed
Implement eviction for persistent cache
1 parent b3e2137 commit 051fa68

File tree

6 files changed

+402
-6
lines changed

6 files changed

+402
-6
lines changed

sycl/include/sycl/detail/os_util.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstdlib> // for size_t
1616
#include <string> // for string
1717
#include <sys/stat.h> // for stat
18+
#include <vector> // for vector
1819

1920
#ifdef _WIN32
2021
#define __SYCL_RT_OS_WINDOWS
@@ -88,6 +89,16 @@ class __SYCL_EXPORT OSUtil {
8889
return !stat(Path.c_str(), &Stat);
8990
#endif
9091
}
92+
93+
// Get size of directory in bytes.
94+
static size_t getDirectorySize(const std::string &Path);
95+
96+
// Get size of file in bytes.
97+
static size_t getFileSize(const std::string &Path);
98+
99+
// Get list of all files in the directory along with its last access time.
100+
static std::vector<std::pair<time_t, std::string>>
101+
getFilesWithAccessTime(const std::string &Path);
91102
};
92103

93104
} // namespace detail

sycl/source/detail/config.hpp

+50
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,56 @@ template <> class SYCLConfig<SYCL_IN_MEM_CACHE_EVICTION_THRESHOLD> {
806806
}
807807
};
808808

809+
// SYCL_CACHE_MAX_SIZE accepts an integer that specifies
810+
// the maximum size of the on-disk Program cache.
811+
// Cache eviction is performed when the cache size exceeds the threshold.
812+
// The thresholds are specified in bytes.
813+
// The default value is "0" which means that eviction is disabled.
814+
template <> class SYCLConfig<SYCL_CACHE_MAX_SIZE> {
815+
using BaseT = SYCLConfigBase<SYCL_CACHE_MAX_SIZE>;
816+
817+
public:
818+
static int get() { return getCachedValue(); }
819+
static void reset() { (void)getCachedValue(true); }
820+
821+
static int getProgramCacheSize() { return getCachedValue(); }
822+
823+
static bool isPersistentCacheEvictionEnabled() {
824+
return getProgramCacheSize() > 0;
825+
}
826+
827+
private:
828+
static int getCachedValue(bool ResetCache = false) {
829+
const auto Parser = []() {
830+
const char *ValStr = BaseT::getRawValue();
831+
832+
// Disable eviction by default.
833+
if (!ValStr)
834+
return 0;
835+
836+
int CacheSize = 0;
837+
try {
838+
CacheSize = std::stoi(ValStr);
839+
if (CacheSize < 0)
840+
throw INVALID_CONFIG_EXCEPTION(BaseT, "Value must be non-negative");
841+
} catch (...) {
842+
std::string Msg =
843+
std::string{"Invalid input to SYCL_CACHE_MAX_SIZE. Please try "
844+
"a positive integer."};
845+
throw exception(make_error_code(errc::runtime), Msg);
846+
}
847+
848+
return CacheSize;
849+
};
850+
851+
static auto EvictionThresholds = Parser();
852+
if (ResetCache)
853+
EvictionThresholds = Parser();
854+
855+
return EvictionThresholds;
856+
}
857+
};
858+
809859
#undef INVALID_CONFIG_EXCEPTION
810860

811861
} // namespace detail

sycl/source/detail/os_util.cpp

+61-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#include <cassert>
1212
#include <limits>
13-
1413
#if __GNUC__ && __GNUC__ < 8
1514
// Don't include <filesystem> for GCC versions less than 8
1615
#else
@@ -277,6 +276,67 @@ int OSUtil::makeDir(const char *Dir) {
277276
return 0;
278277
}
279278

279+
// Get size of a directory in bytes.
280+
size_t OSUtil::getDirectorySize(const std::string &Path) {
281+
282+
size_t Size = 0;
283+
#if __GNUC__ && __GNUC__ < 8
284+
// Should we worry about this case?
285+
assert(false && "getDirectorySize is not implemented for GCC < 8");
286+
#else
287+
// Use C++17 filesystem API to get the size of the directory.
288+
for (const auto &entry :
289+
std::filesystem::recursive_directory_iterator(Path)) {
290+
if (entry.is_regular_file())
291+
Size += entry.file_size();
292+
}
293+
#endif
294+
return Size;
295+
}
296+
297+
// Get size of file in bytes.
298+
size_t OSUtil::getFileSize(const std::string &Path) {
299+
size_t Size = 0;
300+
#if __GNUC__ && __GNUC__ < 8
301+
// Should we worry about this case?
302+
assert(false && "getFileSize is not implemented for GCC < 8");
303+
#else
304+
std::filesystem::path FilePath(Path);
305+
if (std::filesystem::exists(FilePath) &&
306+
std::filesystem::is_regular_file(FilePath))
307+
Size = std::filesystem::file_size(FilePath);
308+
#endif
309+
return Size;
310+
}
311+
312+
// Get list of all files in the directory along with its last access time.
313+
std::vector<std::pair<time_t, std::string>>
314+
OSUtil::getFilesWithAccessTime(const std::string &Path) {
315+
std::vector<std::pair<time_t, std::string>> Files;
316+
#if __GNUC__ && __GNUC__ < 8
317+
// Should we worry about this case?
318+
assert(false && "getFilesWithAccessTime is not implemented for GCC < 8");
319+
#else
320+
for (const auto &entry :
321+
std::filesystem::recursive_directory_iterator(Path)) {
322+
if (entry.is_regular_file()) {
323+
#if defined(__SYCL_RT_OS_LINUX) || defined(__SYCL_RT_OS_DARWIN)
324+
struct stat StatBuf;
325+
if (stat(entry.path().c_str(), &StatBuf) == 0)
326+
Files.push_back({StatBuf.st_atime, entry.path().string()});
327+
#elif defined(__SYCL_RT_OS_WINDOWS)
328+
WIN32_FILE_ATTRIBUTE_DATA FileData;
329+
if (GetFileAttributesEx(entry.path().c_str(), GetFileExInfoStandard,
330+
&FileData))
331+
Files.push_back(
332+
{FileData.ftLastAccessTime.dwLowDateTime, entry.path().string()});
333+
#endif // __SYCL_RT_OS
334+
}
335+
}
336+
#endif
337+
return Files;
338+
}
339+
280340
} // namespace detail
281341
} // namespace _V1
282342
} // namespace sycl

0 commit comments

Comments
 (0)