| 632 | |
| 633 | template <typename Opr> |
| 634 | std::pair< |
| 635 | typename AlgoChooser<Opr>::ImplAlgoDesc, Maybe<AlgoChooserProfileCache::Result>> |
| 636 | AlgoChooser<Opr>::AlgoChooserHelper::get_profile_result_from_cache( |
| 637 | const ExecutionStrategy& selected_strategy) const { |
| 638 | MIDOUT_B(Opr, midout_iv(MGB_HASH_STR("get_profile_result_from_cache"))) |
| 639 | AlgoChooserProfileCache cache(m_cn, profile_name(m_dnn_opr).c_str()); |
| 640 | |
| 641 | typename Opr::Param origin_param = m_dnn_opr->param(); |
| 642 | AlgoChooserProfileCache::Key cache_key{ |
| 643 | m_incache_layouts.data(), m_incache_layouts.size(), &origin_param, |
| 644 | sizeof(origin_param)}; |
| 645 | auto&& rst = cache.get(cache_key); |
| 646 | // failed to find a cache entry, return |
| 647 | if (!rst.valid()) |
| 648 | return {{}, rst}; |
| 649 | |
| 650 | // found a cache entry(it's a vector of Result), but it's empty |
| 651 | auto&& prof = rst.val(); |
| 652 | if (prof.empty()) |
| 653 | return {{}, rst}; |
| 654 | |
| 655 | // found non-empty cache result, filter it by workspace limit and attribute |
| 656 | size_t workspace_limit = |
| 657 | m_desc.get_workspace_limit(m_cn, m_execution_policy.workspace_limit); |
| 658 | auto target_attr = extract_algo_attribute(selected_strategy); |
| 659 | bool skip_by_negative = false; |
| 660 | bool skip_by_workspace = false; |
| 661 | for (auto&& i : prof) { |
| 662 | auto attr_of_algo = static_cast<megdnn::Algorithm::Attribute>(i.attribute); |
| 663 | bool contain_attr_all_positive = |
| 664 | (target_attr.first == (attr_of_algo & target_attr.first)); |
| 665 | bool contain_attr_any_negative = |
| 666 | static_cast<bool>(attr_of_algo & target_attr.second); |
| 667 | if (contain_attr_all_positive) { |
| 668 | if (!contain_attr_any_negative) { |
| 669 | if (i.workspace <= workspace_limit) { |
| 670 | // found a well-suited algothrim with good workspace limit and |
| 671 | // correct attribute |
| 672 | Algorithm::Info::Desc algo_desc = deserialize_read_pod(i.algo); |
| 673 | return {algo_desc, rst}; |
| 674 | } |
| 675 | skip_by_workspace = true; |
| 676 | } else { |
| 677 | skip_by_negative = true; |
| 678 | } |
| 679 | } |
| 680 | } |
| 681 | |
| 682 | // failed to find an algorithm that satisfies the actual workspace limit |
| 683 | if (skip_by_workspace) |
| 684 | return {}; |
| 685 | |
| 686 | // failed to find an algorithm that satisfies the actual attribute |
| 687 | std::string layouts_str = AlgoChooser::format_fixlayouts(m_fastrun_layouts); |
| 688 | if (skip_by_negative) { |
| 689 | mgb_log_error( |
| 690 | "opr: %s, layouts: %s, No usable algo. There are available " |
| 691 | "algos match " |
nothing calls this directly
no test coverage detected