Compute Library
 19.08
CLFFTConvolutionLayer Class Reference

Basic function to execute FFT-based convolution on OpenCL. More...

#include <CLFFTConvolutionLayer.h>

Collaboration diagram for CLFFTConvolutionLayer:
[legend]

Public Member Functions

 CLFFTConvolutionLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Default constructor. More...
 
 CLFFTConvolutionLayer (const CLFFTConvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 CLFFTConvolutionLayer (CLFFTConvolutionLayer &&)=default
 Default move constructor. More...
 
CLFFTConvolutionLayeroperator= (const CLFFTConvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
CLFFTConvolutionLayeroperator= (CLFFTConvolutionLayer &&)=default
 Default move assignment operator. More...
 
void configure (ICLTensor *input, const ICLTensor *weights, const ICLTensor *biases, ICLTensor *output, const PadStrideInfo &conv_info, const ActivationLayerInfo &act_info=ActivationLayerInfo())
 Set the input and output tensors. More...
 
void run () override
 Run the kernels contained in the function. More...
 
void prepare () override
 Prepare the function for executing. More...
 
- Public Member Functions inherited from IFunction
virtual ~IFunction ()=default
 Destructor. More...
 

Static Public Member Functions

static Status validate (const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, const ActivationLayerInfo &act_info=ActivationLayerInfo())
 Static function to check if given info will lead to a valid configuration of CLFFTConvolutionLayer. More...
 

Detailed Description

Basic function to execute FFT-based convolution on OpenCL.

This function calls the following OpenCL functions/kernels:

  1. CLPermute Permute input if NHWC(only NCHW is supported).
  2. CLPadLayer Pad input.
  3. CLFFT2D Forward transform to the frequency domain.
  4. CLComplexPixelWiseMultiplication Complex element-wise product of input and the weights.
  5. CLReductionOperation Reduction across channels.
  6. CLFFT2D Inverse transform back to the time domain.
  7. CLStridedSlice Extract valid output.
  8. CLArithmeticAddition Add bias.
  9. CLActivationLayer Perform activation.
  10. CLPermute Permute output if NHWC(only NCHW is supported).

Definition at line 59 of file CLFFTConvolutionLayer.h.

Constructor & Destructor Documentation

◆ CLFFTConvolutionLayer() [1/3]

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

Default constructor.

Definition at line 56 of file CLFFTConvolutionLayer.cpp.

57  : _memory_group(memory_manager),
58  _flip_weights_func(),
59  _permute_input_func(),
60  _permute_output_func(),
61  _permute_weights_func(),
62  _permute_bias_func(),
63  _pad_input_func(),
64  _pad_weights_func(),
65  _transform_input_func(memory_manager),
66  _transform_weights_func(),
67  _itransform_output_func(memory_manager),
68  _prod_func(),
69  _reduce_func(),
70  _extract_output_func(),
71  _bias_add_func(),
72  _activation_layer_func(),
73  _permuted_input(),
74  _permuted_weights(),
75  _permuted_bias(),
76  _permuted_output(),
77  _padded_input(),
78  _padded_weights(),
79  _flip_axis(),
80  _flipped_weights(),
81  _transformed_input(),
82  _transformed_weights(),
83  _input_weights_product(),
84  _output_product(),
85  _output_reduced(),
86  _itransformed_output(),
87  _reshaped_output(),
88  _bias_output(),
89  _original_weights(nullptr),
90  _original_bias(nullptr),
91  _is_activationlayer_enabled(false),
92  _needs_permute(false),
93  _has_bias(false),
94  _is_prepared(false)
95 {
96 }

◆ CLFFTConvolutionLayer() [2/3]

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

◆ CLFFTConvolutionLayer() [3/3]

Default move constructor.

Member Function Documentation

◆ configure()

void configure ( ICLTensor input,
const ICLTensor weights,
const ICLTensor biases,
ICLTensor output,
const PadStrideInfo conv_info,
const ActivationLayerInfo act_info = ActivationLayerInfo() 
)

Set the input and output tensors.

Note
: This function only works with any square kernel size and unit strides for both NCHW and NHWC data layout
Parameters
[in]inputSource tensor. 3 lower dimensions represent a single input [width, height, IFM], while every optional dimension from 4 and above represent a batch of inputs. Data types supported: F32.
[in]weightsWeights tensor. Weights are 4D tensor with dimensions [kernel_x, kernel_y, IFM, OFM]. Data type supported:Same as input.
[in]biasesBiases tensor. Shared biases supported. Biases are 1D tensor with dimensions [OFM].Data type supported: Same as input
[out]outputDestination tensor. 3 lower dimensions represent a single output [width, height, OFM], while the rest represent batch of outputs. Data types supported: Same as input.
[in]conv_infoContains padding and stride information described in PadStrideInfo.
[in]act_info(Optional) Activation layer information in case of a fused activation.

Definition at line 98 of file CLFFTConvolutionLayer.cpp.

100 {
101  _original_weights = weights;
102  _original_bias = biases;
103 
104  // Flat if bias addition is required
105  _has_bias = biases != nullptr;
106 
107  // Get indices for the width and height
108  const size_t idx_width = get_data_layout_dimension_index(input->info()->data_layout(), DataLayoutDimension::WIDTH);
109  const size_t idx_height = get_data_layout_dimension_index(input->info()->data_layout(), DataLayoutDimension::HEIGHT);
110 
111  // Input shape, kernel size and output tile
112  const Size2D input_dims = Size2D(input->info()->tensor_shape()[idx_width], input->info()->tensor_shape()[idx_height]);
113  const Size2D kernel_size = Size2D(weights->info()->tensor_shape()[idx_width], weights->info()->tensor_shape()[idx_height]);
114  const Size2D pad_valid = Size2D(pad_decomposable(input_dims.x() + kernel_size.x() - 1),
115  pad_decomposable(input_dims.y() + kernel_size.y() - 1));
116  // Tensors to use
117  ICLTensor *input_to_use = input;
118  const ICLTensor *weights_to_use = weights;
119  ICLTensor *output_to_use = _has_bias ? &_bias_output : output;
120 
121  // Permute bias
122  if(biases != nullptr)
123  {
124  _permute_bias_func.configure(biases, &_permuted_bias, PermutationVector(1U, 2U, 0U));
125  _permuted_bias.info()->set_data_layout(DataLayout::NCHW);
126  }
127 
128  // Permute input if needed
129  _needs_permute = input->info()->data_layout() == DataLayout::NHWC;
130  if(_needs_permute)
131  {
132  _memory_group.manage(&_permuted_input);
133  // Configure the function to transform the input tensor from NHWC -> NCHW
134  _permute_input_func.configure(input, &_permuted_input, PermutationVector(1U, 2U, 0U));
135  _permuted_input.info()->set_data_layout(DataLayout::NCHW);
136 
137  // Configure the function to transform the weights tensor from HWI -> IHW
138  _permute_weights_func.configure(weights, &_permuted_weights, PermutationVector(1U, 2U, 0U));
139  _permuted_weights.info()->set_data_layout(DataLayout::NCHW);
140 
141  input_to_use = &_permuted_input;
142  weights_to_use = &_permuted_weights;
143  }
144 
145  // Flip weights
146  _flipped_weights.allocator()->init(weights_to_use->info()->clone()->set_is_resizable(true).reset_padding());
147  _flip_axis.allocator()->init(TensorInfo(TensorShape(2U), 1, DataType::U32));
148  _flip_weights_func.configure(weights_to_use, &_flipped_weights, &_flip_axis);
149 
150  // Pad weights
151  const PaddingList padding_w = { { 0, input_dims.x() + pad_valid.x() - 1 }, { 0, input_dims.y() + pad_valid.y() - 1 } };
152  _pad_weights_func.configure(&_flipped_weights, &_padded_weights, padding_w);
153 
154  // Transform weights
155  _transform_weights_func = support::cpp14::make_unique<CLFFT2D>();
156  _transform_weights_func->configure(&_padded_weights, &_transformed_weights, FFT2DInfo());
157 
158  // Pad input
159  const PaddingList padding_in = { { 0, kernel_size.x() + pad_valid.x() - 1 }, { 0, kernel_size.y() + pad_valid.y() - 1 } };
160  _memory_group.manage(&_padded_input);
161  _pad_input_func.configure(input_to_use, &_padded_input, padding_in);
162  if(_needs_permute)
163  {
164  _permuted_input.allocator()->allocate();
165  }
166 
167  // Transform input
168  _memory_group.manage(&_transformed_input);
169  _transform_input_func.configure(&_padded_input, &_transformed_input, FFT2DInfo());
170  _padded_input.allocator()->allocate();
171 
172  // Perform product
173  _memory_group.manage(&_output_product);
174  _prod_func.configure(&_transformed_input, &_transformed_weights, &_output_product);
175  _transformed_input.allocator()->allocate();
176 
177  // Perform reduction
178  _memory_group.manage(&_output_reduced);
179  _reduce_func.configure(&_output_product, &_output_reduced, 2, ReductionOperation::SUM);
180  _output_product.allocator()->allocate();
181 
182  // Transform output
183  _memory_group.manage(&_itransformed_output);
184  FFT2DInfo itranform_info;
185  itranform_info.direction = FFTDirection::Inverse;
186  _itransformed_output.allocator()->init(_output_reduced.info()->clone()->set_is_resizable(true).set_num_channels(1).reset_padding());
187  _itransform_output_func.configure(&_output_reduced, &_itransformed_output, itranform_info);
188  _output_reduced.allocator()->allocate();
189 
190  // Reshape output
191  TensorShape reshaped_shape = _itransformed_output.info()->tensor_shape();
192  reshaped_shape.remove_dimension(2);
193  _reshaped_output.allocator()->init(_itransformed_output.info()->clone()->set_tensor_shape(reshaped_shape));
194 
195  // Extract correct region
196  const int start_left = kernel_size.x() - conv_info.pad_left() - 1;
197  const int start_top = kernel_size.y() - conv_info.pad_top() - 1;
198  const int end_right = _reshaped_output.info()->tensor_shape().x() - (kernel_size.x() - conv_info.pad_right() - 1) - pad_valid.x();
199  const int end_botton = _reshaped_output.info()->tensor_shape().y() - (kernel_size.y() - conv_info.pad_bottom() - 1) - pad_valid.y();
200  if(_has_bias)
201  {
202  _memory_group.manage(&_bias_output);
203  }
204  else if(_needs_permute)
205  {
206  output_to_use = &_permuted_output;
207  _memory_group.manage(&_permuted_output);
208  }
209  _extract_output_func.configure(&_reshaped_output, output_to_use, Coordinates(start_left, start_top), Coordinates(end_right, end_botton));
210  _itransformed_output.allocator()->allocate();
211 
212  // Add bias
213  if(biases != nullptr)
214  {
215  output_to_use = output;
216  if(_needs_permute)
217  {
218  output_to_use = &_permuted_output;
219  _memory_group.manage(&_permuted_output);
220  }
221  auto_init_if_empty(*output_to_use->info(), *_bias_output.info());
222  _bias_add_func.configure(&_bias_output, &_permuted_bias, output_to_use, ConvertPolicy::WRAP);
223  _bias_output.allocator()->allocate();
224  }
225 
226  // Permute output
227  if(_needs_permute)
228  {
229  // Configure the function to transform the convoluted output to ACL's native ordering format NCHW
230  _permuted_output.info()->set_data_layout(DataLayout::NCHW);
231  _permute_output_func.configure(&_permuted_output, output, PermutationVector(2U, 0U, 1U));
232 
233  // Allocate tensors
234  _permuted_output.allocator()->allocate();
235  }
236 
237  // Configure Activation Layer
238  _is_activationlayer_enabled = act_info.enabled();
239  if(_is_activationlayer_enabled)
240  {
241  _activation_layer_func.configure(output, nullptr, act_info);
242  }
243 
244  // Setup flip axis data
245  _flip_axis.allocator()->allocate();
246  _flip_axis.map(true);
247  auto axis_data = reinterpret_cast<uint32_t *>(_flip_axis.buffer());
248  axis_data[0] = 0;
249  axis_data[1] = 1;
250  _flip_axis.unmap();
251 }
void remove_dimension(size_t n)
Accessor to remove the dimension n from the tensor shape.
Definition: TensorShape.h:110
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:306
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: CLTensor.cpp:35
void configure(const ICLTensor *input, ICLTensor *output, const FFT2DInfo &config)
Initialise the function's source, destinations and border mode.
Definition: CLFFT2D.cpp:37
std::vector< PaddingInfo > PaddingList
List of padding information.
Definition: Types.h:445
void configure(ICLTensor *input, ICLTensor *output, unsigned int axis, ReductionOperation op)
Set the input and output tensors.
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output, ConvertPolicy policy)
Initialise the kernel's inputs, output and conversion policy.
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:55
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
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:201
void map(bool blocking=true)
Enqueue a map operation of the allocated buffer.
Definition: CLTensor.cpp:60
uint8_t * buffer() const override
Interface to be implemented by the child class to return a pointer to CPU memory.
Definition: ICLTensor.cpp:53
T x() const
Alias to access the size of the first dimension.
Definition: Dimensions.h:81
ITensorInfo & set_data_layout(const DataLayout &data_layout) override
Set the data layout of the tensor.
Definition: TensorInfo.cpp:370
void manage(TensorType *obj)
Sets a object to be managed by the given memory group.
1 channel, 1 U32 per channel
void configure(ICLTensor *input, ICLTensor *output, const PaddingList &padding, PixelValue constant_value=PixelValue(), PaddingMode mode=PaddingMode::CONSTANT)
Initialize the function.
Definition: CLPadLayer.cpp:164
Num samples, channels, height, width.
void configure(const ICLTensor *input, ICLTensor *output, const Coordinates &starts, const Coordinates &ends)
Configure kernel.
Definition: CLSlice.cpp:34
void configure(ICLTensor *input1, ICLTensor *input2, ICLTensor *output)
Initialise the kernel's inputs, output.
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
Num samples, height, width, channels.
void configure(ICLTensor *input, ICLTensor *output, ActivationLayerInfo act_info)
Set the input and output tensor.
void configure(const ICLTensor *input, ICLTensor *output, const PermutationVector &perm)
Set the input and output tensors.
Definition: CLPermute.cpp:33
T y() const
Alias to access the size of the second dimension.
Definition: Dimensions.h:86
size_t get_data_layout_dimension_index(const DataLayout data_layout, const DataLayoutDimension data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:326
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:252
void unmap()
Enqueue an unmap operation of the allocated and mapped buffer.
Definition: CLTensor.cpp:65
void configure(const ICLTensor *input, ICLTensor *output, const ICLTensor *axis)
Initialize the function.
Definition: CLReverse.cpp:32

References arm_compute::test::validation::act_info, CLTensorAllocator::allocate(), CLTensor::allocator(), arm_compute::auto_init_if_empty(), ICLTensor::buffer(), ICloneable< T >::clone(), TensorInfo::clone(), CLReverse::configure(), CLPermute::configure(), CLSlice::configure(), CLArithmeticAddition::configure(), CLActivationLayer::configure(), CLFFT2D::configure(), CLReductionOperation::configure(), CLPadLayer::configure(), CLComplexPixelWiseMultiplication::configure(), arm_compute::test::validation::conv_info, ITensorInfo::data_layout(), FFT2DInfo::direction, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, ITensor::info(), CLTensor::info(), ITensorAllocator::init(), arm_compute::Inverse, MemoryGroupBase< TensorType >::manage(), CLTensor::map(), arm_compute::NCHW, arm_compute::NHWC, TensorShape::remove_dimension(), TensorInfo::set_data_layout(), arm_compute::SUM, ITensorInfo::tensor_shape(), TensorInfo::tensor_shape(), arm_compute::U, arm_compute::U32, CLTensor::unmap(), arm_compute::test::validation::weights, arm_compute::WIDTH, arm_compute::WRAP, Dimensions< T >::x(), and Dimensions< T >::y().

◆ operator=() [1/2]

CLFFTConvolutionLayer& operator= ( const CLFFTConvolutionLayer )
delete

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

◆ operator=() [2/2]

CLFFTConvolutionLayer& operator= ( CLFFTConvolutionLayer &&  )
default

Default move assignment operator.

◆ prepare()

void prepare ( )
overridevirtual

Prepare the function for executing.

Any one off pre-processing step required by the function is handled here

Note
Prepare stage might not need all the function's buffers' backing memory to be available in order to execute

Reimplemented from IFunction.

Definition at line 336 of file CLFFTConvolutionLayer.cpp.

337 {
338  if(!_is_prepared)
339  {
340  // Permute bias to NCHW
341  if(_original_bias != nullptr)
342  {
343  _permuted_bias.allocator()->allocate();
344  _permute_bias_func.run();
345  _original_bias->mark_as_unused();
346  }
347 
348  const ICLTensor *cur_weights = _original_weights;
349  // Permute weights
350  if(_needs_permute)
351  {
352  ARM_COMPUTE_ERROR_ON(!cur_weights->is_used());
353 
354  _permuted_weights.allocator()->allocate();
355  _permute_weights_func.run();
356  cur_weights->mark_as_unused();
357  cur_weights = &_permuted_weights;
358  }
359 
360  // Flip weights
361  _flipped_weights.allocator()->allocate();
362  _flip_weights_func.run();
363  cur_weights->mark_as_unused();
364 
365  // Pad weights
366  _padded_weights.allocator()->allocate();
367  _pad_weights_func.run();
368  _flipped_weights.mark_as_unused();
369  CLScheduler::get().queue().finish();
370  _flipped_weights.allocator()->free();
371 
372  // Transform weights to frequency domain
373  _transformed_weights.allocator()->allocate();
374  _transform_weights_func->run();
375  _padded_weights.mark_as_unused();
376  CLScheduler::get().queue().finish();
377  // Delete object and release internal memory
378  _transform_weights_func.reset();
379  _padded_weights.allocator()->free();
380 
381  _is_prepared = true;
382  }
383 }
static CLScheduler & get()
Access the scheduler singleton.
Definition: CLScheduler.cpp:41
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:337
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:55
void mark_as_unused() const
Marks a tensor as unused.
Definition: ITensor.cpp:167
void run() override final
Run the kernels contained in the function.
cl::CommandQueue & queue()
Accessor for the associated CL command queue.
Definition: CLScheduler.h:102
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
void free() override
Free allocated OpenCL memory.
void run() override
Run the kernels contained in the function.
Definition: CLPadLayer.cpp:274

References CLTensorAllocator::allocate(), CLTensor::allocator(), ARM_COMPUTE_ERROR_ON, CLTensorAllocator::free(), CLScheduler::get(), ITensor::is_used(), ITensor::mark_as_unused(), CLScheduler::queue(), ICLSimpleFunction::run(), and CLPadLayer::run().

Referenced by CLFFTConvolutionLayer::run().

◆ 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 297 of file CLFFTConvolutionLayer.cpp.

298 {
299  prepare();
300 
301  MemoryGroupResourceScope scope_mg(_memory_group);
302 
303  // Transform input
304  if(_needs_permute)
305  {
306  _permute_input_func.run();
307  }
308  _pad_input_func.run();
309  _transform_input_func.run();
310 
311  // Perform operations to frequency domain
312  _prod_func.run();
313  _reduce_func.run();
314 
315  // Transform output
316  _itransform_output_func.run();
317  _reshaped_output.allocator()->import_memory(_itransformed_output.cl_buffer());
318  _extract_output_func.run();
319  // Add bias
320  if(_has_bias)
321  {
322  _bias_add_func.run();
323  }
324  if(_needs_permute)
325  {
326  _permute_output_func.run();
327  }
328 
329  // Run activation layer
330  if(_is_activationlayer_enabled)
331  {
332  _activation_layer_func.run();
333  }
334 }
const cl::Buffer & cl_buffer() const override
Interface to be implemented by the child class to return a reference to the OpenCL buffer containing ...
Definition: CLTensor.cpp:45
void run() override
Run the kernels contained in the function.
Definition: CLFFT2D.cpp:86
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:55
Status import_memory(cl::Buffer buffer)
Import an existing memory as a tensor's backing memory.
void run() override final
Run the kernels contained in the function.
void run() override
Run the kernels contained in the function.
void run() override
Run the kernels contained in the function.
Definition: CLPadLayer.cpp:274
void prepare() override
Prepare the function for executing.

References CLTensor::allocator(), CLTensor::cl_buffer(), CLTensorAllocator::import_memory(), CLFFTConvolutionLayer::prepare(), ICLSimpleFunction::run(), CLFFT2D::run(), CLReductionOperation::run(), and CLPadLayer::run().

◆ validate()

Status validate ( const ITensorInfo input,
const ITensorInfo weights,
const ITensorInfo biases,
const ITensorInfo output,
const PadStrideInfo conv_info,
const ActivationLayerInfo act_info = ActivationLayerInfo() 
)
static

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

Note
: This function only works with any square kernel size and unit strides for both NCHW and NHWC data layout
Parameters
[in]inputSource tensor. 3 lower dimensions represent a single input [width, height, IFM], while every optional dimension from 4 and above represent a batch of inputs. Data types supported: F32.
[in]weightsWeights tensor. Weights are 4D tensor with dimensions [kernel_x, kernel_y, IFM, OFM]. Data type supported:Same as input.
[in]biasesBiases tensor. Shared biases supported. Biases are 1D tensor with dimensions [OFM].Data type supported: Same as input
[out]outputDestination tensor. 3 lower dimensions represent a single output [width, height, OFM], while the rest represent batch of outputs. Data types supported: Same as input.
[in]conv_infoContains padding and stride information described in PadStrideInfo.
[in]act_info(Optional) Activation layer information in case of a fused activation.
Returns
a status

Definition at line 253 of file CLFFTConvolutionLayer.cpp.

255 {
258 
259  // Get indices for the width and height
260  const size_t idx_width = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::WIDTH);
261  const size_t idx_height = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::HEIGHT);
262 
263  // Input shape, kernel size and output tile
264  const Size2D kernel_size = Size2D(weights->tensor_shape()[idx_width], weights->tensor_shape()[idx_height]);
265 
266  // Strides
267  const auto strides = conv_info.stride();
268  ARM_COMPUTE_RETURN_ERROR_ON(strides.first != strides.second && strides.first != 1);
269  ARM_COMPUTE_RETURN_ERROR_ON(kernel_size.x() != kernel_size.y());
270  ARM_COMPUTE_RETURN_ERROR_ON(conv_info.pad_left() != (kernel_size.x() / 2) || conv_info.pad_right() != (kernel_size.x() / 2));
271  ARM_COMPUTE_RETURN_ERROR_ON(conv_info.pad_top() != (kernel_size.y() / 2) || conv_info.pad_bottom() != (kernel_size.y() / 2));
272 
273  // Validate biases
274  if(biases != nullptr)
275  {
276  const size_t idx_channels = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::CHANNEL);
278  ARM_COMPUTE_RETURN_ERROR_ON(input->tensor_shape()[idx_channels] != biases->tensor_shape().x());
279  }
280 
281  // Checks performed when output is configured
282  if((output != nullptr) && (output->total_size() != 0))
283  {
285  ARM_COMPUTE_RETURN_ERROR_ON((input->tensor_shape()[idx_height] != output->tensor_shape()[idx_height]) || (input->tensor_shape()[idx_width] != output->tensor_shape()[idx_width]));
286 
287  // Validate Activation Layer
288  if(act_info.enabled())
289  {
291  }
292  }
293 
294  return Status{};
295 }
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const ActivationLayerInfo &act_info)
Static function to check if given info will lead to a valid configuration of CLActivationLayer.
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:545
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:193
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:791
1 channel, 1 F32 per channel
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:244
size_t get_data_layout_dimension_index(const DataLayout data_layout, const DataLayoutDimension data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:326

References arm_compute::test::validation::act_info, ARM_COMPUTE_RETURN_ERROR_ON, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES, ARM_COMPUTE_RETURN_ON_ERROR, arm_compute::CHANNEL, arm_compute::test::validation::conv_info, ITensorInfo::data_layout(), arm_compute::F32, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, ITensorInfo::tensor_shape(), ITensorInfo::total_size(), CLActivationLayer::validate(), arm_compute::test::validation::weights, arm_compute::WIDTH, and Dimensions< T >::x().

Referenced by CLConvolutionLayer::get_convolution_method(), and CLConvolutionLayer::validate().


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