| 221 | } |
| 222 | |
| 223 | Module loadModuleFromDisk(const int device, const string &moduleKey, |
| 224 | const bool isJIT) { |
| 225 | const string &cacheDirectory = getCacheDirectory(); |
| 226 | if (cacheDirectory.empty()) return Module{}; |
| 227 | |
| 228 | auto &dev = arrayfire::opencl::getDevice(device); |
| 229 | const string cacheFile = cacheDirectory + AF_PATH_SEPARATOR + |
| 230 | opencl::getKernelCacheFilename(device, moduleKey); |
| 231 | Program program; |
| 232 | Module retVal{}; |
| 233 | try { |
| 234 | std::ifstream in(cacheFile, std::ios::binary); |
| 235 | if (!in.is_open()) { |
| 236 | AF_TRACE("{{{:<20} : Unable to open {} for {}}}", moduleKey, |
| 237 | cacheFile, dev.getInfo<CL_DEVICE_NAME>()); |
| 238 | removeFile(cacheFile); |
| 239 | return retVal; |
| 240 | } |
| 241 | in.exceptions(std::ios::failbit | std::ios::badbit); |
| 242 | |
| 243 | // TODO Handle cases where program objects are created from contexts |
| 244 | // having multiple devices |
| 245 | size_t clbinHash = 0; |
| 246 | in.read(reinterpret_cast<char *>(&clbinHash), sizeof(clbinHash)); |
| 247 | size_t clbinSize = 0; |
| 248 | in.read(reinterpret_cast<char *>(&clbinSize), sizeof(clbinSize)); |
| 249 | vector<unsigned char> clbin(clbinSize); |
| 250 | in.read(reinterpret_cast<char *>(clbin.data()), clbinSize); |
| 251 | in.close(); |
| 252 | |
| 253 | const size_t recomputedHash = |
| 254 | deterministicHash(clbin.data(), clbinSize); |
| 255 | if (recomputedHash != clbinHash) { |
| 256 | AF_TRACE( |
| 257 | "{{{:<20} : Corrupt binary({}) found on disk for {}, removed}}", |
| 258 | moduleKey, cacheFile, dev.getInfo<CL_DEVICE_NAME>()); |
| 259 | removeFile(cacheFile); |
| 260 | return retVal; |
| 261 | } |
| 262 | program = Program(arrayfire::opencl::getContext(), {dev}, {clbin}); |
| 263 | program.build(); |
| 264 | |
| 265 | AF_TRACE("{{{:<20} : loaded from {} for {} }}", moduleKey, cacheFile, |
| 266 | dev.getInfo<CL_DEVICE_NAME>()); |
| 267 | retVal.set(program); |
| 268 | } catch (const std::ios_base::failure &e) { |
| 269 | AF_TRACE("{{{:<20} : IO failure while loading {} for {}; {}}}", |
| 270 | moduleKey, cacheFile, dev.getInfo<CL_DEVICE_NAME>(), e.what()); |
| 271 | removeFile(cacheFile); |
| 272 | } catch (const cl::Error &e) { |
| 273 | AF_TRACE( |
| 274 | "{{{:<20} : Loading OpenCL binary({}) failed for {}; {}, Build " |
| 275 | "Log: {}}}", |
| 276 | moduleKey, cacheFile, dev.getInfo<CL_DEVICE_NAME>(), e.what(), |
| 277 | opencl::getProgramBuildLog(program)); |
| 278 | removeFile(cacheFile); |
| 279 | } |
| 280 | return retVal; |
nothing calls this directly
no test coverage detected