Compute Library
 23.11
CLReductionOperation.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
33 
34 #include "src/common/utils/Log.h"
37 #include "src/runtime/Utils.h"
38 
39 namespace arm_compute
40 {
41 CLReductionOperation::CLReductionOperation(std::shared_ptr<IMemoryManager> memory_manager)
42  : _memory_group(std::move(memory_manager)),
43  _unreshaped_output(),
44  _reduction_kernel(),
45  _reshape(),
46  _reduction_axis(),
47  _is_reshape_required(false)
48 {
49 }
50 
52 
54  const ITensorInfo *input, const ITensorInfo *output, unsigned int axis, ReductionOperation op, bool keep_dims)
55 {
58  "Reduction axis greater than max number of dimensions");
59  ARM_COMPUTE_RETURN_ERROR_ON_MSG(axis > 3, "Unsupported reduction axis");
60 
61  const bool is_reshape_required = !keep_dims;
62 
63  if (is_reshape_required && output->total_size() != 0)
64  {
65  const TensorInfo expected_output_shape = output->clone()->set_tensor_shape(
66  arm_compute::misc::shape_calculator::compute_reduced_shape(input->tensor_shape(), axis, keep_dims));
67  ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(&expected_output_shape, output);
68  }
69 
70  auto *output_internal = output;
71 
72  TensorInfo output_before_reshape;
73  const auto input_shape = input->tensor_shape();
74  const auto input_num_channles = input->num_channels();
75  const auto input_qinfo = input->quantization_info();
76  const auto output_data_type = output->data_type();
77 
78  auto initialize_tensorinfo = [](TensorInfo &ti, TensorShape shape, DataType data_type, int num_channels,
81  };
82 
83  if (is_reshape_required)
84  {
85  auto shape_before_reshape = input_shape;
86  shape_before_reshape.set(axis, 1);
87  initialize_tensorinfo(output_before_reshape, shape_before_reshape, output_data_type, input_num_channles,
88  input_qinfo);
89  output_internal = &output_before_reshape;
90  }
91 
93 
94  if (is_reshape_required)
95  {
96  ARM_COMPUTE_RETURN_ON_ERROR(CLReshapeLayer::validate(output_internal, output));
97  }
98 
99  return Status{};
100 }
101 
102 ICLTensor *CLReductionOperation::configure_intermediate_result_vector(ICLTensor *input, ICLTensor *output)
103 {
104  if (!_is_reshape_required)
105  {
106  return output;
107  }
108 
109  auto shape = input->info()->tensor_shape();
110  shape.set(_reduction_axis, 1);
111  _unreshaped_output.allocator()->init(input->info()->clone()->set_tensor_shape(shape));
112  return &_unreshaped_output;
113 }
114 
116  ICLTensor *input, ICLTensor *output, unsigned int axis, ReductionOperation op, bool keep_dims)
117 {
118  configure(CLKernelLibrary::get().get_compile_context(), input, output, axis, op, keep_dims);
119 }
120 
122  ICLTensor *input,
123  ICLTensor *output,
124  unsigned int axis,
126  bool keep_dims)
127 {
129  ARM_COMPUTE_LOG_PARAMS(input, output, axis, op, keep_dims);
130  _reduction_axis = axis;
131  _is_reshape_required = !keep_dims;
132 
133  auto *output_internal = configure_intermediate_result_vector(input, output);
134 
135  if (_is_reshape_required)
136  {
137  const TensorShape output_shape =
138  arm_compute::misc::shape_calculator::compute_reduced_shape(input->info()->tensor_shape(), axis, false);
139  const auto output_data_type = input->info()->data_type();
140  auto_init_if_empty(*output->info(), input->info()
141  ->clone()
142  ->set_tensor_shape(output_shape)
143  .set_data_type(output_data_type)
144  .reset_padding()
145  .set_is_resizable(true));
146 
147  _memory_group.manage(&_unreshaped_output);
148  }
149 
150  _reduction_kernel = std::make_unique<CLReductionOperationKernel>();
151  _reduction_kernel->configure(compile_context, input, output_internal, axis, op);
152 
153  if (_is_reshape_required)
154  {
155  _reshape.configure(compile_context, &_unreshaped_output, output);
156  _unreshaped_output.allocator()->allocate();
157  }
158 }
159 
161 {
162  MemoryGroupResourceScope scope_mg(_memory_group);
163 
164  CLScheduler::get().enqueue(*_reduction_kernel, false);
165 
166  if (_is_reshape_required)
167  {
168  _reshape.run();
169  }
170 }
171 } // namespace arm_compute
ICLTensor.h
arm_compute::MemoryGroup::manage
void manage(IMemoryManageable *obj) override
Sets a object to be managed by the given memory group.
Definition: MemoryGroup.h:76
arm_compute::CLReductionOperation::CLReductionOperation
CLReductionOperation(std::shared_ptr< IMemoryManager > memory_manager=nullptr)
Default Constructor.
Definition: CLReductionOperation.cpp:41
arm_compute::CLReductionOperation::~CLReductionOperation
~CLReductionOperation()
Default Destructor.
arm_compute::QuantizationInfo
Quantization information.
Definition: QuantizationInfo.h:67
arm_compute::ITensorInfo::set_num_channels
virtual ITensorInfo & set_num_channels(int num_channels)=0
Set the number of channels to the specified value.
Helpers.h
arm_compute::test::validation::output_shape
TensorShape output_shape
Definition: LSTMLayerQuantized.cpp:469
arm_compute::CLScheduler::enqueue
void enqueue(ICLKernel &kernel, bool flush=true)
Schedule the execution of the passed kernel if possible.
Definition: CLScheduler.cpp:232
arm_compute::TensorShape
Shape of a tensor.
Definition: TensorShape.h:39
arm_compute::ITensorAllocator::init
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
Definition: ITensorAllocator.cpp:33
Utils.h
ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...)
Definition: Validate.h:574
arm_compute::ITensorInfo::set_tensor_shape
virtual ITensorInfo & set_tensor_shape(const TensorShape &shape)=0
Set the shape of an already initialized tensor.
arm_compute::ICLTensor
Interface for OpenCL tensor.
Definition: ICLTensor.h:41
TensorInfo.h
arm_compute::TensorInfo::set_data_type
ITensorInfo & set_data_type(DataType data_type) override
Set the data type to the specified value.
Definition: TensorInfo.cpp:339
arm_compute::ReductionOperation
ReductionOperation
Available reduction operations.
Definition: Types.h:408
arm_compute::CLReshapeLayer::run
void run() override
Run the kernels contained in the function.
Definition: CLReshapeLayer.cpp:73
arm_compute::CLKernelLibrary::get
static CLKernelLibrary & get()
Access the KernelLibrary singleton.
Definition: CLKernelLibrary.cpp:41
ARM_COMPUTE_RETURN_ON_ERROR
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:205
arm_compute::CLReductionOperationKernel::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *output, unsigned int axis, ReductionOperation op)
Static function to check if given info will lead to a valid configuration of CLReductionOperationKern...
Definition: CLReductionOperationKernel.cpp:216
ARM_COMPUTE_ERROR_ON_NULLPTR
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
arm_compute::ITensor::info
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
arm_compute::test::validation::shape
shape
Definition: DFT.cpp:115
arm_compute::CLCompileContext
CLCompileContext class.
Definition: CLCompileContext.h:204
arm_compute::CLReductionOperation::run
void run() override
Run the kernels contained in the function.
Definition: CLReductionOperation.cpp:160
arm_compute::auto_init_if_empty
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
Definition: AutoConfiguration.h:43
arm_compute::Status
Status class.
Definition: Error.h:52
CLScheduler.h
Interface to enqueue OpenCL kernels and get/set the OpenCL CommandQueue and ICLTuner.
arm_compute::ITensorInfo::data_type
virtual DataType data_type() const =0
Data type used for each element of the tensor.
arm_compute::misc::shape_calculator::compute_reduced_shape
TensorShape compute_reduced_shape(const TensorShape &input, unsigned int axis, bool keep_dims=true)
Calculate the reduced shape of a tensor given an axis.
Definition: ShapeCalculator.h:1403
arm_compute::CLTensorAllocator::allocate
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
Definition: CLTensorAllocator.cpp:131
PixelValue.h
arm_compute::CLTensor::allocator
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:61
arm_compute::CLScheduler::get
static CLScheduler & get()
Access the scheduler singleton.
Definition: CLScheduler.cpp:112
AutoConfiguration.h
arm_compute::test::validation::data_type
data_type
Definition: Cast.cpp:222
arm_compute::test::validation::input_shape
TensorShape input_shape
Validate test suite is to test ARM_COMPUTE_RETURN_ON_* macros we use to check the validity of given a...
Definition: LSTMLayerQuantized.cpp:466
arm_compute::misc::ICloneable::clone
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
ShapeCalculator.h
arm_compute::TensorInfo
Store the tensor's metadata.
Definition: TensorInfo.h:41
ARM_COMPUTE_RETURN_ERROR_ON_MSG
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:245
arm_compute::MemoryGroupResourceScope
Memory group resources scope handling class.
Definition: IMemoryGroup.h:82
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
CLReductionOperationKernel.h
arm_compute::CLReductionOperation::configure
void configure(ICLTensor *input, ICLTensor *output, unsigned int axis, ReductionOperation op, bool keep_dims=true)
Set the input and output tensors.
Definition: CLReductionOperation.cpp:115
Log.h
arm_compute::ITensorInfo
Store the tensor's metadata.
Definition: ITensorInfo.h:44
arm_compute::TensorShape::set
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: TensorShape.h:78
arm_compute::CLReshapeLayer::configure
void configure(const ICLTensor *input, ICLTensor *output)
Initialise the kernel's inputs and outputs.
Definition: CLReshapeLayer.cpp:52
CLReductionOperation.h
ARM_COMPUTE_LOG_PARAMS
#define ARM_COMPUTE_LOG_PARAMS(...)
Definition: Log.h:35
Validate.h
arm_compute::CLReductionOperation::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *output, unsigned int axis, ReductionOperation op, bool keep_dims=true)
Static function to check if given info will lead to a valid configuration of CLReductionOperation.
Definition: CLReductionOperation.cpp:53
arm_compute::ITensorInfo::total_size
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
arm_compute::DataType
DataType
Available data types.
Definition: CoreTypes.h:83
arm_compute::Dimensions< size_t >::num_max_dimensions
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:46
arm_compute::test::validation::qinfo
const QuantizationInfo qinfo
Definition: Im2Col.cpp:155
arm_compute::ITensorInfo::set_quantization_info
virtual ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info)=0
Set the quantization settings (scale and offset) of the tensor.
arm_compute::test::validation::input
auto input
Definition: LSTMLayerQuantized.cpp:486
arm_compute::CLReshapeLayer::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLReshapeLayer.
Definition: CLReshapeLayer.cpp:65