| 348 | |
| 349 | template<typename T> |
| 350 | void evalNodes(vector<Param<T>>& outputs, const vector<Node*>& output_nodes) { |
| 351 | const unsigned nrOutputs{static_cast<unsigned>(output_nodes.size())}; |
| 352 | if (nrOutputs == 0) { return; } |
| 353 | assert(outputs.size() == output_nodes.size()); |
| 354 | dim_t* outDims{outputs[0].dims}; |
| 355 | dim_t* outStrides{outputs[0].strides}; |
| 356 | #ifndef NDEBUG |
| 357 | for_each( |
| 358 | begin(outputs)++, end(outputs), |
| 359 | [outDims, outStrides](Param<T>& output) { |
| 360 | assert(equal(output.dims, output.dims + AF_MAX_DIMS, outDims) && |
| 361 | equal(output.strides, output.strides + AF_MAX_DIMS, |
| 362 | outStrides)); |
| 363 | }); |
| 364 | #endif |
| 365 | |
| 366 | dim_t ndims{outDims[3] > 1 ? 4 |
| 367 | : outDims[2] > 1 ? 3 |
| 368 | : outDims[1] > 1 ? 2 |
| 369 | : outDims[0] > 0 ? 1 |
| 370 | : 0}; |
| 371 | bool is_linear{true}; |
| 372 | dim_t numOutElems{1}; |
| 373 | for (dim_t dim{0}; dim < ndims; ++dim) { |
| 374 | is_linear &= (numOutElems == outStrides[dim]); |
| 375 | numOutElems *= outDims[dim]; |
| 376 | } |
| 377 | if (numOutElems == 0) { return; } |
| 378 | |
| 379 | // Use thread local to reuse the memory every time you are |
| 380 | // here. |
| 381 | thread_local Node_map_t nodes; |
| 382 | thread_local vector<Node*> full_nodes; |
| 383 | thread_local vector<Node_ids> full_ids; |
| 384 | thread_local vector<int> output_ids; |
| 385 | |
| 386 | try { |
| 387 | // Reserve some space to improve performance at smaller |
| 388 | // sizes |
| 389 | constexpr size_t CAP{1024}; |
| 390 | if (full_nodes.capacity() < CAP) { |
| 391 | nodes.reserve(CAP); |
| 392 | output_ids.reserve(10); |
| 393 | full_nodes.reserve(CAP); |
| 394 | full_ids.reserve(CAP); |
| 395 | } |
| 396 | |
| 397 | const af::dtype outputType{output_nodes[0]->getType()}; |
| 398 | const size_t outputSizeofType{size_of(outputType)}; |
| 399 | for (Node* node : output_nodes) { |
| 400 | assert(node->getType() == outputType); |
| 401 | const int id = node->getNodesMap(nodes, full_nodes, full_ids); |
| 402 | output_ids.push_back(id); |
| 403 | } |
| 404 | |
| 405 | size_t inputSize{0}; |
| 406 | unsigned nrInputs{0}; |
| 407 | bool moddimsFound{false}; |
no test coverage detected