| 270 | } |
| 271 | |
| 272 | cl::Kernel getKernel(const vector<Node*>& output_nodes, |
| 273 | const vector<int>& output_ids, |
| 274 | const vector<Node*>& full_nodes, |
| 275 | const vector<Node_ids>& full_ids, const bool is_linear, |
| 276 | const bool loop0, const bool loop1, const bool loop3) { |
| 277 | const string funcName{getFuncName(output_nodes, output_ids, full_nodes, |
| 278 | full_ids, is_linear, loop0, loop1, false, |
| 279 | loop3)}; |
| 280 | // A forward lookup in module cache helps avoid recompiling the JIT |
| 281 | // source generated from identical JIT-trees. |
| 282 | const auto entry{ |
| 283 | findModule(getActiveDeviceId(), deterministicHash(funcName))}; |
| 284 | |
| 285 | if (!entry) { |
| 286 | const string jitKer{getKernelString(funcName, full_nodes, full_ids, |
| 287 | output_ids, is_linear, loop0, loop1, |
| 288 | loop3)}; |
| 289 | saveKernel(funcName, jitKer, ".cl"); |
| 290 | |
| 291 | const common::Source jitKer_cl_src{ |
| 292 | jitKer.data(), jitKer.size(), |
| 293 | deterministicHash(jitKer.data(), jitKer.size())}; |
| 294 | const cl::Device device{getDevice()}; |
| 295 | vector<string> options; |
| 296 | if (isDoubleSupported(device)) { |
| 297 | options.emplace_back(DefineKey(USE_DOUBLE)); |
| 298 | } |
| 299 | if (isHalfSupported(device)) { |
| 300 | options.emplace_back(DefineKey(USE_HALF)); |
| 301 | } |
| 302 | return common::getKernel(funcName, {{jit_cl_src, jitKer_cl_src}}, {}, |
| 303 | options, true) |
| 304 | .get(); |
| 305 | } |
| 306 | return common::getKernel(entry, funcName, true).get(); |
| 307 | } |
| 308 | |
| 309 | void evalNodes(vector<Param>& outputs, const vector<Node*>& output_nodes) { |
| 310 | const unsigned nrOutputs{static_cast<unsigned>(outputs.size())}; |
no test coverage detected