| 645 | } |
| 646 | |
| 647 | void CpuGemmLowpMatrixMultiplyCore::run(ITensorPack &tensors) |
| 648 | { |
| 649 | ARM_COMPUTE_TRACE_EVENT(ARM_COMPUTE_PROF_CAT_CPU, ARM_COMPUTE_PROF_LVL_CPU, "CpuGemmLowpMatrixMultiplyCore::run"); |
| 650 | prepare(tensors); |
| 651 | |
| 652 | auto a = tensors.get_const_tensor(TensorType::ACL_SRC_0); |
| 653 | auto b = tensors.get_const_tensor(TensorType::ACL_SRC_1); |
| 654 | auto c = tensors.get_const_tensor(TensorType::ACL_SRC_2); |
| 655 | auto dst = tensors.get_tensor(TensorType::ACL_DST); |
| 656 | auto a_to_use = a; |
| 657 | auto matrix_a = a; |
| 658 | auto matrix_b = b; |
| 659 | |
| 660 | CpuAuxTensorHandler vector_sum_col(offset_int_vec(VectorSumCol), _vector_sum_col, tensors, false); |
| 661 | CpuAuxTensorHandler vector_sum_row(offset_int_vec(VectorSumRow), _vector_sum_row, tensors, false); |
| 662 | CpuAuxTensorHandler tmp_a(offset_int_vec(TmpA), _tmp_a, tensors, false); |
| 663 | CpuAuxTensorHandler tmp_b(offset_int_vec(TmpB), _tmp_b, tensors, true); |
| 664 | CpuAuxTensorHandler mm_result_s32(offset_int_vec(MMResultS32), _mm_result_s32, tensors, false); |
| 665 | CpuAuxTensorHandler signed_a(offset_int_vec(SignedA), _signed_a, tensors, false); |
| 666 | CpuAuxTensorHandler signed_output(offset_int_vec(SignedOutput), _signed_output, tensors, false); |
| 667 | |
| 668 | const QuantizationInfo a_qinfo = a->info()->quantization_info(); |
| 669 | const QuantizationInfo b_qinfo = b->info()->quantization_info(); |
| 670 | |
| 671 | if (a_qinfo.is_dynamic()) |
| 672 | _a_offset = a_qinfo.uniform().offset; |
| 673 | if (b_qinfo.is_dynamic()) |
| 674 | _b_offset = b_qinfo.uniform().offset; |
| 675 | |
| 676 | // Convert QASYMM8->QASYMM8_SIGNED |
| 677 | if (_flip_signedness) |
| 678 | { |
| 679 | ITensorPack pack = {{TensorType::ACL_SRC, a}, {TensorType::ACL_DST, signed_a.get()}}; |
| 680 | NEScheduler::get().schedule_op(_convert_to_signed_asymm.get(), Window::DimY, _convert_to_signed_asymm->window(), |
| 681 | pack); |
| 682 | a_to_use = signed_a.get(); |
| 683 | matrix_a = signed_a.get(); |
| 684 | } |
| 685 | |
| 686 | // Run GEMM |
| 687 | if (_asm_glue->is_configured()) |
| 688 | { |
| 689 | ITensorPack asm_glue_tensors = tensors; |
| 690 | if (is_data_type_quantized_asymmetric(a_to_use->info()->data_type()) && |
| 691 | _gemm_info.gemmlowp_output_stage().type == GEMMLowpOutputStageType::QUANTIZE_DOWN_FIXEDPOINT) |
| 692 | { |
| 693 | asm_glue_tensors.add_const_tensor(TensorType::ACL_SRC_0, a_to_use); |
| 694 | asm_glue_tensors.add_const_tensor(TensorType::ACL_SRC_1, b); |
| 695 | asm_glue_tensors.add_const_tensor(TensorType::ACL_SRC_2, c); |
| 696 | asm_glue_tensors.add_tensor(TensorType::ACL_DST, dst); |
| 697 | } |
| 698 | else |
| 699 | { |
| 700 | auto output_to_use = (_fuse_output_stage ? mm_result_s32.get() : dst); |
| 701 | asm_glue_tensors.add_const_tensor(TensorType::ACL_SRC_0, a_to_use); |
| 702 | asm_glue_tensors.add_const_tensor(TensorType::ACL_SRC_1, b); |
| 703 | asm_glue_tensors.add_tensor(TensorType::ACL_DST, output_to_use); |
| 704 | } |
nothing calls this directly
no test coverage detected