| 63 | } // namespace |
| 64 | |
| 65 | void CpuGemm::configure(const ITensorInfo *a, |
| 66 | const ITensorInfo *b, |
| 67 | const ITensorInfo *c, |
| 68 | ITensorInfo *d, |
| 69 | float alpha, |
| 70 | float beta, |
| 71 | const GEMMInfo &gemm_info) |
| 72 | { |
| 73 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuGemm::configure"); |
| 74 | ARM_COMPUTE_ERROR_ON_NULLPTR(a, b, d); |
| 75 | ARM_COMPUTE_ERROR_THROW_ON(CpuGemm::validate(a, b, c, d, alpha, beta, gemm_info)); |
| 76 | ARM_COMPUTE_LOG_PARAMS(a, b, c, d, alpha, beta, gemm_info); |
| 77 | |
| 78 | const cpu::AsmGemmInfo asm_info = init_assembly_metadata(gemm_info); |
| 79 | const bool is_c_bias = beta == 1 && c != nullptr; |
| 80 | const bool run_optimised = |
| 81 | bool(cpu::CpuGemmAssemblyDispatch::validate(a, b, (is_c_bias) ? c : nullptr, d, asm_info)) && |
| 82 | (c == nullptr || beta == 0.f || beta == 1.f) && // Optimized GeMM doesn't support beta coefficient. |
| 83 | !(!b->are_values_constant() && |
| 84 | b->tensor_shape().z() > 1); // Disable batch matmul as optimized GeMM handles batching differently. |
| 85 | |
| 86 | // Check if we need to reshape the matrix B only on the first run |
| 87 | _is_prepared = false; |
| 88 | _reshape_b_only_on_first_run = b->are_values_constant(); |
| 89 | _run_vector_matrix_multiplication = a->dimension(1) < 2; |
| 90 | _run_alpha_scale = alpha != 1.f; |
| 91 | _run_bias_addition = is_c_bias; |
| 92 | _run_addition = beta != 0 && beta != 1 && c != nullptr; |
| 93 | _run_activation = |
| 94 | gemm_info.activation_info().enabled() && |
| 95 | (!run_optimised || |
| 96 | (run_optimised && !cpu::CpuGemmAssemblyDispatch::is_activation_supported(gemm_info.activation_info()))); |
| 97 | |
| 98 | if (run_optimised) |
| 99 | { |
| 100 | _run_interleave_transpose = false; |
| 101 | const ITensorInfo *c_to_use = is_c_bias ? c : nullptr; |
| 102 | _asm_glue = std::make_unique<cpu::CpuGemmAssemblyDispatch>(); |
| 103 | _asm_glue->configure(a, b, c_to_use, d, asm_info); |
| 104 | ARM_COMPUTE_ERROR_ON(!_asm_glue->is_configured()); |
| 105 | |
| 106 | const auto asm_mem_req = _asm_glue->workspace(); |
| 107 | for (unsigned int slot = 0; slot < asm_mem_req.size(); ++slot) |
| 108 | { |
| 109 | _aux_mem[slot] = asm_mem_req[slot]; |
| 110 | } |
| 111 | |
| 112 | // Scale product by alpha |
| 113 | if (_run_alpha_scale) |
| 114 | { |
| 115 | _alpha_scale_func = std::make_unique<cpu::CpuActivation>(); |
| 116 | _alpha_scale_func->configure( |
| 117 | d, nullptr, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, alpha, 0.f)); |
| 118 | } |
| 119 | } |
| 120 | else |
| 121 | { |
| 122 | _run_interleave_transpose = !_run_vector_matrix_multiplication; |
nothing calls this directly
no test coverage detected