Compute Library
 19.11
NEDeconvolutionLayer Class Reference

Function to run the deconvolution layer. More...

#include <NEDeconvolutionLayer.h>

Collaboration diagram for NEDeconvolutionLayer:
[legend]

Public Member Functions

 NEDeconvolutionLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 Constructor. More...
 
 NEDeconvolutionLayer (const NEDeconvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
NEDeconvolutionLayeroperator= (const NEDeconvolutionLayer &)=delete
 Prevent instances of this class from being copied (As this class contains pointers) More...
 
 NEDeconvolutionLayer (NEDeconvolutionLayer &&)=default
 Allow instances of this class to be moved. More...
 
NEDeconvolutionLayeroperator= (NEDeconvolutionLayer &&)=default
 Allow instances of this class to be moved. More...
 
virtual ~NEDeconvolutionLayer ()=default
 Default destructor. More...
 
void configure (ITensor *input, const ITensor *weights, const ITensor *bias, ITensor *output, const PadStrideInfo &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 &info)
 Static function to check if given info will lead to a valid configuration of NEDeconvolutionLayer. More...
 

Detailed Description

Function to run the deconvolution layer.

Deconvolution Layer is the backward pass of Convolution Layer. First we transform the input depending on the stride and pad info and then perfrom 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 finaly 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 is the size of the first input dimension. height 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. Therefore, it will be necessary to use the weights in the reverse order to perform an actual convolution. This is achieved by using the CPPFlipWeightsKernel.

This function calls the following NEON kernels/functions:

  1. CPPUpsample
  2. NEConvolutionLayer

Definition at line 73 of file NEDeconvolutionLayer.h.

Constructor & Destructor Documentation

◆ NEDeconvolutionLayer() [1/3]

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

Constructor.

Definition at line 36 of file NEDeconvolutionLayer.cpp.

37  : _memory_group(std::move(memory_manager)),
38  _conv_f(),
39  _upsample_f(),
40  _flip_weights(),
41  _permute_input(),
42  _permute_weights(),
43  _permute_output(),
44  _scaled_output(),
45  _weights_flipped(),
46  _permuted_input(),
47  _permuted_weights(),
48  _permuted_output(),
49  _is_nchw(false),
50  _original_weights(nullptr),
51  _input(nullptr),
52  _info(),
53  _is_prepared(false)
54 {
55 }

◆ NEDeconvolutionLayer() [2/3]

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

◆ NEDeconvolutionLayer() [3/3]

Allow instances of this class to be moved.

◆ ~NEDeconvolutionLayer()

virtual ~NEDeconvolutionLayer ( )
virtualdefault

Default destructor.

Member Function Documentation

◆ configure()

void configure ( ITensor input,
const ITensor weights,
const ITensor bias,
ITensor output,
const PadStrideInfo 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: F32/F16/QASYMM8.
[in]weightsThe 4d weights with dimensions [width, height, IFM, OFM]. Data type supported: Same as input.
[in]biasOptional, ignored if NULL. The biases have one dimension. Data type supported: Data types supported: S32 for QASYMM8 input, F32 for F32 input, F16 for F16 input.
[out]outputOutput tensor. The output has the same number of dimensions as the input.
[in]infoContains padding and policies to be used in the deconvolution, this is decribed in PadStrideInfo.

Definition at line 112 of file NEDeconvolutionLayer.cpp.

113 {
114  // Perform validation step
116  ARM_COMPUTE_ERROR_THROW_ON(NEDeconvolutionLayer::validate(input->info(), weights->info(), (bias == nullptr) ? nullptr : bias->info(), output->info(), info));
117 
118  const DataLayout data_layout = input->info()->data_layout();
119 
120  _input = input;
121  _original_weights = weights;
122  _info = info;
123  _is_prepared = false;
124  _is_nchw = data_layout == DataLayout::NCHW;
125 
126  const unsigned int pad_left = info.pad_left();
127  const unsigned int pad_right = info.pad_right();
128  const unsigned int pad_top = info.pad_top();
129  const unsigned int pad_bottom = info.pad_bottom();
130  const unsigned int stride_x = info.stride().first;
131  const unsigned int stride_y = info.stride().second;
132 
135  auto out_dims = deconvolution_output_dimensions(input->info()->dimension(width_idx), input->info()->dimension(height_idx),
136  weights->info()->dimension(width_idx), weights->info()->dimension(height_idx), info);
137 
138  const TensorShape output_shape = compute_deconvolution_output_shape(out_dims, *input->info(), *weights->info());
139  // Output auto initialization if not yet initialized
140  auto_init_if_empty(*output->info(), output_shape, 1, input->info()->data_type(), input->info()->quantization_info());
141 
142  _memory_group.manage(&_scaled_output);
143 
144  if(!_is_nchw)
145  {
146  _memory_group.manage(&_permuted_input);
147  _memory_group.manage(&_permuted_output);
148 
149  // Configure the function to transform the input tensor from NHWC -> NCHW
150  _permuted_input.info()->set_quantization_info(input->info()->quantization_info());
151  _permute_input.configure(input, &_permuted_input, PermutationVector(1U, 2U, 0U));
152  _permuted_input.info()->set_data_layout(DataLayout::NCHW);
153 
154  // Configure the function to transform the weights tensor from NHWC -> NCHW
155  _permuted_weights.info()->set_quantization_info(weights->info()->quantization_info());
156  _permute_weights.configure(weights, &_permuted_weights, PermutationVector(1U, 2U, 0U));
157  _permuted_weights.info()->set_data_layout(DataLayout::NCHW);
158 
159  // Find the upsampled dimensions and the padding needed for the convolution with stride 1 in order to match output shape
160  unsigned int deconv_pad_x = 0;
161  unsigned int deconv_pad_y = 0;
162  const TensorShape scale_out_shape = compute_deconvolution_upsampled_shape(*_permuted_input.info(), *_permuted_weights.info(), stride_x, stride_y, out_dims,
163  deconv_pad_x, deconv_pad_y);
164 
165  unsigned int deconv_pad_left = pad_right > pad_left ? pad_right - pad_left : 0;
166  unsigned int deconv_pad_right = pad_left > pad_right ? pad_left - pad_right : 0;
167  deconv_pad_x -= deconv_pad_left + deconv_pad_right;
168  ARM_COMPUTE_ERROR_ON((deconv_pad_x % 2) != 0);
169  deconv_pad_left += deconv_pad_x / 2;
170  deconv_pad_right += deconv_pad_x / 2;
171 
172  unsigned int deconv_pad_top = pad_bottom > pad_top ? pad_bottom - pad_top : 0;
173  unsigned int deconv_pad_bottom = pad_top > pad_bottom ? pad_top - pad_bottom : 0;
174  deconv_pad_y -= deconv_pad_top + deconv_pad_bottom;
175  ARM_COMPUTE_ERROR_ON((deconv_pad_y % 2) != 0);
176  deconv_pad_top += deconv_pad_y / 2;
177  deconv_pad_bottom += deconv_pad_y / 2;
178 
179  TensorInfo scale_out_info(scale_out_shape, 1, _permuted_input.info()->data_type(), _permuted_input.info()->quantization_info());
180  scale_out_info.set_data_layout(DataLayout::NCHW);
181  _scaled_output.allocator()->init(scale_out_info);
182 
183  const PadStrideInfo upsample_info(stride_x, stride_y, deconv_pad_left, deconv_pad_right, deconv_pad_top, deconv_pad_bottom, DimensionRoundingType::FLOOR);
184  _upsample_f.configure(&_permuted_input, &_scaled_output, upsample_info);
185 
186  _weights_flipped.allocator()->init(*_permuted_weights.info()->clone());
187  _weights_flipped.info()->set_quantization_info(weights->info()->quantization_info());
188  _flip_weights.configure(&_permuted_weights, &_weights_flipped);
189 
190  // setup the function to convolve the upscaled output
191  const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
192 
193  _permuted_output.info()->set_quantization_info(output->info()->quantization_info());
194  _conv_f.configure(&_scaled_output, &_weights_flipped, bias, &_permuted_output, conv_info);
195 
196  // Configure the function to transform the convoluted output to NHWC
197  _permute_output.configure(&_permuted_output, output, PermutationVector(2U, 0U, 1U));
198  _permuted_output.info()->set_data_layout(DataLayout::NCHW);
199 
200  _permuted_input.allocator()->allocate();
201  _permuted_output.allocator()->allocate();
202  }
203  else
204  {
205  // Find the upsampled dimensions and the padding needed for the convolution with stride 1 in order to match output shape
206  unsigned int deconv_pad_x = 0;
207  unsigned int deconv_pad_y = 0;
208  const TensorShape scale_out_shape = compute_deconvolution_upsampled_shape(*input->info(), *weights->info(), stride_x, stride_y,
209  out_dims, deconv_pad_x, deconv_pad_y);
210 
211  unsigned int deconv_pad_left = pad_right > pad_left ? pad_right - pad_left : 0;
212  unsigned int deconv_pad_right = pad_left > pad_right ? pad_left - pad_right : 0;
213  deconv_pad_x -= deconv_pad_left + deconv_pad_right;
214  ARM_COMPUTE_ERROR_ON((deconv_pad_x % 2) != 0);
215  deconv_pad_left += deconv_pad_x / 2;
216  deconv_pad_right += deconv_pad_x / 2;
217 
218  unsigned int deconv_pad_top = pad_bottom > pad_top ? pad_bottom - pad_top : 0;
219  unsigned int deconv_pad_bottom = pad_top > pad_bottom ? pad_top - pad_bottom : 0;
220  deconv_pad_y -= deconv_pad_top + deconv_pad_bottom;
221  ARM_COMPUTE_ERROR_ON((deconv_pad_y % 2) != 0);
222  deconv_pad_top += deconv_pad_y / 2;
223  deconv_pad_bottom += deconv_pad_y / 2;
224 
225  TensorInfo scale_out_info(scale_out_shape, 1, input->info()->data_type(), input->info()->quantization_info());
226  scale_out_info.set_data_layout(data_layout);
227  _scaled_output.allocator()->init(scale_out_info);
228 
229  const PadStrideInfo upsample_info(stride_x, stride_y, deconv_pad_left, deconv_pad_right, deconv_pad_top, deconv_pad_bottom, DimensionRoundingType::FLOOR);
230  _upsample_f.configure(input, &_scaled_output, upsample_info);
231 
232  _weights_flipped.allocator()->init(weights->info()->clone()->set_data_layout(data_layout));
233  _flip_weights.configure(weights, &_weights_flipped);
234 
235  // setup the function to convolve the upscaled output
236  const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
237  _conv_f.configure(&_scaled_output, &_weights_flipped, bias, output, conv_info);
238  }
239  _scaled_output.allocator()->allocate();
240 }
const DataLayout data_layout
Definition: Im2Col.cpp:146
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:314
TensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: CLTensor.cpp:41
void init(const TensorAllocator &allocator, const Coordinates &coords, TensorInfo &sub_info)
Shares the same backing memory with another tensor allocator, while the tensor info might be differen...
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:382
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, const ITensorInfo *output, const PadStrideInfo &info)
Static function to check if given info will lead to a valid configuration of NEDeconvolutionLayer.
size_t dimension(size_t index) const override
Return the size of the requested dimension.
Definition: TensorInfo.h:232
virtual DataType data_type() const =0
Data type used for each element of the tensor.
QuantizationInfo quantization_info() const override
Get the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.h:311
Strides PermutationVector
Permutation vector.
Definition: Types.h:47
#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
void configure(ITensor *input, const ITensor *weights, const ITensor *biases, ITensor *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false, unsigned int num_groups=1)
Set the input and output tensors.
#define ARM_COMPUTE_ERROR_THROW_ON(status)
Definition: Error.h:455
bool auto_init_if_empty(ITensorInfo &info, const TensorShape &shape, int num_channels, DataType data_type, QuantizationInfo quantization_info=QuantizationInfo())
Auto initialize the tensor info (shape, number of channels and data type) if the current assignment i...
Definition: Helpers.inl:202
TensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: Tensor.cpp:48
ITensorInfo * info() const override
Interface to be implemented by the child class to return the tensor's metadata.
Definition: Tensor.cpp:33
void configure(const ITensor *input, ITensor *output)
Set the input and output of the kernel.
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 manage(IMemoryManageable *obj) override
Sets a object to be managed by the given memory group.
Definition: MemoryGroup.h:79
virtual ITensorInfo & set_data_layout(const DataLayout &data_layout)=0
Set the data layout of the tensor.
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
virtual std::unique_ptr< T > clone() const =0
Provide a clone of the current object of class T.
virtual ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info)=0
Set the quantization settings (scale and offset) of the tensor.
TensorShape compute_deconvolution_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, unsigned int sx, unsigned int sy, std::pair< unsigned int, unsigned int > &out_dims, unsigned int &padx, unsigned int &pady)
Calculate the upsampled output shape used for deconvolution.
virtual QuantizationInfo quantization_info() const =0
Get the quantization settings (scale and offset) of the tensor.
Num samples, channels, height, width.
#define ARM_COMPUTE_ERROR_ON_NULLPTR(...)
Definition: Validate.h:161
void configure(const ITensor *input, ITensor *output, const PadStrideInfo &info)
Configure the upsample CPP kernel.
Definition: CPPUpsample.cpp:31
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:327
void configure(const ITensor *input, ITensor *output, const PermutationVector &perm)
Configure the permute NEON kernel.
Definition: NEPermute.cpp:31
DataLayout
[DataLayout enum definition]
Definition: Types.h:116

References TensorAllocator::allocate(), Tensor::allocator(), ARM_COMPUTE_ERROR_ON, ARM_COMPUTE_ERROR_ON_NULLPTR, ARM_COMPUTE_ERROR_THROW_ON, arm_compute::auto_init_if_empty(), arm_compute::test::validation::bias, arm_compute::CEIL, ICloneable< T >::clone(), TensorInfo::clone(), arm_compute::misc::shape_calculator::compute_deconvolution_output_shape(), arm_compute::misc::shape_calculator::compute_deconvolution_upsampled_shape(), CPPUpsample::configure(), NEPermute::configure(), CPPFlipWeightsKernel::configure(), NEConvolutionLayer::configure(), arm_compute::test::validation::conv_info, arm_compute::test::validation::data_layout, ITensorInfo::data_type(), arm_compute::deconvolution_output_dimensions(), TensorInfo::dimension(), arm_compute::FLOOR, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, ITensor::info(), Tensor::info(), CLTensor::info(), arm_compute::test::validation::info, TensorAllocator::init(), arm_compute::test::validation::input, MemoryGroup::manage(), arm_compute::NCHW, arm_compute::test::validation::output_shape, ITensorInfo::quantization_info(), TensorInfo::quantization_info(), ITensorInfo::set_data_layout(), TensorInfo::set_data_layout(), ITensorInfo::set_quantization_info(), arm_compute::U, NEDeconvolutionLayer::validate(), arm_compute::test::validation::weights, and arm_compute::WIDTH.

Referenced by arm_compute::test::validation::DATA_TEST_CASE().

◆ operator=() [1/2]

NEDeconvolutionLayer& operator= ( const NEDeconvolutionLayer )
delete

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

◆ operator=() [2/2]

NEDeconvolutionLayer& operator= ( NEDeconvolutionLayer &&  )
default

Allow instances of this class to be moved.

◆ 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 264 of file NEDeconvolutionLayer.cpp.

265 {
266  if(!_is_prepared)
267  {
268  ARM_COMPUTE_ERROR_ON(!_original_weights->is_used());
269  // Permute weights
270  if(!_is_nchw)
271  {
272  // Manually manage _permuted_weights
273  _permuted_weights.allocator()->allocate();
274  _permute_weights.run();
275  }
276 
277  // Run weights flipping and mark original weights tensor as unused
278  _weights_flipped.allocator()->allocate();
279  NEScheduler::get().schedule(&_flip_weights, Window::DimZ);
280  _original_weights->mark_as_unused();
281 
282  // Prepare convolution
283  _conv_f.prepare();
284 
285  if(!_weights_flipped.is_used())
286  {
287  _weights_flipped.allocator()->free();
288  }
289 
290  if(!_is_nchw)
291  {
292  // Manually manage _permuted_weights
293  // Free _permuted_weights as it not used after this method (prepare)
294  _permuted_weights.allocator()->free();
295  }
296 
297  _is_prepared = true;
298  }
299 }
void run() override final
Run the kernels contained in the function.
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:466
TensorAllocator * allocator()
Return a pointer to the tensor's allocator.
Definition: Tensor.cpp:48
void mark_as_unused() const
Marks a tensor as unused.
Definition: ITensor.cpp:167
void allocate() override
Allocate size specified by TensorInfo of CPU memory.
void free() override
Free allocated CPU memory.
virtual void schedule(ICPPKernel *kernel, const Hints &hints)=0
Runs the kernel in the same thread as the caller synchronously.
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Definition: Window.h:47
void prepare() override
Prepare the function for executing.
static IScheduler & get()
Access the scheduler singleton.
Definition: Scheduler.cpp:95

References TensorAllocator::allocate(), Tensor::allocator(), ARM_COMPUTE_ERROR_ON, Window::DimZ, TensorAllocator::free(), Scheduler::get(), ITensor::is_used(), ITensor::mark_as_unused(), NEConvolutionLayer::prepare(), INESimpleFunctionNoBorder::run(), and IScheduler::schedule().

Referenced by NEDeconvolutionLayer::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 242 of file NEDeconvolutionLayer.cpp.

243 {
244  prepare();
245 
246  MemoryGroupResourceScope scope_mg(_memory_group);
247 
248  // Permute input
249  if(!_is_nchw)
250  {
251  _permute_input.run();
252  }
253 
254  _upsample_f.run();
255  _conv_f.run();
256 
257  // Permute output
258  if(!_is_nchw)
259  {
260  _permute_output.run();
261  }
262 }
void run() override final
Run the kernels contained in the function.
void run() override
Run the kernels contained in the function.
void prepare() override
Prepare the function for executing.
void run() override final
Run the kernels contained in the function.

References NEDeconvolutionLayer::prepare(), ICPPSimpleFunction::run(), INESimpleFunctionNoBorder::run(), and NEConvolutionLayer::run().

◆ validate()

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

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

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

Definition at line 57 of file NEDeconvolutionLayer.cpp.

58 {
63  const unsigned int width_idx = get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::WIDTH);
64  const unsigned int height_idx = get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::HEIGHT);
65  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(width_idx) != weights->dimension(height_idx));
66  ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(width_idx) < 1);
67 
68  auto out_dims = deconvolution_output_dimensions(input->dimension(width_idx), input->dimension(height_idx), weights->dimension(width_idx), weights->dimension(height_idx), info);
69 
71  if(bias != nullptr)
72  {
74  {
76  }
77  else
78  {
80  }
81  }
82 
83  if(output->tensor_shape().total_size() > 0)
84  {
86 
87  const TensorShape output_shape = compute_deconvolution_output_shape(out_dims, *input, *weights);
88 
89  ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimX) != output_shape.x(), "Output's width is invalid.");
90  ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimY) != output_shape.y(), "Output's height is invalid.");
91  ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimZ) != output_shape.z(), "Output's depth is invalid.");
92  }
93 
94  unsigned int deconv_pad_x = 0;
95  unsigned int deconv_pad_y = 0;
96  const unsigned int stride_x = info.stride().first;
97  const unsigned int stride_y = info.stride().second;
98  const TensorShape scale_out_shape = compute_deconvolution_upsampled_shape(*input, *weights, stride_x, stride_y, out_dims, deconv_pad_x, deconv_pad_y);
99  TensorInfo scale_out_info(input->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(scale_out_shape));
100  const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
101 
102  const unsigned int batches_idx = get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::BATCHES);
103  const unsigned int channel_idx = get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::CHANNEL);
104  ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(batches_idx) != scale_out_info.dimension(batches_idx));
105  ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(channel_idx) != scale_out_info.dimension(channel_idx));
106 
107  ARM_COMPUTE_RETURN_ON_ERROR(NEConvolutionLayer::validate(&scale_out_info, weights, bias, output, conv_info, WeightsInfo()));
108 
109  return Status{};
110 }
#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
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:382
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Definition: Validate.h:792
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:296
1 channel, 1 F16 per channel
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 constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
Definition: Window.h:43
quantized, asymmetric fixed-point 8-bit number unsigned
TensorShape compute_deconvolution_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, unsigned int sx, unsigned int sy, std::pair< unsigned int, unsigned int > &out_dims, unsigned int &padx, unsigned int &pady)
Calculate the upsampled output shape used for deconvolution.
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:1044
#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...)
Definition: Validate.h:163
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Definition: Window.h:47
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, msg)
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:327
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info, const WeightsInfo &weights_info=WeightsInfo(), const Size2D &dilation=Size2D(1U, 1U), const ActivationLayerInfo &act_info=ActivationLayerInfo(), bool enable_fast_math=false, unsigned int num_groups=1)
Static function to check if given info will lead to a valid configuration of NEConvolutionLayer.

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_MSG, ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR, ARM_COMPUTE_RETURN_ON_ERROR, arm_compute::BATCHES, arm_compute::test::validation::bias, arm_compute::CEIL, arm_compute::CHANNEL, arm_compute::misc::shape_calculator::compute_deconvolution_output_shape(), arm_compute::misc::shape_calculator::compute_deconvolution_upsampled_shape(), arm_compute::test::validation::conv_info, arm_compute::deconvolution_output_dimensions(), ITensorInfo::dimension(), Window::DimX, Window::DimY, Window::DimZ, arm_compute::F16, arm_compute::F32, arm_compute::get_data_layout_dimension_index(), arm_compute::HEIGHT, arm_compute::test::validation::info, arm_compute::test::validation::input, arm_compute::is_data_type_quantized_asymmetric(), arm_compute::test::validation::output_shape, arm_compute::QASYMM8, arm_compute::S32, ITensorInfo::tensor_shape(), TensorShape::total_size(), NEConvolutionLayer::validate(), arm_compute::test::validation::weights, and arm_compute::WIDTH.

Referenced by NEDeconvolutionLayer::configure().


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