| 908 | } |
| 909 | |
| 910 | void CpuGemmConv2d::run(ITensorPack &tensors) |
| 911 | { |
| 912 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuGemmConv2d::run"); |
| 913 | prepare(tensors); |
| 914 | |
| 915 | auto src = tensors.get_const_tensor(ACL_SRC_0); |
| 916 | auto dst = tensors.get_tensor(ACL_DST); |
| 917 | auto gemm_input_to_use = src; |
| 918 | |
| 919 | CpuAuxTensorHandler im2col_output(offset_int_vec(Im2ColOutput), _im2col_output, tensors, false); |
| 920 | CpuAuxTensorHandler gemm_output(offset_int_vec(GemmOutput), _gemm_output, tensors, false); |
| 921 | |
| 922 | bool out_has_padding = _skip_col2im && (dst->info()->padding().bottom != 0 || dst->info()->padding().top != 0); |
| 923 | if (!_skip_im2col) |
| 924 | { |
| 925 | // Run input reshaping |
| 926 | unsigned int hint_dim = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::HEIGHT); |
| 927 | unsigned int x_dim = get_data_layout_dimension_index(_data_layout, DataLayoutDimension::WIDTH); |
| 928 | unsigned int hint_dim_iterations = _im2col_kernel->window().num_iterations(hint_dim); |
| 929 | unsigned int x_dim_iterations = _im2col_kernel->window().num_iterations(x_dim); |
| 930 | if (hint_dim_iterations < NEScheduler::get().num_threads() && x_dim_iterations > hint_dim_iterations) |
| 931 | { |
| 932 | hint_dim = x_dim; |
| 933 | } |
| 934 | ITensorPack pack = {{TensorType::ACL_SRC, src}, {TensorType::ACL_DST, im2col_output.get()}}; |
| 935 | NEScheduler::get().schedule_op(_im2col_kernel.get(), hint_dim, _im2col_kernel->window(), pack); |
| 936 | gemm_input_to_use = im2col_output.get(); |
| 937 | } |
| 938 | |
| 939 | // Handle the case where output has top/bottom padding |
| 940 | const ITensor *out_to_use = out_has_padding ? gemm_output.get() : dst; |
| 941 | Tensor gemm3d; |
| 942 | TensorInfo gemm3d_info(_gemm_output_3d); |
| 943 | gemm3d_info.set_is_resizable(true); |
| 944 | gemm3d_info.extend_padding(out_to_use->info()->padding()); |
| 945 | gemm3d.allocator()->soft_init(gemm3d_info); |
| 946 | gemm3d.allocator()->import_memory(out_to_use->buffer()); |
| 947 | auto gemm_output_to_use = gemm_output.get(); |
| 948 | |
| 949 | if (_skip_im2col) |
| 950 | { |
| 951 | gemm_output_to_use = &gemm3d; |
| 952 | } |
| 953 | if (_skip_col2im && !out_has_padding) |
| 954 | { |
| 955 | gemm_output_to_use = dst; |
| 956 | } |
| 957 | |
| 958 | ITensorPack gemm_pack = tensors; |
| 959 | gemm_pack.add_const_tensor(TensorType::ACL_SRC_0, gemm_input_to_use); |
| 960 | gemm_pack.add_tensor(TensorType::ACL_DST, gemm_output_to_use); |
| 961 | // Allocate reshaped weights if required |
| 962 | auto weights = gemm_pack.get_const_tensor(TensorType::ACL_SRC_1); |
| 963 | ARM_COMPUTE_ERROR_ON_NULLPTR(weights); |
| 964 | // Re-interpreted weights. Only tensor shape is changed. Only memory import, no allocation |
| 965 | const bool use_reinterpreted_wei = (_run_wt && _wt_method == WeightTransformMethod::ReinterpretThenTranspose); |
| 966 | CpuAuxTensorHandler reinterpreted_wei( |
| 967 | _weights_reshaped, *weights, |
no test coverage detected