Compute Library
 19.11
NEReductionOperation Class Reference

Basic function to simulate a reduction operation. More...

#include <NEReductionOperation.h>

Collaboration diagram for NEReductionOperation:
[legend]

Public Member Functions

 NEReductionOperation (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Default constructor. More...
 
void configure (ITensor *input, ITensor *output, unsigned int axis, ReductionOperation op, bool keep_dims=true)
 Set the input and output tensors. More...
 
void run () override
 Run the kernels contained in the function. More...
 
- Public Member Functions inherited from IFunction
virtual ~IFunction ()=default
 Destructor. More...
 
virtual void prepare ()
 Prepare the function for executing. More...
 

Static Public Member Functions

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 NEReductionOperation. More...
 

Detailed Description

Basic function to simulate a reduction operation.

This function calls the following NEON kernels:

  1. NEFillBorderKernel
  2. NEReductionOperationKernel

Definition at line 45 of file NEReductionOperation.h.

Constructor & Destructor Documentation

◆ NEReductionOperation()

NEReductionOperation ( std::shared_ptr< IMemoryManager memory_manager = nullptr)

Default constructor.

Definition at line 56 of file NEReductionOperation.cpp.

57  : _memory_group(memory_manager), _reduction_kernel(), _fill_border_kernel(), _reshape_kernel(), _output_internal(), _window_split(0), _reduction_axis(), _is_reshape_required(false)
58 {
59 }

Member Function Documentation

◆ configure()

void configure ( ITensor input,
ITensor output,
unsigned int  axis,
ReductionOperation  op,
bool  keep_dims = true 
)

Set the input and output tensors.

Parameters
[in]inputSource tensor. Data type supported: QASYMM8/F16/F32. Data layouts supported: NCHW. (Written to only for border_size != 0)
[out]outputDestination tensor. Data types and data layouts supported: same as input.
[in]axisDimension along which to reduce. Supported reduction axis : 0
[in]opReduction operation to perform.
[in]keep_dims(Optional) Whether to keep the reduced dimension after the operation. Defaults to true.

Definition at line 100 of file NEReductionOperation.cpp.

101 {
103 
104  _is_reshape_required = !keep_dims;
105 
106  auto *output_internal = output;
107  const auto is_arg_min_max = (op == ReductionOperation::ARG_IDX_MAX) || (op == ReductionOperation::ARG_IDX_MIN);
108 
109  if(_is_reshape_required)
110  {
111  const auto output_internal_shape = arm_compute::misc::shape_calculator::compute_reduced_shape(input->info()->tensor_shape(), axis);
112  const auto output_external_shape = arm_compute::misc::shape_calculator::compute_reduced_shape(input->info()->tensor_shape(), axis, false);
113  const auto output_data_type = is_arg_min_max ? DataType::S32 : input->info()->data_type();
114  const auto num_channels = input->info()->num_channels();
115  const auto qinfo = input->info()->quantization_info();
116 
117  _output_internal.allocator()->init(input->info()->clone()->set_data_type(output_data_type).set_tensor_shape(output_internal_shape).reset_padding().set_is_resizable(true).set_num_channels(
118  num_channels).set_quantization_info(qinfo));
119  _memory_group.manage(&_output_internal);
120  output_internal = &_output_internal;
121  auto_init_if_empty(*output->info(), input->info()->clone()->set_data_type(output_data_type).set_tensor_shape(output_external_shape).reset_padding().set_is_resizable(true));
122  }
123 
124  ARM_COMPUTE_ERROR_THROW_ON(NEReductionOperation::validate(input->info(), output->info(), axis, op, keep_dims));
125 
126  // Configure reduction kernel
127  _reduction_kernel.configure(input, output_internal, axis, op);
128  _window_split = reduction_window_split_dimension(axis);
129  _reduction_axis = axis;
130 
131  if(axis == 0)
132  {
133  // Configure fill border kernel
134  const BorderSize fill_border_size = _reduction_kernel.border_size();
135  PixelValue pixelValue;
136  switch(op)
137  {
139  {
140  pixelValue = PixelValue(1, input->info()->data_type(), input->info()->quantization_info());
141  break;
142  }
144  {
145  switch(input->info()->data_type())
146  {
147  case DataType::F32:
148  {
149  pixelValue = PixelValue(std::numeric_limits<float>::max());
150  break;
151  }
152  case DataType::F16:
153  {
154  pixelValue = PixelValue(static_cast<half>(65504.0f));
155  break;
156  }
157  case DataType::QASYMM8:
158  {
159  pixelValue = PixelValue(255, input->info()->data_type(), input->info()->quantization_info());
160  break;
161  }
162  default:
163  {
164  ARM_COMPUTE_ERROR("Unsupported DataType");
165  }
166  }
167  break;
168  }
170  {
171  switch(input->info()->data_type())
172  {
173  case DataType::F32:
174  {
175  pixelValue = PixelValue(-std::numeric_limits<float>::max());
176  break;
177  }
178  case DataType::F16:
179  {
180  pixelValue = PixelValue(static_cast<half>(-65504.0f));
181  break;
182  }
183  case DataType::QASYMM8:
184  {
185  pixelValue = PixelValue(0, input->info()->data_type(), input->info()->quantization_info());
186  break;
187  }
188  default:
189  {
190  ARM_COMPUTE_ERROR("Unsupported DataType");
191  }
192  }
193  break;
194  }
200  {
201  pixelValue = PixelValue(0, input->info()->data_type());
202  break;
203  }
204  default:
205  ARM_COMPUTE_ERROR("Reduction Operation unsupported");
206  }
207  _fill_border_kernel.configure(input, fill_border_size, (is_arg_min_max ? BorderMode::REPLICATE : BorderMode::CONSTANT), pixelValue);
208  }
209 
210  if(_is_reshape_required)
211  {
212  _reshape_kernel.configure(output_internal, output);
213  _output_internal.allocator()->allocate();
214  }
215 }
void init(const TensorAllocator &allocator, const Coordinates &coords, TensorInfo &sub_info)
Shares the same backing memory with another tensor allocator, while the tensor info might be differen...
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
1 channel, 1 F32 per channel
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
void configure(ITensor *tensor, BorderSize border_size, BorderMode border_mode, const PixelValue &constant_border_value=PixelValue())
Initialise the function.
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: Helpers.inl:202
1 channel, 1 F16 per channel
TensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: Tensor.cpp:48
1 channel, 1 S32 per channel
void manage(IMemoryManageable *obj) override
Sets a object to be managed by the given memory group.
Definition: MemoryGroup.h:79
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 NEReductionOperation.
quantized, asymmetric fixed-point 8-bit number unsigned
BorderSize border_size() const override
The size of the border for that kernel.
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
TensorShape compute_reduced_shape(const TensorShape &input, unsigned int axis, bool keep_dims=true)
Calculate the reduced shape of a tensor given an axis.
void configure(const ITensor *input, ITensor *output, unsigned int axis, ReductionOperation op)
Set the source, destination of the kernel.
void configure(const ITensor *input, ITensor *output)
Set the input and output of the kernel.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
Pixels outside the image are assumed to have the same value as the closest image pixel.
const QuantizationInfo qinfo
Definition: Im2Col.cpp:150

References TensorAllocator::allocate(), Tensor::allocator(), arm_compute::ARG_IDX_MAX, arm_compute::ARG_IDX_MIN, ARM_COMPUTE_ERROR, ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, arm_compute::auto_init_if_empty(), arm_compute::test::validation::axis, NEReductionOperationKernel::border_size(), arm_compute::misc::shape_calculator::compute_reduced_shape(), NEReshapeLayerKernel::configure(), NEFillBorderKernel::configure(), NEReductionOperationKernel::configure(), arm_compute::CONSTANT, arm_compute::F16, arm_compute::F32, ITensor::info(), TensorAllocator::init(), arm_compute::test::validation::input, MemoryGroup::manage(), arm_compute::MAX, arm_compute::MEAN_SUM, arm_compute::MIN, arm_compute::test::validation::output_data_type, arm_compute::PROD, arm_compute::QASYMM8, arm_compute::test::validation::qinfo, arm_compute::REPLICATE, arm_compute::S32, arm_compute::SUM, arm_compute::SUM_SQUARE, and NEReductionOperation::validate().

Referenced by NEL2NormalizeLayer::configure(), and NEFFTConvolutionLayer::configure().

◆ run()

void run ( )
overridevirtual

Run the kernels contained in the function.

For NEON kernels:

  • Multi-threading is used for the kernels which are parallelisable.
  • By default std::thread::hardware_concurrency() threads are used.
Note
CPPScheduler::set_num_threads() can be used to manually set the number of threads

For OpenCL kernels:

  • All the kernels are enqueued on the queue associated with CLScheduler.
  • The queue is then flushed.
Note
The function will not block until the kernels are executed. It is the user's responsibility to wait.
Will call prepare() on first run if hasn't been done

Implements IFunction.

Definition at line 217 of file NEReductionOperation.cpp.

218 {
219  if(_reduction_axis == 0)
220  {
221  NEScheduler::get().schedule(&_fill_border_kernel, Window::DimY);
222  }
223  NEScheduler::get().schedule(&_reduction_kernel, _window_split);
224  if(_is_reshape_required)
225  {
226  NEScheduler::get().schedule(&_reshape_kernel, Window::DimY);
227  }
228 }
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
virtual void schedule(ICPPKernel *kernel, const Hints &hints)=0
Runs the kernel in the same thread as the caller synchronously.
static IScheduler & get()
Access the scheduler singleton.
Definition: Scheduler.cpp:95

References Window::DimY, Scheduler::get(), and IScheduler::schedule().

Referenced by NEL2NormalizeLayer::run(), and NEFFTConvolutionLayer::run().

◆ validate()

Status validate ( const ITensorInfo input,
const ITensorInfo output,
unsigned int  axis,
ReductionOperation  op,
bool  keep_dims = true 
)
static

Static function to check if given info will lead to a valid configuration of NEReductionOperation.

Parameters
[in]inputSource tensor info. Data type supported: QASYMM8/F16/F32. Data layouts supported: NCHW. (Written to only for border_size != 0)
[in]outputDestination tensor info. Data types and data layouts supported: same as input.
[in]axisDimension along which to reduce. Supported reduction axis : 0
[in]opReduction operation to perform.
[in]keep_dims(Optional) Whether to keep the reduced dimension after the operation. Defaults to true.
Returns
a status

Definition at line 61 of file NEReductionOperation.cpp.

62 {
63  ARM_COMPUTE_RETURN_ERROR_ON_MSG(axis >= TensorShape::num_max_dimensions, "Reduction axis greater than max number of dimensions");
64  ARM_COMPUTE_RETURN_ERROR_ON_MSG(axis > 3, "Unsupported reduction axis");
65 
66  const auto is_reshape_required = !keep_dims;
67 
68  auto *output_internal = output;
69 
70  TensorInfo info_before_reshape;
71 
72  if(is_reshape_required)
73  {
74  const TensorInfo expected_output_shape = output->clone()->set_tensor_shape(arm_compute::misc::shape_calculator::compute_reduced_shape(input->tensor_shape(), axis, keep_dims));
75  ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(&expected_output_shape, output);
76 
77  auto shape_before_reshape = input->tensor_shape();
78  shape_before_reshape.set(axis, 1);
79 
80  const auto input_num_channles = input->num_channels();
81  const auto input_qinfo = input->quantization_info();
82  const auto is_arg_min_max = (op == ReductionOperation::ARG_IDX_MAX) || (op == ReductionOperation::ARG_IDX_MIN);
83  const auto output_data_type = is_arg_min_max ? DataType::S32 : output->data_type();
84 
85  info_before_reshape.set_data_type(output_data_type).set_tensor_shape(shape_before_reshape).set_num_channels(input_num_channles).set_quantization_info(input_qinfo);
86 
87  output_internal = &info_before_reshape;
88  }
89 
91 
92  if(is_reshape_required)
93  {
95  }
96 
97  return Status{};
98 }
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
1 channel, 1 S32 per channel
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 NEReductionOperationKern...
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...)
Definition: Validate.h:443
TensorShape compute_reduced_shape(const TensorShape &input, unsigned int axis, bool keep_dims=true)
Calculate the reduced shape of a tensor given an axis.
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of NEReshapeLayerKernel.
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
If the condition is true, an error is returned.
Definition: Error.h:244
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:45

References arm_compute::ARG_IDX_MAX, arm_compute::ARG_IDX_MIN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES, ARM_COMPUTE_RETURN_ERROR_ON_MSG, ARM_COMPUTE_RETURN_ON_ERROR, arm_compute::test::validation::axis, ICloneable< T >::clone(), arm_compute::misc::shape_calculator::compute_reduced_shape(), ITensorInfo::data_type(), arm_compute::test::validation::input, Dimensions< uint32_t >::num_max_dimensions, arm_compute::test::validation::output_data_type, arm_compute::S32, TensorInfo::set_data_type(), ITensorInfo::set_num_channels(), ITensorInfo::set_quantization_info(), ITensorInfo::set_tensor_shape(), NEReshapeLayerKernel::validate(), and NEReductionOperationKernel::validate().

Referenced by NEReductionOperation::configure(), NEL2NormalizeLayer::validate(), and NEArgMinMaxLayer::validate().


The documentation for this class was generated from the following files: