| 378 | } |
| 379 | |
| 380 | Status ClGemmConv2d::validate(const ITensorInfo *src, |
| 381 | const ITensorInfo *weights, |
| 382 | const ITensorInfo *biases, |
| 383 | const ITensorInfo *dst, |
| 384 | const Conv2dInfo &conv2d_info, |
| 385 | const WeightsInfo &weights_info) |
| 386 | { |
| 387 | ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src, weights, dst); |
| 388 | ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights_info.are_reshaped(), "Weights already reshaped are not supported!"); |
| 389 | ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED, |
| 390 | DataType::F16, DataType::F32); |
| 391 | const bool is_quantized_per_channel = is_data_type_quantized_per_channel(weights->data_type()); |
| 392 | |
| 393 | if (!is_quantized_per_channel) |
| 394 | { |
| 395 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src, weights); |
| 396 | } |
| 397 | ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(src, weights); |
| 398 | ARM_COMPUTE_RETURN_ERROR_ON_MSG((conv2d_info.num_groups != 1) && (src->data_layout() != DataLayout::NCHW), |
| 399 | "Grouping (num_groups != 1) with NHWC data layout is not supported"); |
| 400 | ARM_COMPUTE_RETURN_ERROR_ON_MSG((conv2d_info.num_groups != 1) && (src->data_type() == DataType::QASYMM8), |
| 401 | "Grouping (num_groups != 1) is not supported with QASYMM8"); |
| 402 | ARM_COMPUTE_RETURN_ERROR_ON(((src->dimension(2) / weights->dimension(2)) != conv2d_info.num_groups) && |
| 403 | (src->data_layout() == DataLayout::NCHW)); |
| 404 | |
| 405 | const DataLayout data_layout = src->data_layout(); |
| 406 | const DataType data_type = src->data_type(); |
| 407 | const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); |
| 408 | const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); |
| 409 | const int idx_channel = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL); |
| 410 | const int idx_kernels = get_data_layout_dimension_index(data_layout, DataLayoutDimension::BATCHES); |
| 411 | |
| 412 | const unsigned int kernel_width = weights->dimension(idx_width); |
| 413 | const unsigned int kernel_height = weights->dimension(idx_height); |
| 414 | const unsigned int num_kernels = weights->dimension(idx_kernels); |
| 415 | |
| 416 | TensorInfo im2col_reshaped_info{}; |
| 417 | TensorInfo info_gemm{}; |
| 418 | TensorInfo weights_reshaped_info{}; |
| 419 | const ITensorInfo *gemm_input_to_use = src; |
| 420 | const ITensorInfo *gemm_output_to_use = dst; |
| 421 | const ITensorInfo *weights_to_use = weights; |
| 422 | const bool is_quantized = is_data_type_quantized_asymmetric(data_type); |
| 423 | const bool skip_im2col = |
| 424 | (data_layout == DataLayout::NHWC && kernel_width == 1 && kernel_height == 1 && |
| 425 | conv2d_info.conv_info.stride().first == 1 && conv2d_info.conv_info.stride().second == 1) && |
| 426 | !conv2d_info.conv_info.has_padding(); |
| 427 | const bool skip_col2im = data_layout == DataLayout::NHWC; |
| 428 | bool fuse_activation = true; |
| 429 | |
| 430 | ARM_COMPUTE_RETURN_ERROR_ON((weights->dimension(idx_channel) * conv2d_info.num_groups) != |
| 431 | src->dimension(idx_channel)); |
| 432 | ARM_COMPUTE_RETURN_ERROR_ON(weights->num_dimensions() > 4); |
| 433 | |
| 434 | // Validate biases |
| 435 | if (biases != nullptr) |
| 436 | { |
| 437 | if (is_quantized) |
nothing calls this directly
no test coverage detected