Compute Library
 21.02
NEReduceMean Class Reference

Basic function to perform reduce operation. More...

#include <NEReduceMean.h>

Collaboration diagram for NEReduceMean:
[legend]

Public Member Functions

 NEReduceMean (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Constructor. More...
 
 NEReduceMean (const NEReduceMean &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
NEReduceMeanoperator= (const NEReduceMean &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 NEReduceMean (NEReduceMean &&)=delete
 Prevent instances of this class from being moved (As this class contains non movable objects) More...
 
NEReduceMeanoperator= (NEReduceMean &&)=delete
 Prevent instances of this class from being moved (As this class contains non movable objects) More...
 
 ~NEReduceMean ()
 Default destructor. More...
 
void configure (ITensor *input, const Coordinates &reduction_axis, bool keep_dims, ITensor *output)
 Configure kernel. 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 Coordinates &reduction_axis, bool keep_dims, const ITensorInfo *output)
 Static function to check if given info will lead to a valid configuration of NEReduceMean. More...
 

Detailed Description

Basic function to perform reduce operation.

Definition at line 40 of file NEReduceMean.h.

Constructor & Destructor Documentation

◆ NEReduceMean() [1/3]

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

Constructor.

Definition at line 102 of file NEReduceMean.cpp.

103  : _memory_group(std::move(memory_manager)), _reduction_kernels(), _reduced_outs(), _reshape(), _dequant(), _requant(), _reduction_ops(), _keep_dims(), _do_requant(), _input_no_quant(),
104  _output_no_quant()
105 {
106 }

◆ NEReduceMean() [2/3]

NEReduceMean ( const NEReduceMean )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ NEReduceMean() [3/3]

NEReduceMean ( NEReduceMean &&  )
delete

Prevent instances of this class from being moved (As this class contains non movable objects)

◆ ~NEReduceMean()

~NEReduceMean ( )
default

Default destructor.

Member Function Documentation

◆ configure()

void configure ( ITensor input,
const Coordinates reduction_axis,
bool  keep_dims,
ITensor output 
)

Configure kernel.

Note
Supported tensor rank: up to 4
Parameters
[in]inputSource tensor. Data type supported: QASYMM8_SIGNED/QASYMM8/F16/F32
[in]reduction_axisReduction axis vector.
[in]keep_dimsIf positive, retains reduced dimensions with length 1.
[out]outputDestination tensor. Data type supported: Same as input

Definition at line 113 of file NEReduceMean.cpp.

References TensorAllocator::allocate(), Tensor::allocator(), ARM_COMPUTE_ERROR_THROW_ON, arm_compute::auto_init_if_empty(), Dimensions< T >::begin(), arm_compute::misc::shape_calculator::calculate_reduce_mean_shape(), ICloneable< T >::clone(), NEDequantizationLayer::configure(), NEQuantizationLayer::configure(), NEReshapeLayer::configure(), arm_compute::convert_negative_axis(), ITensorInfo::data_type(), arm_compute::F32, ITensor::info(), Tensor::info(), arm_compute::test::validation::info, arm_compute::test::validation::input, arm_compute::is_data_type_quantized(), MemoryGroup::manage(), arm_compute::MEAN_SUM, ITensorInfo::num_channels(), Dimensions< T >::num_dimensions(), ITensorInfo::num_dimensions(), arm_compute::test::validation::output_shape, ITensorInfo::quantization_info(), TensorShape::remove_dimension(), TensorShape::set(), TensorInfo::set_data_type(), ITensorInfo::tensor_shape(), and NEReduceMean::validate().

114 {
115  // Perform validate step
116  ARM_COMPUTE_ERROR_THROW_ON(NEReduceMean::validate(input->info(), reduction_axis, keep_dims, output->info()));
117  // Output auto inizialitation if not yet initialized
118  const TensorShape output_shape = arm_compute::misc::shape_calculator::calculate_reduce_mean_shape(input->info(), reduction_axis, keep_dims);
119  auto_init_if_empty(*output->info(), input->info()->clone()->set_tensor_shape(output_shape));
120 
121  _do_requant = is_data_type_quantized(input->info()->data_type()) && input->info()->quantization_info() != output->info()->quantization_info();
122  _reduction_ops = reduction_axis.num_dimensions();
123  _reduction_kernels.resize(_reduction_ops);
124  _reduced_outs.resize(_reduction_ops - (keep_dims ? 1 : 0));
125  _keep_dims = keep_dims;
126 
127  ITensor *tmp_input = input;
128  ITensor *tmp_output = output;
129  if(_do_requant)
130  {
131  _memory_group.manage(&_input_no_quant);
132  _memory_group.manage(&_output_no_quant);
133  TensorInfo output_no_quant_info = input->info()->clone()->set_tensor_shape(output_shape);
134  output_no_quant_info.set_data_type(DataType::F32);
135  auto_init_if_empty(*_output_no_quant.info(), output_no_quant_info);
136  auto_init_if_empty(*_input_no_quant.info(), input->info()->clone()->set_data_type(DataType::F32));
137  _dequant.configure(input, &_input_no_quant);
138  tmp_input = &_input_no_quant;
139  tmp_output = &_output_no_quant;
140  }
141 
142  Coordinates axis_local = reduction_axis;
143  const int input_dims = tmp_input->info()->num_dimensions();
144 
145  convert_negative_axis(axis_local, input_dims);
146 
147  // Perform reduction for every axis
148  for(int i = 0; i < _reduction_ops; ++i)
149  {
150  TensorShape out_shape = i == 0 ? tmp_input->info()->tensor_shape() : (&_reduced_outs[i - 1])->info()->tensor_shape();
151  out_shape.set(axis_local[i], 1);
152  auto in = (i == 0) ? tmp_input : (&_reduced_outs[i - 1]);
153 
154  if(i == _reduction_ops - 1 && keep_dims)
155  {
156  _reduction_kernels[i].configure(in, tmp_output, axis_local[i], ReductionOperation::MEAN_SUM);
157  }
158  else
159  {
160  _reduced_outs[i].allocator()->init(TensorInfo(out_shape, tmp_input->info()->num_channels(), tmp_input->info()->data_type(), tmp_input->info()->quantization_info()));
161  _memory_group.manage(&_reduced_outs[i]);
162  _reduction_kernels[i].configure(in, &_reduced_outs[i], axis_local[i], ReductionOperation::MEAN_SUM);
163  }
164  }
165 
166  // Allocate intermediate tensors
167  for(int i = 0; i < _reduction_ops - (keep_dims ? 1 : 0); ++i)
168  {
169  _reduced_outs[i].allocator()->allocate();
170  }
171 
172  // Configure reshape layer if we want to drop the dimensions
173  if(!keep_dims)
174  {
175  TensorShape out_shape = tmp_input->info()->tensor_shape();
176  // We have to sort the reduction axis vectors in order for remove_dimension
177  // to work properly
178  std::sort(axis_local.begin(), axis_local.begin() + _reduction_ops);
179  for(int i = 0; i < _reduction_ops; ++i)
180  {
181  out_shape.remove_dimension(axis_local[i] - i);
182  }
183  auto_init_if_empty(*tmp_output->info(), tmp_input->info()->clone()->set_tensor_shape(out_shape));
184  _reshape.configure(&_reduced_outs[_reduction_ops - 1], tmp_output);
185  }
186  if(_do_requant)
187  {
188  _requant.configure(&_output_no_quant, output);
189  _input_no_quant.allocator()->allocate();
190  _output_no_quant.allocator()->allocate();
191  }
192 }
bool is_data_type_quantized(DataType dt)
Check if a given data type is of quantized type.
Definition: Utils.h:1168
virtual size_t num_dimensions() const =0
The number of dimensions of the tensor (rank)
void configure(const ITensor *input, ITensor *output)
Configure the kernel.
1 channel, 1 F32 per channel
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
TensorAllocator * allocator()
Return a pointer to the tensor&#39;s allocator.
Definition: Tensor.cpp:48
ITensorInfo * info() const override
Interface to be implemented by the child class to return the tensor&#39;s metadata.
Definition: Tensor.cpp:33
void manage(IMemoryManageable *obj) override
Sets a object to be managed by the given memory group.
Definition: MemoryGroup.h:79
TensorShape calculate_reduce_mean_shape(ITensorInfo *input, const Coordinates &reduction_axis, bool keep_dims)
Calculate the output tensor shape for the reduce mean operation.
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
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...
void configure(const ITensor *input, ITensor *output)
Set the input and output tensors.
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
void configure(const ITensor *input, ITensor *output)
Initialise the kernel&#39;s inputs and outputs.
Coordinates & convert_negative_axis(Coordinates &coords, int max_value)
Convert negative coordinates to positive in the range [0, num_dims_input].
Definition: Helpers.h:241
static Status validate(const ITensorInfo *input, const Coordinates &reduction_axis, bool keep_dims, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of NEReduceMean.

◆ operator=() [1/2]

NEReduceMean& operator= ( const NEReduceMean )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ operator=() [2/2]

NEReduceMean& operator= ( NEReduceMean &&  )
delete

Prevent instances of this class from being moved (As this class contains non movable objects)

◆ 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 194 of file NEReduceMean.cpp.

References INESimpleFunctionNoBorder::run(), and NEReshapeLayer::run().

195 {
196  MemoryGroupResourceScope scope_mg(_memory_group);
197  if(_do_requant)
198  {
199  _dequant.run();
200  }
201  for(auto &kernel : _reduction_kernels)
202  {
203  kernel.run();
204  }
205  if(!_keep_dims)
206  {
207  _reshape.run();
208  }
209  if(_do_requant)
210  {
211  _requant.run();
212  }
213 }
void run() override final
Run the kernels contained in the function.
void run() override
Run the kernels contained in the function.

◆ validate()

Status validate ( const ITensorInfo input,
const Coordinates reduction_axis,
bool  keep_dims,
const ITensorInfo output 
)
static

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

Parameters
[in]inputSource tensor. Data type supported: QASYMM8_SIGNED/QASYMM8/F16/F32
[in]reduction_axisReduction axis vector.
[in]keep_dimsIf positive, retains reduced dimensions with length 1.
[in]outputDestination tensor. Data type supported: Same as input
Returns
A status

Definition at line 108 of file NEReduceMean.cpp.

Referenced by NEReduceMean::configure().

109 {
110  return validate_config(input, reduction_axis, keep_dims, output);
111 }

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