已合并
fix: enforce block dim hardware core budget #1956
zhang_shengjie创建于 6 天前
fix: enforce block dim hardware core budget #1956
已合并
共 14 个文件变更+268-41
| @@ -110,7 +110,10 @@ void GeneralSolverGen::SetBufferCons(const std::map<HardwareDef, Expr> &buffer_c | |||
| 110 | std::string hardware = iter->second; | 110 | std::string hardware = iter->second; |
| 111 | hardware_expr = CreateExpr(hardware.c_str()); | 111 | hardware_expr = CreateExpr(hardware.c_str()); |
| 112 | cons_expr = af::sym::Sub(pair.second, hardware_expr); | 112 | cons_expr = af::sym::Sub(pair.second, hardware_expr); |
| 113 | - if (IsRelated(cons_expr)) { | 113 | + // CORENUM is the launch/core budget and must remain an explicit solver |
| 114 | + // constraint even when the expression only depends on input/container | ||
| 115 | + // variables (and therefore is not searchable by this solver). | ||
| 116 | + if (IsRelated(cons_expr) || pair.first == HardwareDef::CORENUM) { | ||
| 114 | hardware_cost = hardware; | 117 | hardware_cost = hardware; |
| 115 | remain = af::sym::Min(cons_expr, af::sym::kSymbolZero); | 118 | remain = af::sym::Min(cons_expr, af::sym::kSymbolZero); |
| 116 | penalty = af::sym::Max(cons_expr, af::sym::kSymbolZero); | 119 | penalty = af::sym::Max(cons_expr, af::sym::kSymbolZero); |
| @@ -1340,6 +1340,12 @@ af::Status TilingCodeGenImpl::GenGetTiling() { | |||
| 1340 | tiling_func_.AddLine(" }"); | 1340 | tiling_func_.AddLine(" }"); |
| 1341 | tiling_func_.AddLine(" DoApiTiling(tiling_data);"); | 1341 | tiling_func_.AddLine(" DoApiTiling(tiling_data);"); |
| 1342 | tiling_func_.AddLine(" GeneralTiling(tiling_data);"); | 1342 | tiling_func_.AddLine(" GeneralTiling(tiling_data);"); |
| 1343 | + tiling_func_.AddLine(" if (tiling_data.get_block_dim() > corenum_) {"); | ||
| 1344 | + tiling_func_.AddLine( | ||
| 1345 | + " OP_LOGW(OP_NAME, \"Generated block_dim %u exceeds core budget %u.\", " | ||
| 1346 | + "tiling_data.get_block_dim(), corenum_);"); | ||
| 1347 | + tiling_func_.AddLine(" return false;"); | ||
| 1348 | + tiling_func_.AddLine(" }"); | ||
| 1343 | if (config_.gen_extra_infos) { | 1349 | if (config_.gen_extra_infos) { |
| 1344 | tiling_func_.AddLine(" GetWorkSpaceSize(tiling_data);"); | 1350 | tiling_func_.AddLine(" GetWorkSpaceSize(tiling_data);"); |
| 1345 | tiling_func_.AddLine(" ExtraTilingData(tiling_data);"); | 1351 | tiling_func_.AddLine(" ExtraTilingData(tiling_data);"); |
| @@ -4043,7 +4049,7 @@ void TilingCodeGenImpl::GenPGOByCoreNumGetScheduleResult( | |||
| 4043 | tiling_func_.AddLine(" tiling_data_list.insert(tiling_data_list.end(), tiling_data_list_tmp" + | 4049 | tiling_func_.AddLine(" tiling_data_list.insert(tiling_data_list.end(), tiling_data_list_tmp" + |
| 4044 | std::to_string(group_index) + ".begin(), tiling_data_list_tmp" + std::to_string(group_index) + | 4050 | std::to_string(group_index) + ".begin(), tiling_data_list_tmp" + std::to_string(group_index) + |
| 4045 | ".end());"); | 4051 | ".end());"); |
| 4046 | - tiling_func_.AddLine(" return true;"); | 4052 | + tiling_func_.AddLine(" return !tiling_data_list_tmp" + std::to_string(group_index) + ".empty();"); |
| 4047 | tiling_func_.AddLine("}"); | 4053 | tiling_func_.AddLine("}"); |
| 4048 | } | 4054 | } |
| 4049 | 4055 | ||
| @@ -4124,22 +4130,24 @@ af::Status TilingCodeGenImpl::GenPGOGetScheduleResultPerGroup( | |||
| 4124 | tiling_func_.AddLine(" workspaceSize = workspaceSizeTmp;"); | 4130 | tiling_func_.AddLine(" workspaceSize = workspaceSizeTmp;"); |
| 4125 | tiling_func_.AddLine(" }"); | 4131 | tiling_func_.AddLine(" }"); |
| 4126 | tiling_func_.AddLine(" }"); | 4132 | tiling_func_.AddLine(" }"); |
| 4127 | - tiling_func_.AddLine(" workspaceSize += 16 * 1024 * 1024;"); | 4133 | + tiling_func_.AddLine(" std::vector<AutofuseTilingDataPerf> valid_tiling_data_list;"); |
| 4128 | - tiling_func_.AddLine(" if (PgoConfig::Instance().batch_callback) {"); | 4134 | + tiling_func_.AddLine(" valid_tiling_data_list.reserve(valid_candidates.size());"); |
| 4129 | - tiling_func_.AddLine( | ||
| 4130 | - " if (PgoConfig::Instance().batch_callback(PgoConfig::Instance().tensor_args, stream, " | ||
| 4131 | - "workspaceSize, &tiling_data_list_tmp) != 0) {"); | ||
| 4132 | - tiling_func_.AddLine(" return false;"); | ||
| 4133 | - tiling_func_.AddLine(" }"); | ||
| 4134 | - tiling_func_.AddLine(" }"); | ||
| 4135 | tiling_func_.AddLine(" for (size_t candidate_index = " + candidate_begin_name + | 4135 | tiling_func_.AddLine(" for (size_t candidate_index = " + candidate_begin_name + |
| 4136 | "; candidate_index < tiling_data_list_tmp.size(); ++candidate_index) {"); | 4136 | "; candidate_index < tiling_data_list_tmp.size(); ++candidate_index) {"); |
| 4137 | tiling_func_.AddLine(" const size_t candidate_offset = candidate_index - " + candidate_begin_name + ";"); | 4137 | tiling_func_.AddLine(" const size_t candidate_offset = candidate_index - " + candidate_begin_name + ";"); |
| 4138 | - tiling_func_.AddLine( | 4138 | + tiling_func_.AddLine(" if (candidate_offset < valid_candidates.size() && valid_candidates[candidate_offset]) {"); |
| 4139 | - " if (candidate_offset >= valid_candidates.size() || !valid_candidates[candidate_offset]) {"); | 4139 | + tiling_func_.AddLine(" valid_tiling_data_list.push_back(tiling_data_list_tmp[candidate_index]);"); |
| 4140 | - tiling_func_.AddLine(" continue;"); | ||
| 4141 | tiling_func_.AddLine(" }"); | 4140 | tiling_func_.AddLine(" }"); |
| 4142 | - tiling_func_.AddLine(" auto &tiling_data_perf = tiling_data_list_tmp[candidate_index];"); | 4141 | + tiling_func_.AddLine(" }"); |
| 4142 | + tiling_func_.AddLine(" workspaceSize += 16 * 1024 * 1024;"); | ||
| 4143 | + tiling_func_.AddLine(" if (PgoConfig::Instance().batch_callback && !valid_tiling_data_list.empty()) {"); | ||
| 4144 | + tiling_func_.AddLine( | ||
| 4145 | + " if (PgoConfig::Instance().batch_callback(PgoConfig::Instance().tensor_args, stream, " | ||
| 4146 | + "workspaceSize, &valid_tiling_data_list) != 0) {"); | ||
| 4147 | + tiling_func_.AddLine(" return false;"); | ||
| 4148 | + tiling_func_.AddLine(" }"); | ||
| 4149 | + tiling_func_.AddLine(" }"); | ||
| 4150 | + tiling_func_.AddLine(" for (auto &tiling_data_perf : valid_tiling_data_list) {"); | ||
| 4143 | tiling_func_.AddLine(" tiling_data_list.push_back(tiling_data_perf);"); | 4151 | tiling_func_.AddLine(" tiling_data_list.push_back(tiling_data_perf);"); |
| 4144 | tiling_func_.AddLine(" if (tiling_data_perf.best_perf < best_perf) {"); | 4152 | tiling_func_.AddLine(" if (tiling_data_perf.best_perf < best_perf) {"); |
| 4145 | tiling_func_.AddLine(" tiling_data = tiling_data_perf.tiling_data;"); | 4153 | tiling_func_.AddLine(" tiling_data = tiling_data_perf.tiling_data;"); |
| @@ -4161,8 +4169,9 @@ af::Status TilingCodeGenImpl::GenPGOScheduleGroupSearchEntry( | |||
| 4161 | return af::SUCCESS; | 4169 | return af::SUCCESS; |
| 4162 | } | 4170 | } |
| 4163 | GenSetHardwareCodes(group_info.second.second, hardware_iter->second); | 4171 | GenSetHardwareCodes(group_info.second.second, hardware_iter->second); |
| 4164 | - auto [input_vars_set_code, need_update] = ProcessVarRelationsStatement( | 4172 | + auto [input_vars_set_code, need_update] = |
| 4165 | - graph_info, var_relations_[asc_graph_id][impl_graph_id], group_info.first, " tiling_data.", {"return true;"}); | 4173 | + ProcessVarRelationsStatement(graph_info, var_relations_[asc_graph_id][impl_graph_id], group_info.first, |
| 4174 | + " tiling_data.", {"return tiling_data_list.size() > candidate_count_before;"}); | ||
| 4166 | if (need_update) { | 4175 | if (need_update) { |
| 4167 | RequireVarRelationSystemHeaders(); | 4176 | RequireVarRelationSystemHeaders(); |
| 4168 | tiling_func_.AddLine(input_vars_set_code); | 4177 | tiling_func_.AddLine(input_vars_set_code); |
| @@ -4206,6 +4215,7 @@ af::Status TilingCodeGenImpl::GenPGOGetScheduleResult( | |||
| 4206 | "SearchConfig *search_cfg=nullptr) {"); | 4215 | "SearchConfig *search_cfg=nullptr) {"); |
| 4207 | tiling_func_.AddLine(func_define); | 4216 | tiling_func_.AddLine(func_define); |
| 4208 | tiling_func_.AddLine(" (void)cur_perf; (void)cur_block_dim;"); | 4217 | tiling_func_.AddLine(" (void)cur_perf; (void)cur_block_dim;"); |
| 4218 | + tiling_func_.AddLine(" const size_t candidate_count_before = tiling_data_list.size();"); | ||
| 4209 | uint32_t group_index = 0U; | 4219 | uint32_t group_index = 0U; |
| 4210 | tiling_func_.AddLine(" std::vector<AutofuseTilingDataPerf> tiling_data_list_tmp{};"); | 4220 | tiling_func_.AddLine(" std::vector<AutofuseTilingDataPerf> tiling_data_list_tmp{};"); |
| 4211 | tiling_func_.AddLine(" workspaceSize = 0;"); | 4221 | tiling_func_.AddLine(" workspaceSize = 0;"); |
| @@ -4218,7 +4228,7 @@ af::Status TilingCodeGenImpl::GenPGOGetScheduleResult( | |||
| 4218 | GenPGOScheduleGroupSearchEntry(asc_graph_id, impl_graph_id, graph_info, hardware_map, group_info, result_name)); | 4228 | GenPGOScheduleGroupSearchEntry(asc_graph_id, impl_graph_id, graph_info, hardware_map, group_info, result_name)); |
| 4219 | group_index++; | 4229 | group_index++; |
| 4220 | } | 4230 | } |
| 4221 | - tiling_func_.AddLine(" return true;"); | 4231 | + tiling_func_.AddLine(" return tiling_data_list.size() > candidate_count_before;"); |
| 4222 | tiling_func_.AddLine("}"); | 4232 | tiling_func_.AddLine("}"); |
| 4223 | return af::SUCCESS; | 4233 | return af::SUCCESS; |
| 4224 | } | 4234 | } |
| @@ -4411,6 +4421,11 @@ af::Status TilingCodeGenImpl::GenFusedScheduleResultsGetTilingDefine(const Fused | |||
| 4411 | "max_block_dim;"); | 4421 | "max_block_dim;"); |
| 4412 | asc_graph_id++; | 4422 | asc_graph_id++; |
| 4413 | } | 4423 | } |
| 4424 | + tiling_func_.AddLine(" if (org_block_dim > 0U && max_block_dim > org_block_dim) {"); | ||
| 4425 | + tiling_func_.AddLine(" " + failed_log_level + | ||
| 4426 | + "(OP_NAME, \"Aggregated block_dim %u exceeds core budget %u.\", max_block_dim, org_block_dim);"); | ||
| 4427 | + tiling_func_.AddLine(" return false;"); | ||
| 4428 | + tiling_func_.AddLine(" }"); | ||
| 4414 | GenWorkspaceOffsetFinalize("tiling_data"); | 4429 | GenWorkspaceOffsetFinalize("tiling_data"); |
| 4415 | tiling_func_.AddLine(" tiling_data.set_block_dim(max_block_dim);"); | 4430 | tiling_func_.AddLine(" tiling_data.set_block_dim(max_block_dim);"); |
| 4416 | 4431 | ||
| @@ -4458,6 +4473,7 @@ af::Status TilingCodeGenImpl::GenPGOByCoreNumFusedScheduleResultsGetTilingDefine | |||
| 4458 | 4473 | ||
| 4459 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey root.\");"); | 4474 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey root.\");"); |
| 4460 | 4475 | ||
| 4476 | + tiling_func_.AddLine(" ret = !tiling_data_list.empty();"); | ||
| 4461 | tiling_func_.AddLine(" return ret;"); | 4477 | tiling_func_.AddLine(" return ret;"); |
| 4462 | tiling_func_.AddLine("}"); | 4478 | tiling_func_.AddLine("}"); |
| 4463 | return af::SUCCESS; | 4479 | return af::SUCCESS; |
| @@ -4528,6 +4544,7 @@ af::Status TilingCodeGenImpl::GenPGOFusedScheduleResultsGetTilingDefine(const Fu | |||
| 4528 | void TilingCodeGenImpl::GenPGOByCoreNumGetAllSchedulesResults(const size_t asc_graph_id, | 4544 | void TilingCodeGenImpl::GenPGOByCoreNumGetAllSchedulesResults(const size_t asc_graph_id, |
| 4529 | const AscGraphNamepspaceMap &namespace_map) { | 4545 | const AscGraphNamepspaceMap &namespace_map) { |
| 4530 | std::string tiling_key_prefix = "graph" + std::to_string(asc_graph_id) + "_"; | 4546 | std::string tiling_key_prefix = "graph" + std::to_string(asc_graph_id) + "_"; |
| 4547 | + tiling_func_.AddLine(" bool has_valid_tiling = false;"); | ||
| 4531 | tiling_func_.AddLine(" for (int32_t index = 0; index < " + std::to_string(namespace_map.size()) + "; index++) {"); | 4548 | tiling_func_.AddLine(" for (int32_t index = 0; index < " + std::to_string(namespace_map.size()) + "; index++) {"); |
| 4532 | tiling_func_.AddLine(" tiling_data.set_" + tiling_key_prefix + "tiling_key(index);"); | 4549 | tiling_func_.AddLine(" tiling_data.set_" + tiling_key_prefix + "tiling_key(index);"); |
| 4533 | for (const auto &result_id_and_groups : namespace_map) { | 4550 | for (const auto &result_id_and_groups : namespace_map) { |
| @@ -4535,7 +4552,9 @@ void TilingCodeGenImpl::GenPGOByCoreNumGetAllSchedulesResults(const size_t asc_g | |||
| 4535 | tiling_func_.AddLine(" tiling_data." + group_info.second.second + "_tiling_data = {};"); | 4552 | tiling_func_.AddLine(" tiling_data." + group_info.second.second + "_tiling_data = {};"); |
| 4536 | } | 4553 | } |
| 4537 | } | 4554 | } |
| 4538 | - tiling_func_.AddLine(" (void)kScheduleResultFunctionsPGOByCoreNum[index](tiling_data_list, tiling_data);"); | 4555 | + tiling_func_.AddLine(" if (kScheduleResultFunctionsPGOByCoreNum[index](tiling_data_list, tiling_data)) {"); |
| 4556 | + tiling_func_.AddLine(" has_valid_tiling = true;"); | ||
| 4557 | + tiling_func_.AddLine(" }"); | ||
| 4539 | tiling_func_.AddLine(" }"); | 4558 | tiling_func_.AddLine(" }"); |
| 4540 | } | 4559 | } |
| 4541 | 4560 | ||
| @@ -4544,6 +4563,7 @@ void TilingCodeGenImpl::GenPGOGetAllSchedulesResults(const size_t asc_graph_id, | |||
| 4544 | std::string tiling_key_prefix = "graph" + std::to_string(asc_graph_id) + "_"; | 4563 | std::string tiling_key_prefix = "graph" + std::to_string(asc_graph_id) + "_"; |
| 4545 | 4564 | ||
| 4546 | tiling_func_.AddLine(" AutofuseTilingData tilingTmp;"); | 4565 | tiling_func_.AddLine(" AutofuseTilingData tilingTmp;"); |
| 4566 | + tiling_func_.AddLine(" bool has_valid_tiling = false;"); | ||
| 4547 | tiling_func_.AddLine(" for (int32_t index = 0; index < " + std::to_string(namespace_map.size()) + "; index++) {"); | 4567 | tiling_func_.AddLine(" for (int32_t index = 0; index < " + std::to_string(namespace_map.size()) + "; index++) {"); |
| 4548 | tiling_func_.AddLine(" tilingTmp = tiling_data;"); | 4568 | tiling_func_.AddLine(" tilingTmp = tiling_data;"); |
| 4549 | tiling_func_.AddLine(" tilingTmp.set_" + tiling_key_prefix + "tiling_key(index);"); | 4569 | tiling_func_.AddLine(" tilingTmp.set_" + tiling_key_prefix + "tiling_key(index);"); |
| @@ -4554,9 +4574,11 @@ void TilingCodeGenImpl::GenPGOGetAllSchedulesResults(const size_t asc_graph_id, | |||
| 4554 | tiling_func_.AddLine(" continue;"); | 4574 | tiling_func_.AddLine(" continue;"); |
| 4555 | tiling_func_.AddLine(" }"); | 4575 | tiling_func_.AddLine(" }"); |
| 4556 | tiling_func_.AddLine( | 4576 | tiling_func_.AddLine( |
| 4557 | - " (void)kScheduleResultFunctionsPGO[index](tiling_data_list, ori_block_dim, " | 4577 | + " if (kScheduleResultFunctionsPGO[index](tiling_data_list, ori_block_dim, " |
| 4558 | "tiling_case_id, tilingTmp, cur_perf, best_perf, cur_block_dim, " | 4578 | "tiling_case_id, tilingTmp, cur_perf, best_perf, cur_block_dim, " |
| 4559 | - "stream, workspaceSize, block_dim_vec, search_cfg);"); | 4579 | + "stream, workspaceSize, block_dim_vec, search_cfg)) {"); |
| 4580 | + tiling_func_.AddLine(" has_valid_tiling = true;"); | ||
| 4581 | + tiling_func_.AddLine(" }"); | ||
| 4560 | tiling_func_.AddLine(" }"); | 4582 | tiling_func_.AddLine(" }"); |
| 4561 | } | 4583 | } |
| 4562 | 4584 | ||
| @@ -4576,11 +4598,11 @@ af::Status TilingCodeGenImpl::GenGetTilingForAllSchedulesResults(const uint32_t | |||
| 4576 | GenGetMaxScoreIndex(asc_graph_map); | 4598 | GenGetMaxScoreIndex(asc_graph_map); |
| 4577 | } | 4599 | } |
| 4578 | GE_ASSERT_SUCCESS(GenGetAllSchedulesResults(asc_graph_map)); | 4600 | GE_ASSERT_SUCCESS(GenGetAllSchedulesResults(asc_graph_map)); |
| 4579 | - tiling_func_.AddLine(" GetResultSummary(best_perf, tiling_data);"); | 4601 | + tiling_func_.AddLine(" const bool result = GetResultSummary(best_perf, tiling_data);"); |
| 4580 | GE_ASSERT_SUCCESS(GenDurationEndCode(TilingFuncDurationType::TILING_FUNC_DURATION_TOTAL, " "), "Generate end code!"); | 4602 | GE_ASSERT_SUCCESS(GenDurationEndCode(TilingFuncDurationType::TILING_FUNC_DURATION_TOTAL, " "), "Generate end code!"); |
| 4581 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); | 4603 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); |
| 4582 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); | 4604 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); |
| 4583 | - tiling_func_.AddLine(" return true;"); | 4605 | + tiling_func_.AddLine(" return result;"); |
| 4584 | tiling_func_.AddLine("}"); | 4606 | tiling_func_.AddLine("}"); |
| 4585 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id) + " {"); | 4607 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id) + " {"); |
| 4586 | return af::SUCCESS; | 4608 | return af::SUCCESS; |
| @@ -4650,7 +4672,7 @@ af::Status TilingCodeGenImpl::GenPGOGetTilingForAll() { | |||
| 4650 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey in AscGraph.\");"); | 4672 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey in AscGraph.\");"); |
| 4651 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); | 4673 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); |
| 4652 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); | 4674 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); |
| 4653 | - tiling_func_.AddLine(" return true;"); | 4675 | + tiling_func_.AddLine(" return has_valid_tiling;"); |
| 4654 | tiling_func_.AddLine("}"); | 4676 | tiling_func_.AddLine("}"); |
| 4655 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id) + " {"); | 4677 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id) + " {"); |
| 4656 | } | 4678 | } |
| @@ -4679,7 +4701,7 @@ af::Status TilingCodeGenImpl::GenPGOByCoreNumTilingForAll() { | |||
| 4679 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey in AscGraph.\");"); | 4701 | tiling_func_.AddLine(" OP_LOGI(OP_NAME, \"End PGOSearchTilingKey in AscGraph.\");"); |
| 4680 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); | 4702 | GE_ASSERT_SUCCESS(GenDurationPrintCode(" "), "Generate print code failed."); |
| 4681 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); | 4703 | GE_ASSERT_SUCCESS(GenDurationClearCode(" "), "Generate clear code failed."); |
| 4682 | - tiling_func_.AddLine(" return true;"); | 4704 | + tiling_func_.AddLine(" return has_valid_tiling;"); |
| 4683 | tiling_func_.AddLine("}"); | 4705 | tiling_func_.AddLine("}"); |
| 4684 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id)); | 4706 | tiling_func_.AddLine("} // namespace AscGraph" + std::to_string(asc_graph_id)); |
| 4685 | } | 4707 | } |
| @@ -1649,6 +1649,9 @@ std::string TilingLib::GenNonCubeFusionTilingBody(const ascir::FusedScheduledRes | |||
| 1649 | ss << " auto ret = AutofuseTilingWithConfig(config_file, "; | 1649 | ss << " auto ret = AutofuseTilingWithConfig(config_file, "; |
| 1650 | ss << shape_dim_param; | 1650 | ss << shape_dim_param; |
| 1651 | ss << "tiling_data, &workspace_size, &block_dim, &limit);" << std::endl; | 1651 | ss << "tiling_data, &workspace_size, &block_dim, &limit);" << std::endl; |
| 1652 | + ss << " if (ret != 0) {" << std::endl; | ||
| 1653 | + ss << " return ge::GRAPH_FAILED;" << std::endl; | ||
| 1654 | + ss << " }" << std::endl; | ||
| 1652 | ss << " context->SetBlockDim(block_dim);" << std::endl; | 1655 | ss << " context->SetBlockDim(block_dim);" << std::endl; |
| 1653 | 1656 | ||
| 1654 | if (ascgen_utils::IsCubeFusedScheduled(fused_schedule_result) && | 1657 | if (ascgen_utils::IsCubeFusedScheduled(fused_schedule_result) && |
| @@ -656,9 +656,13 @@ std::string codegen::TilingData::GenCVConstTilingData(const std::string &tiling_ | |||
| 656 | ss << " set_g_basen_basem_align(basen_align);" << std::endl; | 656 | ss << " set_g_basen_basem_align(basen_align);" << std::endl; |
| 657 | ss << " OP_LOGI(OP_NAME, \"set_g_basen_basem_align=%d, ub_size=%u\", get_g_basen_basem_align(), ub_size);" | 657 | ss << " OP_LOGI(OP_NAME, \"set_g_basen_basem_align=%d, ub_size=%u\", get_g_basen_basem_align(), ub_size);" |
| 658 | << std::endl; | 658 | << std::endl; |
| 659 | - ss << " (void)AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name; | 659 | + ss << " ret = AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name; |
| 660 | ss << ", &workspace_size, &block_dim, "; | 660 | ss << ", &workspace_size, &block_dim, "; |
| 661 | ss << "&limit, 1);" << std::endl; | 661 | ss << "&limit, 1);" << std::endl; |
| 662 | + ss << " if (ret == -1) {" << std::endl; | ||
| 663 | + ss << " OP_LOGE(OP_NAME, \"AutofuseTilingWithConfig fallback failed: %ld\", ret);" << std::endl; | ||
| 664 | + ss << " return \"\";" << std::endl; | ||
| 665 | + ss << " }" << std::endl; | ||
| 662 | ss << " }" << std::endl; | 666 | ss << " }" << std::endl; |
| 663 | } | 667 | } |
| 664 | 668 | ||
| @@ -753,12 +757,16 @@ std::string codegen::TilingData::GenerateConst(const ascir::FusedScheduledResult | |||
| 753 | if (IsCubeFusedScheduled(fused_schedule_result)) { | 757 | if (IsCubeFusedScheduled(fused_schedule_result)) { |
| 754 | const_gen_ss << GenCVConstTilingData(tiling_data_struct_name, is_inductor_scene); | 758 | const_gen_ss << GenCVConstTilingData(tiling_data_struct_name, is_inductor_scene); |
| 755 | } else { | 759 | } else { |
| 756 | - const_gen_ss << " (void)AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name; | 760 | + const_gen_ss << " auto ret = AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name; |
| 757 | if (is_inductor_scene) { | 761 | if (is_inductor_scene) { |
| 758 | const_gen_ss << ", &workspace_size, &block_dim, nullptr);" << std::endl; | 762 | const_gen_ss << ", &workspace_size, &block_dim, nullptr);" << std::endl; |
| 759 | } else { | 763 | } else { |
| 760 | const_gen_ss << ", &workspace_size, &block_dim, &limit);" << std::endl; | 764 | const_gen_ss << ", &workspace_size, &block_dim, &limit);" << std::endl; |
| 761 | } | 765 | } |
| 766 | + const_gen_ss << " if (ret != 0) {" << std::endl; | ||
| 767 | + const_gen_ss << " OP_LOGE(OP_NAME, \"AutofuseTilingWithConfig failed: %ld\", ret);" << std::endl; | ||
| 768 | + const_gen_ss << " return \"\";" << std::endl; | ||
| 769 | + const_gen_ss << " }" << std::endl; | ||
| 762 | } | 770 | } |
| 763 | 771 | ||
| 764 | pre_func_ss << GenGenTilingDataFieldConstDefFunc() << std::endl; | 772 | pre_func_ss << GenGenTilingDataFieldConstDefFunc() << std::endl; |
| @@ -391,12 +391,12 @@ void TilingLib::GenTopnInitSearchTiling(std::stringstream &ss, const ascir::Fuse | |||
| 391 | ss << " return -1;" << std::endl; | 391 | ss << " return -1;" << std::endl; |
| 392 | ss << " }" << std::endl; | 392 | ss << " }" << std::endl; |
| 393 | ss << std::endl; | 393 | ss << std::endl; |
| 394 | + ss << " const uint32_t available_aiv_num = std::min(limit->aiv_num, g_no_limit_res.aiv_num);" << std::endl; | ||
| 394 | if (use_measured_perf) { | 395 | if (use_measured_perf) { |
| 395 | - ss << " const uint32_t measured_aiv_num = std::min(limit->aiv_num, g_no_limit_res.aiv_num);" << std::endl; | 396 | + ss << " const uint32_t measured_aiv_num = available_aiv_num;" << std::endl; |
| 396 | } | 397 | } |
| 397 | ss << " " << tiling << " search_tiling = {};" << std::endl; | 398 | ss << " " << tiling << " search_tiling = {};" << std::endl; |
| 398 | - ss << " search_tiling.set_block_dim(" << (use_measured_perf ? "measured_aiv_num" : "limit->aiv_num") << ");" | 399 | + ss << " search_tiling.set_block_dim(available_aiv_num);" << std::endl; |
| 399 | - << std::endl; | ||
| 400 | ss << " search_tiling.set_ub_size(limit->ub_size - 256);" << std::endl; | 400 | ss << " search_tiling.set_ub_size(limit->ub_size - 256);" << std::endl; |
| 401 | { | 401 | { |
| 402 | int idx = 0; | 402 | int idx = 0; |
| @@ -92,7 +92,19 @@ std::string TilingLib::GenPgoAutofuseTiling(const ascir::FusedScheduledResult &f | |||
| 92 | } | 92 | } |
| 93 | if (!ascgen_utils::IsJustCubeFixpip(fused_schedule_result)) { | 93 | if (!ascgen_utils::IsJustCubeFixpip(fused_schedule_result)) { |
| 94 | if (enable_autofuse_pgo_) { | 94 | if (enable_autofuse_pgo_) { |
| 95 | - ss << " if (!PGOGetTilingKey(config_file, *tiling)) {" << std::endl; | 95 | + ss << " auto pgo_tiling = *tiling;" << std::endl; |
| 96 | + ss << " bool use_pgo_tiling = PGOGetTilingKey(config_file, pgo_tiling);" << std::endl; | ||
| 97 | + ss << " if (use_pgo_tiling && (pgo_tiling.get_block_dim() == 0U || " | ||
| 98 | + "pgo_tiling.get_block_dim() > limit->aiv_num)) {" | ||
| 99 | + << std::endl; | ||
| 100 | + ss << " OP_LOGW(OP_NAME, \"Loaded PGO block_dim %u is outside core budget [1, %u].\", " | ||
| 101 | + "pgo_tiling.get_block_dim(), limit->aiv_num);" | ||
| 102 | + << std::endl; | ||
| 103 | + ss << " use_pgo_tiling = false;" << std::endl; | ||
| 104 | + ss << " }" << std::endl; | ||
| 105 | + ss << " if (use_pgo_tiling) {" << std::endl; | ||
| 106 | + ss << " *tiling = pgo_tiling;" << std::endl; | ||
| 107 | + ss << " } else {" << std::endl; | ||
| 96 | ss << " if (!optiling::GetTiling(*tiling, tiling_case_id, nullptr)) {" << std::endl; | 108 | ss << " if (!optiling::GetTiling(*tiling, tiling_case_id, nullptr)) {" << std::endl; |
| 97 | ss << " return -1;" << std::endl; | 109 | ss << " return -1;" << std::endl; |
| 98 | ss << " }" << std::endl; | 110 | ss << " }" << std::endl; |
| @@ -378,7 +390,10 @@ std::string TilingLib::GenPGOGetTilingKey(const std::string tiling) const { | |||
| 378 | ss << " std::getline(config_file, line);" << std::endl; | 390 | ss << " std::getline(config_file, line);" << std::endl; |
| 379 | ss << " std::istringstream iss0(line);" << std::endl; | 391 | ss << " std::istringstream iss0(line);" << std::endl; |
| 380 | ss << " int flag = -1;" << std::endl; | 392 | ss << " int flag = -1;" << std::endl; |
| 381 | - ss << " iss0 >> flag;" << std::endl; | 393 | + ss << " if (!(iss0 >> flag) || (flag != 0 && flag != 1)) {" << std::endl; |
| 394 | + ss << " OP_LOGW(OP_NAME, \"Invalid PGO config flag.\");" << std::endl; | ||
| 395 | + ss << " return false;" << std::endl; | ||
| 396 | + ss << " }" << std::endl; | ||
| 382 | ss << " OP_LOGD(OP_NAME, \"best_config %d.\", flag);" << std::endl; | 397 | ss << " OP_LOGD(OP_NAME, \"best_config %d.\", flag);" << std::endl; |
| 383 | ss << " // second line: tiling_data dumped as int32 decimals, space-separated" << std::endl; | 398 | ss << " // second line: tiling_data dumped as int32 decimals, space-separated" << std::endl; |
| 384 | ss << " std::getline(config_file, line);" << std::endl; | 399 | ss << " std::getline(config_file, line);" << std::endl; |
| @@ -393,8 +408,15 @@ std::string TilingLib::GenPGOGetTilingKey(const std::string tiling) const { | |||
| 393 | ss << " tiling_i32.push_back(static_cast<int32_t>(tmp));" << std::endl; | 408 | ss << " tiling_i32.push_back(static_cast<int32_t>(tmp));" << std::endl; |
| 394 | ss << " }" << std::endl; | 409 | ss << " }" << std::endl; |
| 395 | ss << " const size_t expect_num = (sizeof(tiling_data) + sizeof(int32_t) - 1) / sizeof(int32_t);" << std::endl; | 410 | ss << " const size_t expect_num = (sizeof(tiling_data) + sizeof(int32_t) - 1) / sizeof(int32_t);" << std::endl; |
| 396 | - ss << " tiling_i32.resize(expect_num, 0);" << std::endl; | 411 | + ss << " if (!iss1.eof() || tiling_i32.size() != expect_num) {" << std::endl; |
| 397 | - ss << " memcpy_s(&tiling_data, sizeof(tiling_data), tiling_i32.data(), sizeof(tiling_data));" << std::endl; | 412 | + ss << " OP_LOGW(OP_NAME, \"Invalid PGO tiling data length.\");" << std::endl; |
| 413 | + ss << " return false;" << std::endl; | ||
| 414 | + ss << " }" << std::endl; | ||
| 415 | + ss << " if (memcpy_s(&tiling_data, sizeof(tiling_data), tiling_i32.data(), sizeof(tiling_data)) != EOK) {" | ||
| 416 | + << std::endl; | ||
| 417 | + ss << " OP_LOGW(OP_NAME, \"Failed to load PGO tiling data.\");" << std::endl; | ||
| 418 | + ss << " return false;" << std::endl; | ||
| 419 | + ss << " }" << std::endl; | ||
| 398 | ss << " config_file.close();" << std::endl; | 420 | ss << " config_file.close();" << std::endl; |
| 399 | ss << " if (flag == 1) {" << std::endl; | 421 | ss << " if (flag == 1) {" << std::endl; |
| 400 | ss << " best_tiling = tiling_data;" << std::endl; | 422 | ss << " best_tiling = tiling_data;" << std::endl; |
| @@ -644,6 +644,8 @@ def static_shape_compile( | |||
| 644 | ctypes.c_int(int(get_soc_spec("ub_size"))), | 644 | ctypes.c_int(int(get_soc_spec("ub_size"))), |
| 645 | ) | 645 | ) |
| 646 | 646 | ||
| 647 | + if not result: | ||
| 648 | + raise RuntimeError("GenConstTilingData returned empty const tiling data") | ||
| 647 | const_tiling_data = result.decode("utf-8") | 649 | const_tiling_data = result.decode("utf-8") |
| 648 | if hasattr(lib, "GetCVUBFusionStageSizeName"): | 650 | if hasattr(lib, "GetCVUBFusionStageSizeName"): |
| 649 | stage_size_name = get_cv_ub_fusion_stage_size_name( | 651 | stage_size_name = get_cv_ub_fusion_stage_size_name( |
| @@ -1164,6 +1164,8 @@ def try_static_shape_compile(args: argparse.Namespace, temp_dir, so_path): | |||
| 1164 | result = lib.GenConstTilingData( | 1164 | result = lib.GenConstTilingData( |
| 1165 | config_file, ctypes.c_int(aiv_num), ctypes.c_int(ub_size) | 1165 | config_file, ctypes.c_int(aiv_num), ctypes.c_int(ub_size) |
| 1166 | ) | 1166 | ) |
| 1167 | + if not result: | ||
| 1168 | + raise CompileError("GenConstTilingData returned empty const tiling data") | ||
| 1167 | const_tiling_data = result.decode("utf-8") | 1169 | const_tiling_data = result.decode("utf-8") |
| 1168 | tiling_data = os.path.join(temp_dir, "device", "autofuse_tiling_data.h") | 1170 | tiling_data = os.path.join(temp_dir, "device", "autofuse_tiling_data.h") |
| 1169 | tiling_data_bak = os.path.join(temp_dir, "device", "autofuse_tiling_data_bak.h") | 1171 | tiling_data_bak = os.path.join(temp_dir, "device", "autofuse_tiling_data_bak.h") |
| @@ -1033,6 +1033,10 @@ TEST(GeneratorUT, TilingCodeGenImplPGO) { | |||
| 1033 | } | 1033 | } |
| 1034 | DoApiTiling(tiling_data); | 1034 | DoApiTiling(tiling_data); |
| 1035 | GeneralTiling(tiling_data); | 1035 | GeneralTiling(tiling_data); |
| 1036 | + if (tiling_data.get_block_dim() > corenum_) { | ||
| 1037 | + OP_LOGW(OP_NAME, "Generated block_dim %u exceeds core budget %u.", tiling_data.get_block_dim(), corenum_); | ||
| 1038 | + return false; | ||
| 1039 | + } | ||
| 1036 | TilingSummary(tiling_data); | 1040 | TilingSummary(tiling_data); |
| 1037 | return true; | 1041 | return true; |
| 1038 | } | 1042 | } |
| @@ -1137,6 +1141,8 @@ TEST(GeneratorUT, RootGetTilingFailuresUseWarningLogOnlyForPGOPath) { | |||
| 1137 | std::string tiling_func_output = genImpl.tiling_func_.GetOutputStr(); | 1141 | std::string tiling_func_output = genImpl.tiling_func_.GetOutputStr(); |
| 1138 | EXPECT_NE(tiling_func_output.find("OP_LOGE(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); | 1142 | EXPECT_NE(tiling_func_output.find("OP_LOGE(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); |
| 1139 | EXPECT_EQ(tiling_func_output.find("OP_LOGW(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); | 1143 | EXPECT_EQ(tiling_func_output.find("OP_LOGW(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); |
| 1144 | + EXPECT_NE(tiling_func_output.find("OP_LOGE(OP_NAME, \"Aggregated block_dim %u exceeds core budget %u.\""), | ||
| 1145 | + std::string::npos); | ||
| 1140 | 1146 | ||
| 1141 | genImpl.config_.is_inductor_scene = true; | 1147 | genImpl.config_.is_inductor_scene = true; |
| 1142 | genImpl.tiling_func_.Reset(); | 1148 | genImpl.tiling_func_.Reset(); |
| @@ -1144,6 +1150,8 @@ TEST(GeneratorUT, RootGetTilingFailuresUseWarningLogOnlyForPGOPath) { | |||
| 1144 | tiling_func_output = genImpl.tiling_func_.GetOutputStr(); | 1150 | tiling_func_output = genImpl.tiling_func_.GetOutputStr(); |
| 1145 | EXPECT_NE(tiling_func_output.find("OP_LOGW(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); | 1151 | EXPECT_NE(tiling_func_output.find("OP_LOGW(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); |
| 1146 | EXPECT_EQ(tiling_func_output.find("OP_LOGE(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); | 1152 | EXPECT_EQ(tiling_func_output.find("OP_LOGE(OP_NAME, \"Failed to get tiling of AscGraph0.\");"), std::string::npos); |
| 1153 | + EXPECT_NE(tiling_func_output.find("OP_LOGW(OP_NAME, \"Aggregated block_dim %u exceeds core budget %u.\""), | ||
| 1154 | + std::string::npos); | ||
| 1147 | 1155 | ||
| 1148 | genImpl.tiling_func_.Reset(); | 1156 | genImpl.tiling_func_.Reset(); |
| 1149 | EXPECT_EQ(genImpl.GenPGOByCoreNumFusedScheduleResultsGetTilingDefine(namespace_map), af::SUCCESS); | 1157 | EXPECT_EQ(genImpl.GenPGOByCoreNumFusedScheduleResultsGetTilingDefine(namespace_map), af::SUCCESS); |
| @@ -1192,7 +1200,39 @@ TEST(GeneratorUT, PGOByCoreNumSerialGroupsUseMaximumBlockDim) { | |||
| 1192 | EXPECT_NE( | 1200 | EXPECT_NE( |
| 1193 | output.find("result_block_dim = std::max(result_block_dim, tiling_data_tmp.group1_tiling_data.get_block_dim());"), | 1201 | output.find("result_block_dim = std::max(result_block_dim, tiling_data_tmp.group1_tiling_data.get_block_dim());"), |
| 1194 | std::string::npos); | 1202 | std::string::npos); |
| 1203 | + EXPECT_EQ(output.find("result_block_dim = std::min(result_block_dim, block_dim_i);"), std::string::npos); | ||
| 1195 | EXPECT_EQ(output.find("result_block_dim += tiling_data_tmp.group1_tiling_data.get_block_dim();"), std::string::npos); | 1204 | EXPECT_EQ(output.find("result_block_dim += tiling_data_tmp.group1_tiling_data.get_block_dim();"), std::string::npos); |
| 1205 | + EXPECT_NE(output.find("ret = !tiling_data_list.empty();"), std::string::npos); | ||
| 1206 | +} | ||
| 1207 | + | ||
| 1208 | +TEST(GeneratorUT, GetTilingRejectsBlockDimAboveCoreBudget) { | ||
| 1209 | + TilingCodeGenConfig config; | ||
| 1210 | + TilingModelInfo tiling_model_info; | ||
| 1211 | + ScoreFuncs score_funcs; | ||
| 1212 | + ModelInfo model_info; | ||
| 1213 | + model_info.hardware_cons[HardwareDef::CORENUM] = CreateExpr("128"); | ||
| 1214 | + tiling_model_info.push_back(model_info); | ||
| 1215 | + | ||
| 1216 | + MockHighPerfTilingCodeGenImpl genImpl("test", config, tiling_model_info, score_funcs, true); | ||
| 1217 | + ASSERT_EQ(genImpl.GenGetTiling(), af::SUCCESS); | ||
| 1218 | + const std::string output = genImpl.tiling_func_.GetOutputStr(); | ||
| 1219 | + EXPECT_NE(output.find("tiling_data.get_block_dim() > corenum_"), std::string::npos); | ||
| 1220 | +} | ||
| 1221 | + | ||
| 1222 | +TEST(GeneratorUT, GetTilingPropagatesScheduleSummaryFailure) { | ||
| 1223 | + TilingCodeGenConfig config; | ||
| 1224 | + TilingModelInfo tiling_model_info; | ||
| 1225 | + ModelInfo model_info; | ||
| 1226 | + tiling_model_info.push_back(model_info); | ||
| 1227 | + ScoreFuncs score_funcs; | ||
| 1228 | + MockHighPerfTilingCodeGenImpl genImpl("test", config, tiling_model_info, score_funcs, true); | ||
| 1229 | + std::map<size_t, std::map<size_t, std::pair<std::string, std::string>>> namespace_map; | ||
| 1230 | + namespace_map[0] = {}; | ||
| 1231 | + | ||
| 1232 | + ASSERT_EQ(genImpl.GenGetTilingForAllSchedulesResults(0, namespace_map), af::SUCCESS); | ||
| 1233 | + const std::string output = genImpl.tiling_func_.GetOutputStr(); | ||
| 1234 | + EXPECT_NE(output.find("const bool result = GetResultSummary(best_perf, tiling_data);"), std::string::npos); | ||
| 1235 | + EXPECT_NE(output.find("return result;"), std::string::npos); | ||
| 1196 | } | 1236 | } |
| 1197 | 1237 | ||
| 1198 | TEST(GeneratorUT, PGOGetTilingKeyFailureUsesWarningLog) { | 1238 | TEST(GeneratorUT, PGOGetTilingKeyFailureUsesWarningLog) { |
| @@ -1326,6 +1366,8 @@ TEST(GeneratorUT, PGOGetAllSchedulesResultsDoesNotPushGraphTilingTmpOutsideSched | |||
| 1326 | EXPECT_EQ(tiling_func_output.find("tiling_data_list.push_back(tiling_perf);"), std::string::npos); | 1366 | EXPECT_EQ(tiling_func_output.find("tiling_data_list.push_back(tiling_perf);"), std::string::npos); |
| 1327 | EXPECT_EQ(tiling_func_output.find("PgoConfig::Instance().single_callback("), std::string::npos); | 1367 | EXPECT_EQ(tiling_func_output.find("PgoConfig::Instance().single_callback("), std::string::npos); |
| 1328 | EXPECT_EQ(tiling_func_output.find("*tilingData = tilingTmp;"), std::string::npos); | 1368 | EXPECT_EQ(tiling_func_output.find("*tilingData = tilingTmp;"), std::string::npos); |
| 1369 | + EXPECT_NE(tiling_func_output.find("bool has_valid_tiling = false;"), std::string::npos); | ||
| 1370 | + EXPECT_NE(tiling_func_output.find("has_valid_tiling = true;"), std::string::npos); | ||
| 1329 | } | 1371 | } |
| 1330 | 1372 | ||
| 1331 | static const std::string kExpectPGOCode = | 1373 | static const std::string kExpectPGOCode = |
| @@ -1610,6 +1652,12 @@ TEST(GeneratorUT, GenPGOGetScheduleResultGuardsInvalidVarRelationBeforeSet) { | |||
| 1610 | ASSERT_NE(set_pos, std::string::npos); | 1652 | ASSERT_NE(set_pos, std::string::npos); |
| 1611 | ASSERT_NE(invalid_pos, std::string::npos); | 1653 | ASSERT_NE(invalid_pos, std::string::npos); |
| 1612 | ASSERT_NE(search_pos, std::string::npos); | 1654 | ASSERT_NE(search_pos, std::string::npos); |
| 1655 | + EXPECT_NE(tiling_func_output.find("const size_t candidate_count_before = tiling_data_list.size();"), | ||
| 1656 | + std::string::npos); | ||
| 1657 | + EXPECT_NE(tiling_func_output.find("return tiling_data_list.size() > candidate_count_before;"), std::string::npos); | ||
| 1658 | + EXPECT_NE(tiling_func_output.find("std::vector<AutofuseTilingDataPerf> valid_tiling_data_list;"), std::string::npos); | ||
| 1659 | + EXPECT_NE(tiling_func_output.find("&valid_tiling_data_list) != 0"), std::string::npos); | ||
| 1660 | + EXPECT_EQ(tiling_func_output.find("workspaceSize, &tiling_data_list_tmp) != 0"), std::string::npos); | ||
| 1613 | EXPECT_LT(guard_pos, value_pos); | 1661 | EXPECT_LT(guard_pos, value_pos); |
| 1614 | EXPECT_LT(value_pos, finite_pos); | 1662 | EXPECT_LT(value_pos, finite_pos); |
| 1615 | EXPECT_LT(finite_pos, set_pos); | 1663 | EXPECT_LT(finite_pos, set_pos); |
| @@ -1688,6 +1736,17 @@ TEST(GeneratorUT, GenHardwareCheckCode_UseDoubleType) { | |||
| 1688 | EXPECT_TRUE(found_double_type) << "Generated hardware check code should contain 'double ' type to prevent overflow"; | 1736 | EXPECT_TRUE(found_double_type) << "Generated hardware check code should contain 'double ' type to prevent overflow"; |
| 1689 | } | 1737 | } |
| 1690 | 1738 | ||
| 1739 | +TEST(GeneratorUT, GenHardwareJudgeSkipsRelatedCoreNumExpression) { | ||
| 1740 | + TilingModelInfo model_infos{CreateModelInfo(1U, ge::ExprType::kExprVariable)}; | ||
| 1741 | + TilingCodeGenConfig config; | ||
| 1742 | + ScoreFuncs score_funcs; | ||
| 1743 | + MockHighPerfTilingCodeGenImpl gen_impl("test", config, model_infos, score_funcs, true); | ||
| 1744 | + | ||
| 1745 | + ASSERT_EQ(gen_impl.GenHardwareJudge(model_infos.front()), af::SUCCESS); | ||
| 1746 | + const std::string output = gen_impl.tiling_func_.GetOutputStr(); | ||
| 1747 | + EXPECT_EQ(output.find("block_dim expr"), std::string::npos); | ||
| 1748 | +} | ||
| 1749 | + | ||
| 1691 | // Task 3: Inductor scene triggers ATT PGO main search skeleton, PGOSearchTilingKey and perf extraction | 1750 | // Task 3: Inductor scene triggers ATT PGO main search skeleton, PGOSearchTilingKey and perf extraction |
| 1692 | 1751 | ||
| 1693 | TEST(GeneratorUT, InductorSceneTriggersPGOSkeletonAndSearchTilingKey) { | 1752 | TEST(GeneratorUT, InductorSceneTriggersPGOSkeletonAndSearchTilingKey) { |
Mautofuse/tests/ut/att/testcase/solver_pass_gen/general_solver_gen/ut_general_solver_gen_01.cpp+10-0
| @@ -179,6 +179,16 @@ TEST_F(UTTEST_GENERAL_SOLVER_GEN_01, test_set_buff_cons) { | |||
| 179 | EXPECT_EQ(Str(solver->hardware_args_[0]), Str(gm)); | 179 | EXPECT_EQ(Str(solver->hardware_args_[0]), Str(gm)); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | +TEST_F(UTTEST_GENERAL_SOLVER_GEN_01, test_set_core_num_cons_with_input_args) { | ||
| 183 | + GeneralSolverGen solver("Case0", "TilingData"); | ||
| 184 | + const Expr input_axis = CreateExpr("input_axis"); | ||
| 185 | + solver.SetInputArgs({input_axis}); | ||
| 186 | + solver.SetBufferCons({{HardwareDef::CORENUM, input_axis * CreateExpr(2)}}); | ||
| 187 | + | ||
| 188 | + ASSERT_EQ(solver.leqs_.size(), 1U); | ||
| 189 | + EXPECT_NE(Str(solver.leqs_.front()).find("block_dim"), std::string::npos); | ||
| 190 | +} | ||
| 191 | + | ||
| 182 | TEST_F(UTTEST_GENERAL_SOLVER_GEN_01, test_set_cut_cons) { | 192 | TEST_F(UTTEST_GENERAL_SOLVER_GEN_01, test_set_cut_cons) { |
| 183 | GeneralSolverGen *solver; | 193 | GeneralSolverGen *solver; |
| 184 | std::vector<Expr> cut_cons; | 194 | std::vector<Expr> cut_cons; |
| @@ -3279,7 +3279,7 @@ TEST_F(TestCodegenTiling, SplitHeaderApiTilingSourceShouldIncludeApiHeaders) { | |||
| 3279 | } | 3279 | } |
| 3280 | 3280 | ||
| 3281 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForTfShouldGuardRuntimeHeadersForCceKtTest) { | 3281 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForTfShouldGuardRuntimeHeadersForCceKtTest) { |
| 3282 | - auto fused_schedule_result = this->GenBasicFusedScheduleResult({af::Symbol("s0"), af::Symbol("s1")}); | 3282 | + auto fused_schedule_result = this->GenBasicFusedScheduleResult({af::Symbol("s0"), af::Symbol("s1")}, af::Symbol(1)); |
| 3283 | const std::map<std::string, std::string> shape_info; | 3283 | const std::map<std::string, std::string> shape_info; |
| 3284 | auto tiling_files = this->Generate(fused_schedule_result, shape_info, ".", "10"); | 3284 | auto tiling_files = this->Generate(fused_schedule_result, shape_info, ".", "10"); |
| 3285 | 3285 | ||
| @@ -3292,6 +3292,14 @@ TEST_F(TestCodegenTiling, SplitHeaderGenerateForTfShouldGuardRuntimeHeadersForCc | |||
| 3292 | "#endif\n"; | 3292 | "#endif\n"; |
| 3293 | EXPECT_NE(entry.find(guarded_headers), std::string::npos); | 3293 | EXPECT_NE(entry.find(guarded_headers), std::string::npos); |
| 3294 | EXPECT_EQ(entry.find("#include \"platform_ascendc.h\""), std::string::npos); | 3294 | EXPECT_EQ(entry.find("#include \"platform_ascendc.h\""), std::string::npos); |
| 3295 | + | ||
| 3296 | + const auto tiling_call = entry.find("auto ret = AutofuseTilingWithConfig"); | ||
| 3297 | + const auto failure_check = entry.find("if (ret != 0) {", tiling_call); | ||
| 3298 | + const auto set_block_dim = entry.find("context->SetBlockDim(block_dim);", tiling_call); | ||
| 3299 | + ASSERT_NE(tiling_call, std::string::npos); | ||
| 3300 | + ASSERT_NE(failure_check, std::string::npos); | ||
| 3301 | + ASSERT_NE(set_block_dim, std::string::npos); | ||
| 3302 | + EXPECT_LT(failure_check, set_block_dim); | ||
| 3295 | } | 3303 | } |
| 3296 | 3304 | ||
| 3297 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForPgoShouldIncludeDirectEntryDependencies) { | 3305 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForPgoShouldIncludeDirectEntryDependencies) { |
| @@ -3308,6 +3316,29 @@ TEST_F(TestCodegenTiling, SplitHeaderGenerateForPgoShouldIncludeDirectEntryDepen | |||
| 3308 | EXPECT_NE(entry.find("#include \"exe_graph/runtime/tiling_context.h\""), std::string::npos); | 3316 | EXPECT_NE(entry.find("#include \"exe_graph/runtime/tiling_context.h\""), std::string::npos); |
| 3309 | EXPECT_NE(entry.find("#include \"autofuse_tiling_func_pgo.h\""), std::string::npos); | 3317 | EXPECT_NE(entry.find("#include \"autofuse_tiling_func_pgo.h\""), std::string::npos); |
| 3310 | EXPECT_NE(entry.find("#include \"autofuse_tiling_func_solver.h\""), std::string::npos); | 3318 | EXPECT_NE(entry.find("#include \"autofuse_tiling_func_solver.h\""), std::string::npos); |
| 3319 | + | ||
| 3320 | + bool found_pgo_core_budget_check = false; | ||
| 3321 | + bool found_pgo_config_validation = false; | ||
| 3322 | + bool found_pgo_tiling_isolation = false; | ||
| 3323 | + for (const auto &[name, source] : tiling_files) { | ||
| 3324 | + (void)name; | ||
| 3325 | + if (source.find("Loaded PGO block_dim %u is outside core budget [1, %u]") != std::string::npos) { | ||
| 3326 | + found_pgo_core_budget_check = true; | ||
| 3327 | + } | ||
| 3328 | + if (source.find("tiling_i32.size() != expect_num") != std::string::npos && | ||
| 3329 | + source.find("memcpy_s(&tiling_data, sizeof(tiling_data), tiling_i32.data(), sizeof(tiling_data)) != EOK") != | ||
| 3330 | + std::string::npos) { | ||
| 3331 | + found_pgo_config_validation = true; | ||
| 3332 | + } | ||
| 3333 | + if (source.find("auto pgo_tiling = *tiling;") != std::string::npos && | ||
| 3334 | + source.find("PGOGetTilingKey(config_file, pgo_tiling)") != std::string::npos && | ||
| 3335 | + source.find("*tiling = pgo_tiling;") != std::string::npos) { | ||
| 3336 | + found_pgo_tiling_isolation = true; | ||
| 3337 | + } | ||
| 3338 | + } | ||
| 3339 | + EXPECT_TRUE(found_pgo_core_budget_check); | ||
| 3340 | + EXPECT_TRUE(found_pgo_config_validation); | ||
| 3341 | + EXPECT_TRUE(found_pgo_tiling_isolation); | ||
| 3311 | } | 3342 | } |
| 3312 | 3343 | ||
| 3313 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForInductorPgoShouldIncludeDirectEntryDependencies) { | 3344 | TEST_F(TestCodegenTiling, SplitHeaderGenerateForInductorPgoShouldIncludeDirectEntryDependencies) { |
| @@ -4571,6 +4602,8 @@ TEST_F(TestCodegenTiling, GenerateForInductorPgoFalseShouldKeepModeledTopn) { | |||
| 4571 | ASSERT_NE(modeled_search, std::string::npos); | 4602 | ASSERT_NE(modeled_search, std::string::npos); |
| 4572 | ASSERT_NE(modeled_entry, std::string::npos); | 4603 | ASSERT_NE(modeled_entry, std::string::npos); |
| 4573 | const std::string modeled_body = result.tiling.substr(modeled_search, modeled_entry - modeled_search); | 4604 | const std::string modeled_body = result.tiling.substr(modeled_search, modeled_entry - modeled_search); |
| 4605 | + EXPECT_NE(modeled_body.find("const uint32_t available_aiv_num = std::min(limit->aiv_num, g_no_limit_res.aiv_num)"), | ||
| 4606 | + std::string::npos); | ||
| 4574 | EXPECT_EQ(modeled_body.find("PGOByCoreNumSearchTilingKey"), std::string::npos); | 4607 | EXPECT_EQ(modeled_body.find("PGOByCoreNumSearchTilingKey"), std::string::npos); |
| 4575 | } | 4608 | } |
| 4576 | 4609 | ||
| @@ -4762,8 +4795,9 @@ TEST_F(TestCodegenTiling, GenerateForInductorPgoTrueShouldReuseTfAllCoreSearch) | |||
| 4762 | ASSERT_NE(measured_search, std::string::npos); | 4795 | ASSERT_NE(measured_search, std::string::npos); |
| 4763 | ASSERT_NE(measured_entry, std::string::npos); | 4796 | ASSERT_NE(measured_entry, std::string::npos); |
| 4764 | const std::string measured_body = result.tiling.substr(measured_search, measured_entry - measured_search); | 4797 | const std::string measured_body = result.tiling.substr(measured_search, measured_entry - measured_search); |
| 4765 | - EXPECT_NE(measured_body.find("const uint32_t measured_aiv_num = std::min(limit->aiv_num, g_no_limit_res.aiv_num)"), | 4798 | + EXPECT_NE(measured_body.find("const uint32_t available_aiv_num = std::min(limit->aiv_num, g_no_limit_res.aiv_num)"), |
| 4766 | std::string::npos); | 4799 | std::string::npos); |
| 4800 | + EXPECT_NE(measured_body.find("const uint32_t measured_aiv_num = available_aiv_num"), std::string::npos); | ||
| 4767 | EXPECT_NE(measured_body.find("optiling::PGOByCoreNumSearchTilingKey(measured_tiling_datas, &cur_search_tiling, " | 4801 | EXPECT_NE(measured_body.find("optiling::PGOByCoreNumSearchTilingKey(measured_tiling_datas, &cur_search_tiling, " |
| 4768 | "measured_aiv_num)"), | 4802 | "measured_aiv_num)"), |
| 4769 | std::string::npos); | 4803 | std::string::npos); |
| @@ -214,7 +214,11 @@ extern "C" const char* GenConstTilingData(char* config_file, int aiv_num, int ub | |||
| 214 | ResLimit limit; | 214 | ResLimit limit; |
| 215 | limit.aiv_num = aiv_num; | 215 | limit.aiv_num = aiv_num; |
| 216 | limit.ub_size = ub_size - 256; | 216 | limit.ub_size = ub_size - 256; |
| 217 | - (void)AutofuseTilingWithConfig(config_file, &TilingDataValue, &workspace_size, &block_dim, nullptr); | 217 | + auto ret = AutofuseTilingWithConfig(config_file, &TilingDataValue, &workspace_size, &block_dim, nullptr); |
| 218 | + if (ret != 0) { | ||
| 219 | + OP_LOGE(OP_NAME, "AutofuseTilingWithConfig failed: %ld", ret); | ||
| 220 | + return ""; | ||
| 221 | + } | ||
| 218 | std::string GenTilingDataValue_block_dim_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("block_dim", TilingDataValue.block_dim); | 222 | std::string GenTilingDataValue_block_dim_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("block_dim", TilingDataValue.block_dim); |
| 219 | std::string GenTilingDataValue_corenum_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("corenum", TilingDataValue.corenum); | 223 | std::string GenTilingDataValue_corenum_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("corenum", TilingDataValue.corenum); |
| 220 | std::string GenTilingDataValue_ub_size_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("ub_size", TilingDataValue.ub_size); | 224 | std::string GenTilingDataValue_ub_size_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("ub_size", TilingDataValue.ub_size); |
| @@ -373,7 +377,11 @@ extern "C" const char* GenConstTilingData(char* config_file, int aiv_num, int ub | |||
| 373 | ResLimit limit; | 377 | ResLimit limit; |
| 374 | limit.aiv_num = aiv_num; | 378 | limit.aiv_num = aiv_num; |
| 375 | limit.ub_size = ub_size - 256; | 379 | limit.ub_size = ub_size - 256; |
| 376 | - (void)AutofuseTilingWithConfig(config_file, &TilingDataValue, &workspace_size, &block_dim, nullptr); | 380 | + auto ret = AutofuseTilingWithConfig(config_file, &TilingDataValue, &workspace_size, &block_dim, nullptr); |
| 381 | + if (ret != 0) { | ||
| 382 | + OP_LOGE(OP_NAME, "AutofuseTilingWithConfig failed: %ld", ret); | ||
| 383 | + return ""; | ||
| 384 | + } | ||
| 377 | std::string GenTilingDataValue_block_dim_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("block_dim", TilingDataValue.block_dim); | 385 | std::string GenTilingDataValue_block_dim_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("block_dim", TilingDataValue.block_dim); |
| 378 | std::string GenTilingDataValue_corenum_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("corenum", TilingDataValue.corenum); | 386 | std::string GenTilingDataValue_corenum_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("corenum", TilingDataValue.corenum); |
| 379 | std::string GenTilingDataValue_ub_size_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("ub_size", TilingDataValue.ub_size); | 387 | std::string GenTilingDataValue_ub_size_field_DeclareFunc_def = GenTilingDataFieldConstDefFunc("ub_size", TilingDataValue.ub_size); |
| @@ -523,6 +523,22 @@ class TestStaticShapeCompileHasattrCheck: | |||
| 523 | 523 | ||
| 524 | assert fake_lib.GenConstTilingData.calls[0][1].value == 4 | 524 | assert fake_lib.GenConstTilingData.calls[0][1].value == 4 |
| 525 | 525 | ||
| 526 | + | ||
| 527 | + def test_static_shape_compile_rejects_empty_const_tiling( | ||
| 528 | + asc_codegen_compile_module, tmpdir, monkeypatch | ||
| 529 | + ): | ||
| 530 | + temp_dir = str(tmpdir) | ||
| 531 | + fake_lib = SimpleNamespace(GenConstTilingData=FakeCFunc(b"")) | ||
| 532 | + TestStaticShapeCompileHasattrCheck._prepare_tiling_file(temp_dir) | ||
| 533 | + TestStaticShapeCompileHasattrCheck._mock_static_compile_dependencies( | ||
| 534 | + asc_codegen_compile_module, monkeypatch, fake_lib | ||
| 535 | + ) | ||
| 536 | + | ||
| 537 | + with pytest.raises(RuntimeError, match="GenConstTilingData returned empty"): | ||
| 538 | + asc_codegen_compile_module.static_shape_compile( | ||
| 539 | + kernel_name="kernel", temp_dir=temp_dir, graph_name="graph" | ||
| 540 | + ) | ||
| 541 | + | ||
| 526 | 542 | ||
| 527 | def test_static_shape_cv_compile_uses_vector_core_num_when_provided( | 543 | def test_static_shape_cv_compile_uses_vector_core_num_when_provided( |
| 528 | asc_codegen_compile_module, tmpdir, monkeypatch | 544 | asc_codegen_compile_module, tmpdir, monkeypatch |
| @@ -583,14 +599,16 @@ class TestStaticShapeCompileHasattrCheck: | |||
| 583 | monkeypatch.setattr( | 599 | monkeypatch.setattr( |
| 584 | asc_codegen_compile_module, | 600 | asc_codegen_compile_module, |
| 585 | "static_shape_cv_compile", | 601 | "static_shape_cv_compile", |
| 586 | - lambda **kwargs: calls.append(("cv_compile", kwargs["vector_core_num"])) | 602 | + lambda **kwargs: ( |
| 587 | - or -1, | 603 | + calls.append(("cv_compile", kwargs["vector_core_num"])) or -1 |
| 604 | + ), | ||
| 588 | ) | 605 | ) |
| 589 | monkeypatch.setattr( | 606 | monkeypatch.setattr( |
| 590 | asc_codegen_compile_module, | 607 | asc_codegen_compile_module, |
| 591 | "static_shape_cv_common_compile", | 608 | "static_shape_cv_common_compile", |
| 592 | - lambda **kwargs: calls.append(("cv_common", kwargs["vector_core_num"])) | 609 | + lambda **kwargs: ( |
| 593 | - or (4, 16), | 610 | + calls.append(("cv_common", kwargs["vector_core_num"])) or (4, 16) |
| 611 | + ), | ||
| 594 | ) | 612 | ) |
| 595 | 613 | ||
| 596 | tiling_info = SimpleNamespace(tiling_key=2, file_content="") | 614 | tiling_info = SimpleNamespace(tiling_key=2, file_content="") |
| @@ -751,6 +751,42 @@ def test_try_static_shape_compile_records_stage_when_force_unknown( | |||
| 751 | assert ["InductorCompile", "all", "PrepareStaticShapeRecompile", "graph"] in labels | 751 | assert ["InductorCompile", "all", "PrepareStaticShapeRecompile", "graph"] in labels |
| 752 | 752 | ||
| 753 | 753 | ||
| 754 | +def test_try_static_shape_compile_rejects_empty_const_tiling( | ||
| 755 | + ascendc_compile_module, tmpdir | ||
| 756 | +): | ||
| 757 | + device_dir = tmpdir.mkdir("device") | ||
| 758 | + device_dir.join("autofuse_tiling_data.h").write("old tiling") | ||
| 759 | + | ||
| 760 | + def is_static_shape(): | ||
| 761 | + return True | ||
| 762 | + | ||
| 763 | + def gen_const_tiling_data(*args): | ||
| 764 | + return b"" | ||
| 765 | + | ||
| 766 | + fake_lib = types.SimpleNamespace( | ||
| 767 | + AutofuseIsStaticShape=is_static_shape, | ||
| 768 | + GenConstTilingData=gen_const_tiling_data, | ||
| 769 | + ) | ||
| 770 | + ascendc_compile_module.module.ctypes.CDLL = lambda path: fake_lib | ||
| 771 | + ascendc_compile_module.module.static_shape_kernel_proc = lambda *args: None | ||
| 772 | + ascendc_compile_module.module.init_torch_npu_for_const_tiling = lambda: None | ||
| 773 | + args = type( | ||
| 774 | + "Args", | ||
| 775 | + (), | ||
| 776 | + { | ||
| 777 | + "force_unknown": False, | ||
| 778 | + "stage": "all", | ||
| 779 | + "graph_name": "graph", | ||
| 780 | + "config_file": "config.txt", | ||
| 781 | + }, | ||
| 782 | + )() | ||
| 783 | + | ||
| 784 | + with pytest.raises( | ||
| 785 | + ascendc_compile_module.CompileError, match="GenConstTilingData returned empty" | ||
| 786 | + ): | ||
| 787 | + ascendc_compile_module.try_static_shape_compile(args, str(tmpdir), "kernel.so") | ||
| 788 | + | ||
| 789 | + | ||
| 754 | def test_copy_so_to_output_records_stage(ascendc_compile_module, tmpdir): | 790 | def test_copy_so_to_output_records_stage(ascendc_compile_module, tmpdir): |
| 755 | src_file = tmpdir.join("source.so") | 791 | src_file = tmpdir.join("source.so") |
| 756 | dst_file = tmpdir.mkdir("out").join("target.so") | 792 | dst_file = tmpdir.mkdir("out").join("target.so") |