| 459 | } |
| 460 | |
| 461 | void CpuGemmConv2d::configure(const ITensorInfo *src, |
| 462 | const ITensorInfo *weights, |
| 463 | const ITensorInfo *biases, |
| 464 | ITensorInfo *dst, |
| 465 | const PadStrideInfo &conv_info, |
| 466 | const WeightsInfo &weights_info, |
| 467 | const Size2D &dilation, |
| 468 | const ActivationLayerInfo &act_info, |
| 469 | bool enable_fast_math, |
| 470 | unsigned int num_groups) |
| 471 | { |
| 472 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuGemmConv2d::configure"); |
| 473 | ARM_COMPUTE_ERROR_ON_NULLPTR(src, weights, dst); |
| 474 | ARM_COMPUTE_UNUSED(num_groups, weights_info); |
| 475 | ARM_COMPUTE_ERROR_THROW_ON(CpuGemmConv2d::validate(src, weights, biases, dst, conv_info, weights_info, dilation, |
| 476 | act_info, enable_fast_math, num_groups)); |
| 477 | ARM_COMPUTE_LOG_PARAMS(src, weights, biases, dst, conv_info, weights_info, dilation, act_info, enable_fast_math, |
| 478 | num_groups); |
| 479 | |
| 480 | const DataType data_type = src->data_type(); |
| 481 | const DataLayout data_layout = src->data_layout(); |
| 482 | const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); |
| 483 | const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); |
| 484 | const int idx_channel = get_data_layout_dimension_index(data_layout, DataLayoutDimension::CHANNEL); |
| 485 | const int idx_kernels = get_data_layout_dimension_index(data_layout, DataLayoutDimension::BATCHES); |
| 486 | |
| 487 | const unsigned int kernel_width = weights->dimension(idx_width); |
| 488 | const unsigned int kernel_height = weights->dimension(idx_height); |
| 489 | |
| 490 | _is_prepared = weights_info.retain_internal_weights(); |
| 491 | _is_quantized = is_data_type_quantized_asymmetric(src->data_type()); |
| 492 | _data_layout = data_layout; |
| 493 | _skip_im2col = (data_layout == DataLayout::NHWC && kernel_width == 1 && kernel_height == 1 && |
| 494 | conv_info.stride().first == 1 && conv_info.stride().second == 1); |
| 495 | |
| 496 | const ITensorInfo *gemm_input_to_use = src; |
| 497 | ITensorInfo *gemm_output_to_use = dst; |
| 498 | |
| 499 | // Get convolved dimensions |
| 500 | unsigned int conv_w = 0; |
| 501 | unsigned int conv_h = 0; |
| 502 | std::tie(conv_w, conv_h) = scaled_dimensions(src->dimension(idx_width), src->dimension(idx_height), kernel_width, |
| 503 | kernel_height, conv_info, dilation); |
| 504 | |
| 505 | ARM_COMPUTE_ERROR_ON_MSG((dst->dimension(idx_width) != conv_w) || (dst->dimension(idx_height) != conv_h), |
| 506 | "Output shape does not match the expected one"); |
| 507 | |
| 508 | // Check if GEMM3D is supported |
| 509 | const CpuGemmConv2d::SkipInfo skip_info = |
| 510 | CpuGemmConv2d::skip_im_col_info(src, weights, conv_info, dilation, act_info); |
| 511 | _skip_im2col = skip_info.skip_im2col; |
| 512 | _skip_col2im = skip_info.skip_col2im; |
| 513 | |
| 514 | // Get parameters from conv_info |
| 515 | unsigned int stride_x = 0; |
| 516 | unsigned int stride_y = 0; |
| 517 | std::tie(stride_x, stride_y) = conv_info.stride(); |
| 518 |
no test coverage detected