| 54 | } |
| 55 | |
| 56 | void CpuDirectConv2d::configure(ITensorInfo *src, |
| 57 | ITensorInfo *weights, |
| 58 | const ITensorInfo *bias, |
| 59 | ITensorInfo *dst, |
| 60 | const PadStrideInfo &conv_info, |
| 61 | const ActivationLayerInfo &act_info) |
| 62 | { |
| 63 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuDirectConv2d::configure"); |
| 64 | ARM_COMPUTE_ERROR_ON(src->data_layout() != DataLayout::NCHW && src->data_layout() != DataLayout::NHWC); |
| 65 | ARM_COMPUTE_LOG_PARAMS(src, weights, bias, dst, conv_info, act_info); |
| 66 | |
| 67 | _output_stage_kernel = std::make_unique<kernels::CpuDirectConv2dOutputStageKernel>(); |
| 68 | _conv_kernel = std::make_unique<kernels::CpuDirectConv2dKernel>(); |
| 69 | _input_border_handler = std::make_unique<NEFillBorderKernel>(); |
| 70 | _is_nchw = src->data_layout() == DataLayout::NCHW; |
| 71 | _has_bias = bias != nullptr; |
| 72 | _is_padding_required = !_conv_kernel->border_size().empty(); |
| 73 | |
| 74 | // Free accumulator |
| 75 | if (_accumulator.buffer() != nullptr) |
| 76 | { |
| 77 | _accumulator.allocator()->free(); |
| 78 | } |
| 79 | |
| 80 | ITensorInfo *input_to_use = src; |
| 81 | ITensorInfo *weights_to_use = weights; |
| 82 | ITensorInfo *output_to_use = dst; |
| 83 | |
| 84 | if (_is_nchw) |
| 85 | { |
| 86 | _permute_input = std::make_unique<cpu::CpuPermute>(); |
| 87 | _permute_weights = std::make_unique<cpu::CpuPermute>(); |
| 88 | |
| 89 | _permute_input->configure(src, &_src_perm_info, PermutationVector(2U, 0U, 1U)); |
| 90 | _src_perm_info.set_data_layout(DataLayout::NHWC); |
| 91 | input_to_use = &_src_perm_info; |
| 92 | |
| 93 | _aux_mem[PermInput] = experimental::MemoryInfo( |
| 94 | offset_int_vec(PermInput), experimental::MemoryLifetime::Temporary, input_to_use->total_size()); |
| 95 | |
| 96 | _permute_weights->configure(weights, &_wei_perm_info, PermutationVector(2U, 0U, 1U)); |
| 97 | _wei_perm_info.set_data_layout(DataLayout::NHWC); |
| 98 | weights_to_use = &_wei_perm_info; |
| 99 | |
| 100 | // @note: possible optimization to do weight transform once if the weight is constant. But, it requires changes to the API. |
| 101 | _aux_mem[PermWeights] = experimental::MemoryInfo( |
| 102 | offset_int_vec(PermWeights), experimental::MemoryLifetime::Temporary, weights_to_use->total_size()); |
| 103 | |
| 104 | _dst_perm_info.set_data_layout(DataLayout::NHWC); |
| 105 | output_to_use = &_dst_perm_info; |
| 106 | } |
| 107 | |
| 108 | _conv_kernel->configure(input_to_use, weights_to_use, output_to_use, conv_info); |
| 109 | |
| 110 | if (_is_padding_required) |
| 111 | { |
| 112 | // Add zero padding XY |
| 113 | _input_border_handler->configure(input_to_use, _conv_kernel->border_size(), BorderMode::CONSTANT, |
nothing calls this directly
no test coverage detected