Compute Library
 21.05
CLGEMMDeconvolutionLayer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020 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 
46 
47 #include <tuple>
48 
49 namespace arm_compute
50 {
51 namespace
52 {
53 std::pair<Coordinates, Coordinates> compute_start_end_slice_coordinates(const ITensorInfo &output_info, const PadStrideInfo &deconv_info, bool is_nchw)
54 {
55  Coordinates start;
56  Coordinates end;
57 
58  if(is_nchw)
59  {
60  start.set(0, deconv_info.pad_left());
61  start.set(1, deconv_info.pad_top());
62  end.set(0, output_info.dimension(0) - deconv_info.pad_right());
63  end.set(1, output_info.dimension(1) - deconv_info.pad_bottom());
64  }
65  else
66  {
67  start.set(0, 0);
68  start.set(1, deconv_info.pad_left());
69  start.set(2, deconv_info.pad_top());
70 
71  end.set(0, output_info.dimension(0));
72  end.set(1, output_info.dimension(1) - deconv_info.pad_right());
73  end.set(2, output_info.dimension(2) - deconv_info.pad_bottom());
74  }
75 
76  return { start, end };
77 }
78 Status construct_gemmlowp_output_stage(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *output, GEMMLowpOutputStageInfo &output_stage_info)
79 {
80  const auto data_type = input->data_type();
81 
83  {
84  const UniformQuantizationInfo iq_info = input->quantization_info().uniform();
85  const UniformQuantizationInfo wq_info = weights->quantization_info().uniform();
86  const UniformQuantizationInfo oq_info = output->quantization_info().uniform();
87 
88  float multiplier = iq_info.scale * wq_info.scale / oq_info.scale;
89  int output_multiplier(0);
90  int output_shift(0);
91  ARM_COMPUTE_RETURN_ON_ERROR(quantization::calculate_quantized_multiplier(multiplier, &output_multiplier, &output_shift));
92 
94  output_stage_info.gemmlowp_multiplier = output_multiplier;
95  output_stage_info.gemmlowp_shift = output_shift;
96  output_stage_info.gemmlowp_offset = oq_info.offset;
97  const auto min_max_bound = get_min_max(data_type);
98  output_stage_info.gemmlowp_min_bound = (std::get<0>(min_max_bound)).get<int32_t>();
99  output_stage_info.gemmlowp_max_bound = (std::get<1>(min_max_bound)).get<int32_t>();
100  output_stage_info.output_data_type = data_type;
101  }
102  return Status{};
103 }
104 
105 } // namespace
106 
107 CLGEMMDeconvolutionLayer::CLGEMMDeconvolutionLayer(std::shared_ptr<IMemoryManager> memory_manager) // NOLINT
108  : _memory_group(std::move(memory_manager)),
109  _mm_gemm(),
110  _mm_gemmlowp(),
111  _gemmlowp_output_stage(),
112  _permute_input_to_nhwc(),
113  _permute_weights_to_nhwc(),
114  _reshape_weights(),
115  _transpose_weights(),
116  _deconv_reshape(std::make_unique<CLDeconvolutionReshapeOutputKernel>()),
117  _slice_gemm(),
118  _gemmlowp_final(),
119  _reshaped_weights(),
120  _reshaped_weights_t(),
121  _permuted_input(),
122  _permuted_weights(),
123  _gemm_output(),
124  _slice_gemm_input(),
125  _original_weights(),
126  _is_prepared(false),
127  _padded_input(false),
128  _is_nchw(false),
129  _is_quantized(false)
130 {
131 }
132 
134 
135 Status CLGEMMDeconvolutionLayer::validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, const ITensorInfo *output, const PadStrideInfo &deconv_info)
136 {
137  ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output);
141 
142  DataLayout data_layout = input->data_layout();
143  const bool padded_input = deconv_info.pad_bottom() > 0 || deconv_info.pad_left() > 0 || deconv_info.pad_right() > 0 || deconv_info.pad_top() > 0;
144  const bool is_nchw = input->data_layout() == DataLayout::NCHW;
145  const bool is_quantized = is_data_type_quantized_asymmetric(input->data_type());
146 
150 
151  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_w) != deconv_info.stride().first);
152  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_h) != deconv_info.stride().second);
153 
154  TensorShape nhwc_weights_shape = weights->tensor_shape();
155  TensorShape nhwc_input_shape = input->tensor_shape();
156 
157  if(is_nchw)
158  {
159  permute(nhwc_weights_shape, PermutationVector(2, 0, 1));
160  permute(nhwc_input_shape, PermutationVector(2, 0, 1));
161 
162  TensorInfo nhwc_input_info = input->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(nhwc_input_shape).set_data_layout(DataLayout::NCHW);
163 
164  TensorInfo nhwc_weights_info = weights->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(nhwc_weights_shape).set_data_layout(DataLayout::NCHW);
165 
166  CLPermute::validate(weights, &nhwc_weights_info, PermutationVector(2, 0, 1));
167  CLPermute::validate(input, &nhwc_input_info, PermutationVector(2, 0, 1));
168  }
169 
170  const TensorShape reshaped_shape = TensorShape(nhwc_weights_shape[0], nhwc_weights_shape[1] * nhwc_weights_shape[2] * nhwc_weights_shape[3]);
171  const TensorInfo reshaped_info = weights->clone()->set_tensor_shape(reshaped_shape).set_data_layout(DataLayout::NCHW).set_is_resizable(true);
172  ARM_COMPUTE_RETURN_ON_ERROR(CLReshapeLayer::validate(weights, &reshaped_info));
173 
174  TensorShape transposed_shape(reshaped_shape[1], reshaped_shape[0]);
175  const TensorInfo reshaped_t_info = reshaped_info.clone()->set_is_resizable(true).set_tensor_shape(transposed_shape);
176  ARM_COMPUTE_RETURN_ON_ERROR(CLTranspose::validate(&reshaped_info, &reshaped_t_info));
177 
178  TensorShape gemm_output_shape(weights->dimension(idx_w) * weights->dimension(idx_h) * weights->dimension(idx_b),
179  input->dimension(idx_w),
180  input->dimension(idx_h),
181  input->dimension(idx_b));
182 
183  TensorInfo gemm_output_info = reshaped_t_info.clone()->set_tensor_shape(gemm_output_shape).set_is_resizable(true);
184  GEMMInfo gemm_info(false, false, true, input->dimension(idx_h), true);
185 
186  GEMMLowpOutputStageInfo output_stage_info;
187 
188  if(is_quantized)
189  {
190  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),
191  gemm_info));
192  ARM_COMPUTE_RETURN_ON_ERROR(construct_gemmlowp_output_stage(input, weights, output, output_stage_info));
193  }
194  else
195  {
196  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));
197  }
198 
199  const PadStrideInfo stride_info(deconv_info.stride().first, deconv_info.stride().second);
200  auto out_dims = deconvolution_output_dimensions(input->dimension(idx_w), input->dimension(idx_h), weights->dimension(idx_w), weights->dimension(idx_h), stride_info);
201  const TensorShape deconv_shape = misc::shape_calculator::compute_deconvolution_output_shape(out_dims, *input, *weights);
202  TensorInfo col2im_output_info = gemm_output_info.clone()->set_tensor_shape(deconv_shape).set_is_resizable(true);
203 
204  if(padded_input && is_quantized)
205  {
206  const auto start_end = compute_start_end_slice_coordinates(col2im_output_info, deconv_info, is_nchw);
207  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
208  ARM_COMPUTE_RETURN_ON_ERROR(CLGEMMLowpOutputStage::validate(&col2im_output_info, nullptr, &col2im_output_info.clone()->set_is_resizable(true).set_data_type(input->data_type()), output_stage_info));
209  ARM_COMPUTE_RETURN_ON_ERROR(CLSlice::validate(&col2im_output_info.clone()->set_is_resizable(true).set_data_type(input->data_type()), output, start_end.first, start_end.second));
210  }
211  else if(padded_input)
212  {
213  const auto start_end = compute_start_end_slice_coordinates(col2im_output_info, deconv_info, is_nchw);
214  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
215  ARM_COMPUTE_RETURN_ON_ERROR(CLSlice::validate(&col2im_output_info, output, start_end.first, start_end.second));
216  }
217  else if(is_quantized)
218  {
219  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, &col2im_output_info, input, weights, deconv_info));
220  ARM_COMPUTE_RETURN_ON_ERROR(CLGEMMLowpOutputStage::validate(&col2im_output_info, nullptr, output, output_stage_info));
221  }
222  else
223  {
224  ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionReshapeOutputKernel::validate(&gemm_output_info, bias, output, input, weights, deconv_info));
225  }
226 
227  return Status{};
228 }
229 
230 void CLGEMMDeconvolutionLayer::configure(const ICLTensor *input, const ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const PadStrideInfo &deconv_info)
231 {
232  configure(CLKernelLibrary::get().get_compile_context(), input, weights, bias, output, deconv_info);
233 }
234 
235 void CLGEMMDeconvolutionLayer::configure(const CLCompileContext &compile_context, const ICLTensor *input, const ICLTensor *weights, const ICLTensor *bias, ICLTensor *output,
236  const PadStrideInfo &deconv_info)
237 {
238  ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
240  weights->info(),
241  bias != nullptr ? bias->info() : nullptr,
242  output->info(),
243  deconv_info));
244 
245  _original_weights = weights;
246  _padded_input = deconv_info.pad_bottom() > 0 || deconv_info.pad_left() > 0 || deconv_info.pad_right() > 0 || deconv_info.pad_top() > 0;
247  _is_nchw = input->info()->data_layout() == DataLayout::NCHW;
248  _is_quantized = is_data_type_quantized_asymmetric(input->info()->data_type());
249 
250  const ICLTensor *input_to_use = input;
251  const ICLTensor *weights_to_use = weights;
252 
253  // If the data layout is NCHW, transform everything in NHWC. Another alternative could be to
254  // do an outer product in NCHW and then an accumulation through a reduction. This would have two
255  // drawbacks: first, the outer product is less efficient than a full GEMM. Second, the reduction
256  // might be slower than GEMM.
257  if(_is_nchw)
258  {
259  _memory_group.manage(&_permuted_input);
260  _permute_input_to_nhwc.configure(compile_context, input, &_permuted_input, PermutationVector(2U, 0U, 1U));
261 
262  _permute_weights_to_nhwc.configure(compile_context, weights, &_permuted_weights, PermutationVector(2U, 0U, 1U));
263 
264  input_to_use = &_permuted_input;
265  weights_to_use = &_permuted_weights;
266  }
267 
268  // Reshape the input weights. The weights will be reshaped only once during the call to prepare()
269  _reshaped_weights.allocator()->init(TensorInfo(TensorShape(weights_to_use->info()->dimension(0),
270  weights_to_use->info()->dimension(1) * weights_to_use->info()->dimension(2) * weights_to_use->info()->dimension(3)),
271  1,
272  input->info()->data_type(), weights->info()->quantization_info()));
273 
274  _reshape_weights.configure(compile_context, weights_to_use, &_reshaped_weights);
275  _transpose_weights.configure(compile_context, &_reshaped_weights, &_reshaped_weights_t);
276 
277  const size_t idx_h = get_data_layout_dimension_index(input->info()->data_layout(), DataLayoutDimension::HEIGHT);
278  GEMMInfo gemm_info(false, false, true, input->info()->dimension(idx_h), true);
279 
280  // Configure output stage for asymmetric quantized types
281  if(_is_quantized)
282  {
283  // gemmlowp adds the offsets (instead of subtracting them). Thus, we need to negate the original
284  // and restore them back to make it work properly.
285  QuantizationInfo iq_info = input->info()->quantization_info();
286  QuantizationInfo wq_info = weights->info()->quantization_info();
287 
288  input_to_use->info()->set_quantization_info(QuantizationInfo(iq_info.uniform().scale, -iq_info.uniform().offset));
289  _reshaped_weights_t.info()->set_quantization_info(QuantizationInfo(wq_info.uniform().scale, -wq_info.uniform().offset));
290 
291  _mm_gemmlowp.configure(compile_context, input_to_use, &_reshaped_weights_t, nullptr, &_gemm_output, gemm_info);
292 
293  input_to_use->info()->set_quantization_info(iq_info);
294  _reshaped_weights_t.info()->set_quantization_info(wq_info);
295  }
296  else
297  {
298  _mm_gemm.configure(compile_context, input_to_use, &_reshaped_weights_t, nullptr, &_gemm_output, 1.f, 0.0f, gemm_info);
299  }
300 
301  if(_is_nchw)
302  {
303  _permuted_input.allocator()->allocate();
304  }
305 
306  ICLTensor *deconv_reshape_output = nullptr;
307  ICLTensor *slice_output = nullptr;
308  ICLTensor *output_stage_output = nullptr;
309 
310  if(_padded_input && _is_quantized)
311  {
312  _memory_group.manage(&_slice_gemm_input);
313  _memory_group.manage(&_gemmlowp_final);
314  deconv_reshape_output = &_gemmlowp_final;
315  output_stage_output = &_slice_gemm_input;
316  slice_output = output;
317  }
318  else if(_padded_input)
319  {
320  _memory_group.manage(&_slice_gemm_input);
321  deconv_reshape_output = &_slice_gemm_input;
322  slice_output = output;
323  }
324  else if(_is_quantized)
325  {
326  _memory_group.manage(&_gemmlowp_final);
327  deconv_reshape_output = &_gemmlowp_final;
328  output_stage_output = output;
329  }
330  else
331  {
332  deconv_reshape_output = output;
333  }
334 
335  // Configure a Col2Im call to reshape the output of GEMM
336  _deconv_reshape->configure(compile_context, &_gemm_output, bias, deconv_reshape_output, input->info(), weights->info(), deconv_info);
337  _gemm_output.allocator()->allocate();
338 
339  if(_is_quantized)
340  {
341  GEMMLowpOutputStageInfo output_stage_info;
342  construct_gemmlowp_output_stage(input->info(), weights->info(), output->info(), output_stage_info);
343  _gemmlowp_output_stage.configure(compile_context, &_gemmlowp_final, nullptr, output_stage_output, output_stage_info);
344  _gemmlowp_final.allocator()->allocate();
345  }
346 
347  // If the input was padded, the output needs to be sliced.
348  if(_padded_input)
349  {
350  const auto start_end = compute_start_end_slice_coordinates(*deconv_reshape_output->info(), deconv_info, _is_nchw);
351  _slice_gemm.configure(compile_context, &_slice_gemm_input, slice_output, start_end.first, start_end.second);
352  _slice_gemm_input.allocator()->allocate();
353  }
354 }
355 
357 {
358  prepare();
359 
360  MemoryGroupResourceScope scope_mg(_memory_group);
361 
362  if(_is_nchw)
363  {
364  _permute_input_to_nhwc.run();
365  }
366 
367  if(_is_quantized)
368  {
369  _mm_gemmlowp.run();
370  }
371  else
372  {
373  _mm_gemm.run();
374  }
375 
376  CLScheduler::get().enqueue(*_deconv_reshape, false);
377 
378  if(_is_quantized)
379  {
380  _gemmlowp_output_stage.run();
381  }
382 
383  if(_padded_input)
384  {
385  _slice_gemm.run();
386  }
387 }
388 
390 {
391  if(!_is_prepared)
392  {
393  ARM_COMPUTE_ERROR_ON(!_original_weights->is_used());
394 
395  if(_is_nchw)
396  {
397  _permuted_weights.allocator()->allocate();
398  _permute_weights_to_nhwc.run();
399  }
400 
401  _reshaped_weights.allocator()->allocate();
402  _reshape_weights.run();
403 
404  if(_is_nchw)
405  {
406  _permuted_weights.allocator()->free();
407  }
408 
409  _reshaped_weights_t.allocator()->allocate();
410  _transpose_weights.run();
411 
412  // Prepare gemm
413  if(!_is_quantized)
414  {
415  _mm_gemm.prepare();
416  }
417  else
418  {
419  _mm_gemmlowp.prepare();
420  }
421 
422  // Free resources
423  if(!_reshaped_weights_t.is_used())
424  {
425  _reshaped_weights_t.allocator()->free();
426  }
427 
428  _original_weights->mark_as_unused();
429  _is_prepared = true;
430  }
431 }
432 } // namespace arm_compute
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.
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...
Shape of a tensor.
Definition: TensorShape.h:39
Quantize using a fixed point multiplication.
void prepare() override
Prepare the function for executing.
Definition: CLGEMM.cpp:870
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:281
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: CLTensor.cpp:41
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...)
Definition: Validate.h:490
void prepare() override
Prepare the function for executing.
void run() override
Run the kernels contained in the function.
Definition: CLGEMM.cpp:778
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
static CLScheduler & get()
Access the scheduler singleton.
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, const PadStrideInfo &pad_stride_info)
Returns expected width and height of the deconvolution's output tensor.
Definition: Utils.cpp:375
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.
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
bool is_used() const
Flags if the tensor is used or not.
Definition: ITensor.cpp:163
CLGEMMDeconvolutionLayer(std::shared_ptr< IMemoryManager > memory_manager=nullptr)
Constructor.
1 channel, 1 F32 per channel
ITensorInfo & set_data_type(DataType data_type) override
Set the data type to the specified value.
Definition: TensorInfo.cpp:286
Strides PermutationVector
Permutation vector.
Definition: Types.h:49
void configure(const ICLTensor *input, const ICLTensor *bias, ICLTensor *output, const GEMMLowpOutputStageInfo &info)
Initialise the kernel's inputs, output.
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
const DataLayout data_layout
Definition: Im2Col.cpp:151
void run() override
Run the kernels contained in the function.
static CLKernelLibrary & get()
Access the KernelLibrary singleton.
Store the tensor's metadata.
Definition: ITensorInfo.h:40
CLTensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: CLTensor.cpp:61
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
void configure(const ICLTensor *a, const ICLTensor *b, const ICLTensor *c, ICLTensor *output, const GEMMInfo &gemm_info=GEMMInfo())
Initialise the kernel's inputs, output.
unsigned int pad_top() const
Get the top padding.
Definition: Types.h:734
Status calculate_quantized_multiplier(float multiplier, int32_t *quant_multiplier, int32_t *shift, bool ignore_epsilon=false)
Calculate quantized representation of multiplier.
Status class.
Definition: Error.h:52
void run() override
Run the kernels contained in the function.
#define ARM_COMPUTE_RETURN_ERROR_ON(cond)
If the condition is true, an error is returned.
Definition: Error.h:296
void init(const TensorInfo &input, size_t alignment=0)
Initialize a tensor based on the passed TensorInfo.
Copyright (c) 2017-2021 Arm Limited.
void run() override
Run the kernels contained in the function.
Definition: CLPermute.cpp:70
1 channel, 1 F16 per channel
void run() override
Run the kernels contained in the function.
ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info) override
Set the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.cpp:345
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:159
void permute(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes given Dimensions according to a permutation vector.
Definition: Helpers.h:125
static Status validate(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const GEMMLowpOutputStageInfo &info)
Static function to check if given info will lead to a valid configuration of CLGEMMLowpQuantizeDownIn...
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.
void mark_as_unused() const
Marks a tensor as unused.
Definition: ITensor.cpp:168
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
const DataType data_type
Definition: Im2Col.cpp:150
Interface to enqueue OpenCL kernels and get/set the OpenCL CommandQueue and ICLTuner.
Quantization information.
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...
void run() override final
Run the kernels contained in the function.
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
quantized, asymmetric fixed-point 8-bit number unsigned
void run() override
Run the kernels contained in the function.
Definition: CLTranspose.cpp:66
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: Types.h:698
UniformQuantizationInfo uniform() const
Return per layer quantization info.
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
GEMMLowp output stage info.
Definition: Types.h:1887
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:79
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
unsigned int pad_right() const
Get the right padding.
Definition: Types.h:729
Padding and stride information class.
Definition: Types.h:650
void end(TokenStream &in, bool &valid)
Definition: MLGOParser.cpp:290
virtual QuantizationInfo quantization_info() const =0
Get the quantization settings (scale and offset) of the tensor.
void enqueue(ICLKernel &kernel, bool flush=true)
Schedule the execution of the passed kernel if possible.
Num samples, channels, height, width.
CLCompileContext class.
void configure(const ICLTensor *input, ICLTensor *output, const Coordinates &starts, const Coordinates &ends)
Configure kernel.
Definition: CLSlice.cpp:84
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:989
Interface for the OpenCL kernel to be used for reshaping the tensor before returning the result of de...
void allocate() override
Allocate size specified by TensorInfo of OpenCL memory.
Memory group resources scope handling class.
Definition: IMemoryGroup.h:82
Interface for OpenCL tensor.
Definition: ICLTensor.h:42
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:61
void run() override
Run the kernels contained in the function.
Definition: CLSlice.cpp:97
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:666
#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...)
Definition: Validate.h:541
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:788
void free() override
Free allocated OpenCL memory.
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:727
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:157
Store the tensor's metadata.
Definition: TensorInfo.h:43
GEMM information class.
Definition: Types.h:1938
void configure(const ICLTensor *input, ICLTensor *output, const PermutationVector &perm)
Set the input and output tensors.
Definition: CLPermute.cpp:49
void configure(const ICLTensor *input, ICLTensor *output)
Initialise the kernel's inputs and outputs.
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:65
quantized, asymmetric fixed-point 8-bit number signed
void configure(const ICLTensor *input, ICLTensor *output)
Initialise the kernel's inputs and output.
Definition: CLTranspose.cpp:47
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:193
unsigned int pad_bottom() const
Get the bottom padding.
Definition: Types.h:739
unsigned int pad_left() const
Get the left padding.
Definition: Types.h:724
void prepare() override
Prepare the function for executing.
DataLayout
[DataLayout enum definition]
Definition: Types.h:114
std::tuple< PixelValue, PixelValue > get_min_max(DataType dt)
Compute the mininum and maximum values a data type can take.
Definition: Utils.h:564
~CLGEMMDeconvolutionLayer()
Default desctructor.