| 209 | } |
| 210 | |
| 211 | void NEDeconvolutionLayer::configure(ITensor *input, |
| 212 | const ITensor *weights, |
| 213 | const ITensor *bias, |
| 214 | ITensor *output, |
| 215 | const PadStrideInfo &info, |
| 216 | bool enable_fast_math, |
| 217 | const WeightsInfo &weights_info) |
| 218 | { |
| 219 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "NEDeconvolutionLayer::configure"); |
| 220 | // Perform validation step |
| 221 | ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output); |
| 222 | ARM_COMPUTE_ERROR_THROW_ON(NEDeconvolutionLayer::validate(input->info(), weights->info(), |
| 223 | (bias == nullptr) ? nullptr : bias->info(), |
| 224 | output->info(), info, enable_fast_math, weights_info)); |
| 225 | ARM_COMPUTE_LOG_PARAMS(input, weights, bias, output, info, enable_fast_math, weights_info); |
| 226 | |
| 227 | const DataLayout data_layout = input->info()->data_layout(); |
| 228 | const unsigned int width_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); |
| 229 | const unsigned int height_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); |
| 230 | auto out_dims = deconvolution_output_dimensions( |
| 231 | input->info()->dimension(width_idx), input->info()->dimension(height_idx), |
| 232 | weights->info()->dimension(width_idx), weights->info()->dimension(height_idx), info); |
| 233 | |
| 234 | const TensorShape output_shape = compute_deconvolution_output_shape(out_dims, *input->info(), *weights->info()); |
| 235 | |
| 236 | _input = input; |
| 237 | _original_weights = weights; |
| 238 | _info = info; |
| 239 | _is_prepared = false; |
| 240 | |
| 241 | const unsigned int stride_x = info.stride().first; |
| 242 | const unsigned int stride_y = info.stride().second; |
| 243 | |
| 244 | // Output auto initialization if not yet initialized |
| 245 | auto_init_if_empty(*output->info(), output_shape, 1, input->info()->data_type(), |
| 246 | input->info()->quantization_info()); |
| 247 | |
| 248 | _flip_axis.allocator()->init(TensorInfo(TensorShape(2U), 1, DataType::U32)); |
| 249 | |
| 250 | _weights_flipped.allocator()->init(weights->info()->clone()->set_data_layout(data_layout)); |
| 251 | _flip_weights.configure(weights, &_weights_flipped, &_flip_axis); |
| 252 | |
| 253 | // setup the function to convolve the upscaled output |
| 254 | uint32_t deconv_pad_x = 0; |
| 255 | uint32_t deconv_pad_y = 0; |
| 256 | const TensorShape scale_out_shape = compute_deconvolution_upsampled_shape( |
| 257 | *input->info(), *weights->info(), stride_x, stride_y, out_dims, deconv_pad_x, deconv_pad_y); |
| 258 | |
| 259 | PadStrideInfo upsample_info; |
| 260 | bool negative_padding; |
| 261 | std::tie(upsample_info, negative_padding) = compute_upsample_info(info, deconv_pad_x, deconv_pad_y); |
| 262 | |
| 263 | ARM_COMPUTE_ERROR_ON(negative_padding); |
| 264 | // Do not perform upsampling when the operation uses unit stride in all dimensions |
| 265 | _do_upsampling = stride_x != 1 || stride_y != 1; |
| 266 | |
| 267 | // Setup flip axis data |
| 268 | _flip_axis.allocator()->allocate(); |
nothing calls this directly
no test coverage detected