| 154 | namespace common { |
| 155 | |
| 156 | Module compileModule(const string &moduleKey, span<const string> sources, |
| 157 | span<const string> options, span<const string> kInstances, |
| 158 | const bool isJIT) { |
| 159 | UNUSED(kInstances); |
| 160 | UNUSED(isJIT); |
| 161 | |
| 162 | auto compileBegin = high_resolution_clock::now(); |
| 163 | auto program = arrayfire::opencl::buildProgram(sources, options); |
| 164 | auto compileEnd = high_resolution_clock::now(); |
| 165 | |
| 166 | #ifdef AF_CACHE_KERNELS_TO_DISK |
| 167 | const int device = arrayfire::opencl::getActiveDeviceId(); |
| 168 | const string &cacheDirectory = getCacheDirectory(); |
| 169 | if (!cacheDirectory.empty()) { |
| 170 | const string cacheFile = |
| 171 | cacheDirectory + AF_PATH_SEPARATOR + |
| 172 | opencl::getKernelCacheFilename(device, moduleKey); |
| 173 | const string tempFile = |
| 174 | cacheDirectory + AF_PATH_SEPARATOR + makeTempFilename(); |
| 175 | try { |
| 176 | auto binaries = program.getInfo<CL_PROGRAM_BINARIES>(); |
| 177 | |
| 178 | // TODO Handle cases where program objects are created from contexts |
| 179 | // having multiple devices |
| 180 | const size_t clbinSize = binaries[0].size(); |
| 181 | const char *clbin = |
| 182 | reinterpret_cast<const char *>(binaries[0].data()); |
| 183 | const size_t clbinHash = deterministicHash(clbin, clbinSize); |
| 184 | |
| 185 | // write module hash and binary data to file |
| 186 | ofstream out(tempFile, std::ios::binary); |
| 187 | |
| 188 | out.write(reinterpret_cast<const char *>(&clbinHash), |
| 189 | sizeof(clbinHash)); |
| 190 | out.write(reinterpret_cast<const char *>(&clbinSize), |
| 191 | sizeof(clbinSize)); |
| 192 | out.write(static_cast<const char *>(clbin), clbinSize); |
| 193 | out.close(); |
| 194 | |
| 195 | // try to rename temporary file into final cache file, if this fails |
| 196 | // this means another thread has finished compiling this kernel |
| 197 | // before the current thread. |
| 198 | if (!renameFile(tempFile, cacheFile)) { removeFile(tempFile); } |
| 199 | } catch (const cl::Error &e) { |
| 200 | AF_TRACE( |
| 201 | "{{{:<20} : Failed to fetch opencl binary for {}, {}}}", |
| 202 | moduleKey, |
| 203 | arrayfire::opencl::getDevice(device).getInfo<CL_DEVICE_NAME>(), |
| 204 | e.what()); |
| 205 | } catch (const std::ios_base::failure &e) { |
| 206 | AF_TRACE( |
| 207 | "{{{:<20} : Failed writing binary to {} for {}, {}}}", |
| 208 | moduleKey, cacheFile, |
| 209 | arrayfire::opencl::getDevice(device).getInfo<CL_DEVICE_NAME>(), |
| 210 | e.what()); |
| 211 | } |
| 212 | } |
| 213 | #endif |
nothing calls this directly
no test coverage detected