ONE - On-device Neural Engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 auto [stride_x, stride_y] = info.stride();
158
159 const DataLayout data_layout = input->info()->data_layout();
160
161 const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
162 const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
163
164 _original_weights = weights;
165 _flip_axis.allocator()->init(TensorInfo(TensorShape(2U), 1, DataType::U32));
166 _weights_flipped.allocator()->init(weights->info()->clone()->set_data_layout(data_layout));
167 _flip_weights.configure(compile_context, weights, &_weights_flipped, &_flip_axis, false);
168
169 auto out_dims = transposeconv_output_dimensions(
170 input->info()->dimension(idx_w), input->info()->dimension(idx_h),
171 weights->info()->dimension(idx_w), weights->info()->dimension(idx_h), info, invalid_right,
172 invalid_bottom);
173
175 compute_transposeconv_output_shape(out_dims, *input->info(), *weights->info());
176
177 // Output auto initialization if not yet initialized
178 auto_init_if_empty(
179 *output->info(),
180 input->info()->clone()->set_tensor_shape(output_shape).set_data_layout(data_layout));
181
182 // Perform validation step
183 ARM_COMPUTE_ERROR_THROW_ON(CLDirectTransposeConvLayer::validate(
184 input->info(), weights->info(), bias == nullptr ? nullptr : bias->info(), output->info(), info,
185 invalid_right, invalid_bottom));
186
187 _is_prepared = weights_info.retain_internal_weights();
188
189 _memory_group.manage(&_scaled_output);
190
191 // Find the upsampled dimensions and the padding needed for the convolution with stride 1 in order
192 // to match output shape
194 *input->info(), *weights->info(), info, out_dims, invalid_right, invalid_bottom, pad_left,
195 pad_right, pad_top, pad_bottom);
196
197 TensorInfo scale_out_info(scale_out_shape, 1, input->info()->data_type(),
198 input->info()->quantization_info());
199 scale_out_info.set_data_layout(data_layout);
200 _scaled_output.allocator()->init(scale_out_info);
201
202 // configure scale function
203 const PadStrideInfo upsample_info(stride_x, stride_y, pad_left, pad_right, pad_top, pad_bottom,
204 DimensionRoundingType::FLOOR);
205 _scale_f.configure(input, &_scaled_output, upsample_info);
206
207 // Setup the function to convolve the upscaled output
208 const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
209 _conv_f.configure(compile_context, &_scaled_output, &_weights_flipped, bias, output, conv_info,
210 weights_info);
211 _scaled_output.allocator()->allocate();
212
213 // Setup flip axis data
214 _flip_axis.allocator()->allocate();
215 _flip_axis.map(true);
216 auto axis_data = reinterpret_cast<uint32_t *>(_flip_axis.buffer());
217 if (weights->info()->data_layout() == DataLayout::NHWC)
218 {
219 axis_data[0] = 1;
220 axis_data[1] = 2;
221 }
222 else
223 {
224 axis_data[0] = 0;
225 axis_data[1] = 1;
226 }
227 _flip_axis.unmap();
228}
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 240 of file CLDirectTransposeConvLayer.cpp.

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

Referenced by run().

◆ run()

void arm_compute::CLDirectTransposeConvLayer::run ( )
override

Definition at line 230 of file CLDirectTransposeConvLayer.cpp.

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

References prepare().

◆ 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: