From 2788609b8a10306e9eae47543b39812a7b075aaa Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Thu, 25 Feb 2021 20:15:01 +0000 Subject: Port ClTranspose to new API Partially Resolves: COMPMID-4277 (1/2) Signed-off-by: Teresa Charlin Change-Id: I704c2303135cbe1ba46d2fd5642c84c562204bc7 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5194 Tested-by: Arm Jenkins Reviewed-by: Georgios Pinitas Comments-Addressed: Arm Jenkins --- Android.bp | 3 +- .../runtime/CL/functions/CLFullyConnectedLayer.h | 27 +++- arm_compute/runtime/CL/functions/CLLSTMLayer.h | 177 +++++++++++---------- arm_compute/runtime/CL/functions/CLPermute.h | 4 +- arm_compute/runtime/CL/functions/CLTranspose.h | 33 +++- docs/00_introduction.dox | 4 +- src/core/CL/CLKernels.h | 1 - src/core/CL/kernels/CLTransposeKernel.cpp | 116 -------------- src/core/CL/kernels/CLTransposeKernel.h | 64 -------- src/core/gpu/cl/kernels/ClPermuteKernel.cpp | 9 +- src/core/gpu/cl/kernels/ClPermuteKernel.h | 11 +- src/core/gpu/cl/kernels/ClTransposeKernel.cpp | 119 ++++++++++++++ src/core/gpu/cl/kernels/ClTransposeKernel.h | 65 ++++++++ src/runtime/CL/functions/CLFullyConnectedLayer.cpp | 36 ++++- src/runtime/CL/functions/CLLSTMLayer.cpp | 14 +- src/runtime/CL/functions/CLPermute.cpp | 5 +- src/runtime/CL/functions/CLTranspose.cpp | 39 ++++- src/runtime/gpu/cl/operators/ClPermute.h | 6 +- src/runtime/gpu/cl/operators/ClTranspose.cpp | 45 ++++++ src/runtime/gpu/cl/operators/ClTranspose.h | 58 +++++++ 20 files changed, 513 insertions(+), 323 deletions(-) delete mode 100644 src/core/CL/kernels/CLTransposeKernel.cpp delete mode 100644 src/core/CL/kernels/CLTransposeKernel.h create mode 100644 src/core/gpu/cl/kernels/ClTransposeKernel.cpp create mode 100644 src/core/gpu/cl/kernels/ClTransposeKernel.h create mode 100644 src/runtime/gpu/cl/operators/ClTranspose.cpp create mode 100644 src/runtime/gpu/cl/operators/ClTranspose.h diff --git a/Android.bp b/Android.bp index dcf4b802fa..90e28a67fc 100644 --- a/Android.bp +++ b/Android.bp @@ -146,7 +146,6 @@ cc_library_static { "src/core/CL/kernels/CLStackLayerKernel.cpp", "src/core/CL/kernels/CLStridedSliceKernel.cpp", "src/core/CL/kernels/CLTileKernel.cpp", - "src/core/CL/kernels/CLTransposeKernel.cpp", "src/core/CL/kernels/CLWeightsReshapeKernel.cpp", "src/core/CL/kernels/CLWinogradFilterTransformKernel.cpp", "src/core/CL/kernels/CLWinogradInputTransformKernel.cpp", @@ -387,6 +386,7 @@ cc_library_static { "src/core/gpu/cl/kernels/ClReshapeKernel.cpp", "src/core/gpu/cl/kernels/ClScaleKernel.cpp", "src/core/gpu/cl/kernels/ClSoftmaxKernel.cpp", + "src/core/gpu/cl/kernels/ClTransposeKernel.cpp", "src/core/gpu/cl/kernels/ClWidthConcatenate2TensorsKernel.cpp", "src/core/gpu/cl/kernels/ClWidthConcatenate4TensorsKernel.cpp", "src/core/gpu/cl/kernels/ClWidthConcatenateKernel.cpp", @@ -691,6 +691,7 @@ cc_library_static { "src/runtime/gpu/cl/operators/ClScale.cpp", "src/runtime/gpu/cl/operators/ClSoftmax.cpp", "src/runtime/gpu/cl/operators/ClSub.cpp", + "src/runtime/gpu/cl/operators/ClTranspose.cpp", "utils/CommonGraphOptions.cpp", "utils/GraphUtils.cpp", "utils/Utils.cpp", diff --git a/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h b/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h index 3f17e4a921..a640e344d4 100644 --- a/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h +++ b/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Arm Limited. + * Copyright (c) 2017-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -36,15 +36,27 @@ namespace arm_compute { -/** Basic function to reshape the weights of Fully Connected layer with OpenCL. This function calls the following kernels: +/** Function to reshape the weights of Fully Connected layer with OpenCL by transposing input tensor. This function calls the following kernel: * - * -# @ref CLTransposeKernel + * -# @ref opencl::kernels::ClTransposeKernel * * @note The fully connected layer accepts "weights" tensors only with 2 dimensions. */ -class CLFullyConnectedLayerReshapeWeights : public ICLSimpleFunction +class CLFullyConnectedLayerReshapeWeights : public IFunction { public: + /** Constructor */ + CLFullyConnectedLayerReshapeWeights(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLFullyConnectedLayerReshapeWeights(const CLFullyConnectedLayerReshapeWeights &) = delete; + /** Default move constructor */ + CLFullyConnectedLayerReshapeWeights(CLFullyConnectedLayerReshapeWeights &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLFullyConnectedLayerReshapeWeights &operator=(const CLFullyConnectedLayerReshapeWeights &) = delete; + /** Default move assignment operator */ + CLFullyConnectedLayerReshapeWeights &operator=(CLFullyConnectedLayerReshapeWeights &&) = default; + /** Default destructor */ + ~CLFullyConnectedLayerReshapeWeights(); /** Set the input and output tensors. * * @param[in] input Weights tensor. The weights must be 2 dimensional. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32. @@ -66,6 +78,13 @@ public: * @return a status */ static Status validate(const ITensorInfo *input, const ITensorInfo *output); + + // Inherited methods overridden + void run() override; + +private: + struct Impl; + std::unique_ptr _impl; }; namespace weights_transformations diff --git a/arm_compute/runtime/CL/functions/CLLSTMLayer.h b/arm_compute/runtime/CL/functions/CLLSTMLayer.h index 20b068316c..38a24d030b 100644 --- a/arm_compute/runtime/CL/functions/CLLSTMLayer.h +++ b/arm_compute/runtime/CL/functions/CLLSTMLayer.h @@ -46,8 +46,14 @@ namespace arm_compute { class CLCompileContext; -class CLTransposeKernel; class ICLTensor; +namespace opencl +{ +namespace kernels +{ +class ClTransposeKernel; +} +} /** This function performs a single time step in a Long Short-Term Memory (LSTM) layer. * @@ -212,90 +218,91 @@ public: void prepare() override; private: - MemoryGroup _memory_group; - CLFullyConnectedLayer _fully_connected_input_gate; - CLArithmeticAddition _accum_input_gate1; - CLArithmeticSubtraction _subtract_input_gate; - CLPixelWiseMultiplication _pixelwise_mul_input_gate; - CLActivationLayer _activation_input_gate; - CLFullyConnectedLayer _fully_connected_forget_gate; - CLArithmeticAddition _accum_forget_gate1; - CLPixelWiseMultiplication _pixelwise_mul_forget_gate; - CLActivationLayer _activation_forget_gate; - CLFullyConnectedLayer _fully_connected_cell_state; - CLGEMM _gemm_cell_state1; - std::unique_ptr _transpose_cell_state; - CLArithmeticAddition _accum_cell_state1; - CLArithmeticAddition _accum_cell_state2; - CLPixelWiseMultiplication _pixelwise_mul_cell_state1; - CLActivationLayer _activation_cell_state; - CLActivationLayer _cell_clip; - CLPixelWiseMultiplication _pixelwise_mul_cell_state2; - CLFullyConnectedLayer _fully_connected_output; - CLPixelWiseMultiplication _pixelwise_mul_output_state1; - CLArithmeticAddition _accum_output1; - CLActivationLayer _activation_output; - CLActivationLayer _activation_output_state; - CLPixelWiseMultiplication _pixelwise_mul_output_state2; - CLFullyConnectedLayer _fully_connected_output_state; - CLActivationLayer _projection_clip; - CLCopy _copy_cell_state; - CLCopy _copy_output; - CLConcatenateLayer _concat_scratch_buffer; - CLConcatenateLayer _concat_inputs_forget_gate; - CLConcatenateLayer _concat_weights_forget_gate; - CLConcatenateLayer _concat_weights_input_gate; - CLConcatenateLayer _concat_weights_output; - CLFill _ones_fill; - CLMeanStdDevNormalizationLayer _mean_std_norm_input_gate; - CLPixelWiseMultiplication _pixelwise_mul_input_gate_coeff; - CLArithmeticAddition _accum_input_gate_bias; - CLMeanStdDevNormalizationLayer _mean_std_norm_forget_gate; - CLPixelWiseMultiplication _pixelwise_mul_forget_gate_coeff; - CLArithmeticAddition _accum_forget_gate_bias; - CLMeanStdDevNormalizationLayer _mean_std_norm_cell_gate; - CLPixelWiseMultiplication _pixelwise_mul_cell_gate_coeff; - CLArithmeticAddition _accum_cell_gate_bias; - CLMeanStdDevNormalizationLayer _mean_std_norm_output_gate; - CLPixelWiseMultiplication _pixelwise_mul_output_gate_coeff; - CLArithmeticAddition _accum_output_gate_bias; - CLTensor _input_gate_out1; - CLTensor _input_gate_out2; - CLTensor _input_gate_out3; - CLTensor _input_gate_out4; - CLTensor _forget_gate_out1; - CLTensor _forget_gate_out2; - CLTensor _forget_gate_out3; - CLTensor _forget_gate_out4; - CLTensor _forget_gate_out5; - CLTensor _forget_gate_out6; - CLTensor _cell_state_out1; - CLTensor _cell_state_out2; - CLTensor _cell_state_out3; - CLTensor _cell_state_out4; - CLTensor _cell_state_out5; - CLTensor _output1; - CLTensor _output2; - CLTensor _output3; - CLTensor _output4; - CLTensor _cell_state_activation; - CLTensor _output_state1; - CLTensor _ones; - CLTensor _input_layer_norm_out1; - CLTensor _input_layer_norm_out2; - CLTensor _forget_layer_norm_out1; - CLTensor _forget_layer_norm_out2; - CLTensor _cell_layer_norm_out1; - CLTensor _cell_layer_norm_out2; - CLTensor _output_layer_norm_out1; - CLTensor _output_layer_norm_out2; - bool _run_peephole_opt; - bool _run_cifg_opt; - bool _perform_cell_clipping; - bool _has_projection_weights; - bool _perform_projection_clipping; - bool _is_prepared; - bool _is_layer_norm_lstm; + MemoryGroup _memory_group; + CLFullyConnectedLayer _fully_connected_input_gate; + CLArithmeticAddition _accum_input_gate1; + CLArithmeticSubtraction _subtract_input_gate; + CLPixelWiseMultiplication _pixelwise_mul_input_gate; + CLActivationLayer _activation_input_gate; + CLFullyConnectedLayer _fully_connected_forget_gate; + CLArithmeticAddition _accum_forget_gate1; + CLPixelWiseMultiplication _pixelwise_mul_forget_gate; + CLActivationLayer _activation_forget_gate; + CLFullyConnectedLayer _fully_connected_cell_state; + CLGEMM _gemm_cell_state1; + std::unique_ptr _transpose_cell_state; + CLArithmeticAddition _accum_cell_state1; + CLArithmeticAddition _accum_cell_state2; + CLPixelWiseMultiplication _pixelwise_mul_cell_state1; + CLActivationLayer _activation_cell_state; + CLActivationLayer _cell_clip; + CLPixelWiseMultiplication _pixelwise_mul_cell_state2; + CLFullyConnectedLayer _fully_connected_output; + CLPixelWiseMultiplication _pixelwise_mul_output_state1; + CLArithmeticAddition _accum_output1; + CLActivationLayer _activation_output; + CLActivationLayer _activation_output_state; + CLPixelWiseMultiplication _pixelwise_mul_output_state2; + CLFullyConnectedLayer _fully_connected_output_state; + CLActivationLayer _projection_clip; + CLCopy _copy_cell_state; + CLCopy _copy_output; + CLConcatenateLayer _concat_scratch_buffer; + CLConcatenateLayer _concat_inputs_forget_gate; + CLConcatenateLayer _concat_weights_forget_gate; + CLConcatenateLayer _concat_weights_input_gate; + CLConcatenateLayer _concat_weights_output; + CLFill _ones_fill; + CLMeanStdDevNormalizationLayer _mean_std_norm_input_gate; + CLPixelWiseMultiplication _pixelwise_mul_input_gate_coeff; + CLArithmeticAddition _accum_input_gate_bias; + CLMeanStdDevNormalizationLayer _mean_std_norm_forget_gate; + CLPixelWiseMultiplication _pixelwise_mul_forget_gate_coeff; + CLArithmeticAddition _accum_forget_gate_bias; + CLMeanStdDevNormalizationLayer _mean_std_norm_cell_gate; + CLPixelWiseMultiplication _pixelwise_mul_cell_gate_coeff; + CLArithmeticAddition _accum_cell_gate_bias; + CLMeanStdDevNormalizationLayer _mean_std_norm_output_gate; + CLPixelWiseMultiplication _pixelwise_mul_output_gate_coeff; + CLArithmeticAddition _accum_output_gate_bias; + CLTensor _input_gate_out1; + CLTensor _input_gate_out2; + CLTensor _input_gate_out3; + CLTensor _input_gate_out4; + CLTensor _forget_gate_out1; + CLTensor _forget_gate_out2; + CLTensor _forget_gate_out3; + CLTensor _forget_gate_out4; + CLTensor _forget_gate_out5; + CLTensor _forget_gate_out6; + CLTensor _cell_state_out1; + CLTensor _cell_state_out2; + CLTensor _cell_state_out3; + CLTensor _cell_state_out4; + CLTensor _cell_state_out5; + CLTensor _output1; + CLTensor _output2; + CLTensor _output3; + CLTensor _output4; + CLTensor _cell_state_activation; + CLTensor _output_state1; + CLTensor _ones; + CLTensor _input_layer_norm_out1; + CLTensor _input_layer_norm_out2; + CLTensor _forget_layer_norm_out1; + CLTensor _forget_layer_norm_out2; + CLTensor _cell_layer_norm_out1; + CLTensor _cell_layer_norm_out2; + CLTensor _output_layer_norm_out1; + CLTensor _output_layer_norm_out2; + bool _run_peephole_opt; + bool _run_cifg_opt; + bool _perform_cell_clipping; + bool _has_projection_weights; + bool _perform_projection_clipping; + bool _is_prepared; + bool _is_layer_norm_lstm; + const ICLTensor *_recurrent_to_cell_weights{ nullptr }; }; } // namespace arm_compute #endif /* ARM_COMPUTE_CLLSTMLAYER_H */ diff --git a/arm_compute/runtime/CL/functions/CLPermute.h b/arm_compute/runtime/CL/functions/CLPermute.h index bcd9566fbf..e59cca2a67 100644 --- a/arm_compute/runtime/CL/functions/CLPermute.h +++ b/arm_compute/runtime/CL/functions/CLPermute.h @@ -46,11 +46,11 @@ public: /** Prevent instances of this class from being copied (As this class contains pointers) */ CLPermute(const CLPermute &) = delete; /** Default move constructor */ - CLPermute(CLPermute &&); + CLPermute(CLPermute &&) = default; /** Prevent instances of this class from being copied (As this class contains pointers) */ CLPermute &operator=(const CLPermute &) = delete; /** Default move assignment operator */ - CLPermute &operator=(CLPermute &&); + CLPermute &operator=(CLPermute &&) = default; /** Set the input and output tensors. * * @note Arbitrary permutation vectors are supported with rank not greater than 4 diff --git a/arm_compute/runtime/CL/functions/CLTranspose.h b/arm_compute/runtime/CL/functions/CLTranspose.h index 2b7a03f23f..43cebeba90 100644 --- a/arm_compute/runtime/CL/functions/CLTranspose.h +++ b/arm_compute/runtime/CL/functions/CLTranspose.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Arm Limited. + * Copyright (c) 2017-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -25,7 +25,9 @@ #define ARM_COMPUTE_CLTRANSPOSE_H #include "arm_compute/core/Error.h" -#include "arm_compute/runtime/CL/ICLSimpleFunction.h" +#include "arm_compute/runtime/IFunction.h" + +#include namespace arm_compute { @@ -33,14 +35,22 @@ class CLCompileContext; class ICLTensor; class ITensorInfo; -/** Basic function to transpose a matrix on OpenCL. This function calls the following OpenCL kernel: - * - * -# @ref CLTransposeKernel - * - */ -class CLTranspose : public ICLSimpleFunction +/** Basic function to execute an @ref opencl::kernels::ClTransposeKernel. */ +class CLTranspose : public IFunction { public: + /** Constructor */ + CLTranspose(); + /** Destructor */ + ~CLTranspose(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLTranspose(const CLTranspose &) = delete; + /** Default move constructor */ + CLTranspose(CLTranspose &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLTranspose &operator=(const CLTranspose &) = delete; + /** Default move assignment operator */ + CLTranspose &operator=(CLTranspose &&) = default; /** Initialise the kernel's inputs and output * * @param[in] input Input tensor. Data types supported: All. @@ -62,6 +72,13 @@ public: * @return a status */ static Status validate(const ITensorInfo *input, const ITensorInfo *output); + + // Inherited methods overridden: + void run() override; + +private: + struct Impl; + std::unique_ptr _impl; }; } diff --git a/docs/00_introduction.dox b/docs/00_introduction.dox index 00a5e93ce5..b5bf34644a 100644 --- a/docs/00_introduction.dox +++ b/docs/00_introduction.dox @@ -197,7 +197,7 @@ v21.02 Public major release - @ref CLSelectKernel - @ref CLBitwiseKernel - @ref opencl::kernels::ClFloorKernel - - @ref CLTransposeKernel + - CLTransposeKernel - Deprecate functions in CLTuner: - add_lws_to_table - import_lws_table @@ -1390,7 +1390,7 @@ v17.03 Sources preview - CLGradientKernel, CLEdgeNonMaxSuppressionKernel, CLEdgeTraceKernel / CLCannyEdge - GEMM refactoring + FP16 support: CLGEMMInterleave4x4Kernel, CLGEMMTranspose1xWKernel, @ref CLGEMMMatrixMultiplyKernel, CLGEMMMatrixAdditionKernel / @ref CLGEMM - CLGEMMMatrixAccumulateBiasesKernel / @ref CLFullyConnectedLayer - - @ref CLTransposeKernel / @ref CLTranspose + - CLTransposeKernel / @ref CLTranspose - @ref CLLKTrackerInitKernel, @ref CLLKTrackerStage0Kernel, @ref CLLKTrackerStage1Kernel, @ref CLLKTrackerFinalizeKernel / CLOpticalFlow - @ref CLNormalizationLayerKernel / @ref CLNormalizationLayer - CLLaplacianPyramid, CLLaplacianReconstruct diff --git a/src/core/CL/CLKernels.h b/src/core/CL/CLKernels.h index eaac415bc4..d81b60b663 100644 --- a/src/core/CL/CLKernels.h +++ b/src/core/CL/CLKernels.h @@ -89,7 +89,6 @@ #include "src/core/CL/kernels/CLStackLayerKernel.h" #include "src/core/CL/kernels/CLStridedSliceKernel.h" #include "src/core/CL/kernels/CLTileKernel.h" -#include "src/core/CL/kernels/CLTransposeKernel.h" #include "src/core/CL/kernels/CLWeightsReshapeKernel.h" #include "src/core/CL/kernels/CLWinogradFilterTransformKernel.h" #include "src/core/CL/kernels/CLWinogradInputTransformKernel.h" diff --git a/src/core/CL/kernels/CLTransposeKernel.cpp b/src/core/CL/kernels/CLTransposeKernel.cpp deleted file mode 100644 index 56ff48be1f..0000000000 --- a/src/core/CL/kernels/CLTransposeKernel.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2017-2021 Arm Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "src/core/CL/kernels/CLTransposeKernel.h" - -#include "arm_compute/core/CL/CLHelpers.h" -#include "arm_compute/core/CL/CLKernelLibrary.h" -#include "arm_compute/core/CL/ICLTensor.h" -#include "arm_compute/core/CL/OpenCL.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/TensorInfo.h" -#include "arm_compute/core/Utils.h" -#include "src/core/CL/CLValidate.h" -#include "src/core/helpers/AutoConfiguration.h" -#include "src/core/helpers/WindowHelpers.h" -#include "support/StringSupport.h" - -namespace arm_compute -{ -namespace -{ -TensorShape transposed_tensor_shape(const TensorShape &in) -{ - TensorShape output_shape{ in }; - const size_t w_out = in[1]; - const size_t h_out = in[0]; - output_shape.set(0, w_out); - output_shape.set(1, h_out); - - return output_shape; -} - -Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output) -{ - ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output); - ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(input); - ARM_COMPUTE_RETURN_ERROR_ON(input->data_type() == DataType::UNKNOWN); - - if(output->total_size() != 0) - { - const TensorInfo tensor_info = input->clone()->set_tensor_shape(transposed_tensor_shape(input->tensor_shape())); - - ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(output, &tensor_info); - ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output); - ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(input, output); - } - - return Status{}; -} -} // namespace - -Status CLTransposeKernel::validate(const ITensorInfo *input, const ITensorInfo *output) -{ - ARM_COMPUTE_ERROR_ON_NULLPTR(input, output); - ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output)); - return Status{}; -} - -void CLTransposeKernel::configure(const ICLTensor *input, ICLTensor *output) -{ - configure(CLKernelLibrary::get().get_compile_context(), input, output); -} - -void CLTransposeKernel::configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output) -{ - ARM_COMPUTE_ERROR_ON_NULLPTR(input, output); - - // Output tensor auto inizialitation if not yet initialized - auto_init_if_empty(*output->info(), input->info()->clone()->set_tensor_shape(transposed_tensor_shape(input->info()->tensor_shape()))); - - ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info())); - auto padding_info = get_padding_info({ input, output }); - - _input = input; - _output = output; - - const unsigned int vec_size_x = adjust_vec_size(max_cl_vector_width / input->info()->element_size(), input->info()->dimension(0)); - const int vec_size_x_leftovers = input->info()->dimension(0) % vec_size_x; - const unsigned int vec_size_y = adjust_vec_size(max_cl_vector_width / input->info()->element_size(), input->info()->dimension(1)); - const int vec_size_y_leftovers = input->info()->dimension(1) % vec_size_y; - - CLBuildOptions build_opts; - build_opts.add_option("-DDATA_TYPE_IN_BYTES=" + support::cpp11::to_string(input->info()->element_size())); - build_opts.add_option("-DVEC_SIZE_X=" + support::cpp11::to_string(vec_size_x)); - build_opts.add_option("-DVEC_SIZE_LEFTOVER_X=" + support::cpp11::to_string(vec_size_x_leftovers)); - build_opts.add_option("-DVEC_SIZE_Y=" + support::cpp11::to_string(vec_size_y)); - build_opts.add_option("-DVEC_SIZE_LEFTOVER_Y=" + support::cpp11::to_string(vec_size_y_leftovers)); - - _kernel = create_kernel(compile_context, "transpose", build_opts.options()); - - // Configure kernel window - Window win = calculate_max_window(*input->info(), Steps(vec_size_x, vec_size_y)); - ICLKernel::configure_internal(win, cl::NDRange(2, 8)); - ARM_COMPUTE_ERROR_ON(has_padding_changed(padding_info)); -} -} // namespace arm_compute \ No newline at end of file diff --git a/src/core/CL/kernels/CLTransposeKernel.h b/src/core/CL/kernels/CLTransposeKernel.h deleted file mode 100644 index 0c4b7b4aff..0000000000 --- a/src/core/CL/kernels/CLTransposeKernel.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017-2020 Arm Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef ARM_COMPUTE_CLTRANSPOSEKERNEL_H -#define ARM_COMPUTE_CLTRANSPOSEKERNEL_H - -#include "src/core/CL/ICLSimple2DKernel.h" - -namespace arm_compute -{ -class ICLTensor; - -/** OpenCL kernel which transposes the elements of a matrix. - * - * [width, height, batch] -> [height, width, batch] - * - */ -class CLTransposeKernel : public ICLSimple2DKernel -{ -public: - /** Initialise the kernel's input and output. - * - * @param[in] input Input tensor. Data types supported: All. - * @param[out] output Output tensor. Data type supported: Same as @p input - */ - void configure(const ICLTensor *input, ICLTensor *output); - /** Initialise the kernel's input and output. - * - * @param[in] compile_context The compile context to be used. - * @param[in] input Input tensor. Data types supported: All. - * @param[out] output Output tensor. Data type supported: Same as @p input - */ - void configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output); - /** Static function to check if given info will lead to a valid configuration of @ref CLTransposeKernel - * - * @param[in] input Input tensor. Data types supported: All. - * @param[in] output Output tensor. Data type supported: Same as @p input - * - * @return a status - */ - static Status validate(const ITensorInfo *input, const ITensorInfo *output); -}; -} // namespace arm_compute -#endif /* ARM_COMPUTE_CLTRANSPOSEKERNEL_H */ diff --git a/src/core/gpu/cl/kernels/ClPermuteKernel.cpp b/src/core/gpu/cl/kernels/ClPermuteKernel.cpp index 04e649b911..ffc13060a8 100644 --- a/src/core/gpu/cl/kernels/ClPermuteKernel.cpp +++ b/src/core/gpu/cl/kernels/ClPermuteKernel.cpp @@ -57,7 +57,7 @@ Status validate_arguments(const ITensorInfo *src, const ITensorInfo *dst, const ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, dst); ARM_COMPUTE_RETURN_ERROR_ON(src->data_type() == DataType::UNKNOWN); ARM_COMPUTE_RETURN_ERROR_ON_MSG(src->num_dimensions() < 1 || src->num_dimensions() > 4, - "Permutation upto 4-D src tensor is supported"); + "Permutation up to 4-D src tensor is supported"); ARM_COMPUTE_RETURN_ERROR_ON_MSG(perm.num_dimensions() < 1 || perm.num_dimensions() > 4, "Permutation vector size should be less than or equal to 4"); for(const auto &p : perm) @@ -77,17 +77,12 @@ Status validate_arguments(const ITensorInfo *src, const ITensorInfo *dst, const } } // namespace -void ClPermuteKernel::configure(const ITensorInfo *src, ITensorInfo *dst, const PermutationVector &perm) -{ - configure(CLKernelLibrary::get().get_compile_context(), src, dst, perm); -} - void ClPermuteKernel::configure(const CLCompileContext &compile_context, const ITensorInfo *src, ITensorInfo *dst, const PermutationVector &perm) { ARM_COMPUTE_ERROR_ON_NULLPTR(src, dst); auto padding_info = get_padding_info({ src, dst }); const TensorShape dst_shape = get_dst_shape(src, perm); - // Output auto inizialitation if not yet initialized + // Output auto initialization if not yet initialized auto_init_if_empty(*dst, src->clone()->set_tensor_shape(dst_shape)); ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(src, dst, perm)); diff --git a/src/core/gpu/cl/kernels/ClPermuteKernel.h b/src/core/gpu/cl/kernels/ClPermuteKernel.h index ae3996fca1..b844214595 100644 --- a/src/core/gpu/cl/kernels/ClPermuteKernel.h +++ b/src/core/gpu/cl/kernels/ClPermuteKernel.h @@ -38,21 +38,12 @@ namespace kernels * * Permutes given a permutation vector */ -class ClPermuteKernel : public ICLKernel +class ClPermuteKernel : public IClKernel { public: /** Default constructor */ ClPermuteKernel() = default; ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(ClPermuteKernel); - /** Set the src and dst of the kernel. - * - * @note Arbitrary permutation vectors are supported with rank not greater than 4 - * - * @param[in] src The src tensor info. Data types supported: All. - * @param[in] dst The dst tensor info. Data types supported: Same as @p src - * @param[in] perm Permutation vector - */ - void configure(const ITensorInfo *src, ITensorInfo *dst, const PermutationVector &perm); /** Set the src and dst of the kernel. * * @note Arbitrary permutation vectors are supported with rank not greater than 4 diff --git a/src/core/gpu/cl/kernels/ClTransposeKernel.cpp b/src/core/gpu/cl/kernels/ClTransposeKernel.cpp new file mode 100644 index 0000000000..704d0152cf --- /dev/null +++ b/src/core/gpu/cl/kernels/ClTransposeKernel.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017-2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "src/core/gpu/cl/kernels/ClTransposeKernel.h" + +#include "arm_compute/core/CL/CLHelpers.h" +#include "arm_compute/core/CL/CLKernelLibrary.h" +#include "arm_compute/core/CL/ICLTensor.h" +#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/TensorInfo.h" +#include "arm_compute/core/Utils.h" +#include "arm_compute/core/Validate.h" +#include "arm_compute/core/utils/misc/ShapeCalculator.h" +#include "src/core/CL/CLValidate.h" +#include "src/core/helpers/AutoConfiguration.h" +#include "src/core/helpers/WindowHelpers.h" +#include "support/Cast.h" +#include "support/StringSupport.h" + +namespace arm_compute +{ +namespace opencl +{ +namespace kernels +{ +void ClTransposeKernel::configure(const CLCompileContext &compile_context, const ITensorInfo *src, ITensorInfo *dst) +{ + ARM_COMPUTE_ERROR_ON_NULLPTR(src, dst); + + // Output auto initialization if not yet initialized + const TensorShape dst_shape = misc::shape_calculator::compute_transposed_shape(*src); + auto_init_if_empty(*dst, src->clone()->set_tensor_shape(dst_shape)); + + ARM_COMPUTE_ERROR_THROW_ON(ClTransposeKernel::validate(src, dst)); + auto padding_info = get_padding_info({ src, dst }); + + // Create kernel + const unsigned int vec_size_x = adjust_vec_size(max_cl_vector_width / src->element_size(), src->dimension(0)); + const int vec_size_x_leftovers = src->dimension(0) % vec_size_x; + const unsigned int vec_size_y = adjust_vec_size(max_cl_vector_width / src->element_size(), src->dimension(1)); + const int vec_size_y_leftovers = src->dimension(1) % vec_size_y; + + CLBuildOptions build_opts; + build_opts.add_option("-DDATA_TYPE_IN_BYTES=" + support::cpp11::to_string(src->element_size())); + build_opts.add_option("-DVEC_SIZE_X=" + support::cpp11::to_string(vec_size_x)); + build_opts.add_option("-DVEC_SIZE_LEFTOVER_X=" + support::cpp11::to_string(vec_size_x_leftovers)); + build_opts.add_option("-DVEC_SIZE_Y=" + support::cpp11::to_string(vec_size_y)); + build_opts.add_option("-DVEC_SIZE_LEFTOVER_Y=" + support::cpp11::to_string(vec_size_y_leftovers)); + + _kernel = create_kernel(compile_context, "transpose", build_opts.options()); + + // Configure kernel window + Window win = calculate_max_window(*src, Steps(vec_size_x, vec_size_y)); + ICLKernel::configure_internal(win, cl::NDRange(2, 8)); + ARM_COMPUTE_ERROR_ON(has_padding_changed(padding_info)); +} + +Status ClTransposeKernel::validate(const ITensorInfo *src, const ITensorInfo *dst) +{ + ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, dst); + ARM_COMPUTE_RETURN_ERROR_ON_F16_UNSUPPORTED(src); + ARM_COMPUTE_RETURN_ERROR_ON(src->data_type() == DataType::UNKNOWN); + ARM_COMPUTE_RETURN_ERROR_ON_MSG(src->num_dimensions() > 2, "Transpose up to 2-D src tensor is supported"); + + // Validate configured dst + if(dst->total_size() != 0) + { + const TensorInfo dst_info = src->clone()->set_tensor_shape(misc::shape_calculator::compute_transposed_shape(*src)); + ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(dst, &dst_info); + + ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(src, dst); + ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src, dst); + } + + return Status{}; +} + +void ClTransposeKernel::run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue) +{ + ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this); + ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(ICLKernel::window(), window); + + const auto src = utils::cast::polymorphic_downcast(tensors.get_const_tensor(TensorType::ACL_SRC)); + auto dst = utils::cast::polymorphic_downcast(tensors.get_tensor(TensorType::ACL_DST)); + + Window slice = window.first_slice_window_2D(); + + do + { + unsigned int idx = 0; + add_2D_tensor_argument(idx, src, slice); + add_2D_tensor_argument(idx, dst, slice); + enqueue(queue, *this, slice, lws_hint()); + } + while(window.slide_window_slice_2D(slice)); +} +} // namespace kernels +} // namespace opencl +} // namespace arm_compute \ No newline at end of file diff --git a/src/core/gpu/cl/kernels/ClTransposeKernel.h b/src/core/gpu/cl/kernels/ClTransposeKernel.h new file mode 100644 index 0000000000..21d4fd41f5 --- /dev/null +++ b/src/core/gpu/cl/kernels/ClTransposeKernel.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017-2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_CL_TRANSPOSE_KERNEL_H +#define ARM_COMPUTE_CL_TRANSPOSE_KERNEL_H + +#include "src/core/common/Macros.h" +#include "src/core/gpu/cl/ClCompileContext.h" +#include "src/core/gpu/cl/IClKernel.h" + +namespace arm_compute +{ +namespace opencl +{ +namespace kernels +{ +/** OpenCL kernel to transpose a 2D tensor. */ +class ClTransposeKernel : public IClKernel +{ +public: + ClTransposeKernel() = default; + ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(ClTransposeKernel); + /** Set the src and dst of the kernel. + * + * @param[in] compile_context The compile context to be used. + * @param[in] src The src tensor info. Data types supported: All. + * @param[in] dst The dst tensor info. Data types supported: Same as @p src + */ + void configure(const CLCompileContext &compile_context, const ITensorInfo *src, ITensorInfo *dst); + /** Static function to check if given info will lead to a valid configuration of @ref ClTransposeKernel + * + * @param[in] src The src tensor info. Data types supported: All. + * @param[in] dst The dst tensor info. Data types supported: same as @p src. + * + * @return a status + */ + static Status validate(const ITensorInfo *src, const ITensorInfo *dst); + + // Inherited methods overridden: + void run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue) override; +}; +} // namespace kernels +} // namespace opencl +} // namespace arm_compute +#endif /*ARM_COMPUTE_CL_TRANSPOSE_KERNEL_H */ diff --git a/src/runtime/CL/functions/CLFullyConnectedLayer.cpp b/src/runtime/CL/functions/CLFullyConnectedLayer.cpp index 46a90a54b7..176c5bebd5 100644 --- a/src/runtime/CL/functions/CLFullyConnectedLayer.cpp +++ b/src/runtime/CL/functions/CLFullyConnectedLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Arm Limited. + * Copyright (c) 2017-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -40,7 +40,7 @@ #include "src/core/CL/kernels/CLGEMMMatrixMultiplyReshapedOnlyRHSKernel.h" #include "src/core/CL/kernels/CLGEMMReshapeLHSMatrixKernel.h" #include "src/core/CL/kernels/CLGEMMReshapeRHSMatrixKernel.h" -#include "src/core/CL/kernels/CLTransposeKernel.h" +#include "src/core/gpu/cl/kernels/ClTransposeKernel.h" #include "support/Cast.h" #include @@ -141,6 +141,20 @@ Status validate_mm(const ITensorInfo &input, const ITensorInfo &weights, const I } } // namespace +struct CLFullyConnectedLayerReshapeWeights::Impl +{ + const ITensor *src{ nullptr }; + ITensor *dst{ nullptr }; + std::unique_ptr op{ nullptr }; +}; + +CLFullyConnectedLayerReshapeWeights::CLFullyConnectedLayerReshapeWeights() + : _impl(std::make_unique()) +{ +} + +CLFullyConnectedLayerReshapeWeights::~CLFullyConnectedLayerReshapeWeights() = default; + void CLFullyConnectedLayerReshapeWeights::configure(const ICLTensor *input, ICLTensor *output) { configure(CLKernelLibrary::get().get_compile_context(), input, output); @@ -148,14 +162,23 @@ void CLFullyConnectedLayerReshapeWeights::configure(const ICLTensor *input, ICLT void CLFullyConnectedLayerReshapeWeights::configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output) { - auto k = std::make_unique(); - k->configure(compile_context, input, output); - _kernel = std::move(k); + _impl->src = input; + _impl->dst = output; + _impl->op = std::make_unique(); + _impl->op->configure(compile_context, _impl->src->info(), _impl->dst->info()); } Status CLFullyConnectedLayerReshapeWeights::validate(const ITensorInfo *input, const ITensorInfo *output) { - return CLTransposeKernel::validate(input, output); + return opencl::kernels::ClTransposeKernel::validate(input, output); +} + +void CLFullyConnectedLayerReshapeWeights::run() +{ + ITensorPack pack{}; + pack.add_tensor(TensorType::ACL_SRC, _impl->src); + pack.add_tensor(TensorType::ACL_DST, _impl->dst); + CLScheduler::get().enqueue_op(*_impl->op.get(), pack, false); } CLFullyConnectedLayer::CLFullyConnectedLayer(std::shared_ptr memory_manager, IWeightsManager *weights_manager) @@ -164,6 +187,7 @@ CLFullyConnectedLayer::CLFullyConnectedLayer(std::shared_ptr mem _are_weights_reshaped(true), _is_fc_after_conv(true), _is_quantized(false), _is_prepared(false), _original_weights(nullptr) { } + void CLFullyConnectedLayer::configure_mm(const CLCompileContext &compile_context, const ICLTensor *input, const ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const FullyConnectedLayerInfo &fc_info) { diff --git a/src/runtime/CL/functions/CLLSTMLayer.cpp b/src/runtime/CL/functions/CLLSTMLayer.cpp index 5036126aea..05d459c899 100644 --- a/src/runtime/CL/functions/CLLSTMLayer.cpp +++ b/src/runtime/CL/functions/CLLSTMLayer.cpp @@ -41,7 +41,7 @@ #include "src/core/CL/kernels/CLGEMMMatrixMultiplyReshapedOnlyRHSKernel.h" #include "src/core/CL/kernels/CLGEMMReshapeLHSMatrixKernel.h" #include "src/core/CL/kernels/CLGEMMReshapeRHSMatrixKernel.h" -#include "src/core/CL/kernels/CLTransposeKernel.h" +#include "src/core/gpu/cl/kernels/ClTransposeKernel.h" namespace arm_compute { @@ -51,7 +51,7 @@ using namespace arm_compute::utils::info_helpers; CLLSTMLayer::CLLSTMLayer(std::shared_ptr memory_manager) : _memory_group(std::move(memory_manager)), _fully_connected_input_gate(), _accum_input_gate1(), _subtract_input_gate(), _pixelwise_mul_input_gate(), _activation_input_gate(), _fully_connected_forget_gate(), _accum_forget_gate1(), _pixelwise_mul_forget_gate(), _activation_forget_gate(), _fully_connected_cell_state(), _gemm_cell_state1(), - _transpose_cell_state(std::make_unique()), _accum_cell_state1(), _accum_cell_state2(), _pixelwise_mul_cell_state1(), _activation_cell_state(), _cell_clip(), + _transpose_cell_state(std::make_unique()), _accum_cell_state1(), _accum_cell_state2(), _pixelwise_mul_cell_state1(), _activation_cell_state(), _cell_clip(), _pixelwise_mul_cell_state2(), _fully_connected_output(), _pixelwise_mul_output_state1(), _accum_output1(), _activation_output(), _activation_output_state(), _pixelwise_mul_output_state2(), _fully_connected_output_state(), _projection_clip(), _copy_cell_state(), _copy_output(), _concat_scratch_buffer(), _concat_inputs_forget_gate(), _concat_weights_forget_gate(), _concat_weights_input_gate(), _concat_weights_output(), _ones_fill(), _mean_std_norm_input_gate(), _pixelwise_mul_input_gate_coeff(), _accum_input_gate_bias(), _mean_std_norm_forget_gate(), @@ -256,7 +256,8 @@ void CLLSTMLayer::configure(const CLCompileContext &compile_context, const ICLTe _memory_group.manage(&_cell_state_out1); _fully_connected_cell_state.configure(compile_context, input, input_to_cell_weights, (_is_layer_norm_lstm) ? nullptr : cell_bias, &_cell_state_out1); _memory_group.manage(&_cell_state_out2); - _transpose_cell_state->configure(compile_context, recurrent_to_cell_weights, &_cell_state_out2); + _transpose_cell_state->configure(compile_context, recurrent_to_cell_weights->info(), _cell_state_out2.info()); + _recurrent_to_cell_weights = recurrent_to_cell_weights; _memory_group.manage(&_cell_state_out3); _gemm_cell_state1.configure(compile_context, output_state_in, &_cell_state_out2, nullptr, &_cell_state_out3, 1.f, 0.f); _cell_state_out2.allocator()->allocate(); @@ -680,7 +681,12 @@ void CLLSTMLayer::run() } _fully_connected_cell_state.run(); - CLScheduler::get().enqueue(*_transpose_cell_state); + ITensorPack pack; + pack.add_tensor(TensorType::ACL_SRC, _recurrent_to_cell_weights); + pack.add_tensor(TensorType::ACL_DST, &_cell_state_out2); + CLScheduler::get().enqueue_op(*_transpose_cell_state, + pack, + false); _gemm_cell_state1.run(); _accum_cell_state1.run(); if(_is_layer_norm_lstm) diff --git a/src/runtime/CL/functions/CLPermute.cpp b/src/runtime/CL/functions/CLPermute.cpp index eeb0169241..c1da2a9eca 100644 --- a/src/runtime/CL/functions/CLPermute.cpp +++ b/src/runtime/CL/functions/CLPermute.cpp @@ -43,9 +43,8 @@ CLPermute::CLPermute() : _impl(std::make_unique()) { } -CLPermute::CLPermute(CLPermute &&) = default; -CLPermute &CLPermute::operator=(CLPermute &&) = default; -CLPermute::~CLPermute() = default; + +CLPermute::~CLPermute() = default; void CLPermute::configure(const ICLTensor *input, ICLTensor *output, const PermutationVector &perm) { diff --git a/src/runtime/CL/functions/CLTranspose.cpp b/src/runtime/CL/functions/CLTranspose.cpp index 67151be9a1..142cf73259 100644 --- a/src/runtime/CL/functions/CLTranspose.cpp +++ b/src/runtime/CL/functions/CLTranspose.cpp @@ -23,12 +23,27 @@ */ #include "arm_compute/runtime/CL/functions/CLTranspose.h" -#include "src/core/CL/kernels/CLTransposeKernel.h" - -#include +#include "arm_compute/core/CL/CLKernelLibrary.h" +#include "arm_compute/core/CL/ICLTensor.h" +#include "arm_compute/core/Types.h" +#include "arm_compute/core/Validate.h" +#include "src/core/CL/ICLKernel.h" +#include "src/runtime/gpu/cl/operators/ClTranspose.h" namespace arm_compute { +struct CLTranspose::Impl +{ + const ICLTensor *src{ nullptr }; + ICLTensor *dst{ nullptr }; + std::unique_ptr op{ nullptr }; +}; +CLTranspose::CLTranspose() + : _impl(std::make_unique()) +{ +} +CLTranspose::~CLTranspose() = default; + void CLTranspose::configure(const ICLTensor *input, ICLTensor *output) { configure(CLKernelLibrary::get().get_compile_context(), input, output); @@ -36,13 +51,23 @@ void CLTranspose::configure(const ICLTensor *input, ICLTensor *output) void CLTranspose::configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output) { - auto k = std::make_unique(); - k->configure(compile_context, input, output); - _kernel = std::move(k); + ARM_COMPUTE_ERROR_ON_NULLPTR(input, output); + _impl->src = input; + _impl->dst = output; + _impl->op = std::make_unique(); + _impl->op->configure(compile_context, _impl->src->info(), _impl->dst->info()); } Status CLTranspose::validate(const ITensorInfo *input, const ITensorInfo *output) { - return CLTransposeKernel::validate(input, output); + return opencl::ClTranspose::validate(input, output); +} + +void CLTranspose::run() +{ + ITensorPack pack; + pack.add_tensor(TensorType::ACL_SRC, _impl->src); + pack.add_tensor(TensorType::ACL_DST, _impl->dst); + _impl->op->run(pack); } } // namespace arm_compute \ No newline at end of file diff --git a/src/runtime/gpu/cl/operators/ClPermute.h b/src/runtime/gpu/cl/operators/ClPermute.h index 65648c1434..20e7a32428 100644 --- a/src/runtime/gpu/cl/operators/ClPermute.h +++ b/src/runtime/gpu/cl/operators/ClPermute.h @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_CL_RESHAPE_H -#define ARM_COMPUTE_CL_RESHAPE_H +#ifndef ARM_COMPUTE_CL_PERMUTE_H +#define ARM_COMPUTE_CL_PERMUTE_H #include "src/core/gpu/cl/ClCompileContext.h" #include "src/runtime/gpu/cl/IClOperator.h" @@ -61,4 +61,4 @@ public: }; } // namespace opencl } // namespace arm_compute -#endif /* ARM_COMPUTE_CL_RESHAPE_H */ \ No newline at end of file +#endif /* ARM_COMPUTE_CL_PERMUTE_H */ \ No newline at end of file diff --git a/src/runtime/gpu/cl/operators/ClTranspose.cpp b/src/runtime/gpu/cl/operators/ClTranspose.cpp new file mode 100644 index 0000000000..48f44282e8 --- /dev/null +++ b/src/runtime/gpu/cl/operators/ClTranspose.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "src/runtime/gpu/cl/operators/ClTranspose.h" + +#include "src/core/gpu/cl/ClCompileContext.h" +#include "src/core/gpu/cl/kernels/ClTransposeKernel.h" + +namespace arm_compute +{ +namespace opencl +{ +void ClTranspose::configure(const ClCompileContext &compile_context, const ITensorInfo *src, ITensorInfo *dst) +{ + auto k = std::make_unique(); + k->configure(compile_context, src, dst); + _kernel = std::move(k); +} + +Status ClTranspose::validate(const ITensorInfo *src, const ITensorInfo *dst) +{ + return kernels::ClTransposeKernel::validate(src, dst); +} +} // namespace opencl +} // namespace arm_compute \ No newline at end of file diff --git a/src/runtime/gpu/cl/operators/ClTranspose.h b/src/runtime/gpu/cl/operators/ClTranspose.h new file mode 100644 index 0000000000..d898f677ca --- /dev/null +++ b/src/runtime/gpu/cl/operators/ClTranspose.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_CL_TRANSPOSE_H +#define ARM_COMPUTE_CL_TRANSPOSE_H + +#include "src/core/gpu/cl/ClCompileContext.h" +#include "src/runtime/gpu/cl/IClOperator.h" + +namespace arm_compute +{ +namespace opencl +{ +/** Basic function to run @ref kernels::ClTransposeKernel */ +class ClTranspose : public IClOperator +{ +public: + /** Constructor */ + ClTranspose() = default; + /** Initialise the kernel's inputs and outputs + * + * @param[in] compile_context The compile context to be used. + * @param[in] src The src tensor info. Data types supported: All. + * @param[in] dst The dst tensor info. Data types supported: Same as @p src + */ + void configure(const CLCompileContext &compile_context, const ITensorInfo *src, ITensorInfo *dst); + /** Static function to check if given info will lead to a valid configuration of @ref kernels::ClTransposeKernel. + * + * @param[in] src First tensor src info. Data types supported: All. + * @param[in] dst Output tensor info. Data types supported: same as @p src. + * + * @return a status + */ + static Status validate(const ITensorInfo *src, const ITensorInfo *dst); +}; +} // namespace opencl +} // namespace arm_compute +#endif /* ARM_COMPUTE_CL_TRANSPOSE_H */ -- cgit v1.2.1