已合并
fix: enforce block dim hardware core budget #1956
fix: enforce block dim hardware core budget #1956
已合并
zhang_shengjie创建于 6 天前
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
4528void TilingCodeGenImpl::GenPGOByCoreNumGetAllSchedulesResults(const size_t asc_graph_id,4544void 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 
1198TEST(GeneratorUT, PGOGetTilingKeyFailureUsesWarningLog) {1238TEST(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 
1331static const std::string kExpectPGOCode =1373static 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 extraction1750// Task 3: Inductor scene triggers ATT PGO main search skeleton, PGOSearchTilingKey and perf extraction
1692 1751 
1693TEST(GeneratorUT, InductorSceneTriggersPGOSkeletonAndSearchTilingKey) {1752TEST(GeneratorUT, InductorSceneTriggersPGOSkeletonAndSearchTilingKey) {
@@ -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+ 
182TEST_F(UTTEST_GENERAL_SOLVER_GEN_01, test_set_cut_cons) {192TEST_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 
3281TEST_F(TestCodegenTiling, SplitHeaderGenerateForTfShouldGuardRuntimeHeadersForCceKtTest) {3281TEST_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 
3297TEST_F(TestCodegenTiling, SplitHeaderGenerateForPgoShouldIncludeDirectEntryDependencies) {3305TEST_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 
3313TEST_F(TestCodegenTiling, SplitHeaderGenerateForInductorPgoShouldIncludeDirectEntryDependencies) {3344TEST_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 == 4524 assert fake_lib.GenConstTilingData.calls[0][1].value == 4
525 525 
526+ @staticmethod
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 @staticmethod542 @staticmethod
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, monkeypatch544 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 labels751 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+ 
754def test_copy_so_to_output_records_stage(ascendc_compile_module, tmpdir):790def 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")