| 577 | } |
| 578 | |
| 579 | void ClFullyConnected::run(ITensorPack &tensors) |
| 580 | { |
| 581 | prepare(tensors); |
| 582 | |
| 583 | #ifdef ARM_COMPUTE_ASSERTS_ENABLED |
| 584 | ++_asrt_run_count; |
| 585 | ARM_COMPUTE_ERROR_ON(_dynamic_gemm && _asrt_prepare_count != _asrt_run_count); |
| 586 | #endif // ARM_COMPUTE_ASSERTS_ENABLED |
| 587 | |
| 588 | auto src = tensors.get_const_tensor(ACL_SRC_0); |
| 589 | |
| 590 | CLAuxTensorHandler flattened_src(offset_int_vec(FlattenedSrc), _flattened_src, tensors, false); |
| 591 | CLAuxTensorHandler weights(_weights_to_use_idx, _weights_to_use, tensors, false); |
| 592 | |
| 593 | // Linearize input if it comes from a convolutional layer |
| 594 | if (_is_fc_after_conv) |
| 595 | { |
| 596 | ITensorPack flatten_pack{{ACL_SRC, src}, {ACL_DST, flattened_src.get()}}; |
| 597 | _flatten->run(flatten_pack); |
| 598 | } |
| 599 | |
| 600 | ITensorPack gemm_pack = tensors; |
| 601 | gemm_pack.add_const_tensor(ACL_SRC_0, (_is_fc_after_conv) ? flattened_src.get() : src); |
| 602 | if (_weights_to_use_idx != ACL_SRC_1) |
| 603 | { |
| 604 | gemm_pack.add_const_tensor(ACL_SRC_1, weights.get()); |
| 605 | } |
| 606 | |
| 607 | // Run MatMul Op |
| 608 | if (_use_matmul) |
| 609 | { |
| 610 | // Run matmul kernels for matrix multiplication |
| 611 | if (_is_quantized) |
| 612 | { |
| 613 | CLScheduler::get().enqueue_op(*_matmul_lowp_native_kernel, gemm_pack, true); |
| 614 | } |
| 615 | else |
| 616 | { |
| 617 | CLScheduler::get().enqueue_op(*_matmul_native_kernel, gemm_pack, true); |
| 618 | } |
| 619 | } |
| 620 | else |
| 621 | { |
| 622 | // Run matrix multiply |
| 623 | if (_is_quantized) |
| 624 | { |
| 625 | _mm_gemmlowp->run(gemm_pack); |
| 626 | } |
| 627 | else |
| 628 | { |
| 629 | _mm_gemm->run(gemm_pack); |
| 630 | } |
| 631 | } |
| 632 | } |
| 633 | |
| 634 | void ClFullyConnected::prepare(ITensorPack &tensors) |
| 635 | { |
no test coverage detected