LCOV - code coverage report
Current view: top level - ut/autofuse/codegen - codegen_tiling_data.cpp Coverage Total Hit
Test: CHG Lines: 100.0 % 8 8
Test Date: 2026-08-20 14:28:35
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "codegen_tiling_data.h"
      12              : #include <sstream>
      13              : #include <iomanip>
      14              : 
      15              : #include "common_utils.h"
      16              : #include "common/ge_common/debug/log.h"
      17              : 
      18              : using namespace ascgen_utils;
      19              : 
      20              : namespace {
      21              : void AppendCVAutofuseCommonTilingFields(std::stringstream &ss) {
      22              :   ss << "    union {\n";
      23              :   ss << "        CVAutofuseExternTilingData extern_tiling_data;\n";
      24              :   ss << "        struct {\n";
      25              :   ss << "            AutofuseTilingData tiling_data;\n";
      26              :   ss << "            uint64_t cube_tiling_key;\n";
      27              :   ss << "            CVTilingData cv_tiling_data;\n";
      28              :   ss << "        };\n";
      29              :   ss << "    };\n";
      30              :   ss << "    uint32_t stage_size_name;\n";
      31              :   ss << "    uint32_t cube_ub_stage_size;\n";
      32              : }
      33              : }  // namespace
      34              : 
      35              : codegen::TilingData::TilingData(const std::string &kernel, const std::string &name_class)
      36              :     : class_name(name_class), kernel_name(kernel) {}
      37              : 
      38              : std::string codegen::TilingData::macros_and_includes = {  // 不却分是否const
      39              :     "#include <stdint.h>\n"
      40              :     "#include \"kernel_tiling/kernel_tiling.h\"\n"
      41              :     "#define BEGIN_TILING_DATA_DEF_T(name) struct name {\n"
      42              :     "#define TILING_DATA_FIELD_DEF_T(type, name) \\\n"
      43              :     "  type name; \\\n"
      44              :     "  inline void set_##name(type value) { name = value; } \\\n"
      45              :     "  inline type get_##name() const { return name; } \\\n"
      46              :     "  inline type* get_addr_##name() {return &name;}\n"
      47              :     "#define END_TILING_DATA_DEF_T };\n"
      48              :     "#define TILING_DATA_FIELD_DEF_T_STRUCT(struct_type, filed_name) \\\n"
      49              :     "  struct_type filed_name;\n"};
      50              : 
      51              : std::string codegen::TilingData::common_tiling_filed = {  // 非const模式
      52              :     "  TILING_DATA_FIELD_DEF_T(uint32_t, block_dim);\n"
      53              :     "  TILING_DATA_FIELD_DEF_T(uint32_t, corenum);\n"
      54              :     "  TILING_DATA_FIELD_DEF_T(uint32_t, ub_size);\n"
      55              :     "  TILING_DATA_FIELD_DEF_T(uint32_t, hbm_size);"};
      56              : 
      57              : std::string codegen::TilingData::GenGenTilingDataFieldConstDefFunc() const {
      58              :   std::stringstream ss;
      59              :   // 支持 uint32_t 类型
      60              :   ss << "std::string GenTilingDataFieldConstDefFunc(const std::string &f_name, uint32_t value) {" << std::endl;
      61              :   ss << "  std::stringstream ss_mid;" << std::endl;
      62              :   ss << "  ss_mid << \"const uint32_t \";" << std::endl;
      63              :   ss << "  ss_mid << f_name << \" = \" << std::to_string(value) << \";\" << std::endl;" << std::endl;
      64              :   ss << "  return ss_mid.str();" << std::endl;
      65              :   ss << "}" << std::endl;
      66              : 
      67              :   // 支持 uint64_t 类型
      68              :   ss << "std::string GenTilingDataFieldConstDefFunc(const std::string &f_name, uint64_t value) {" << std::endl;
      69              :   ss << "  std::stringstream ss_mid;" << std::endl;
      70              :   ss << "  ss_mid << \"const uint64_t \";" << std::endl;
      71              :   ss << "  ss_mid << f_name << \" = \" << std::to_string(value) << \";\" << std::endl;" << std::endl;
      72              :   ss << "  return ss_mid.str();" << std::endl;
      73              :   ss << "}" << std::endl;
      74              : 
      75              :   return ss.str();
      76              : }
      77              : 
      78              : std::string codegen::TilingData::GenGenTilingDataFieldConstValueFunc() const {
      79              :   std::stringstream ss;
      80              :   ss << "std::string GenTilingDataFieldConstValueFunc(uint32_t value) {" << std::endl;
      81              :   ss << "  std::stringstream ss_mid;" << std::endl;
      82              :   ss << "  ss_mid << std::to_string(value) << std::endl;" << std::endl;
      83              :   ss << "  return ss_mid.str();" << std::endl;
      84              :   ss << "}" << std::endl;
      85              : 
      86              :   return ss.str();
      87              : }
      88              : 
      89              : std::string codegen::TilingData::GetCommonTilingField(bool is_group,
      90              :                                                       const ascir::FusedScheduledResult &fused_schedule_result) {
      91              :   std::stringstream ss;
      92              :   std::vector<ascir::TensorId> workspace_tensor_id = GetWorkspaceTensorIdListInOneScheduleResult(fused_schedule_result);
      93              :   std::vector<std::string> common_tiling_fileds = {"block_dim", "corenum", "ub_size", "hbm_size"};
      94              :   for (auto tId : workspace_tensor_id) {
      95              :     common_tiling_fileds.push_back("workspace" + std::to_string(tId));
      96              :   }
      97              :   if (!const_mode_) {
      98              :     // 非const模式
      99              :     ss << common_tiling_filed << std::endl;
     100              :     for (auto tId : workspace_tensor_id) {
     101              :       ss << "  TILING_DATA_FIELD_DEF_T(uint32_t, workspace" << std::to_string(tId) << ");" << std::endl;
     102              :     }
     103              :     if (is_group || ((fused_schedule_result.node_idx_to_scheduled_results.size() == 1) &&
     104              :                      (fused_schedule_result.node_idx_to_scheduled_results[0].size() == 1) &&
     105              :                      (fused_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups.size() == 1))) {
     106              :       ss << "  TILING_DATA_FIELD_DEF_T(uint32_t, tiling_key);";
     107              :       return ss.str();
     108              :     }
     109              :     for (size_t i = 0U; i < fused_schedule_result.node_idx_to_scheduled_results.size(); i++) {
     110              :       ss << "  TILING_DATA_FIELD_DEF_T(uint32_t, " << "graph" << std::to_string(i) << "_tiling_key);";
     111              :       if (i < (fused_schedule_result.node_idx_to_scheduled_results.size() - 1U)) {
     112              :         ss << std::endl;
     113              :       }
     114              :     }
     115              :     return ss.str();
     116              :   }
     117              : 
     118              :   // const模式
     119              :   if (is_group || ((fused_schedule_result.node_idx_to_scheduled_results.size() == 1) &&
     120              :                    (fused_schedule_result.node_idx_to_scheduled_results[0].size() == 1) &&
     121              :                    (fused_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups.size() == 1))) {
     122              :     common_tiling_fileds.push_back("tiling_key");
     123              :   } else {
     124              :     for (size_t i = 0U; i < fused_schedule_result.node_idx_to_scheduled_results.size(); i++) {
     125              :       common_tiling_fileds.push_back("graph" + std::to_string(i) + "_tiling_key");
     126              :     }
     127              :   }
     128              :   uint32_t idx = 0U;
     129              :   for (auto &field : common_tiling_fileds) {
     130              :     std::string field_func_str = GetNameOfGenTilingDataFieldConstDefFunc(field);
     131              :     std::string field_func_str_simple = GetNameOfGenTilingDataFieldConstDefFuncSimple(field);
     132              :     std::string field_def = field_func_str + "_def";
     133              :     pre_var_ss << "  std::string " << field_def << " = " << field_func_str_simple << ";" << std::endl;
     134              :     ss << "  " << field_def;
     135              :     // 最后一个不加换行,在外面加换行
     136              :     if (idx < (common_tiling_fileds.size() - 1U)) {
     137              :       ss << std::endl;
     138              :     }
     139              :     field_var_defs_.push_back(field_def);
     140              :     idx++;
     141              :   }
     142              : 
     143              :   return ss.str();
     144              : }
     145              : 
     146              : std::string codegen::TilingData::pgo_perf_struct = {
     147              :     "struct AutofuseTilingDataPerf {\n"
     148              :     "  AutofuseTilingData tiling_data;\n"
     149              :     "  double best_perf;\n"
     150              :     "};\n"};
     151              : 
     152              : af::Status codegen::TilingData::ProcessCubeFusionResult(ascir::FusedScheduledResult &schedule_result) {
     153              :   if (ascgen_utils::IsCubeUBFusedScheduled(schedule_result)) {
     154              :     GE_ASSERT_SUCCESS(ascgen_utils::CreateCVFusionResult(schedule_result));
     155              :   } else if (ascgen_utils::IsCubeCommonFusedScheduled(schedule_result)) {
     156              :     GE_ASSERT_SUCCESS(ascgen_utils::CreateCVFusionCommonResult(schedule_result));
     157              :   }
     158              :   return af::SUCCESS;
     159              : }
     160              : 
     161              : std::string codegen::TilingData::Generate(const ascir::FusedScheduledResult &fused_schedule_result, bool is_inductor) {
     162              :   std::stringstream ss;
     163              :   std::stringstream ss1;  // ss1 是最外层的tilingData结构体定义
     164              :   std::stringstream ss2;  // ss1 是最内层的子tilingData结构体定义
     165              : 
     166              :   ss << "#ifndef __" << this->kernel_name << "_Tiling_Data_H__" << std::endl;
     167              :   ss << "#define __" << this->kernel_name << "_Tiling_Data_H__" << std::endl;
     168              :   ss << macros_and_includes << std::endl;
     169              : 
     170              :   auto generate_footer = [this, &ss, &ss1, &ss2]() {
     171              :     ss1 << this->ClassEnd() << std::endl << std::endl;
     172              :     ss << ss2.str() << ss1.str();
     173              :     std::string input_type = this->kernel_name + this->class_name;
     174              :     if (input_type != "AutofuseTilingData") {
     175              :       ss << "using AutofuseTilingData = " << input_type << ";" << std::endl;
     176              :     }
     177              :     ss << pgo_perf_struct;
     178              :     ss << "#endif" << std::endl;
     179              :   };
     180              :   if (ascgen_utils::IsJustCubeFixpip(fused_schedule_result)) {
     181              :     GE_ASSERT(fused_schedule_result.node_idx_to_scheduled_results.size() == 1U, "Cube Fixpip results just one.");
     182              :     GE_ASSERT(fused_schedule_result.node_idx_to_scheduled_results[0].size() == 1U,
     183              :               "Cube Fixpip scheduled_results just one.");
     184              :     GE_ASSERT(fused_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups.size() == 1U,
     185              :               "Cube Fixpip schedule groups just one.");
     186              :     ss1 << this->ClassBegin(this->kernel_name, this->class_name) << std::endl;
     187              :     ss1 << GetCommonTilingField(false, fused_schedule_result) << std::endl;
     188              :     this->ProcessSingleGroup(fused_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups[0], ss1);
     189              :     GELOGI("TilingCaseId:ProcessSingleGroup\n");
     190              :     generate_footer();
     191              :     return ss.str();
     192              :   }
     193              :   ascir::FusedScheduledResult elemwise_schedule_result = fused_schedule_result;
     194              :   if (ascgen_utils::IsCubeFusedScheduled(fused_schedule_result) && is_inductor) {
     195              :     GE_ASSERT_SUCCESS(ascgen_utils::ProcessCubeFusionResultDynamic(elemwise_schedule_result));
     196              :   } else {
     197              :     GE_ASSERT_SUCCESS(ProcessCubeFusionResult(elemwise_schedule_result));
     198              :   }
     199              : 
     200              :   ss1 << this->ClassBegin(this->kernel_name, this->class_name) << std::endl;
     201              :   ss1 << GetCommonTilingField(false, elemwise_schedule_result) << std::endl;
     202              : 
     203              :   if ((elemwise_schedule_result.node_idx_to_scheduled_results.size() == 1U) &&
     204              :       (elemwise_schedule_result.node_idx_to_scheduled_results[0].size() == 1U) &&
     205              :       (elemwise_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups.size() == 1U)) {
     206              :     this->ProcessSingleGroup(elemwise_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups[0], ss1);
     207              :     GELOGI("TilingCaseId:ProcessSingleGroup\n");
     208              :   } else {
     209              :     for (size_t i = 0U; i < elemwise_schedule_result.node_idx_to_scheduled_results.size(); i++) {
     210              :       auto scheduled_results = elemwise_schedule_result.node_idx_to_scheduled_results[i];
     211              :       for (size_t j = 0U; j < scheduled_results.size(); j++) {
     212              :         this->ProcessMultiGroup(j, i, scheduled_results[j].schedule_groups, ss1, ss2);
     213              :         GELOGI("TilingCaseId:ProcessMultiGroup\n");
     214              :       }
     215              :     }
     216              :   }
     217              :   generate_footer();
     218              :   if (ascgen_utils::IsCubeFusedScheduled(fused_schedule_result) && is_inductor) {
     219              :     bool is_batch = false;
     220              :     bool is_conv = false;
     221              :     std::string input_type;
     222              :     std::string output_type;
     223              :     GE_ASSERT_SUCCESS(ascgen_utils::GetCubeInfo(fused_schedule_result, is_batch, is_conv, input_type, output_type),
     224              :                       "Failed to get cube info from FusedScheduledResult");
     225              :     std::string axis_name;
     226              :     if ((elemwise_schedule_result.node_idx_to_scheduled_results.size() > 0U) &&
     227              :         (elemwise_schedule_result.node_idx_to_scheduled_results[0].size() > 0U) &&
     228              :         (elemwise_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups.size() > 0U) &&
     229              :         (elemwise_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups[0].impl_graphs.size() > 0U)) {
     230              :       auto graph = elemwise_schedule_result.node_idx_to_scheduled_results[0][0].schedule_groups[0].impl_graphs[0];
     231              :       for (auto axis : graph.GetAllAxis()) {
     232              :         if (axis->type == ascir::Axis::Type::kAxisTypeTileInner) {
     233              :           axis_name = axis->name;
     234              :           GELOGD("gen GetCVUBFusionStageSizeName axis name:%s", axis->name.c_str());
     235              :           break;
     236              :         }
     237              :       }
     238              :     }
     239              : 
     240              :     ss << "#ifndef DYNAMIC_MM_TILING_DATA\n"
     241              :        << "#define DYNAMIC_MM_TILING_DATA\n"
     242              :        << "#include \"arch35/mat_mul_tiling_data.h\"\n"
     243              :        << "#define CV_TILING_MAX_SIZE(lhs, rhs) ((lhs) > (rhs) ? (lhs) : (rhs))\n"
     244              :        << "#define MATMUL_TILING_DATA_STORAGE_SIZE \\\n"
     245              :        << "    CV_TILING_MAX_SIZE(sizeof(MatMulV3TilingDataCopy), \\\n"
     246              :        << "    CV_TILING_MAX_SIZE(sizeof(BatchMatMulV3TilingData), \\\n"
     247              :        << "    CV_TILING_MAX_SIZE(sizeof(BatchMatMulV3BasicTilingData), \\\n"
     248              :        << "    CV_TILING_MAX_SIZE(sizeof(BatchMatMulV3IterBatchBasicTilingData), \\\n"
     249              :        << "    CV_TILING_MAX_SIZE(sizeof(BatchMatMulV3MergeBatchBasicTilingData), \\\n"
     250              :        << "    CV_TILING_MAX_SIZE(sizeof(BatchMatMulToMulBasicTilingData), "
     251              :           "sizeof(MatMulV3KEqZeroBasicTilingData)))))))\n"
     252              :        << "struct CVTilingData {\n"
     253              :        << "    uint8_t fusion_mode; // 0:ub; 1:safety\n"
     254              :        << "    uint8_t ub_mode; // 0:no db; 1:db\n"
     255              :        << "    uint8_t cv_aic_num;\n"
     256              :        << "    uint8_t cv_aiv_num;\n"
     257              :        << "    uint32_t cv_vec_wss;\n"
     258              :        << "    uint8_t mix_mode;\n"
     259              :        << "};\n"
     260              :        << "#define CV_TILING_ALIGN_UP(value, align) ((((value) + (align) - 1) / (align)) * (align))\n"
     261              :        << "template <typename MatmulTilingT>\n"
     262              :        << "struct CVAutofuseUbTilingDataT {\n"
     263              :        << "    static constexpr size_t kMatmulTilingBytes = CV_TILING_ALIGN_UP(sizeof(MatmulTilingT), 8);\n"
     264              :        << "    uint32_t stage_size_name;\n"
     265              :        << "    uint32_t cube_ub_stage_size;\n"
     266              :        << "    alignas(8) uint8_t matmul_tiling_data[kMatmulTilingBytes];\n"
     267              :        << "};\n"
     268              :        << "template <typename MatmulTilingT>\n"
     269              :        << "struct CVAutofuseTilingDataT {\n"
     270              :        << "    static constexpr size_t kMatmulTilingBytes = CV_TILING_ALIGN_UP(sizeof(MatmulTilingT), 8);\n"
     271              :        << "    AutofuseTilingData tiling_data;\n"
     272              :        << "    uint64_t cube_tiling_key;\n"
     273              :        << "    CVTilingData cv_tiling_data;\n"
     274              :        << "    uint32_t stage_size_name;\n"
     275              :        << "    uint32_t cube_ub_stage_size;\n"
     276              :        << "    alignas(8) uint8_t matmul_tiling_data[kMatmulTilingBytes];\n"
     277              :        << "};\n"
     278              :        << "struct CVAutofuseExternTilingData {\n"
     279              :        << "    AutofuseTilingData tiling_data;\n"
     280              :        << "    uint64_t cube_tiling_key;\n"
     281              :        << "    CVTilingData cv_tiling_data;\n"
     282              :        << "};\n"
     283              :        << "struct CVAutofuseUbTilingData {\n";
     284              : 
     285              :     ss << "    uint32_t stage_size_name;\n";
     286              :     ss << "    uint32_t cube_ub_stage_size;\n";
     287              :     ss << "    alignas(8) uint8_t matmul_tiling_data[MATMUL_TILING_DATA_STORAGE_SIZE];\n";
     288              : 
     289              :     ss << "};\n"
     290              :        << "struct CVAutofuseTilingData {\n";
     291              : 
     292              :     AppendCVAutofuseCommonTilingFields(ss);
     293              :     ss << "    alignas(8) uint8_t matmul_tiling_data[MATMUL_TILING_DATA_STORAGE_SIZE];\n";
     294              : 
     295              :     ss << "};\n"
     296              :        << "#define INDUCTOR_CV_FUSION\n"
     297              :        << "#define INDUCTOR_TILING_DATA\n"
     298              :        << "#define STAGE_SIZE_NAME " << axis_name << "_size\n"
     299              :        << "#define DTYPE_X1 " << input_type << "\n"
     300              :        << "#define DTYPE_X2 " << input_type << "\n"
     301              :        << "#define DTYPE_Y " << output_type << "\n"
     302              :        << "#define DTYPE_BIAS " << output_type << "\n"
     303              :        << "#define OP_TYPE_RELU_VALUE 0\n";
     304              :     if (const_mode_) {
     305              :       ss << "template <typename T>\n"
     306              :          << "T convert_from_bytes(const uint8_t *bytes) {\n"
     307              :          << "  T value;\n"
     308              :          << "  __builtin_memcpy(&value, bytes, sizeof(T));\n"
     309              :          << "  return value;\n"
     310              :          << "}\n";
     311              :       ss << "#define GET_TILING_DATA_WITH_STRUCT(tiling_struct, tiling_data, tiling_arg) \\\n"
     312              :          << "const tiling_struct tiling_data = convert_from_bytes<tiling_struct>(kConstMatmulTilingBytes); \n"
     313              :          << "#define GET_TILING_DATA_WITH_STRUCT_PTR(tiling_struct, tiling_data, tiling_arg) \\\n"
     314              :          << "const tiling_struct tiling_data = convert_from_bytes<tiling_struct>(kConstMatmulTilingBytes); \n";
     315              :       ss << "#define INDUCTOR_CONST_TILING_DATA\n";
     316              :       ss << "const CVAutofuseTilingData kConstTilingData = {};\n";
     317              :     } else {
     318              :       ss << "#define GET_TILING_DATA_WITH_STRUCT(tiling_struct, tiling_data, tiling_arg) \\\n"
     319              :          << "const tiling_struct &tiling_data = *reinterpret_cast<const tiling_struct "
     320              :             "*>(&((tiling_arg).matmul_tiling_data)); \n"
     321              :          << "#define GET_TILING_DATA_WITH_STRUCT_PTR(tiling_struct, tiling_data, tiling_arg) \\\n"
     322              :          << "const tiling_struct &tiling_data = *reinterpret_cast<const tiling_struct "
     323              :             "*>(&((tiling_arg).matmul_tiling_data)); \n";
     324              :     }
     325              :     ss << "#endif\n";
     326              :   }
     327              :   return ss.str();
     328              : }
     329              : 
     330              : std::string codegen::TilingData::ClassBegin(const std::string &begin_kernel_name,
     331              :                                             const std::string &begin_class_name) const {
     332              :   std::stringstream ss;
     333              :   ss << "BEGIN_TILING_DATA_DEF_T(" << begin_kernel_name << begin_class_name << ")";
     334              :   return ss.str();
     335              : }
     336              : 
     337              : std::string codegen::TilingData::DataFieldDefine(ascir::SizeVar &size) const {
     338              :   std::stringstream ss;
     339              :   ss << "TILING_DATA_FIELD_DEF_T(uint32_t, " << std::string(size.expr.Str().get()) << ");";
     340              :   return ss.str();
     341              : }
     342              : 
     343              : std::string codegen::TilingData::DataFieldConstDefine(ascir::SizeVar &size) {
     344              :   std::stringstream ss;
     345              : 
     346              :   std::string field = std::string(size.expr.Str().get());
     347              :   std::string field_func_str = GetNameOfGenTilingDataFieldConstDefFunc(field);
     348              :   std::string field_func_str_simple = GetNameOfGenTilingDataFieldConstDefFuncSimple(field);
     349              :   std::string field_def = field_func_str + "_def";
     350              :   pre_var_ss << "  std::string " << field_def << " = " << field_func_str_simple << ";" << std::endl;
     351              :   ss << field_def;
     352              :   field_var_defs_.push_back(field_def);
     353              : 
     354              :   return ss.str();
     355              : }
     356              : 
     357              : std::string codegen::TilingData::StructDataFiledDefine(const std::string &type_name,
     358              :                                                        const std::string &filed_name) const {
     359              :   std::stringstream ss;
     360              :   ss << "TILING_DATA_FIELD_DEF_T_STRUCT(" << type_name << ", " << filed_name << ");";
     361              :   return ss.str();
     362              : }
     363              : 
     364              : std::string codegen::TilingData::ClassEnd() const {
     365              :   std::stringstream ss;
     366              :   ss << "END_TILING_DATA_DEF_T;";
     367              :   return ss.str();
     368              : }
     369              : 
     370              : std::string codegen::TilingData::ClassRegister() {
     371              :   std::stringstream ss;
     372              :   ss << "REGISTER_TILING_DATA_CLASS(" << this->kernel_name << ", " << this->class_name << ")";
     373              :   return ss.str();
     374              : }
     375              : 
     376              : af::Status codegen::TilingData::GetApiTilingDataName(const ascir::NodeView &node,
     377              :                                                      std::vector<std::string> &api_tiling_data_names) {
     378              :   // transpose api tiling data包含的字段:
     379              :   // param0, param1, param2, ... param17
     380              :   const std::vector<std::string> transpose_params = {"param0",  "param1",  "param2",  "param3",  "param4",  "param5",
     381              :                                                      "param6",  "param7",  "param8",  "param9",  "param10", "param11",
     382              :                                                      "param12", "param13", "param14", "param15", "param16", "param17"};
     383              :   const std::vector<std::string> pad_params = {"srcHeight",
     384              :                                                "srcWidth",
     385              :                                                "srcOriWidth",
     386              :                                                "widthWithoutLastBlock",
     387              :                                                "blocksPerRow",
     388              :                                                "heightTiling",
     389              :                                                "heightFractal",
     390              :                                                "heightFractalTail",
     391              :                                                "mainLoopOffset",
     392              :                                                "tailBlockOffset",
     393              :                                                "tmpBuffer1BlockNum",
     394              :                                                "tmpBuffer1RowNum",
     395              :                                                "tmpBuffer2Offset",
     396              :                                                "widthTiling",
     397              :                                                "widthFractal",
     398              :                                                "widthFractalTail",
     399              :                                                "widthFractalTailAlingned",
     400              :                                                "brcbTiling",
     401              :                                                "brcbFractal",
     402              :                                                "brcbFractalTail",
     403              :                                                "maxRepeatTimes",
     404              :                                                "brcbTilingRepeatTimes",
     405              :                                                "brcbTilingRepeatTimesTail",
     406              :                                                "brcbFractalTailRepeatTimes",
     407              :                                                "brcbFractalTailRepeatTimesTail",
     408              :                                                "reserved"};
     409              :   std::map<std::string, std::vector<std::string>> node_with_api_tiling = {{"Transpose", transpose_params},
     410              :                                                                           {"Pad", pad_params}};
     411              :   auto it = node_with_api_tiling.find(node->GetType());
     412              :   if (it == node_with_api_tiling.end()) {
     413              :     GELOGE(af::FAILED, "not supported const api tilingdata node type:%s.", node->GetType().c_str());
     414              :     return af::FAILED;
     415              :   }
     416              : 
     417              :   api_tiling_data_names.assign(it->second.begin(), it->second.end());
     418              :   return af::SUCCESS;
     419              : }
     420              : 
     421              : std::string codegen::TilingData::ConstApiTilingDataFiledDefine(std::string &type_name, std::string &field_name,
     422              :                                                                const ascir::NodeView &node) {
     423              :   std::vector<std::string> node_with_api_tiling;
     424              :   if (GetApiTilingDataName(node, node_with_api_tiling) != af::SUCCESS) {
     425              :     return "";
     426              :   }
     427              : 
     428              :   std::stringstream ss;
     429              :   bool is_first = true;
     430              :   for (auto &param : node_with_api_tiling) {
     431              :     std::string param_func_str = GetNameOfGenTilingDataFieldConstDefFunc(param);
     432              :     std::string param_func_str_simple = GetNameOfGenTilingDataFieldConstValueFuncSimple(param);
     433              :     std::string param_def = param_func_str + "_field_def";
     434              :     pre_var_ss << "  std::string " << param_def << " = " << param_func_str_simple << ";" << std::endl;
     435              :     field_var_defs_.push_back(param_def);
     436              : 
     437              :     if (is_first) {
     438              :       ss << "const " << type_name << " " << field_name << " = {" << param_def;
     439              :       is_first = false;
     440              :     } else {
     441              :       ss << ", " << param_def;
     442              :     }
     443              :   }
     444              : 
     445              :   ss << "};" << std::endl;
     446              :   return ss.str();
     447              : }
     448              : 
     449              : void codegen::TilingData::AddApiTilingData(const af::AscGraph &graph, std::stringstream &ss, uint32_t tiling_case_id) {
     450              :   for (const auto &node : graph.GetAllNodes()) {
     451              :     std::string device_type_name;
     452              :     std::string host_type_name;
     453              :     std::string field_name;
     454              :     if (af::SUCCESS == GetApiTilingTypeName(node, device_type_name) &&
     455              :         (af::SUCCESS == GetApiTilingFieldName(node, field_name))) {
     456              :       host_type_name = "optiling::" + device_type_name;
     457              :       field_name = field_name + "_" + std::to_string(tiling_case_id);
     458              :       const_tiling_data_field.push_back(field_name);
     459              : 
     460              :       if (const_mode_) {
     461              :         std::string host_api_tiling_data_def = this->ConstApiTilingDataFiledDefine(device_type_name, field_name, node);
     462              :         ss << "  " << host_api_tiling_data_def << std::endl;
     463              :       } else {
     464              :         std::string dev_api_tiling_data_def = this->StructDataFiledDefine(device_type_name, field_name);
     465              :         ss << "  " << dev_api_tiling_data_def << std::endl;
     466              :       }
     467              :       ConstTilingDataFieldPopBack();
     468              :     }
     469              :   }
     470              : }
     471              : 
     472              : void codegen::TilingData::GetTqueAndTbufId(const af::AscGraph &graph, std::set<int64_t> &q_ids,
     473              :                                            std::set<int64_t> &b_ids) {
     474              :   for (auto node : graph.GetAllNodes()) {
     475              :     for (auto out : node->outputs()) {
     476              :       int64_t q_id = out->attr.que.id;
     477              :       int64_t b_id = out->attr.buf.id;
     478              :       if (q_ids.find(q_id) == q_ids.end()) {
     479              :         q_ids.insert(q_id);
     480              :       }
     481              :       if (b_ids.find(b_id) == b_ids.end()) {
     482              :         b_ids.insert(b_id);
     483              :       }
     484              :     }
     485              :   }
     486              : }
     487              : 
     488              : void codegen::TilingData::GetTmpBufName(const af::AscGraph &graph, std::set<int64_t> &b_ids) {
     489              :   for (auto node : graph.GetAllNodes()) {
     490              :     for (auto &tmp_buffer : node->attr.tmp_buffers) {
     491              :       GELOGD("Get tmp buffer [%ld, %s] for node %s.", tmp_buffer.buf_desc.life_time_axis_id,
     492              :              tmp_buffer.buf_desc.size.Str().get(), node->GetNamePtr());
     493              :       if (tmp_buffer.id == -1L) {
     494              :         continue;
     495              :       }
     496              :       b_ids.insert(tmp_buffer.id);
     497              :     }
     498              :   }
     499              : }
     500              : 
     501              : void codegen::TilingData::GenTqueTbufTmpBufFunc(const std::set<int64_t> &q_ids, const std::set<int64_t> &b_ids,
     502              :                                                 std::stringstream &ss) {
     503              :   for (const auto &q_id : q_ids) {
     504              :     if (q_id < 0) {
     505              :       continue;
     506              :     }
     507              :     std::string field_def =
     508              :         const_mode_ ? this->TqueOrTbufDataFieldConstDefine(q_id, "q") : this->TqueOrTbufDataFieldDefine(q_id, "q");
     509              :     ss << "  " << field_def << std::endl;
     510              :   }
     511              :   for (const auto &b_id : b_ids) {
     512              :     if (b_id < 0) {
     513              :       continue;
     514              :     }
     515              :     std::string field_def =
     516              :         const_mode_ ? this->TqueOrTbufDataFieldConstDefine(b_id, "b") : this->TqueOrTbufDataFieldDefine(b_id, "b");
     517              :     ss << "  " << field_def << std::endl;
     518              :   }
     519              : }
     520              : 
     521              : void codegen::TilingData::ProcessSingleGroup(const ascir::ScheduleGroup &schedule_group, std::stringstream &ss) {
     522              :   std::unordered_set<std::string> size_var_names;
     523              :   std::set<int64_t> q_ids;
     524              :   std::set<int64_t> b_ids;
     525              :   for (size_t i = 0U; i < schedule_group.impl_graphs.size(); i++) {
     526              :     auto &graph = schedule_group.impl_graphs[i];
     527              :     for (auto size : graph.GetAllSizeVar()) {
     528              :       if (size->expr.IsConstExpr()) {
     529              :         continue;
     530              :       }
     531              :       if (size_var_names.find(std::string(size->expr.Str().get())) == size_var_names.end()) {
     532              :         std::string field_def = const_mode_ ? this->DataFieldConstDefine(*size) : this->DataFieldDefine(*size);
     533              :         ss << "  " << field_def << std::endl;
     534              :         size_var_names.emplace(std::string(size->expr.Str().get()));
     535              :       }
     536              :     }
     537              :     GetTqueAndTbufId(graph, q_ids, b_ids);
     538              :     GetTmpBufName(graph, b_ids);
     539              :     AddApiTilingData(graph, ss, i);
     540              :     GELOGI("TilingCaseId:ProcessSingleGroup, tilingcaseNum:%d\n", schedule_group.impl_graphs.size());
     541              :   }
     542              :   GenTqueTbufTmpBufFunc(q_ids, b_ids, ss);
     543              :   return;
     544              : }
     545              : 
     546              : void codegen::TilingData::ProcessMultiGroup(uint64_t pos, const int graph_id,
     547              :                                             const std::vector<ascir::ScheduleGroup> &schedule_groups,
     548              :                                             std::stringstream &ss1, std::stringstream &ss2) {
     549              :   for (uint64_t i = 0; i < schedule_groups.size(); i++) {
     550              :     std::stringstream struct_name;
     551              :     struct_name << "AscGraph" << std::to_string(graph_id) << "Schedule";
     552              :     std::stringstream struct_name_tail;
     553              :     struct_name_tail << "Result" << std::to_string(pos) << "G" << std::to_string(i);
     554              :     struct_name << struct_name_tail.str();
     555              :     std::string filed_name =
     556              :         "graph" + std::to_string(graph_id) + "_" + CamelToLowerSneak(struct_name_tail.str() + this->class_name);
     557              :     ss1 << "  " << this->StructDataFiledDefine(struct_name.str() + this->class_name, filed_name) << std::endl;
     558              :     const_tiling_data_field.push_back(filed_name);
     559              :     std::unordered_set<std::string> size_var_names;
     560              :     ss2 << this->ClassBegin(struct_name.str(), this->class_name) << std::endl;
     561              :     ss2 << GetCommonTilingField(true, ascir::FusedScheduledResult()) << std::endl;
     562              : 
     563              :     std::set<int64_t> q_ids;
     564              :     std::set<int64_t> b_ids;
     565              :     for (uint32_t j = 0; j < schedule_groups[i].impl_graphs.size(); j++) {
     566              :       auto &graph = schedule_groups[i].impl_graphs[j];
     567              :       for (auto size : graph.GetAllSizeVar()) {
     568              :         if (size->expr.IsConstExpr()) {
     569              :           continue;
     570              :         }
     571              :         if (size_var_names.find(std::string(size->expr.Str().get())) == size_var_names.end()) {
     572              :           std::string field_def = const_mode_ ? this->DataFieldConstDefine(*size) : this->DataFieldDefine(*size);
     573              :           ss2 << "  " << field_def << std::endl;
     574              :           size_var_names.emplace(std::string(size->expr.Str().get()));
     575              :         }
     576              :       }
     577              :       GetTqueAndTbufId(graph, q_ids, b_ids);
     578              :       GetTmpBufName(graph, b_ids);
     579              :       AddApiTilingData(graph, ss2, j);
     580              :       GELOGI("TilingCaseId:ProcessMultiGroup, i_%d, i_num:%d, j_%d, j_num:%d\n", i, schedule_groups.size(), j,
     581              :              schedule_groups[i].impl_graphs.size());
     582              :     }
     583              :     GenTqueTbufTmpBufFunc(q_ids, b_ids, ss2);
     584              :     ss2 << this->ClassEnd() << std::endl;
     585              :     ConstTilingDataFieldPopBack();
     586              :     ss2 << std::endl;
     587              :   }
     588              :   return;
     589              : }
     590              : 
     591              : std::string codegen::TilingData::GenStringReplaceFunc() const {
     592              :   std::stringstream ss;
     593              :   ss << "void replaceSubstring(std::string& ori_str, ";
     594              :   ss << "const std::string& old_sub_str, ";
     595              :   ss << "const std::string& new_sub_str) {" << std::endl;
     596              :   ss << "  size_t pos = ori_str.find(old_sub_str);" << std::endl;
     597              :   ss << "  if (pos != std::string::npos) {" << std::endl;
     598              :   ss << "    ori_str.replace(pos, old_sub_str.length(), new_sub_str);" << std::endl;
     599              :   ss << "  }" << std::endl;
     600              :   ss << "}" << std::endl;
     601              : 
     602              :   return ss.str();
     603              : }
     604              : 
     605           80 : std::string codegen::TilingData::GenConstGenResultReplace() const {
     606              :   std::stringstream ss;
     607              : 
     608         1403 :   for (const auto &field_var : field_var_defs_) {
     609              :     ss << "  replaceSubstring(tiling_data_const_gen_result, \"" << field_var << "\"," << field_var << ");" << std::endl;
     610              :   }
     611              : 
     612              :   return ss.str();
     613              : }
     614              : 
     615              : void codegen::TilingData::ConstTilingDataFieldPopBack() {
     616              :   if (const_tiling_data_field.size() > 0) {
     617              :     const_tiling_data_field.pop_back();
     618              :   } else {
     619              :     // todo: tilingData的生成过程中遇错终止, 此处是内部逻辑错误,先打印一条Error日志
     620              :     GELOGE(af::FAILED, "The const_tiling_data_field is empty.");
     621              :   }
     622              : }
     623              : 
     624              : std::string codegen::TilingData::GenCVConstTilingData(const std::string &tiling_data_struct_name,
     625              :                                                       bool is_inductor_scene) {
     626              :   std::stringstream ss;
     627              : 
     628              :   if (is_inductor_scene) {
     629              :     // Inductor场景:调用AutofuseTiling获取CVAutofuseTilingData
     630              :     ss << "  // Call AutofuseTiling to get CV tiling data" << std::endl;
     631              :     ss << "  int64_t result = AutofuseTiling(&" << tiling_data_struct_name << ", &workspace_size, &block_dim, nullptr);"
     632              :        << std::endl;
     633              :     ss << "  if (result != 0) {" << std::endl;
     634              :     ss << "    OP_LOGE(OP_NAME, \"AutofuseTiling failed: %ld\", result);" << std::endl;
     635              :     ss << "    return \"\";" << std::endl;
     636              :     ss << "  }" << std::endl;
     637              :     ss << std::endl;
     638              : 
     639              :     ss << "  // matmul_tiling_data: serialize to byte array" << std::endl;
     640              :     ss << "  std::vector<uint8_t> g_matmul_tiling_bytes;" << std::endl;
     641              :     ss << "  g_matmul_tiling_bytes.resize(sizeof(" << tiling_data_struct_name << ".matmul_tiling_data));" << std::endl;
     642              :     ss << "  std::memcpy(g_matmul_tiling_bytes.data(), &" << tiling_data_struct_name << ".matmul_tiling_data, sizeof("
     643              :        << tiling_data_struct_name << ".matmul_tiling_data));" << std::endl;
     644              :   } else {
     645              :     // 非Inductor场景:原有逻辑,调用AutofuseTilingWithConfig
     646              :     ss << "  set_g_basen_basem_align(basen_basem_align);" << std::endl;
     647              :     ss << "  OP_LOGI(OP_NAME, \"basen_basem_align=%d, basen_align=%d, set_g_basen_basem_align=%d\", ";
     648              :     ss << "basen_basem_align, basen_align, get_g_basen_basem_align());" << std::endl;
     649              :     ss << "  auto ret = AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name;
     650              :     ss << ", &workspace_size, &block_dim, ";
     651              :     ss << "&limit, 0);" << std::endl;
     652              :     ss << "  if (ret == -1) {" << std::endl;
     653              :     ss << "    uint32_t basen_basem_align_tmp = (uint32_t)basen_basem_align;" << std::endl;
     654              :     ss << "    // ub_size必大于 basen_basem_align_tmp" << std::endl;
     655              :     ss << "    limit.ub_size = limit.ub_size - basen_basem_align_tmp * cube_output_type_size;" << 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);"
     658              :        << std::endl;
     659              :     ss << "    (void)AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name;
     660              :     ss << ", &workspace_size, &block_dim, ";
     661              :     ss << "&limit, 1);" << std::endl;
     662              :     ss << "  }" << std::endl;
     663              :   }
     664              : 
     665              :   return ss.str();
     666              : }
     667              : 
     668              : // GenCVConstReplace: 执行CV字段的替换(必须在raw string赋值之后调用)
     669              : std::string codegen::TilingData::GenCVConstReplace(const std::string &tiling_data_struct_name) {
     670              :   std::stringstream ss;
     671              : 
     672              :   // matmul_tiling_data bytes are also used by GET_TILING_DATA_WITH_STRUCT.
     673              :   ss << "  // Replace kConstTilingData with complete CV const values" << std::endl;
     674              :   ss << "  std::stringstream matmul_bytes_ss;" << std::endl;
     675              :   ss << "  for (size_t i = 0; i < g_matmul_tiling_bytes.size(); ++i) {" << std::endl;
     676              :   ss << "    if (i > 0) matmul_bytes_ss << \", \";" << std::endl;
     677              :   ss << "    matmul_bytes_ss << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << "
     678              :         "(int)g_matmul_tiling_bytes[i];"
     679              :      << std::endl;
     680              :   ss << "  }" << std::endl;
     681              :   ss << "  std::string matmul_bytes = matmul_bytes_ss.str();" << std::endl;
     682              :   ss << "  std::string matmul_global = \"static constexpr unsigned char kConstMatmulTilingBytes[\" + "
     683              :         "std::to_string(g_matmul_tiling_bytes.size()) + \"] = {\" + matmul_bytes + \"};\\n\";"
     684              :      << std::endl;
     685              :   ss << "  std::stringstream k_const_tiling_data_ss;" << std::endl;
     686              :   ss << "  k_const_tiling_data_ss << \"const CVAutofuseTilingData kConstTilingData = "
     687              :         "{{CVAutofuseExternTilingData{{}, \";"
     688              :      << std::endl;
     689              :   ss << "  k_const_tiling_data_ss << std::to_string((uint64_t)" << tiling_data_struct_name
     690              :      << ".cube_tiling_key) << \", {\";" << std::endl;
     691              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     692              :      << ".cv_tiling_data.fusion_mode) << \", \";" << std::endl;
     693              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     694              :      << ".cv_tiling_data.ub_mode) << \", \";" << std::endl;
     695              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     696              :      << ".cv_tiling_data.cv_aic_num) << \", \";" << std::endl;
     697              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     698              :      << ".cv_tiling_data.cv_aiv_num) << \", \";" << std::endl;
     699              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     700              :      << ".cv_tiling_data.cv_vec_wss) << \", \";" << std::endl;
     701              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     702              :      << ".cv_tiling_data.mix_mode) << \"}}}, \";" << std::endl;
     703              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     704              :      << ".stage_size_name) << \", \";" << std::endl;
     705              :   ss << "  k_const_tiling_data_ss << std::to_string((uint32_t)" << tiling_data_struct_name
     706              :      << ".cube_ub_stage_size) << \", {\";" << std::endl;
     707              :   ss << "  k_const_tiling_data_ss << matmul_bytes << \"}};\";" << std::endl;
     708              :   ss << "  replaceSubstring(tiling_data_const_gen_result, " << std::endl;
     709              :   ss << "    \"const CVAutofuseTilingData kConstTilingData = {};\", " << std::endl;
     710              :   ss << "    k_const_tiling_data_ss.str());" << std::endl;
     711              :   ss << "  replaceSubstring(tiling_data_const_gen_result, " << std::endl;
     712              :   ss << "    \"#define GET_TILING_DATA_WITH_STRUCT(tiling_struct, tiling_data, tiling_arg)\", " << std::endl;
     713              :   ss << "    matmul_global + \"#define GET_TILING_DATA_WITH_STRUCT(tiling_struct, tiling_data, tiling_arg)\");"
     714              :      << std::endl;
     715              : 
     716              :   return ss.str();
     717              : }
     718              : 
     719              : // GenerateConst生成的信息放在tiling func .cpp中
     720              : std::string codegen::TilingData::GenerateConst(const ascir::FusedScheduledResult &fused_schedule_result,
     721              :                                                bool is_inductor_scene) {
     722              :   if (!IsStaticSchedResult(fused_schedule_result)) {
     723              :     return "";
     724              :   }
     725              : 
     726              :   const_mode_ = true;
     727              :   // 生成GenConstTilingData, GenConstTilingData实现对tilingfunc的调用得到的tilingData为初值,初始化生成的常量TilingData
     728              :   std::stringstream ss;
     729              :   std::stringstream global_pre_def_ss;
     730              :   std::stringstream const_gen_ss;
     731              : 
     732              :   global_pre_def_ss << "std::string tiling_data_const_gen_result;" << std::endl;
     733              :   std::string tiling_data_struct_name = "TilingDataValue";
     734              :   const_tiling_data_field.push_back(tiling_data_struct_name);
     735              : 
     736              :   // 根据场景定义正确的变量类型:CV fusion场景使用CVAutofuseTilingData,普通场景使用AutofuseTilingData
     737              :   if (IsCubeFusedScheduled(fused_schedule_result) && is_inductor_scene) {
     738              :     global_pre_def_ss << "CVAutofuseTilingData " << tiling_data_struct_name << ";" << std::endl << std::endl;
     739              :   } else {
     740              :     global_pre_def_ss << "AutofuseTilingData " << tiling_data_struct_name << ";" << std::endl << std::endl;
     741              :   }
     742              : 
     743              :   global_pre_def_ss << GenStringReplaceFunc() << std::endl;  // 生成一个字符串替换接口
     744              : 
     745              :   const_gen_ss << "extern \"C\" const char* GenConstTilingData(char* config_file, int aiv_num, int ub_size) {"
     746              :                << std::endl;
     747              :   const_gen_ss << "  uint32_t workspace_size;" << std::endl;
     748              :   const_gen_ss << "  uint32_t block_dim;" << std::endl;
     749              :   const_gen_ss << "  ResLimit limit;" << std::endl;
     750              :   const_gen_ss << "  limit.aiv_num = aiv_num;" << std::endl;
     751              :   const_gen_ss << "  limit.ub_size = ub_size - 256;" << std::endl;
     752              : 
     753              :   if (IsCubeFusedScheduled(fused_schedule_result)) {
     754              :     const_gen_ss << GenCVConstTilingData(tiling_data_struct_name, is_inductor_scene);
     755              :   } else {
     756              :     const_gen_ss << "  (void)AutofuseTilingWithConfig(config_file, &" << tiling_data_struct_name;
     757              :     if (is_inductor_scene) {
     758              :       const_gen_ss << ", &workspace_size, &block_dim, nullptr);" << std::endl;
     759              :     } else {
     760              :       const_gen_ss << ", &workspace_size, &block_dim, &limit);" << std::endl;
     761              :     }
     762              :   }
     763              : 
     764              :   pre_func_ss << GenGenTilingDataFieldConstDefFunc() << std::endl;
     765              :   pre_func_ss << GenGenTilingDataFieldConstValueFunc() << std::endl;
     766              : 
     767              :   // CV+inductor: AutofuseTilingData fields are inside tiling_data member of CVAutofuseTilingData
     768              :   // Push "tiling_data" so field paths become TilingDataValue.tiling_data.xxx
     769              :   if (IsCubeFusedScheduled(fused_schedule_result) && is_inductor_scene) {
     770              :     const_tiling_data_field.push_back("tiling_data");
     771              :   }
     772              : 
     773              :   std::string g_str = Generate(fused_schedule_result, is_inductor_scene);
     774              : 
     775              :   // Pop "tiling_data" after Generate
     776              :   if (IsCubeFusedScheduled(fused_schedule_result) && is_inductor_scene) {
     777              :     ConstTilingDataFieldPopBack();
     778              :   }
     779              : 
     780              :   global_pre_def_ss << pre_func_ss.str() << std::endl;  // 一些前置函数定义放在前面,
     781              : 
     782              :   const_gen_ss << pre_var_ss.str() << std::endl;  // 前置函数的调用,生成"const声明"放在这里
     783              :   const_gen_ss << "  tiling_data_const_gen_result = R\"(" << g_str << ")\";" << std::endl;
     784              : 
     785              :   const_gen_ss << GenConstGenResultReplace() << std::endl;
     786              : 
     787              :   // CV-specific const tiling data replacement
     788              :   if (IsCubeFusedScheduled(fused_schedule_result) && is_inductor_scene) {
     789              :     const_gen_ss << GenCVConstReplace(tiling_data_struct_name) << std::endl;
     790              :   }
     791              :   const_gen_ss << "  return tiling_data_const_gen_result.c_str();" << std::endl;
     792              :   const_gen_ss << "}" << std::endl;
     793              :   ConstTilingDataFieldPopBack();
     794              : 
     795              :   ss << global_pre_def_ss.str();
     796              :   ss << const_gen_ss.str() << std::endl;
     797              : 
     798              :   const_mode_ = false;
     799              :   return ss.str();
     800              : }
     801              : 
     802         1323 : std::string codegen::TilingData::GenTingDataField(std::string field_name) const {
     803              :   if (!const_mode_) {
     804              :     return "";
     805              :   }
     806              : 
     807              :   std::stringstream ss;
     808         3419 :   for (const auto &field : const_tiling_data_field) {
     809              :     ss << field << ".";
     810              :   }
     811              :   ss << field_name;
     812              : 
     813              :   return ss.str();
     814              : }
     815              : 
     816         1323 : std::string codegen::TilingData::GetNameOfGenTilingDataFieldConstDefFunc(const std::string field_name) const {
     817              :   if (!const_mode_) {
     818              :     return "";
     819              :   }
     820              : 
     821              :   std::stringstream ss;
     822              :   ss << "Gen";
     823         3419 :   for (const auto &field : const_tiling_data_field) {
     824              :     ss << field << "_";
     825              :   }
     826              :   ss << field_name << "_field_DeclareFunc";
     827              : 
     828              :   return ss.str();
     829              : }
     830              : 
     831         1233 : std::string codegen::TilingData::GetNameOfGenTilingDataFieldConstDefFuncSimple(const std::string field_name) const {
     832              :   if (!const_mode_) {
     833              :     return "";
     834              :   }
     835              : 
     836              :   std::string complete_fields = GenTingDataField(field_name);
     837              :   std::stringstream ss;
     838              :   ss << "GenTilingDataFieldConstDefFunc(\"" << field_name << "\", " << complete_fields << ")";
     839              :   return ss.str();
     840              : }
     841              : 
     842           90 : std::string codegen::TilingData::GetNameOfGenTilingDataFieldConstValueFuncSimple(const std::string field_name) const {
     843              :   if (!const_mode_) {
     844              :     return "";
     845              :   }
     846              : 
     847              :   std::string complete_fields = GenTingDataField(field_name);
     848              :   std::stringstream ss;
     849              :   ss << "GenTilingDataFieldConstValueFunc(" << complete_fields << ")";
     850              :   return ss.str();
     851              : }
     852              : 
     853              : std::string codegen::TilingData::DataFieldConstDefine(const std::string &buf_name) {
     854              :   std::stringstream ss;
     855              :   std::string field = buf_name + "_size";
     856              :   std::string field_func_str = GetNameOfGenTilingDataFieldConstDefFunc(field);
     857              :   std::string field_func_str_simple = GetNameOfGenTilingDataFieldConstDefFuncSimple(field);
     858              :   std::string field_def = field_func_str + "_def";
     859              :   pre_var_ss << "  std::string " << field_def << " = " << field_func_str_simple << ";" << std::endl;
     860              :   ss << field_def;
     861              :   field_var_defs_.push_back(field_def);
     862              : 
     863              :   return ss.str();
     864              : }
     865              : 
     866              : std::string codegen::TilingData::TqueOrTbufDataFieldDefine(int64_t index, const std::string &que_or_buf) const {
     867              :   std::stringstream ss;
     868              :   ss << "TILING_DATA_FIELD_DEF_T(uint32_t, " << que_or_buf << std::to_string(index) << "_size);";
     869              :   return ss.str();
     870              : }
     871              : 
     872              : std::string codegen::TilingData::TqueOrTbufDataFieldConstDefine(int64_t index, const std::string &que_or_buf) {
     873              :   return DataFieldConstDefine(que_or_buf + std::to_string(index));
     874              : }
     875              : 
     876              : std::string codegen::TilingData::TmpBufDataFieldDefine(const std::string &tmp_tbuf_name) const {
     877              :   std::stringstream ss;
     878              :   ss << "TILING_DATA_FIELD_DEF_T(uint32_t, " << tmp_tbuf_name << "_size);";
     879              :   return ss.str();
     880              : }
     881              : 
     882              : std::string codegen::TilingData::TmpBufDataFieldConstDefine(const std::string &tmp_tbuf_name) {
     883              :   return DataFieldConstDefine(tmp_tbuf_name);
     884              : }
        

Generated by: LCOV version 2.3.2-1