17 #if defined(__SYCL_RT_OS_POSIX_SUPPORT)
29 const char LockCacheItem::LockSuffix[] =
".lock";
31 LockCacheItem::LockCacheItem(
const std::string &Path)
32 : FileName(Path + LockSuffix) {
36 if ((fd = open(FileName.c_str(), O_CREAT | O_EXCL, S_IWRITE)) != -1) {
45 if (Owned && std::remove(FileName.c_str()))
58 bool PersistentDeviceCodeCache::isImageCached(
const RTDeviceBinaryImage &Img) {
69 static auto MaxImgSize = getNumParam<SYCL_CACHE_MAX_DEVICE_IMAGE_SIZE>(
70 DEFAULT_MAX_DEVICE_IMAGE_SIZE);
71 static auto MinImgSize = getNumParam<SYCL_CACHE_MIN_DEVICE_IMAGE_SIZE>(
72 DEFAULT_MIN_DEVICE_IMAGE_SIZE);
76 if ((MaxImgSize && (Img.getSize() > MaxImgSize)) ||
77 (MinImgSize && (Img.getSize() < MinImgSize)))
87 const SerializedObj &SpecConsts,
const std::string &BuildOptionsString,
90 if (!isImageCached(Img))
102 std::string FileName;
104 FileName = DirName +
"/" + std::to_string(i++);
107 unsigned int DeviceNum = 0;
113 std::vector<size_t> BinarySizes(DeviceNum);
116 sizeof(size_t) * BinarySizes.size(), BinarySizes.data(),
nullptr);
118 std::vector<std::vector<char>> Result;
119 std::vector<char *> Pointers;
120 for (
size_t I = 0; I < BinarySizes.size(); ++I) {
121 Result.emplace_back(BinarySizes[I]);
122 Pointers.push_back(Result[I].data());
126 sizeof(
char *) * Pointers.size(),
127 Pointers.data(),
nullptr);
132 if (Lock.isOwned()) {
133 std::string FullFileName = FileName +
".bin";
134 writeBinaryDataToFile(FullFileName, Result);
135 trace(
"device binary has been cached: " + FullFileName);
136 writeSourceItem(FileName +
".src", Device, Img, SpecConsts,
150 const SerializedObj &SpecConsts,
const std::string &BuildOptionsString) {
152 if (!isImageCached(Img))
163 std::string FileName{Path +
"/" + std::to_string(i)};
168 isCacheItemSrcEqual(FileName +
".src", Device, Img, SpecConsts,
169 BuildOptionsString)) {
171 std::string FullFileName = FileName +
".bin";
172 std::vector<std::vector<char>> res =
173 readBinaryDataFromFile(FullFileName);
174 trace(
"using cached device binary: " + FullFileName);
180 FileName = Path +
"/" + std::to_string(++i);
187 std::string PersistentDeviceCodeCache::getDeviceIDString(
const device &Device) {
188 return Device.get_platform().get_info<sycl::info::platform::name>() +
"/" +
189 Device.get_info<sycl::info::device::name>() +
"/" +
190 Device.get_info<sycl::info::device::version>() +
"/" +
191 Device.get_info<sycl::info::device::driver_version>();
198 void PersistentDeviceCodeCache::writeBinaryDataToFile(
199 const std::string &FileName,
const std::vector<std::vector<char>> &Data) {
200 std::ofstream FileStream{FileName, std::ios::binary};
202 size_t Size = Data.size();
203 FileStream.write((
char *)&Size,
sizeof(Size));
205 for (
size_t i = 0; i < Data.size(); ++i) {
206 Size = Data[i].size();
207 FileStream.write((
char *)&Size,
sizeof(Size));
208 FileStream.write(Data[i].data(), Size);
211 if (FileStream.fail())
212 trace(
"Failed to write binary file " + FileName);
218 std::vector<std::vector<char>>
219 PersistentDeviceCodeCache::readBinaryDataFromFile(
const std::string &FileName) {
220 std::ifstream FileStream{FileName, std::ios::binary};
221 size_t ImgNum = 0, ImgSize = 0;
222 FileStream.read((
char *)&ImgNum,
sizeof(ImgNum));
224 std::vector<std::vector<char>> Res(ImgNum);
225 for (
size_t i = 0; i < ImgNum; ++i) {
226 FileStream.read((
char *)&ImgSize,
sizeof(ImgSize));
228 std::vector<char> ImgData(ImgSize);
229 FileStream.read(ImgData.data(), ImgSize);
231 Res[i] = std::move(ImgData);
235 if (FileStream.fail()) {
236 trace(
"Failed to read binary file from " + FileName);
247 void PersistentDeviceCodeCache::writeSourceItem(
248 const std::string &FileName,
const device &Device,
249 const RTDeviceBinaryImage &Img,
const SerializedObj &SpecConsts,
250 const std::string &BuildOptionsString) {
251 std::ofstream FileStream{FileName, std::ios::binary};
253 std::string DeviceString{getDeviceIDString(Device)};
254 size_t Size = DeviceString.size();
255 FileStream.write((
char *)&Size,
sizeof(Size));
256 FileStream.write(DeviceString.data(), Size);
258 Size = BuildOptionsString.size();
259 FileStream.write((
char *)&Size,
sizeof(Size));
260 FileStream.write(BuildOptionsString.data(), Size);
262 Size = SpecConsts.size();
263 FileStream.write((
char *)&Size,
sizeof(Size));
264 FileStream.write((
const char *)SpecConsts.data(), Size);
266 Size = Img.getSize();
267 FileStream.write((
char *)&Size,
sizeof(Size));
268 FileStream.write((
const char *)Img.getRawData().BinaryStart, Size);
271 if (FileStream.fail()) {
272 trace(
"Failed to write source file to " + FileName);
279 bool PersistentDeviceCodeCache::isCacheItemSrcEqual(
280 const std::string &FileName,
const device &Device,
281 const RTDeviceBinaryImage &Img,
const SerializedObj &SpecConsts,
282 const std::string &BuildOptionsString) {
283 std::ifstream FileStream{FileName, std::ios::binary};
285 std::string ImgString{(
const char *)Img.getRawData().BinaryStart,
287 std::string SpecConstsString{(
const char *)SpecConsts.data(),
291 FileStream.read((
char *)&Size,
sizeof(Size));
292 std::string res(Size,
'\0');
293 FileStream.read(&res[0], Size);
294 if (getDeviceIDString(Device).compare(res))
297 FileStream.read((
char *)&Size,
sizeof(Size));
299 FileStream.read(&res[0], Size);
300 if (BuildOptionsString.compare(res))
303 FileStream.read((
char *)&Size,
sizeof(Size));
305 FileStream.read(&res[0], Size);
306 if (SpecConstsString.compare(res))
309 FileStream.read((
char *)&Size,
sizeof(Size));
311 FileStream.read(&res[0], Size);
312 if (ImgString.compare(res))
317 if (FileStream.fail()) {
318 trace(
"Failed to read source file from " + FileName);
329 const SerializedObj &SpecConsts,
const std::string &BuildOptionsString) {
330 std::string cache_root{getRootDir()};
331 if (cache_root.empty()) {
332 trace(
"Disable persistent cache due to unconfigured cache root.");
336 std::string ImgString =
"";
340 std::string DeviceString{getDeviceIDString(Device)};
341 std::string SpecConstsString{(
const char *)SpecConsts.data(),
343 std::hash<std::string> StringHasher{};
345 return cache_root +
"/" + std::to_string(StringHasher(DeviceString)) +
"/" +
346 std::to_string(StringHasher(ImgString)) +
"/" +
347 std::to_string(StringHasher(SpecConstsString)) +
"/" +
348 std::to_string(StringHasher(BuildOptionsString));
353 bool PersistentDeviceCodeCache::isEnabled() {
355 static bool FirstCheck =
true;
360 return CacheIsEnabled;
365 std::string PersistentDeviceCodeCache::getRootDir() {