| 247 | namespace |
| 248 | { |
| 249 | Status validate_arguments(const ITensorInfo *input, |
| 250 | const ITensorInfo *output, |
| 251 | const Size2D &kernel_dims, |
| 252 | const PadStrideInfo &conv_info, |
| 253 | bool has_bias, |
| 254 | const Size2D &dilation, |
| 255 | unsigned int num_groups, |
| 256 | unsigned int channel_pad_right) |
| 257 | { |
| 258 | ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input); |
| 259 | ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(output); |
| 260 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED, |
| 261 | DataType::BFLOAT16, DataType::F16, DataType::F32); |
| 262 | ARM_COMPUTE_RETURN_ERROR_ON(is_data_type_quantized(input->data_type()) && has_bias); |
| 263 | ARM_COMPUTE_RETURN_ERROR_ON((dilation.x() < 1) || (dilation.y() < 1)); |
| 264 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(num_groups > 1, "Number of groups greater than one are not supported on Neon"); |
| 265 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(channel_pad_right > 0 && input->data_layout() != DataLayout::NHWC, |
| 266 | "Channel padding is not supported for data layouts other than NHWC"); |
| 267 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(input); |
| 268 | |
| 269 | // Since there's no implicit padding added, check the total input spatial dimensions (with conv paddings) are big enough for the kernel dimensions |
| 270 | const unsigned int width_idx = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::WIDTH); |
| 271 | const unsigned int height_idx = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::HEIGHT); |
| 272 | const unsigned total_width = input->dimension(width_idx) + conv_info.pad_left() + conv_info.pad_right(); |
| 273 | const unsigned total_height = input->dimension(height_idx) + conv_info.pad_top() + conv_info.pad_bottom(); |
| 274 | ARM_COMPUTE_RETURN_ERROR_ON((total_width < kernel_dims.width) || (total_height < kernel_dims.height)); |
| 275 | |
| 276 | const TensorShape out_shape = compute_im2col_conv_shape(input, kernel_dims, conv_info, has_bias, dilation, false, |
| 277 | num_groups, channel_pad_right); |
| 278 | |
| 279 | if (output->total_size() > 0) |
| 280 | { |
| 281 | TensorInfo expected_output = output->clone()->set_tensor_shape(out_shape); |
| 282 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(&expected_output, output); |
| 283 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output); |
| 284 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(input, output); |
| 285 | } |
| 286 | else |
| 287 | { |
| 288 | const auto dst_info = TensorInfo(out_shape, 1, input->data_type()); |
| 289 | ARM_COMPUTE_RETURN_ERROR_ON_SIZE_UNSUPPORTED(&dst_info); |
| 290 | } |
| 291 | |
| 292 | return Status{}; |
| 293 | } |
| 294 | } // namespace |
| 295 | |
| 296 | void CpuIm2ColKernel::configure(const ITensorInfo *src, |
no test coverage detected