| 541 | } |
| 542 | |
| 543 | void CpuFullyConnected::prepare(ITensorPack &tensors) |
| 544 | { |
| 545 | if (!_is_prepared || _dynamic_weights) |
| 546 | { |
| 547 | #ifdef ARM_COMPUTE_ASSERTS_ENABLED |
| 548 | ++_asrt_prepare_count; |
| 549 | ARM_COMPUTE_ERROR_ON(!_dynamic_weights && _asrt_prepare_count > 1); |
| 550 | #endif // ARM_COMPUTE_ASSERTS_ENABLED |
| 551 | |
| 552 | auto weights = tensors.get_const_tensor(ACL_SRC_1); |
| 553 | |
| 554 | CpuAuxTensorHandler reshaped_weights(offset_int_vec(TransposedWeights), _reshaped_weights, tensors, false); |
| 555 | CpuAuxTensorHandler converted_weights(offset_int_vec(ConvertedWeights), _converted_weights, tensors, false); |
| 556 | |
| 557 | // Pointer to current weights |
| 558 | const ITensor *cur_weights = weights; |
| 559 | |
| 560 | // Reshape of the weights (happens only once) |
| 561 | if (_needs_weights_reshape) |
| 562 | { |
| 563 | // Run reshape weights kernel and mark weights as unused |
| 564 | ITensorPack transpose_pack{{ACL_SRC, weights}, {ACL_DST, reshaped_weights.get()}}; |
| 565 | NEScheduler::get().schedule_op(_transpose_weights.get(), Window::DimY, _transpose_weights->window(), |
| 566 | transpose_pack); |
| 567 | |
| 568 | cur_weights->mark_as_unused(); |
| 569 | cur_weights = reshaped_weights.get(); |
| 570 | } |
| 571 | |
| 572 | // Convert weights if needed (happens only once) |
| 573 | if (_needs_weights_conversion) |
| 574 | { |
| 575 | ITensorPack convert_pack{{ACL_SRC, cur_weights}, {ACL_DST, converted_weights.get()}}; |
| 576 | _convert_weights->run(convert_pack); |
| 577 | |
| 578 | cur_weights->mark_as_unused(); |
| 579 | cur_weights = converted_weights.get(); |
| 580 | } |
| 581 | |
| 582 | ITensorPack gemm_pack = tensors; |
| 583 | gemm_pack.add_const_tensor(ACL_SRC_1, cur_weights); |
| 584 | |
| 585 | // Prepare GEMM prepare and release unused weights |
| 586 | if (!_is_quantized_asymmetric) |
| 587 | { |
| 588 | _mm_gemm->prepare(gemm_pack); |
| 589 | } |
| 590 | else |
| 591 | { |
| 592 | _mm_gemmlowp->prepare(gemm_pack); |
| 593 | } |
| 594 | |
| 595 | _is_prepared = true; |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | experimental::MemoryRequirements CpuFullyConnected::workspace() const |
| 600 | { |
nothing calls this directly
no test coverage detected