ONE - On-device Neural Engine
Loading...
Searching...
No Matches
arm_compute::CLDirectTransposeConvLayer Class Reference

#include <CLDirectTransposeConvLayer.h>

Collaboration diagram for arm_compute::CLDirectTransposeConvLayer:

Public Member Functions

 CLDirectTransposeConvLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 
 CLDirectTransposeConvLayer (const CLDirectTransposeConvLayer &)=delete
 
 CLDirectTransposeConvLayer (CLDirectTransposeConvLayer &&)=default
 
CLDirectTransposeConvLayeroperator= (const CLDirectTransposeConvLayer &)=delete
 
CLDirectTransposeConvLayeroperator= (CLDirectTransposeConvLayer &&)=default
 
void configure (ICLTensor *input, ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom, const WeightsInfo &weights_info=WeightsInfo())
 
void configure (const CLCompileContext &compile_context, ICLTensor *input, ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom, const WeightsInfo &weights_info=WeightsInfo())
 
void run () override
 
void prepare () override
 

Static Public Member Functions

static Status validate (const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, ITensorInfo *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom, const WeightsInfo &weights_info=WeightsInfo())
 

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 perform a 1x1 convolution pass. Input stride defines how many zeroes we should put between each element of the input and pad is the amount of padding.

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. Therefore, it will be necessary to use the weights in the reverse order to perform an actual convolution. This is achieved by using CLReverse.

This function calls the following OpenCL kernels/functions:

  1. CLDeconvolutionLayerUpsample
  2. CLConvolutionLayer

And the following CPP kernels:

  1. CLReverse

Definition at line 94 of file CLDirectTransposeConvLayer.h.

Constructor & Destructor Documentation

◆ CLDirectTransposeConvLayer() [1/3]

arm_compute::CLDirectTransposeConvLayer::CLDirectTransposeConvLayer ( std::shared_ptr< IMemoryManager >  memory_manager = nullptr)

Constructor

Definition at line 58 of file CLDirectTransposeConvLayer.cpp.

60 : _memory_group(std::move(memory_manager)), _scale_f(), _conv_f(), _flip_weights(),
61 _scaled_output(), _original_weights(nullptr), _weights_flipped(), _flip_axis(),
62 _is_prepared(false)
63{
64}

◆ CLDirectTransposeConvLayer() [2/3]

arm_compute::CLDirectTransposeConvLayer::CLDirectTransposeConvLayer ( const CLDirectTransposeConvLayer )
delete

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

◆ CLDirectTransposeConvLayer() [3/3]

arm_compute::CLDirectTransposeConvLayer::CLDirectTransposeConvLayer ( CLDirectTransposeConvLayer &&  )
default

Default move constructor

Member Function Documentation

◆ configure() [1/2]

void arm_compute::CLDirectTransposeConvLayer::configure ( const CLCompileContext &  compile_context,
ICLTensor *  input,
ICLTensor *  weights,
const ICLTensor *  bias,
ICLTensor *  output,
const PadStrideInfo &  info,
unsigned int  invalid_right,
unsigned int  invalid_bottom,
const WeightsInfo &  weights_info = WeightsInfo() 
)

Set the input, weights, biases and output tensors.

Parameters
[in]compile_contextThe compile context to be used.
[in,out]inputInput tensor. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: QASYMM8_SIGNED/QASYMM8/F16/F32.
[in]weightsThe 4d weights with dimensions [width, height, IFM, OFM]. Data type supported: Same as input.
[in]bias(Optional) The biases have one dimension. Data type supported: Should match input data type, except for input of QASYMM8 and QASYMM8_SIGNED type where biases should be of S32 type
[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.
[in]invalid_rightThe number of zeros added to right edge of the output.
[in]invalid_bottomThe number of zeros added to bottom edge of the output.
[in]weights_info(Optional) Weights information needed for CLConvolutionLayer, specifies if the weights tensor has been reshaped with CLWeightsReshapeKernel.

Definition at line 144 of file CLDirectTransposeConvLayer.cpp.

150{
151 ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
152
153 unsigned int pad_left = 0;
154 unsigned int pad_right = 0;
155 unsigned int pad_top = 0;
156 unsigned int pad_bottom = 0;
157 const unsigned int stride_x = info.stride().first;
158 const unsigned int stride_y = info.stride().second;
159
160 const DataLayout data_layout = input->info()->data_layout();
161
162 const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
163 const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
164
165 _original_weights = weights;
166 _flip_axis.allocator()->init(TensorInfo(TensorShape(2U), 1, DataType::U32));
167 _weights_flipped.allocator()->init(weights->info()->clone()->set_data_layout(data_layout));
168 _flip_weights.configure(compile_context, weights, &_weights_flipped, &_flip_axis, false);
169
170 auto out_dims = transposeconv_output_dimensions(
171 input->info()->dimension(idx_w), input->info()->dimension(idx_h),
172 weights->info()->dimension(idx_w), weights->info()->dimension(idx_h), info, invalid_right,
173 invalid_bottom);
174
176 compute_transposeconv_output_shape(out_dims, *input->info(), *weights->info());
177
178 // Output auto initialization if not yet initialized
179 auto_init_if_empty(
180 *output->info(),
181 input->info()->clone()->set_tensor_shape(output_shape).set_data_layout(data_layout));
182
183 // Perform validation step
184 ARM_COMPUTE_ERROR_THROW_ON(CLDirectTransposeConvLayer::validate(
185 input->info(), weights->info(), bias == nullptr ? nullptr : bias->info(), output->info(), info,
186 invalid_right, invalid_bottom));
187
188 _is_prepared = weights_info.retain_internal_weights();
189
190 _memory_group.manage(&_scaled_output);
191
192 // Find the upsampled dimensions and the padding needed for the convolution with stride 1 in order
193 // to match output shape
195 *input->info(), *weights->info(), info, out_dims, invalid_right, invalid_bottom, pad_left,
196 pad_right, pad_top, pad_bottom);
197
198 TensorInfo scale_out_info(scale_out_shape, 1, input->info()->data_type(),
199 input->info()->quantization_info());
200 scale_out_info.set_data_layout(data_layout);
201 _scaled_output.allocator()->init(scale_out_info);
202
203 // configure scale function
204 const PadStrideInfo upsample_info(stride_x, stride_y, pad_left, pad_right, pad_top, pad_bottom,
205 DimensionRoundingType::FLOOR);
206 _scale_f.configure(input, &_scaled_output, upsample_info);
207
208 // Setup the function to convolve the upscaled output
209 const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
210 _conv_f.configure(compile_context, &_scaled_output, &_weights_flipped, bias, output, conv_info,
211 weights_info);
212 _scaled_output.allocator()->allocate();
213
214 // Setup flip axis data
215 _flip_axis.allocator()->allocate();
216 _flip_axis.map(true);
217 auto axis_data = reinterpret_cast<uint32_t *>(_flip_axis.buffer());
218 if (weights->info()->data_layout() == DataLayout::NHWC)
219 {
220 axis_data[0] = 1;
221 axis_data[1] = 2;
222 }
223 else
224 {
225 axis_data[0] = 0;
226 axis_data[1] = 1;
227 }
228 _flip_axis.unmap();
229}
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, ITensorInfo *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom, const WeightsInfo &weights_info=WeightsInfo())
volatile const char info[]
const luci_interpreter::RuntimeShape output_shape
::nncc::core::ADT::tensor::Shape TensorShape
Definition TensorShape.h:25
TensorShape compute_transposeconv_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, const PadStrideInfo &info, std::pair< unsigned int, unsigned int > &out_dims, unsigned int invalid_right, unsigned int invalid_bottom, unsigned int &pad_left, unsigned int &pad_right, unsigned int &pad_top, unsigned int &pad_bottom)
TensorShape compute_transposeconv_output_shape(const std::pair< unsigned int, unsigned int > &out_dims, const ITensorInfo &input, const ITensorInfo &weights)
const std::pair< unsigned int, unsigned int > transposeconv_output_dimensions(unsigned int in_width, unsigned int in_height, unsigned int kernel_width, unsigned int kernel_height, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_top)
Definition UtilsEx.cpp:47

References arm_compute::misc::shape_calculator::compute_transposeconv_output_shape(), arm_compute::misc::shape_calculator::compute_transposeconv_upsampled_shape(), info, output_shape, arm_compute::transposeconv_output_dimensions(), and validate().

◆ configure() [2/2]

void arm_compute::CLDirectTransposeConvLayer::configure ( ICLTensor *  input,
ICLTensor *  weights,
const ICLTensor *  bias,
ICLTensor *  output,
const PadStrideInfo &  info,
unsigned int  invalid_right,
unsigned int  invalid_bottom,
const WeightsInfo &  weights_info = WeightsInfo() 
)

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: QASYMM8_SIGNED/QASYMM8/F16/F32.
[in]weightsThe 4d weights with dimensions [width, height, IFM, OFM]. Data type supported: Same as input.
[in]bias(Optional) The biases have one dimension. Data type supported: Should match input data type, except for input of QASYMM8 and QASYMM8_SIGNED type where biases should be of S32 type
[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.
[in]invalid_rightThe number of zeros added to right edge of the output.
[in]invalid_bottomThe number of zeros added to bottom edge of the output.
[in]weights_info(Optional) Weights information needed for CLConvolutionLayer, specifies if the weights tensor has been reshaped with CLWeightsReshapeKernel.

Definition at line 134 of file CLDirectTransposeConvLayer.cpp.

139{
140 configure(CLKernelLibrary::get().get_compile_context(), input, weights, bias, output, info,
141 invalid_right, invalid_bottom, weights_info);
142}
void configure(ICLTensor *input, ICLTensor *weights, const ICLTensor *bias, ICLTensor *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom, const WeightsInfo &weights_info=WeightsInfo())

References configure(), and info.

Referenced by configure().

◆ operator=() [1/2]

CLDirectTransposeConvLayer & arm_compute::CLDirectTransposeConvLayer::operator= ( CLDirectTransposeConvLayer &&  )
default

Default move assignment operator

References validate().

◆ operator=() [2/2]

CLDirectTransposeConvLayer & arm_compute::CLDirectTransposeConvLayer::operator= ( const CLDirectTransposeConvLayer )
delete

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

◆ prepare()

void arm_compute::CLDirectTransposeConvLayer::prepare ( )
override

Definition at line 241 of file CLDirectTransposeConvLayer.cpp.

242{
243 if (!_is_prepared)
244 {
245 ARM_COMPUTE_ERROR_ON(!_original_weights->is_used());
246
247 // Run weights flipping and mark original weights tensor as unused
248 _weights_flipped.allocator()->allocate();
249 _flip_weights.run();
250 _original_weights->mark_as_unused();
251
252 // Prepare convolution
253 _conv_f.prepare();
254
255 // Free flipped weights
256 if (!_weights_flipped.is_used())
257 {
258 _weights_flipped.allocator()->free();
259 }
260
261 _is_prepared = true;
262 }
263}

Referenced by run().

◆ run()

void arm_compute::CLDirectTransposeConvLayer::run ( )
override

Definition at line 231 of file CLDirectTransposeConvLayer.cpp.

232{
233 prepare();
234
235 MemoryGroupResourceScope scope_mg(_memory_group);
236
237 _scale_f.run();
238 _conv_f.run();
239}

References prepare().

Referenced by package.infer.session::inference().

◆ validate()

Status arm_compute::CLDirectTransposeConvLayer::validate ( const ITensorInfo *  input,
const ITensorInfo *  weights,
const ITensorInfo *  bias,
ITensorInfo *  output,
const PadStrideInfo &  info,
unsigned int  invalid_right,
unsigned int  invalid_bottom,
const WeightsInfo &  weights_info = WeightsInfo() 
)
static

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

Parameters
[in]inputInput tensor info. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: QASYMM8_SIGNED/QASYMM8/F16/F32.
[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: Should match input data type, except for input of QASYMM8 and QASYMM8_SIGNED type where biases should be of S32 type
[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.
[in]invalid_rightThe number of zeros added to right edge of the output.
[in]invalid_bottomThe number of zeros added to bottom edge of the output.
[in]weights_info(Optional) Weights information needed for CLConvolutionLayer, specifies if the weights tensor has been reshaped with CLWeightsReshapeKernel.
Returns
a status

Definition at line 66 of file CLDirectTransposeConvLayer.cpp.

71{
72 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output);
73 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(
74 input, 1, DataType::QASYMM8_SIGNED, DataType::QASYMM8, DataType::F16, DataType::F32);
75 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, weights);
76 const DataLayout data_layout = input->data_layout();
77
78 const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
79 const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
80 const size_t idx_c = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL);
81
82 ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_w) != weights->dimension(idx_h));
83 ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_w) < 1);
84
85 auto out_dims = transposeconv_output_dimensions(
86 input->dimension(idx_w), input->dimension(idx_h), weights->dimension(idx_w),
87 weights->dimension(idx_h), info, invalid_right, invalid_bottom);
88
89 const TensorShape output_shape = compute_transposeconv_output_shape(out_dims, *input, *weights);
90
91 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output, weights);
92
93 if (bias != nullptr)
94 {
95 if (is_data_type_quantized_asymmetric(input->data_type()))
96 {
97 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(bias, 1, DataType::S32);
98 }
99 else
100 {
101 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, bias);
102 }
103 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, bias);
104 }
105
106 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(idx_w) != output_shape[idx_w],
107 "Output's width is invalid.");
108 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(idx_h) != output_shape[idx_h],
109 "Output's height is invalid.");
110 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(idx_c) != output_shape[idx_c],
111 "Output's depth is invalid.");
112
113 unsigned int pad_left = 0;
114 unsigned int pad_right = 0;
115 unsigned int pad_top = 0;
116 unsigned int pad_bottom = 0;
117 const TensorShape scale_out_shape =
118 compute_transposeconv_upsampled_shape(*input, *weights, info, out_dims, invalid_right,
119 invalid_bottom, pad_left, pad_right, pad_top, pad_bottom);
120 TensorInfo scale_out_info(input->clone()
121 ->set_is_resizable(true)
122 .reset_padding()
123 .set_tensor_shape(scale_out_shape)
124 .set_data_layout(data_layout));
125 const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
126
127 ARM_COMPUTE_RETURN_ON_ERROR(CLDeconvolutionLayerUpsample::validate(input, &scale_out_info, info));
128 ARM_COMPUTE_RETURN_ON_ERROR(
129 CLConvolutionLayer::validate(&scale_out_info, weights, bias, output, conv_info, weights_info));
130
131 return Status{};
132}

References arm_compute::misc::shape_calculator::compute_transposeconv_output_shape(), arm_compute::misc::shape_calculator::compute_transposeconv_upsampled_shape(), info, output_shape, and arm_compute::transposeconv_output_dimensions().

Referenced by configure(), operator=(), and arm_compute::CLTransposeConvLayer::validate().


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