Compute Library
 19.08
CLGEMMDeconvolutionLayer Class Reference

Function to run the deconvolution layer through a call to GEMM. More...

#include <CLGEMMDeconvolutionLayer.h>

Collaboration diagram for CLGEMMDeconvolutionLayer:
[legend]

Public Member Functions

 CLGEMMDeconvolutionLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Constructor. More...
 
 CLGEMMDeconvolutionLayer (const CLGEMMDeconvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 CLGEMMDeconvolutionLayer (CLGEMMDeconvolutionLayer &&)=default
 Default move constructor. More...
 
CLGEMMDeconvolutionLayeroperator= (const CLGEMMDeconvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
CLGEMMDeconvolutionLayeroperator= (CLGEMMDeconvolutionLayer &&)=default
 Default move assignment operator. More...
 
void configure (const ICLTensor *input, const ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const PadStrideInfo &deconv_info)
 Set the input, weights, biases 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 *bias, const ITensorInfo *output, const PadStrideInfo &deconv_info)
 Static function to check if given info will lead to a valid configuration of CLDeconvolutionLayer. More...
 

Detailed Description

Function to run the deconvolution layer through a call to GEMM.

Deconvolution Layer is the backward pass of Convolution Layer. First we transform the input depending on the stride and pad info and then perform a 1x1 convolution pass. Input stride defines how many zeroes we should put between each element of the input, pad is the amount of padding and finally a is a user specified value where a < stride - 1, that increases the padding top and right of the input image.

The relation between input to output is as follows:

\[ width\_output = (width\_input - 1) \cdot stride\_x - 2 \cdot padding\_x + kernel\_x \]

\[ height\_output = (height\_input - 1) \cdot stride\_y - 2 \cdot padding\_y + kernel\_y \]

where: width_input is the size of the first input dimension. height_input is the size of the second input dimension. width_output is the size of the first output dimension. height_output is the size of the second output dimension. kernel_x and kernel_y are the convolution sizes in x and y. stride_x and stride_y is the input stride of the first and second dimension.

The weights used by Deconvolution are supposed to be the same as the ones used for Convolution.

This function calls the following OpenCL kernels/functions:

  1. CLGEMMLowpMatrixMultiplyCore
  2. CLGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPoint
  3. CLPermute
  4. CLPermute
  5. CLReshapeLayer
  6. CLTranspose
  7. CLDeconvolutionReshapeOutputKernel
  8. CLSlice

Definition at line 78 of file CLGEMMDeconvolutionLayer.h.

Constructor & Destructor Documentation

◆ CLGEMMDeconvolutionLayer() [1/3]

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

Constructor.

Definition at line 67 of file CLGEMMDeconvolutionLayer.cpp.

68  : _memory_group(std::move(memory_manager)),
69  _mm_gemm(),
70  _mm_gemmlowp(),
71  _gemmlowp_output_stage(),
72  _permute_input_to_nhwc(),
73  _permute_weights_to_nhwc(),
74  _reshape_weights(),
75  _transpose_weights(),
76  _deconv_reshape(),
77  _slice_gemm(),
78  _gemmlowp_final(),
79  _reshaped_weights(),
80  _reshaped_weights_t(),
81  _permuted_input(),
82  _permuted_weights(),
83  _gemm_output(),
84  _slice_gemm_input(),
85  _original_weights(),
86  _is_prepared(false),
87  _padded_input(false),
88  _is_nchw(false),
89  _is_quantized(false)
90 {
91 }

◆ CLGEMMDeconvolutionLayer() [2/3]

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

◆ CLGEMMDeconvolutionLayer() [3/3]

Default move constructor.

Member Function Documentation

◆ configure()

void configure ( const ICLTensor input,
const ICLTensor weights,
const ICLTensor bias,
ICLTensor output,
const PadStrideInfo deconv_info 
)

Set the input, weights, biases and output tensors.

Parameters
[in,out]inputInput tensor. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: F16/F32. Data layout supported: NHWC
[in]weightsThe 4d weights with dimensions [width, height, IFM, OFM]. Data type supported: Same as input. Data layout supported: same as input.
[in]bias(Optional) The biases have one dimension. Data type supported: Same as input. Data layout supported: same as input.
[out]outputOutput tensor. The output has the same number of dimensions as the input. Data layout supported: same as input.
[in]deconv_infoContains padding and policies to be used in the deconvolution, this is described in PadStrideInfo. This function supports only stride_x = weights.width && stride_y = weights.height. Moreover, padding is not supported.

Definition at line 186 of file CLGEMMDeconvolutionLayer.cpp.

187 {
188  ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
190  weights->info(),
191  bias != nullptr ? bias->info() : nullptr,
192  output->info(),
193  deconv_info));
194 
195  _original_weights = weights;
196  _padded_input = deconv_info.pad_bottom() > 0 || deconv_info.pad_left() > 0 || deconv_info.pad_right() > 0 || deconv_info.pad_top() > 0;
197  _is_nchw = input->info()->data_layout() == DataLayout::NCHW;
198  _is_quantized = is_data_type_quantized_asymmetric(input->info()->data_type());
199 
200  const ICLTensor *input_to_use = input;
201  const ICLTensor *weights_to_use = weights;
202 
203  // If the data layout is NCHW, transform everything in NHWC. Another alternative could be to
204  // do an outer product in NCHW and then an accumulation through a reduction. This would have two
205  // drawbacks: first, the outer product is less efficient than a full GEMM. Second, the reduction
206  // might be slower than GEMM.
207  if(_is_nchw)
208  {
209  _memory_group.manage(&_permuted_input);
210  _permute_input_to_nhwc.configure(input, &_permuted_input, PermutationVector(2U, 0U, 1U));
211 
212  _permute_weights_to_nhwc.configure(weights, &_permuted_weights, PermutationVector(2U, 0U, 1U));
213 
214  input_to_use = &_permuted_input;
215  weights_to_use = &_permuted_weights;
216  }
217 
218  // Reshape the input weights. The weights will be reshaped only once during the call to prepare()
219  _reshaped_weights.allocator()->init(TensorInfo(TensorShape(weights_to_use->info()->dimension(0),
220  weights_to_use->info()->dimension(1) * weights_to_use->info()->dimension(2) * weights_to_use->info()->dimension(3)),
221  1,
222  input->info()->data_type(), weights->info()->quantization_info()));
223 
224  _reshape_weights.configure(weights_to_use, &_reshaped_weights);
225  _transpose_weights.configure(&_reshaped_weights, &_reshaped_weights_t);
226 
227  const size_t idx_h = get_data_layout_dimension_index(input->info()->data_layout(), DataLayoutDimension::HEIGHT);
228  GEMMInfo gemm_info(false, false, true, input->info()->dimension(idx_h), true);
229 
230  // Configure output stage for asymmetric quantized types
231  if(_is_quantized)
232  {
233  _mm_gemmlowp.configure(input_to_use, &_reshaped_weights_t, nullptr, &_gemm_output, gemm_info);
234  }
235  else
236  {
237  _mm_gemm.configure(input_to_use, &_reshaped_weights_t, nullptr, &_gemm_output, 1.f, 0.0f, gemm_info);
238  }
239 
240  if(_is_nchw)
241  {
242  _permuted_input.allocator()->allocate();
243  }
244 
245  ICLTensor *deconv_reshape_output = nullptr;
246  ICLTensor *slice_output = nullptr;
247  ICLTensor *output_stage_output = nullptr;
248 
249  if(_padded_input && _is_quantized)
250  {
251  _memory_group.manage(&_slice_gemm_input);
252  _memory_group.manage(&_gemmlowp_final);
253  deconv_reshape_output = &_gemmlowp_final;
254  output_stage_output = &_slice_gemm_input;
255  slice_output = output;
256  }
257  else if(_padded_input)
258  {
259  _memory_group.manage(&_slice_gemm_input);
260  deconv_reshape_output = &_slice_gemm_input;
261  slice_output = output;
262  }
263  else if(_is_quantized)
264  {
265  _memory_group.manage(&_gemmlowp_final);
266  deconv_reshape_output = &_gemmlowp_final;
267  output_stage_output = output;
268  }
269  else
270  {
271  deconv_reshape_output = output;
272  }
273 
274  // Configure a Col2Im call to reshape the output of GEMM
275  _deconv_reshape.configure(&_gemm_output, bias, deconv_reshape_output, input->info(), weights->info(), deconv_info);
276  _gemm_output.allocator()->allocate();
277 
278  if(_is_quantized)
279  {
280  const UniformQuantizationInfo iq_info = input->info()->quantization_info().uniform();
281  const UniformQuantizationInfo wq_info = weights->info()->quantization_info().uniform();
282  const UniformQuantizationInfo oq_info = _gemmlowp_final.info()->quantization_info().uniform();
283 
284  float multiplier = iq_info.scale * wq_info.scale / oq_info.scale;
285  int output_multiplier(0);
286  int output_shift(0);
287  quantization::calculate_quantized_multiplier_less_than_one(multiplier, &output_multiplier, &output_shift);
288  _gemmlowp_output_stage.configure(&_gemmlowp_final, nullptr, output_stage_output, output_multiplier, output_shift, oq_info.offset);
289  _gemmlowp_final.allocator()->allocate();
290  }
291 
292  // If the input was padded, the output needs to be sliced.
293  if(_padded_input)
294  {
295  const auto start_end = compute_start_end_slice_coordinates(*deconv_reshape_output->info(), deconv_info, _is_nchw);
296  _slice_gemm.configure(&_slice_gemm_input, slice_output, start_end.first, start_end.second);
297  _slice_gemm_input.allocator()->allocate();
298  }
299 }
arm_compute::Status calculate_quantized_multiplier_less_than_one(float multiplier, int *quant_multiplier, int *right_shift)
Calculate quantized representation of multiplier with value less than one.
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: CLTensor.cpp:35
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, const ITensorInfo *output, const PadStrideInfo &deconv_info)
Static function to check if given info will lead to a valid configuration of CLDeconvolutionLayer.
QuantizationInfo quantization_info() const override
Get the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.h:293
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
void configure(const ICLTensor *input, const ICLTensor *bias, ICLTensor *output, int result_fixedpoint_multiplier, int result_shift, int result_offset_after_shift, int min=0, int max=0)
Initialise the kernel's inputs, output.
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:55
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:327
void configure(const ICLTensor *a, const ICLTensor *b, const ICLTensor *c, ICLTensor *output, const GEMMInfo &gemm_info=GEMMInfo())
Initialise the kernel's inputs, output.
void configure(const ICLTensor *input, const ICLTensor *bias, ICLTensor *output, const ITensorInfo *input_info, const ITensorInfo *weights_info, const PadStrideInfo &deconv_info)
Initialise the kernel's source and destination.
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
void manage(TensorType *obj)
Sets a object to be managed by the given memory group.
UniformQuantizationInfo uniform() const
Return per layer quantization info.
Num samples, channels, height, width.
void configure(const ICLTensor *input, ICLTensor *output, const Coordinates &starts, const Coordinates &ends)
Configure kernel.
Definition: CLSlice.cpp:34
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:1030
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
void configure(const ICLTensor *a, const ICLTensor *b, const ICLTensor *c, ICLTensor *output, float alpha, float beta, const GEMMInfo &gemm_info=GEMMInfo())
Initialise the kernel's inputs and output.
Definition: CLGEMM.cpp:470
void configure(const ICLTensor *input, ICLTensor *output, const PermutationVector &perm)
Set the input and output tensors.
Definition: CLPermute.cpp:33
void configure(const ICLTensor *input, ICLTensor *output)
Initialise the kernel's inputs and outputs.
void configure(const ICLTensor *input, ICLTensor *output)
Initialise the kernel's inputs and output.
Definition: CLTranspose.cpp:33
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 CLTensorAllocator::allocate(), CLTensor::allocator(), ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, arm_compute::test::validation::bias, arm_compute::quantization::calculate_quantized_multiplier_less_than_one(), CLReshapeLayer::configure(), CLPermute::configure(), CLTranspose::configure(), CLSlice::configure(), CLDeconvolutionReshapeOutputKernel::configure(), CLGEMMLowpMatrixMultiplyCore::configure(), CLGEMM::configure(), CLGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPoint::configure(), ITensorInfo::data_layout(), ITensorInfo::data_type(), ITensorInfo::dimension(), arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, ITensor::info(), CLTensor::info(), ITensorAllocator::init(), arm_compute::is_data_type_quantized_asymmetric(), MemoryGroupBase< TensorType >::manage(), arm_compute::NCHW, UniformQuantizationInfo::offset, PadStrideInfo::pad_bottom(), PadStrideInfo::pad_left(), PadStrideInfo::pad_right(), PadStrideInfo::pad_top(), ITensorInfo::quantization_info(), TensorInfo::quantization_info(), UniformQuantizationInfo::scale, arm_compute::U, QuantizationInfo::uniform(), CLGEMMDeconvolutionLayer::validate(), and arm_compute::test::validation::weights.

◆ operator=() [1/2]

CLGEMMDeconvolutionLayer& operator= ( const CLGEMMDeconvolutionLayer )
delete

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

◆ operator=() [2/2]

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 334 of file CLGEMMDeconvolutionLayer.cpp.

335 {
336  if(!_is_prepared)
337  {
338  ARM_COMPUTE_ERROR_ON(!_original_weights->is_used());
339 
340  if(_is_nchw)
341  {
342  _permuted_weights.allocator()->allocate();
343  _permute_weights_to_nhwc.run();
344  }
345 
346  _reshaped_weights.allocator()->allocate();
347  _reshape_weights.run();
348 
349  if(_is_nchw)
350  {
351  _permuted_weights.allocator()->free();
352  }
353 
354  _reshaped_weights_t.allocator()->allocate();
355  _transpose_weights.run();
356 
357  // Prepare gemm
358  if(!_is_quantized)
359  {
360  _mm_gemm.prepare();
361  }
362  else
363  {
364  _mm_gemmlowp.prepare();
365  }
366 
367  // Free resources
368  if(!_reshaped_weights_t.is_used())
369  {
370  _reshaped_weights_t.allocator()->free();
371  }
372 
373  _original_weights->mark_as_unused();
374  _is_prepared = true;
375  }
376 }
void prepare() override
Prepare the function for executing.
Definition: CLGEMM.cpp:632
void prepare() override
Prepare the function for executing.
bool is_used() const
Flags if the tensor is used or not.
Definition: ITensor.cpp:162
#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.
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
void free() override
Free allocated OpenCL memory.

References CLTensorAllocator::allocate(), CLTensor::allocator(), ARM_COMPUTE_ERROR_ON, CLTensorAllocator::free(), ITensor::is_used(), ITensor::mark_as_unused(), CLGEMMLowpMatrixMultiplyCore::prepare(), CLGEMM::prepare(), and ICLSimpleFunction::run().

Referenced by CLGEMMDeconvolutionLayer::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 301 of file CLGEMMDeconvolutionLayer.cpp.

302 {
303  prepare();
304 
305  MemoryGroupResourceScope scope_mg(_memory_group);
306 
307  if(_is_nchw)
308  {
309  _permute_input_to_nhwc.run();
310  }
311 
312  if(_is_quantized)
313  {
314  _mm_gemmlowp.run();
315  }
316  else
317  {
318  _mm_gemm.run();
319  }
320 
321  CLScheduler::get().enqueue(_deconv_reshape, false);
322 
323  if(_is_quantized)
324  {
325  _gemmlowp_output_stage.run();
326  }
327 
328  if(_padded_input)
329  {
330  _slice_gemm.run();
331  }
332 }
void run() override
Run the kernels contained in the function.
Definition: CLGEMM.cpp:572
static CLScheduler & get()
Access the scheduler singleton.
Definition: CLScheduler.cpp:41
void run() override
Run the kernels contained in the function.
void run() override final
Run the kernels contained in the function.
void enqueue(ICLKernel &kernel, bool flush=true)
Schedule the execution of the passed kernel if possible.
Definition: CLScheduler.cpp:95
void prepare() override
Prepare the function for executing.

References CLScheduler::enqueue(), CLScheduler::get(), CLGEMMDeconvolutionLayer::prepare(), ICLSimpleFunction::run(), CLGEMMLowpMatrixMultiplyCore::run(), and CLGEMM::run().

◆ validate()

Status validate ( const ITensorInfo input,
const ITensorInfo weights,
const ITensorInfo bias,
const ITensorInfo output,
const PadStrideInfo deconv_info 
)
static

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

Parameters
[in]inputInput tensor info. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: F16/F32. Data layout supported: NHWC
[in]weightsThe 4d weights info with dimensions [width, height, IFM, OFM]. Data type supported: Same as input. Data layout supported: same as input.
[in]bias(Optional) The biases have one dimension. Data type supported: Same as input. Data layout supported: same as input.
[in]outputOutput tensor info. The output has the same number of dimensions as the input. Data layout supported: same as input.
[in]deconv_infoContains padding and policies to be used in the deconvolution, this is described in PadStrideInfo.
Returns
a status

Definition at line 93 of file CLGEMMDeconvolutionLayer.cpp.

94 {
99 
100  DataLayout data_layout = input->data_layout();
101  const bool padded_input = deconv_info.pad_bottom() > 0 || deconv_info.pad_left() > 0 || deconv_info.pad_right() > 0 || deconv_info.pad_top() > 0;
102  const bool is_nchw = input->data_layout() == DataLayout::NCHW;
103  const bool is_quantized = is_data_type_quantized_asymmetric(input->data_type());
104 
108 
109  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_w) != deconv_info.stride().first);
110  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_h) != deconv_info.stride().second);
111 
112  TensorShape nhwc_weights_shape = weights->tensor_shape();
113  TensorShape nhwc_input_shape = input->tensor_shape();
114 
115  if(is_nchw)
116  {
117  permute(nhwc_weights_shape, PermutationVector(2, 0, 1));
118  permute(nhwc_input_shape, PermutationVector(2, 0, 1));
119 
120  TensorInfo nhwc_input_info = input->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(nhwc_input_shape).set_data_layout(DataLayout::NCHW);
121 
122  TensorInfo nhwc_weights_info = weights->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(nhwc_weights_shape).set_data_layout(DataLayout::NCHW);
123 
124  CLPermute::validate(weights, &nhwc_weights_info, PermutationVector(2, 0, 1));
125  CLPermute::validate(input, &nhwc_input_info, PermutationVector(2, 0, 1));
126  }
127 
128  const TensorShape reshaped_shape = TensorShape(nhwc_weights_shape[0], nhwc_weights_shape[1] * nhwc_weights_shape[2] * nhwc_weights_shape[3]);
129  const TensorInfo reshaped_info = weights->clone()->set_tensor_shape(reshaped_shape).set_data_layout(DataLayout::NCHW).set_is_resizable(true);
131 
132  TensorShape transposed_shape(reshaped_shape[1], reshaped_shape[0]);
133  const TensorInfo reshaped_t_info = reshaped_info.clone()->set_is_resizable(true).set_tensor_shape(transposed_shape);
134  ARM_COMPUTE_RETURN_ON_ERROR(CLTranspose::validate(&reshaped_info, &reshaped_t_info));
135 
136  TensorShape gemm_output_shape(weights->dimension(idx_w) * weights->dimension(idx_h) * weights->dimension(idx_b),
137  input->dimension(idx_w),
138  input->dimension(idx_h),
139  input->dimension(idx_b));
140 
141  TensorInfo gemm_output_info = reshaped_t_info.clone()->set_tensor_shape(gemm_output_shape).set_is_resizable(true);
142  GEMMInfo gemm_info(false, false, true, input->dimension(idx_h), true);
143 
144  if(is_quantized)
145  {
146  ARM_COMPUTE_RETURN_ON_ERROR(CLGEMMLowpMatrixMultiplyCore::validate(&input->clone()->set_tensor_shape(nhwc_input_shape), &reshaped_t_info, nullptr, &gemm_output_info.set_data_type(DataType::S32),
147  gemm_info));
148  }
149  else
150  {
151  ARM_COMPUTE_RETURN_ON_ERROR(CLGEMM::validate(&input->clone()->set_tensor_shape(nhwc_input_shape).set_is_resizable(true), &reshaped_t_info, nullptr, &gemm_output_info, 1.0f, 0.0f, gemm_info));
152  }
153 
154  auto out_dims = deconvolution_output_dimensions(input->dimension(idx_w), input->dimension(idx_h), weights->dimension(idx_w), weights->dimension(idx_h),
155  0, 0, deconv_info.stride().first, deconv_info.stride().second);
156  const TensorShape deconv_shape = misc::shape_calculator::compute_deconvolution_output_shape(out_dims, *input, *weights);
157  TensorInfo col2im_output_info = gemm_output_info.clone()->set_tensor_shape(deconv_shape).set_is_resizable(true);
158 
159  if(padded_input && is_quantized)
160  {
161  const auto start_end = compute_start_end_slice_coordinates(col2im_output_info, deconv_info, is_nchw);
162  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
164  &col2im_output_info.clone()->set_is_resizable(true).set_data_type(DataType::QASYMM8)));
165  ARM_COMPUTE_RETURN_ON_ERROR(CLSlice::validate(&col2im_output_info.clone()->set_is_resizable(true).set_data_type(DataType::QASYMM8), output, start_end.first, start_end.second));
166  }
167  else if(padded_input)
168  {
169  const auto start_end = compute_start_end_slice_coordinates(col2im_output_info, deconv_info, is_nchw);
170  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
171  ARM_COMPUTE_RETURN_ON_ERROR(CLSlice::validate(&col2im_output_info, output, start_end.first, start_end.second));
172  }
173  else if(is_quantized)
174  {
175  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
177  }
178  else
179  {
180  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, output, input, weights, deconv_info));
181  }
182 
183  return Status{};
184 }
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLReshapeLayer.
static Status validate(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const ITensorInfo *input_info, const ITensorInfo *weights_info, const PadStrideInfo &deconv_info)
Static function to check if given info will lead to a valid configuration of CLDeconvolutionReshapeOu...
const DataLayout data_layout
Definition: Im2Col.cpp:146
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:494
#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
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:244
1 channel, 1 F16 per channel
static Status validate(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, int min=0, int max=0)
Static function to check if given info will lead to a valid configuration of CLGEMMLowpQuantizeDownIn...
void permute(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes given Dimensions according to a permutation vector.
Definition: Helpers.h:570
TensorShape compute_deconvolution_output_shape(const std::pair< unsigned int, unsigned int > &out_dims, const ITensorInfo &input, const ITensorInfo &weights)
Calculate the output shape of the deconvolution layer.
1 channel, 1 S32 per channel
static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *output, const GEMMInfo &gemm_info=GEMMInfo())
Static function to check if given info will lead to a valid configuration of CLGEMMLowpMatrixMultiply...
quantized, asymmetric fixed-point 8-bit number
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const Coordinates &starts, const Coordinates &ends)
Static function to check if given info will lead to a valid configuration of CLSlice.
Definition: CLSlice.cpp:46
Num samples, channels, height, width.
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:1030
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:163
std::pair< unsigned int, unsigned int > deconvolution_output_dimensions(unsigned int in_width, unsigned int in_height, unsigned int kernel_width, unsigned int kernel_height, unsigned int padx, unsigned int pady, unsigned int stride_x, unsigned int stride_y)
Returns expected width and height of the deconvolution's output tensor.
Definition: Utils.cpp:374
static Status validate(const ITensorInfo *input, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of CLTranspose.
Definition: CLTranspose.cpp:40
static Status validate(const ITensorInfo *a, const ITensorInfo *b, const ITensorInfo *c, const ITensorInfo *output, float alpha, float beta, const GEMMInfo &gemm_info=GEMMInfo())
Static function to check if given info will lead to a valid configuration of CLGEMM.
Definition: CLGEMM.cpp:525
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const PermutationVector &perm)
Static function to check if given info will lead to a valid configuration of CLPermute.
Definition: CLPermute.cpp:40
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
DataLayout
[DataLayout enum definition]
Definition: Types.h:114

References ARM_COMPUTE_RETURN_ERROR_ON, ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT, ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES, ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR, ARM_COMPUTE_RETURN_ON_ERROR, arm_compute::BATCHES, arm_compute::test::validation::bias, ICloneable< T >::clone(), TensorInfo::clone(), arm_compute::misc::shape_calculator::compute_deconvolution_output_shape(), arm_compute::test::validation::data_layout, ITensorInfo::data_layout(), ITensorInfo::data_type(), arm_compute::deconvolution_output_dimensions(), ITensorInfo::dimension(), arm_compute::F16, arm_compute::F32, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, arm_compute::is_data_type_quantized_asymmetric(), arm_compute::NCHW, PadStrideInfo::pad_bottom(), PadStrideInfo::pad_left(), PadStrideInfo::pad_right(), PadStrideInfo::pad_top(), arm_compute::permute(), arm_compute::QASYMM8, arm_compute::S32, TensorInfo::set_data_type(), PadStrideInfo::stride(), ITensorInfo::tensor_shape(), CLReshapeLayer::validate(), CLTranspose::validate(), CLPermute::validate(), CLSlice::validate(), CLDeconvolutionReshapeOutputKernel::validate(), CLGEMMLowpMatrixMultiplyCore::validate(), CLGEMM::validate(), CLGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPoint::validate(), arm_compute::test::validation::weights, and arm_compute::WIDTH.

Referenced by CLGEMMDeconvolutionLayer::configure(), and CLDeconvolutionLayer::validate().


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