| 269 | /// limitation on the platform. For NVIDIA this is 4096 bytes. The |
| 270 | template<typename T> |
| 271 | kJITHeuristics passesJitHeuristics(span<Node *> root_nodes) { |
| 272 | if (!evalFlag()) { return kJITHeuristics::Pass; } |
| 273 | static auto getLogger = [&] { return spdlog::get("jit"); }; |
| 274 | for (Node *n : root_nodes) { |
| 275 | if (n->getHeight() > static_cast<int>(getMaxJitSize())) { |
| 276 | AF_TRACE( |
| 277 | "JIT tree evaluated because of tree height exceeds limit: {} > " |
| 278 | "{}", |
| 279 | n->getHeight(), getMaxJitSize()); |
| 280 | return kJITHeuristics::TreeHeight; |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | // A lightweight check based on the height of the node. This is an |
| 285 | // inexpensive operation and does not traverse the JIT tree. |
| 286 | int heightCheckLimit = 6; |
| 287 | bool atHeightLimit = |
| 288 | std::any_of(std::begin(root_nodes), std::end(root_nodes), |
| 289 | [heightCheckLimit](Node *n) { |
| 290 | return (n->getHeight() + 1 >= heightCheckLimit); |
| 291 | }); |
| 292 | if (atHeightLimit || getMemoryPressure() >= getMemoryPressureThreshold()) { |
| 293 | // The size of the parameters without any extra arguments from the |
| 294 | // JIT tree. This includes one output Param object and 4 integers. |
| 295 | size_t base_param_size = |
| 296 | sizeof(Param<T>) * root_nodes.size() + (4 * sizeof(uint)); |
| 297 | |
| 298 | // extra padding for safety to avoid failure during compilation |
| 299 | constexpr size_t jit_padding_size = 256; //@umar dontfix! |
| 300 | // This is the maximum size of the params that can be allowed by the |
| 301 | // CUDA platform. |
| 302 | size_t max_param_size = 4096 - base_param_size - jit_padding_size; |
| 303 | |
| 304 | struct tree_info { |
| 305 | size_t total_buffer_size; |
| 306 | size_t num_buffers; |
| 307 | size_t param_scalar_size; |
| 308 | }; |
| 309 | NodeIterator<> end_node; |
| 310 | tree_info info = tree_info{0, 0, 0}; |
| 311 | |
| 312 | for (Node *n : root_nodes) { |
| 313 | info = accumulate( |
| 314 | NodeIterator<>(n), end_node, info, |
| 315 | [](tree_info &prev, const Node &node) { |
| 316 | if (node.isBuffer()) { |
| 317 | const auto &buf_node = |
| 318 | static_cast<const BufferNode<T> &>(node); |
| 319 | // getBytes returns the size of the data Array. |
| 320 | // Sub arrays will be represented by their |
| 321 | // parent size. |
| 322 | prev.total_buffer_size += buf_node.getBytes(); |
| 323 | prev.num_buffers++; |
| 324 | } else { |
| 325 | prev.param_scalar_size += node.getParamBytes(); |
| 326 | } |
| 327 | return prev; |
| 328 | }); |
nothing calls this directly
no test coverage detected