| 128 | CLGEMMDeconvolutionLayer::~CLGEMMDeconvolutionLayer() = default; |
| 129 | |
| 130 | Status CLGEMMDeconvolutionLayer::validate(const ITensorInfo *input, |
| 131 | const ITensorInfo *weights, |
| 132 | const ITensorInfo *bias, |
| 133 | const ITensorInfo *output, |
| 134 | const PadStrideInfo &deconv_info) |
| 135 | { |
| 136 | ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output); |
| 137 | ARM_COMPUTE_RETURN_ERROR_ON_DYNAMIC_SHAPE(input, weights, bias, output); |
| 138 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F32, DataType::F16, DataType::QASYMM8, |
| 139 | DataType::QASYMM8_SIGNED); |
| 140 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, weights); |
| 141 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, weights); |
| 142 | |
| 143 | DataLayout data_layout = input->data_layout(); |
| 144 | const bool padded_input = deconv_info.pad_bottom() > 0 || deconv_info.pad_left() > 0 || |
| 145 | deconv_info.pad_right() > 0 || deconv_info.pad_top() > 0; |
| 146 | const bool is_nchw = input->data_layout() == DataLayout::NCHW; |
| 147 | const bool is_quantized = is_data_type_quantized_asymmetric(input->data_type()); |
| 148 | |
| 149 | const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); |
| 150 | const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); |
| 151 | const size_t idx_b = get_data_layout_dimension_index(data_layout, DataLayoutDimension::BATCHES); |
| 152 | |
| 153 | ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_w) != deconv_info.stride().first); |
| 154 | ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(idx_h) != deconv_info.stride().second); |
| 155 | |
| 156 | TensorShape nhwc_weights_shape = weights->tensor_shape(); |
| 157 | TensorShape nhwc_input_shape = input->tensor_shape(); |
| 158 | |
| 159 | if (is_nchw) |
| 160 | { |
| 161 | permute(nhwc_weights_shape, PermutationVector(2, 0, 1)); |
| 162 | permute(nhwc_input_shape, PermutationVector(2, 0, 1)); |
| 163 | |
| 164 | TensorInfo nhwc_input_info = input->clone() |
| 165 | ->set_is_resizable(true) |
| 166 | .reset_padding() |
| 167 | .set_tensor_shape(nhwc_input_shape) |
| 168 | .set_data_layout(DataLayout::NCHW); |
| 169 | |
| 170 | TensorInfo nhwc_weights_info = weights->clone() |
| 171 | ->set_is_resizable(true) |
| 172 | .reset_padding() |
| 173 | .set_tensor_shape(nhwc_weights_shape) |
| 174 | .set_data_layout(DataLayout::NCHW); |
| 175 | |
| 176 | CLPermute::validate(weights, &nhwc_weights_info, PermutationVector(2, 0, 1)); |
| 177 | CLPermute::validate(input, &nhwc_input_info, PermutationVector(2, 0, 1)); |
| 178 | } |
| 179 | |
| 180 | const TensorShape reshaped_shape = |
| 181 | TensorShape(nhwc_weights_shape[0], nhwc_weights_shape[1] * nhwc_weights_shape[2] * nhwc_weights_shape[3]); |
| 182 | const TensorInfo reshaped_info = |
| 183 | weights->clone()->set_tensor_shape(reshaped_shape).set_data_layout(DataLayout::NCHW).set_is_resizable(true); |
| 184 | ARM_COMPUTE_RETURN_ON_ERROR(CLReshapeLayer::validate(weights, &reshaped_info)); |
| 185 | |
| 186 | TensorShape transposed_shape(reshaped_shape[1], reshaped_shape[0]); |
| 187 | const TensorInfo reshaped_t_info = reshaped_info.clone()->set_is_resizable(true).set_tensor_shape(transposed_shape); |
nothing calls this directly
no test coverage detected