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 ¶m : 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 163 : std::string codegen::TilingData::GenConstGenResultReplace() const {
606 : std::stringstream ss;
607 :
608 4931 : 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 4768 : std::string codegen::TilingData::GenTingDataField(std::string field_name) const {
803 : if (!const_mode_) {
804 : return "";
805 : }
806 :
807 : std::stringstream ss;
808 12806 : for (const auto &field : const_tiling_data_field) {
809 : ss << field << ".";
810 : }
811 : ss << field_name;
812 :
813 : return ss.str();
814 : }
815 :
816 4768 : 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 12806 : 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 4750 : 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 18 : 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 : }
|