已合并
【refactor】: 重构Reduce/RegReduce代码生成架构 #904
【refactor】: 重构Reduce/RegReduce代码生成架构 #904
已合并
chenyukai创建于 6月17日
共 13 个文件变更+570-283
@@ -637,7 +637,7 @@ class MaxAscIrCodegenImpl : public AscIrCodegen {
637 return "ReduceApiCall";637 return "ReduceApiCall";
638 }638 }
639 std::string GetApiName() const override {639 std::string GetApiName() const override {
640- return "Max";640+ return "ReduceMax";
641 }641 }
642 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {642 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
643 return {"reduce_init.h", "reduce.h"};643 return {"reduce_init.h", "reduce.h"};
@@ -748,7 +748,7 @@ class SumAscIrCodegenImpl : public AscIrCodegen {
748 return "ReduceApiCall";748 return "ReduceApiCall";
749 }749 }
750 std::string GetApiName() const override {750 std::string GetApiName() const override {
751- return "Sum";751+ return "ReduceSum";
752 }752 }
753 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {753 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
754 return {"reduce_init.h", "reduce.h"};754 return {"reduce_init.h", "reduce.h"};
@@ -780,7 +780,7 @@ class MinAscIrCodegenImpl : public AscIrCodegen {
780 return "ReduceApiCall";780 return "ReduceApiCall";
781 }781 }
782 std::string GetApiName() const override {782 std::string GetApiName() const override {
783- return "Min";783+ return "ReduceMin";
784 }784 }
785 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {785 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
786 return {"reduce_init.h", "reduce.h"};786 return {"reduce_init.h", "reduce.h"};
@@ -812,7 +812,7 @@ class MeanAscIrCodegenImpl : public AscIrCodegen {
812 return "ReduceApiCall";812 return "ReduceApiCall";
813 }813 }
814 std::string GetApiName() const override {814 std::string GetApiName() const override {
815- return "Mean";815+ return "ReduceMean";
816 }816 }
817 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {817 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
818 return {"reduce_init.h", "reduce.h"};818 return {"reduce_init.h", "reduce.h"};
@@ -844,7 +844,7 @@ class ProdAscIrCodegenImpl : public AscIrCodegen {
844 return "ReduceApiCall";844 return "ReduceApiCall";
845 }845 }
846 std::string GetApiName() const override {846 std::string GetApiName() const override {
847- return "Prod";847+ return "ReduceProd";
848 }848 }
849 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {849 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
850 return {"reduce_init.h", "reduce.h"};850 return {"reduce_init.h", "reduce.h"};
@@ -876,7 +876,7 @@ class AnyAscIrCodegenImpl : public AscIrCodegen {
876 return "ReduceApiCall";876 return "ReduceApiCall";
877 }877 }
878 std::string GetApiName() const override {878 std::string GetApiName() const override {
879- return "Any";879+ return "ReduceAny";
880 }880 }
881 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {881 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
882 return {"reduce_init.h", "reduce.h"};882 return {"reduce_init.h", "reduce.h"};
@@ -908,7 +908,7 @@ class AllAscIrCodegenImpl : public AscIrCodegen {
908 return "ReduceApiCall";908 return "ReduceApiCall";
909 }909 }
910 std::string GetApiName() const override {910 std::string GetApiName() const override {
911- return "All";911+ return "ReduceAll";
912 }912 }
913 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {913 std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
914 return {"reduce_init.h", "reduce.h"};914 return {"reduce_init.h", "reduce.h"};
@@ -21,6 +21,7 @@
21#include "api_call/utils/api_call_factory.h"21#include "api_call/utils/api_call_factory.h"
22#include "api_call/utils/api_call_utils.h"22#include "api_call/utils/api_call_utils.h"
23#include "codegen/expression_convert_struct.h"23#include "codegen/expression_convert_struct.h"
24+#include "codegen_api_param/codegen_api_param.h"
24 25 
25namespace codegen {26namespace codegen {
26using namespace std;27using namespace std;
@@ -38,10 +39,9 @@ int64_t ReduceApiCall::GetTmpBufIdByLifeTime(int64_t life_time, const std::strin
38 return it->second;39 return it->second;
39}40}
40 41 
41-Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,42+Status ReduceApiCall::BuildApiParam(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,
42- const std::vector<std::reference_wrapper<const Tensor>> &inputs,43+ const std::vector<std::reference_wrapper<const Tensor>> &inputs,
43- const std::vector<std::reference_wrapper<const Tensor>> &outputs,44+ const std::vector<std::reference_wrapper<const Tensor>> &outputs) const {
44- std::string &result) const {
45 auto iter = reduce_type_map.find(this->api_name_);45 auto iter = reduce_type_map.find(this->api_name_);
46 GE_CHK_BOOL_RET_STATUS(iter != reduce_type_map.end(), ge::FAILED, "Codegen unsupported reduce api::%s",46 GE_CHK_BOOL_RET_STATUS(iter != reduce_type_map.end(), ge::FAILED, "Codegen unsupported reduce api::%s",
47 this->api_name_.c_str());47 this->api_name_.c_str());
@@ -53,8 +53,6 @@ Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::Axis
53 // 获取tmp_buf复用TBuf的id53 // 获取tmp_buf复用TBuf的id
54 int64_t id = GetTmpBufIdByLifeTime(-1L, this->api_name_);54 int64_t id = GetTmpBufIdByLifeTime(-1L, this->api_name_);
55 55 
56- (void)RegisterBasicDumpParam(this->api_name_, inputs, outputs, {}, tpipe.tmp_buf.name + "_" + std::to_string(id));
57- 
58 std::string reduce_pattern;56 std::string reduce_pattern;
59 GetIsArAndPattern(y, x.isAr, reduce_pattern);57 GetIsArAndPattern(y, x.isAr, reduce_pattern);
60 CheckReduceSpecificParamsForCodegen({this->node, this->api_name_, &tpipe, &x, &y, current_axis.back()});58 CheckReduceSpecificParamsForCodegen({this->node, this->api_name_, &tpipe, &x, &y, current_axis.back()});
@@ -64,44 +62,61 @@ Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::Axis
64 GE_CHK_STATUS_RET(GetDtypeNameForReduce(this->api_name_, x, y, dtype_name),62 GE_CHK_STATUS_RET(GetDtypeNameForReduce(this->api_name_, x, y, dtype_name),
65 "Codegen get dtype name failed for api:%s", this->api_name_.c_str());63 "Codegen get dtype name failed for api:%s", this->api_name_.c_str());
66 64 
67- stringstream ss;65+ auto api_param = af::ComGraphMakeShared<CodegenApiParam>();
66+ GE_ASSERT_NOTNULL(api_param);
68 67 
69- ReduceMergedSizeCodeGen(tpipe, ss, x, y);68+ ReduceMergedSizeCodeGen(tpipe, api_param->api_pre_process, x, y);
70 69 
71- ReduceDimACodeGen(x, this->api_name_, ss);70+ ReduceDimACodeGen(x, this->api_name_, api_param->api_pre_process);
72 71 
73- ReduceInitCodeGen(x, y, type_value, ss, tpipe, dtype_name);72+ ReduceInitCodeGen(x, y, type_value, api_param->api_pre_process, tpipe, dtype_name);
74 73 
75 // 生成accumulated_offset变量声明(ArgMax和ArgMaxMultiRPhase1需要)74 // 生成accumulated_offset变量声明(ArgMax和ArgMaxMultiRPhase1需要)
76- GenAccumulatedOffsetDeclForArgMax(this->api_name_, x, y, tpipe, ss);75+ GenAccumulatedOffsetDeclForArgMax(this->api_name_, x, y, tpipe, api_param->api_pre_process);
77 76 
78- ss << "uint32_t tmp_reduce_shape[] = {first_actual, last};" << std::endl;77+ api_param->api_pre_process.emplace_back("uint32_t tmp_reduce_shape[] = {first_actual, last};\n");
78+ 
79+ // Mean算子实际调用ReduceSum(或ReduceSumInt32),其他算子映射到真实API名
80+ std::string new_api_name = this->api_name_ == "ReduceMean" ? "ReduceSum" : this->api_name_;
81+ // ReduceSum + int32_t 特殊处理:实际调用 ReduceSumInt32
82+ if (new_api_name == "ReduceSum" && dtype_name == "int32_t") {
83+ new_api_name = "ReduceSumInt32";
84+ }
79 85 
80- std::string new_api_name = this->api_name_ == "Mean" ? "Sum" : this->api_name_;
81 if (!IsNeedMultiReduce(tpipe.tiler, x, y, current_axis.back())) {86 if (!IsNeedMultiReduce(tpipe.tiler, x, y, current_axis.back())) {
82- if (new_api_name == "ArgMax") {87+ if (this->api_name_ == "ArgMax") {
83- ss << "ArgMaxExtend<int64_t, " << dtype_name << ", " << reduce_pattern << ">(" << y << "["88+ api_param->api_name = "ArgMaxExtend";
84- << tpipe.tiler.TensorVectorizedOffset(current_axis, y) << "], " << x << "["89+ api_param->template_params.emplace_back("int64_t");
85- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], " << tpipe.tmp_buf << "_" << std::to_string(id)90+ api_param->template_params.emplace_back(dtype_name);
86- << ", tmp_reduce_shape, false);" << std::endl;91+ api_param->template_params.emplace_back(reduce_pattern);
87- } else if (new_api_name == "Sum" && dtype_name == "int32_t") {92+ api_param->output_params.emplace_back(
88- ss << "ReduceSumInt32<" << dtype_name << ", " << reduce_pattern << ", false>(" << y << "["93+ y.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, y)));
89- << tpipe.tiler.TensorVectorizedOffset(current_axis, y) << "], " << x << "["94+ api_param->input_params.emplace_back(
90- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], " << tpipe.tmp_buf << "_" << std::to_string(id)95+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
91- << ", tmp_reduce_shape, true);" << std::endl;96+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
97+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
92 } else {98 } else {
93- ss << "Reduce" << new_api_name << "<" << dtype_name << ", " << reduce_pattern << ", false>(" << y << "["99+ // 普通Reduce 不需要multi_reduce(包括Mean在内)
94- << tpipe.tiler.TensorVectorizedOffset(current_axis, y) << "], " << x << "["100+ api_param->api_name = new_api_name;
95- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], " << tpipe.tmp_buf << "_" << std::to_string(id)101+ api_param->template_params.emplace_back(dtype_name);
96- << ", tmp_reduce_shape, true);" << std::endl;102+ api_param->template_params.emplace_back(reduce_pattern);
97- }103+ api_param->template_params.emplace_back("false");
98- if (this->api_name_ == "Mean") {104+ api_param->output_params.emplace_back(
99- ReduceMeanCodeGen(dtype_name, tpipe, x, y, ss);105+ y.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, y)));
106+ api_param->input_params.emplace_back(
107+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
108+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
109+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
110+ 
111+ // Mean算子在非multi_reduce时需要额外的后处理(除法)
112+ if (this->api_name_ == "ReduceMean") {
113+ ReduceMeanCodeGen(dtype_name, tpipe, x, y, api_param->api_post_process);
114+ }
100 }115 }
101 } else {116 } else {
102 int64_t tmp_lifetime_0_id = GetTmpBufIdByLifeTime(0L, this->api_name_);117 int64_t tmp_lifetime_0_id = GetTmpBufIdByLifeTime(0L, this->api_name_);
103 118 
104- if (new_api_name == "ArgMax") {119+ if (this->api_name_ == "ArgMax") {
105 // ArgMax 特殊处理:需要维护全局最大值和索引,以及累加的 offset120 // ArgMax 特殊处理:需要维护全局最大值和索引,以及累加的 offset
106 // ArgMax 有三个额外的tmp_buf:121 // ArgMax 有三个额外的tmp_buf:
107 // - desc2(life_time=0):索引的临时存储122 // - desc2(life_time=0):索引的临时存储
@@ -109,55 +124,68 @@ Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::Axis
109 // - desc4(life_time=2):value的历史最大结果124 // - desc4(life_time=2):value的历史最大结果
110 125 
111 // 索引:生命周期0的 tmp_argmax_index (desc2)126 // 索引:生命周期0的 tmp_argmax_index (desc2)
112- ss << "LocalTensor<int64_t> tmp_argmax_index;" << std::endl;127+ api_param->api_pre_process.emplace_back("LocalTensor<int64_t> tmp_argmax_index;\n");
113- ss << "tmp_argmax_index = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_0_id)128+ api_param->api_pre_process.emplace_back(
114- << ".template ReinterpretCast<int64_t>();" << std::endl;129+ "tmp_argmax_index = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_0_id)
130+ + ".template ReinterpretCast<int64_t>();\n");
115 131 
116 // 当前计算的value:生命周期1的 tmp_argmax_value (desc3)132 // 当前计算的value:生命周期1的 tmp_argmax_value (desc3)
117 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMax");133 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMax");
118- ss << "LocalTensor<" << dtype_name << "> tmp_argmax_value;" << std::endl;134+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_argmax_value;\n");
119- ss << "tmp_argmax_value = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_1_id)135+ api_param->api_pre_process.emplace_back(
120- << ".template ReinterpretCast<" << dtype_name << ">();" << std::endl;136+ "tmp_argmax_value = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_1_id)
137+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
121 138 
122 // 历史最大value:生命周期2的 tmp_argmax_value_saved (desc4)139 // 历史最大value:生命周期2的 tmp_argmax_value_saved (desc4)
123 int64_t tmp_lifetime_2_id = GetTmpBufIdByLifeTime(2L, "ArgMax");140 int64_t tmp_lifetime_2_id = GetTmpBufIdByLifeTime(2L, "ArgMax");
124- ss << "LocalTensor<" << dtype_name << "> tmp_argmax_value_saved;" << std::endl;141+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_argmax_value_saved;\n");
125- ss << "tmp_argmax_value_saved = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_2_id)142+ api_param->api_pre_process.emplace_back(
126- << ".template ReinterpretCast<" << dtype_name << ">();" << std::endl;143+ "tmp_argmax_value_saved = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_2_id)
144+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
127 145 
128- // 调用 ArgMaxWithValueExtend 获取本次迭代的局部索引和最大值146+ // ArgMaxWithValueExtend 核心 API 参数
129- ss << "ArgMaxWithValueExtend<int64_t, " << dtype_name << ", " << reduce_pattern << ">("147+ api_param->api_name = "ArgMaxWithValueExtend";
130- << "tmp_argmax_index[0], " << "tmp_argmax_value[0], " << x << "["148+ api_param->template_params.emplace_back("int64_t");
131- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], " << tpipe.tmp_buf << "_" << std::to_string(id)149+ api_param->template_params.emplace_back(dtype_name);
132- << ", tmp_reduce_shape, false);" << std::endl;150+ api_param->template_params.emplace_back(reduce_pattern);
133- 151+ api_param->output_params.emplace_back("tmp_argmax_index", true, CombinedExprFactory::Constant(0));
134- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;152+ api_param->output_params.emplace_back("tmp_argmax_value", true, CombinedExprFactory::Constant(0));
153+ api_param->input_params.emplace_back(
154+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
155+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
156+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
135 157 
158+ // 后处理段:ArgMax multi_reduce
159+ api_param->api_post_process.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
136 // 如果是第一次迭代,直接赋值;否则使用 UpdateMaxIndexAndValue 更新全局最大值和索引160 // 如果是第一次迭代,直接赋值;否则使用 UpdateMaxIndexAndValue 更新全局最大值和索引
137- ss << "uint32_t temp_size_index = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 4);" << std::endl;161+ api_param->api_post_process.emplace_back("uint32_t temp_size_index = " + KernelUtils::SizeAlign() + "(" +
138- ss << "uint32_t temp_size_value = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 32/sizeof("162+ y.actual_size.Str() + ", 4);\n");
139- << dtype_name << "));" << std::endl;163+ api_param->api_post_process.emplace_back("uint32_t temp_size_value = " + KernelUtils::SizeAlign() + "(" +
140- ss << "if (" << tpipe.tiler.GetAxis(current_axis.back()) << " == 0) {" << std::endl;164+ y.actual_size.Str() + ", 32/sizeof(" + dtype_name + "));\n");
141- ss << "DataCopyExtend(" << y << "[0], " << "tmp_argmax_index[0], " << "temp_size_index);" << std::endl;165+ api_param->api_post_process.emplace_back("if (" + tpipe.tiler.GetAxis(current_axis.back()).Str() + " == 0) {\n");
142- ss << "DataCopyExtend(" << "tmp_argmax_value_saved[0], " << "tmp_argmax_value[0], temp_size_value);" << std::endl;166+ api_param->api_post_process.emplace_back("DataCopyExtend(" + y.Str() + "[0], tmp_argmax_index[0], temp_size_index);\n");
143- ss << "} else {" << std::endl;167+ api_param->api_post_process.emplace_back(
168+ "DataCopyExtend(tmp_argmax_value_saved[0], tmp_argmax_value[0], temp_size_value);\n");
169+ api_param->api_post_process.emplace_back("} else {\n");
144 // 使用当前的 accumulated_offset(标量)来更新全局最大值和索引170 // 使用当前的 accumulated_offset(标量)来更新全局最大值和索引
145 // tmp_argmax_value_current是当前计算的value,tmp_argmax_value_saved是历史最大171 // tmp_argmax_value_current是当前计算的value,tmp_argmax_value_saved是历史最大
146- ss << "UpdateMaxIndexAndValue<" << dtype_name << ">(tmp_argmax_index[0], tmp_argmax_value[0], " << y << "[0], "172+ api_param->api_post_process.emplace_back("UpdateMaxIndexAndValue<" + dtype_name +
147- << "tmp_argmax_value_saved[0], "173+ ">(tmp_argmax_index[0], tmp_argmax_value[0], " + y.Str() +
148- << "accumulated_offset, " << tpipe.tmp_buf << "_" << std::to_string(id) << ", temp_size_value);" << std::endl;174+ "[0], tmp_argmax_value_saved[0], " + "accumulated_offset, " +
149- ss << "}" << std::endl;175+ tpipe.tmp_buf.name + "_" + std::to_string(id) + ", temp_size_value);\n");
176+ api_param->api_post_process.emplace_back("}\n");
150 177 
151 // 累加 offset:accumulated_offset += 本次处理的 R 轴 actual_size178 // 累加 offset:accumulated_offset += 本次处理的 R 轴 actual_size
152 // 根据 AR/RA 模式决定累加哪个值179 // 根据 AR/RA 模式决定累加哪个值
153 if (x.isAr) {180 if (x.isAr) {
154 // AR 模式:累加 vectorized_axis 的 actual_size181 // AR 模式:累加 vectorized_axis 的 actual_size
155- ss << "accumulated_offset += " << tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size << ";" << std::endl;182+ api_param->api_post_process.emplace_back(
183+ "accumulated_offset += " + tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size.Str() + ";\n");
156 } else {184 } else {
157 // RA 模式:累加 first_actual185 // RA 模式:累加 first_actual
158- ss << "accumulated_offset += first_actual;" << std::endl;186+ api_param->api_post_process.emplace_back("accumulated_offset += first_actual;\n");
159 }187 }
160- } else if (new_api_name == "ArgMaxMultiRPhase1") {188+ } else if (this->api_name_ == "ArgMaxMultiRPhase1") {
161 // ArgMaxMultiRPhase1特殊处理:在IsNeedMultiReduce分支中也需要处理189 // ArgMaxMultiRPhase1特殊处理:在IsNeedMultiReduce分支中也需要处理
162 // ArgMaxMultiRPhase1 有两个额外的tmp_buf:190 // ArgMaxMultiRPhase1 有两个额外的tmp_buf:
163 // - desc2(life_time=0):索引的临时存储191 // - desc2(life_time=0):索引的临时存储
@@ -165,61 +193,71 @@ Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::Axis
165 // 注意:ArgMaxMultiRPhase1本身自带两个输出,所以不需要历史最大值的tmp_buf193 // 注意:ArgMaxMultiRPhase1本身自带两个输出,所以不需要历史最大值的tmp_buf
166 194 
167 // 索引:生命周期0的 tmp_argmax1_index (desc2)195 // 索引:生命周期0的 tmp_argmax1_index (desc2)
168- ss << "LocalTensor<int64_t> tmp_argmax1_index;" << std::endl;196+ api_param->api_pre_process.emplace_back("LocalTensor<int64_t> tmp_argmax1_index;\n");
169- ss << "tmp_argmax1_index = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_0_id)197+ api_param->api_pre_process.emplace_back(
170- << ".template ReinterpretCast<int64_t>();" << std::endl;198+ "tmp_argmax1_index = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_0_id)
199+ + ".template ReinterpretCast<int64_t>();\n");
171 200 
172 // 当前value:生命周期1的 tmp_argmax1_value (desc3)201 // 当前value:生命周期1的 tmp_argmax1_value (desc3)
173 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMaxMultiRPhase1");202 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMaxMultiRPhase1");
174- ss << "LocalTensor<" << dtype_name << "> tmp_argmax1_value;" << std::endl;203+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_argmax1_value;\n");
175- ss << "tmp_argmax1_value = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_1_id)204+ api_param->api_pre_process.emplace_back(
176- << ".template ReinterpretCast<" << dtype_name << ">();" << std::endl;205+ "tmp_argmax1_value = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_1_id)
206+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
177 207 
178- // 调用 ArgMaxWithValueExtend 获取本次迭代的局部索引和最大值208+ // ArgMaxWithValueExtend 核心 API 参数
179- ss << "ArgMaxWithValueExtend<int64_t, " << dtype_name << ", " << reduce_pattern << ">("209+ api_param->api_name = "ArgMaxWithValueExtend";
180- << "tmp_argmax1_index[0], " << "tmp_argmax1_value[0], " << x << "["210+ api_param->template_params.emplace_back("int64_t");
181- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], " << tpipe.tmp_buf << "_" << std::to_string(id)211+ api_param->template_params.emplace_back(dtype_name);
182- << ", tmp_reduce_shape, false);" << std::endl;212+ api_param->template_params.emplace_back(reduce_pattern);
213+ api_param->output_params.emplace_back("tmp_argmax1_index", true, CombinedExprFactory::Constant(0));
214+ api_param->output_params.emplace_back("tmp_argmax1_value", true, CombinedExprFactory::Constant(0));
215+ api_param->input_params.emplace_back(
216+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
217+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
218+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
183 219 
184- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;220+ // 后处理段:ArgMaxMultiRPhase1
185- 
186- // ArgMaxMultiRPhase1有两个输出:
187- // - outputs[0]: value
188- // - outputs[1]: index
189 GE_ASSERT_TRUE(outputs.size() >= ARGMAXMULTIRPHASE_OUTPUT_AND_INPUT_NUM,221 GE_ASSERT_TRUE(outputs.size() >= ARGMAXMULTIRPHASE_OUTPUT_AND_INPUT_NUM,
190 "ArgMaxMultiRPhase1 requires at least 2 outputs.");222 "ArgMaxMultiRPhase1 requires at least 2 outputs.");
191 auto y_value = outputs[0].get();223 auto y_value = outputs[0].get();
192 auto y_index = outputs[1].get();224 auto y_index = outputs[1].get();
193 225 
194- // 如果是第一次迭代,直接赋值;否则使用UpdateMaxIndexAndValue更新全局最大值和索引226+ api_param->api_post_process.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
195- ss << "uint32_t temp_size_index = " << KernelUtils::SizeAlign() << "(" << y_index.actual_size << ", 4);"227+ api_param->api_post_process.emplace_back(
196- << std::endl;228+ "uint32_t temp_size_index = " + KernelUtils::SizeAlign() + "(" + y_index.actual_size.Str() + ", 4);\n");
197- ss << "uint32_t temp_size_value = " << KernelUtils::SizeAlign() << "(" << y_value.actual_size << ", 32/sizeof("229+ api_param->api_post_process.emplace_back(
198- << dtype_name << "));" << std::endl;230+ "uint32_t temp_size_value = " + KernelUtils::SizeAlign() + "(" + y_value.actual_size.Str()
199- ss << "if (" << tpipe.tiler.GetAxis(current_axis.back()) << " == 0) {" << std::endl;231+ + ", 32/sizeof(" + dtype_name + "));\n");
232+ api_param->api_post_process.emplace_back(
233+ "if (" + tpipe.tiler.GetAxis(current_axis.back()).Str() + " == 0) {\n");
200 // 第一次迭代:直接复制到输出234 // 第一次迭代:直接复制到输出
201- ss << "DataCopyExtend(" << y_value << "[0], tmp_argmax1_value[0], temp_size_value);" << std::endl;235+ api_param->api_post_process.emplace_back(
202- ss << "DataCopyExtend(" << y_index << "[0], tmp_argmax1_index[0], temp_size_index);" << std::endl;236+ "DataCopyExtend(" + y_value.Str() + "[0], tmp_argmax1_value[0], temp_size_value);\n");
203- ss << "} else {" << std::endl;237+ api_param->api_post_process.emplace_back(
238+ "DataCopyExtend(" + y_index.Str() + "[0], tmp_argmax1_index[0], temp_size_index);\n");
239+ api_param->api_post_process.emplace_back("} else {\n");
204 // 后续迭代:使用UpdateMaxIndexAndValue更新全局最大值和索引240 // 后续迭代:使用UpdateMaxIndexAndValue更新全局最大值和索引
205 // 注意:这里需要offset,offset = 当前核id * R轴每块大小 + 累加的offset241 // 注意:这里需要offset,offset = 当前核id * R轴每块大小 + 累加的offset
206 // 暂时传入accumulated_offset,需要在循环外初始化242 // 暂时传入accumulated_offset,需要在循环外初始化
207- ss << "UpdateMaxIndexAndValue<" << dtype_name << ">(tmp_argmax1_index[0], tmp_argmax1_value[0], " << y_index243+ api_param->api_post_process.emplace_back(
208- << "[0], " << y_value << "[0], "244+ "UpdateMaxIndexAndValue<" + dtype_name + ">(tmp_argmax1_index[0], tmp_argmax1_value[0], "
209- << "accumulated_offset + block_dim * r_axis_block_size, " << tpipe.tmp_buf << "_" << std::to_string(id)245+ + y_index.Str() + "[0], " + y_value.Str() + "[0], "
210- << ", temp_size_value);" << std::endl;246+ + "accumulated_offset + block_dim * r_axis_block_size, "
211- ss << "}" << std::endl;247+ + tpipe.tmp_buf.name + "_" + std::to_string(id) + ", temp_size_value);\n");
248+ api_param->api_post_process.emplace_back("}\n");
212 249 
213 // 累加 offset:accumulated_offset += 本次处理的 R 轴 actual_size250 // 累加 offset:accumulated_offset += 本次处理的 R 轴 actual_size
214 // 根据 AR/RA 模式决定累加哪个值251 // 根据 AR/RA 模式决定累加哪个值
215 if (x.isAr) {252 if (x.isAr) {
216 // AR 模式:累加 vectorized_axis 的 actual_size253 // AR 模式:累加 vectorized_axis 的 actual_size
217- ss << "accumulated_offset += " << tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size << ";" << std::endl;254+ api_param->api_post_process.emplace_back(
255+ "accumulated_offset += " + tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size.Str() + ";\n");
218 } else {256 } else {
219 // RA 模式:累加 first_actual257 // RA 模式:累加 first_actual
220- ss << "accumulated_offset += first_actual;" << std::endl;258+ api_param->api_post_process.emplace_back("accumulated_offset += first_actual;\n");
221 }259 }
222- } else if (new_api_name == "ArgMaxMultiRPhase2") {260+ } else if (this->api_name_ == "ArgMaxMultiRPhase2") {
223 // ArgMaxMultiRPhase2特殊处理:有两个输入和一个输出,需要处理多次迭代261 // ArgMaxMultiRPhase2特殊处理:有两个输入和一个输出,需要处理多次迭代
224 // - inputs[0]: value (来自Phase1的value输出,是该块的最大值)262 // - inputs[0]: value (来自Phase1的value输出,是该块的最大值)
225 // - inputs[1]: index (来自Phase1的index输出,是该块最大值的位置)263 // - inputs[1]: index (来自Phase1的index输出,是该块最大值的位置)
@@ -234,71 +272,106 @@ Status ReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::Axis
234 auto x_index = inputs[1].get();272 auto x_index = inputs[1].get();
235 273 
236 // 索引:生命周期0的第一个 tmp_argmax2_index274 // 索引:生命周期0的第一个 tmp_argmax2_index
237- ss << "LocalTensor<int64_t> tmp_argmax2_index;" << std::endl;275+ api_param->api_pre_process.emplace_back("LocalTensor<int64_t> tmp_argmax2_index;\n");
238- ss << "tmp_argmax2_index = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_0_id)276+ api_param->api_pre_process.emplace_back(
239- << ".template ReinterpretCast<int64_t>();" << std::endl;277+ "tmp_argmax2_index = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_0_id)
278+ + ".template ReinterpretCast<int64_t>();\n");
240 279 
241 // 当前计算的value:生命周期1的 tmp_argmax2_value (desc3)280 // 当前计算的value:生命周期1的 tmp_argmax2_value (desc3)
242 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMaxMultiRPhase2");281 int64_t tmp_lifetime_1_id = GetTmpBufIdByLifeTime(1L, "ArgMaxMultiRPhase2");
243- ss << "LocalTensor<" << dtype_name << "> tmp_argmax2_value;" << std::endl;282+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_argmax2_value;\n");
244- ss << "tmp_argmax2_value = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_1_id)283+ api_param->api_pre_process.emplace_back(
245- << ".template ReinterpretCast<" << dtype_name << ">();" << std::endl;284+ "tmp_argmax2_value = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_1_id)
285+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
246 286 
247 // 历史最大value:生命周期2的 tmp_argmax2_value_saved (desc4)287 // 历史最大value:生命周期2的 tmp_argmax2_value_saved (desc4)
248 int64_t tmp_lifetime_2_id = GetTmpBufIdByLifeTime(2L, "ArgMaxMultiRPhase2");288 int64_t tmp_lifetime_2_id = GetTmpBufIdByLifeTime(2L, "ArgMaxMultiRPhase2");
249- ss << "LocalTensor<" << dtype_name << "> tmp_argmax2_value_saved;" << std::endl;289+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_argmax2_value_saved;\n");
250- ss << "tmp_argmax2_value_saved = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_2_id)290+ api_param->api_pre_process.emplace_back(
251- << ".template ReinterpretCast<" << dtype_name << ">();" << std::endl;291+ "tmp_argmax2_value_saved = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_2_id)
292+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
252 293 
253 // 调用 ArgMaxWithValueExtend 获取本次迭代的局部索引和最大值294 // 调用 ArgMaxWithValueExtend 获取本次迭代的局部索引和最大值
254- ss << "ArgMaxWithValueExtend<int64_t, " << dtype_name << ", " << reduce_pattern << ">("295+ api_param->api_name = "ArgMaxWithValueExtend";
255- << "tmp_argmax2_index[0], " << "tmp_argmax2_value[0], " << x_value << "["296+ api_param->template_params.emplace_back("int64_t");
256- << tpipe.tiler.TensorVectorizedOffset(current_axis, x_value) << "], " << tpipe.tmp_buf << "_"297+ api_param->template_params.emplace_back(dtype_name);
257- << std::to_string(id) << ", tmp_reduce_shape, false);" << std::endl;298+ api_param->template_params.emplace_back(reduce_pattern);
258- 299+ api_param->output_params.emplace_back("tmp_argmax2_index", true, CombinedExprFactory::Constant(0));
259- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;300+ api_param->output_params.emplace_back("tmp_argmax2_value", true, CombinedExprFactory::Constant(0));
301+ api_param->input_params.emplace_back(
302+ x_value.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x_value)));
303+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
304+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
260 305 
306+ // 后处理段:ArgMaxMultiRPhase2
307+ api_param->api_post_process.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
261 // 如果是第一次迭代,直接赋值;否则使用UpdateMaxIndexAndValue更新全局最大值和索引308 // 如果是第一次迭代,直接赋值;否则使用UpdateMaxIndexAndValue更新全局最大值和索引
262- ss << "uint32_t temp_size_index = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 4);" << std::endl;309+ api_param->api_post_process.emplace_back(
263- ss << "uint32_t temp_size_value = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 32/sizeof("310+ "uint32_t temp_size_index = " + KernelUtils::SizeAlign() + "(" + y.actual_size.Str() + ", 4);\n");
264- << dtype_name << "));" << std::endl;311+ api_param->api_post_process.emplace_back(
265- ss << "if (" << tpipe.tiler.GetAxis(current_axis.back()) << " == 0) {" << std::endl;312+ "uint32_t temp_size_value = " + KernelUtils::SizeAlign() + "(" + y.actual_size.Str()
266- ss << "DataCopyExtend(" << y << "[0], tmp_argmax2_index[0], temp_size_index);" << std::endl;313+ + ", 32/sizeof(" + dtype_name + "));\n");
267- ss << "DataCopyExtend(" << "tmp_argmax2_value_saved[0], " << "tmp_argmax2_value[0], temp_size_value);"314+ api_param->api_post_process.emplace_back(
268- << std::endl;315+ "if (" + tpipe.tiler.GetAxis(current_axis.back()).Str() + " == 0) {\n");
269- ss << "} else {" << std::endl;316+ api_param->api_post_process.emplace_back(
317+ "DataCopyExtend(" + y.Str() + "[0], tmp_argmax2_index[0], temp_size_index);\n");
318+ api_param->api_post_process.emplace_back(
319+ "DataCopyExtend(tmp_argmax2_value_saved[0], tmp_argmax2_value[0], temp_size_value);\n");
320+ api_param->api_post_process.emplace_back("} else {\n");
270 // 使用UpdateMaxIndexAndValue更新,注意这里offset传入0(因为Phase1已经处理了offset)321 // 使用UpdateMaxIndexAndValue更新,注意这里offset传入0(因为Phase1已经处理了offset)
271- ss << "UpdateMaxIndexAndValue<" << dtype_name << ">(tmp_argmax2_index[0], tmp_argmax2_value[0], " << y << "[0], "322+ api_param->api_post_process.emplace_back(
272- << "tmp_argmax2_value_saved[0], "323+ "UpdateMaxIndexAndValue<" + dtype_name + ">(tmp_argmax2_index[0], tmp_argmax2_value[0], "
273- << "0, " << tpipe.tmp_buf << "_" << std::to_string(id) << ", temp_size_value);" << std::endl;324+ + y.Str() + "[0], tmp_argmax2_value_saved[0], "
274- ss << "}" << std::endl;325+ + "0, " + tpipe.tmp_buf.name + "_" + std::to_string(id) + ", temp_size_value);\n");
326+ api_param->api_post_process.emplace_back("}\n");
275 } else {327 } else {
276- ss << "LocalTensor<" << dtype_name << "> tmp_reduce;" << std::endl;328+ // 普通Reduce multi_reduce(包括Mean在内):声明 tmp_reduce 变量
277- ss << "tmp_reduce = " << tpipe.tmp_buf << "_" << std::to_string(tmp_lifetime_0_id) << ".template ReinterpretCast<"329+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_reduce;\n");
278- << dtype_name << ">();" << std::endl;330+ api_param->api_pre_process.emplace_back(
279- if (new_api_name == "Sum" && dtype_name == "int32_t") {331+ "tmp_reduce = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_lifetime_0_id)
280- ss << "ReduceSumInt32<" << dtype_name << ", " << reduce_pattern << ", false>"332+ + ".template ReinterpretCast<" + dtype_name + ">();\n");
281- << "(tmp_reduce[0], " << x << "[" << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], "333+ 
282- << tpipe.tmp_buf << "_" << std::to_string(id) << ", tmp_reduce_shape, true);" << std::endl;334+ // 核心 API 参数
283- } else {335+ api_param->api_name = new_api_name;
284- ss << "Reduce" << new_api_name << "<" << dtype_name << "," << reduce_pattern << ", false>"336+ api_param->template_params.emplace_back(dtype_name);
285- << "(tmp_reduce[0], " << x << "[" << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], "337+ api_param->template_params.emplace_back(reduce_pattern);
286- << tpipe.tmp_buf << "_" << std::to_string(id) << ", tmp_reduce_shape, true);" << std::endl;338+ api_param->template_params.emplace_back("false");
287- }339+ api_param->output_params.emplace_back("tmp_reduce", true, CombinedExprFactory::Constant(0));
288- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;340+ api_param->input_params.emplace_back(
289- ss << "uint32_t temp_size = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 32/sizeof(" << dtype_name341+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
290- << "));" << std::endl;342+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
291- ss << "if (" << tpipe.tiler.GetAxis(current_axis.back()) << " == 0) {" << std::endl;343+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
292- ss << "DataCopyExtend(" << y << "[0], " << "tmp_reduce[0], " << "temp_size);" << std::endl;344+ 
293- ss << "} else {" << std::endl;345+ // 后处理段:普通Reduce multi_reduce
294- ss << "AscendC::" << instr_type << "(" << y << "[0], " << "tmp_reduce[0], " << y << "[0], temp_size);\n"346+ api_param->api_post_process.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
295- << "}" << std::endl;347+ api_param->api_post_process.emplace_back(
348+ "uint32_t temp_size = " + KernelUtils::SizeAlign() + "(" + y.actual_size.Str()
349+ + ", 32/sizeof(" + dtype_name + "));\n");
350+ api_param->api_post_process.emplace_back(
351+ "if (" + tpipe.tiler.GetAxis(current_axis.back()).Str() + " == 0) {\n");
352+ api_param->api_post_process.emplace_back(
353+ "DataCopyExtend(" + y.Str() + "[0], tmp_reduce[0], temp_size);\n");
354+ api_param->api_post_process.emplace_back("} else {\n");
355+ api_param->api_post_process.emplace_back(
356+ "AscendC::" + instr_type + "(" + y.Str() + "[0], tmp_reduce[0], " + y.Str() + "[0], temp_size);\n");
357+ api_param->api_post_process.emplace_back("}\n");
296 }358 }
297 }359 }
298 360 
299- ss << "}" << std::endl;361+ // 结束代码块(与ReduceMergedSizeCodeGen生成的 { 对应)
300- result = ss.str();362+ api_param->api_post_process.emplace_back("}\n");
301- return ge::SUCCESS;363+ 
364+ GE_CHK_STATUS_RET(CodegenApiParam::Register(this->node, api_param),
365+ "CodegenApiParam Register failed for node %s", this->node_name.c_str());
366+ return af::SUCCESS;
367+}
368+ 
369+Status ReduceApiCall::GenDimensionParam(const CodegenApiParam &api_param, const Tiler &tiler, std::stringstream &ss) const {
370+ // ArgMax 系列(ArgMaxExtend / ArgMaxWithValueExtend)最后一个布尔参数为 false(src_inner_pad 未使用),
371+ // 普通 Reduce 为 true,与重构前 Generate 内直接拼接的语义保持一致
372+ const bool is_argmax = (api_param.api_name == "ArgMaxExtend") || (api_param.api_name == "ArgMaxWithValueExtend");
373+ ss << api_param.cal_count.ToStr(tiler) << ", " << (is_argmax ? "false" : "true") << ");" << std::endl;
374+ return af::SUCCESS;
302}375}
303 376 
304static ApiCallRegister<ReduceApiCall> register_reduce_api_call("ReduceApiCall");377static ApiCallRegister<ReduceApiCall> register_reduce_api_call("ReduceApiCall");
@@ -17,9 +17,10 @@ class ReduceApiCall : public ApiCall {
17 using ApiCall::Generate;17 using ApiCall::Generate;
18 explicit ReduceApiCall(const std::string &api_name) : ApiCall(api_name) {}18 explicit ReduceApiCall(const std::string &api_name) : ApiCall(api_name) {}
19 ~ReduceApiCall() final = default;19 ~ReduceApiCall() final = default;
20- Status Generate(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,20+ Status BuildApiParam(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,
21- const std::vector<std::reference_wrapper<const Tensor>> &inputs,21+ const std::vector<std::reference_wrapper<const Tensor>> &inputs,
22- const std::vector<std::reference_wrapper<const Tensor>> &outputs, std::string &result) const override;22+ const std::vector<std::reference_wrapper<const Tensor>> &outputs) const override;
23+ Status GenDimensionParam(const CodegenApiParam &api_param, const Tiler &tiler, std::stringstream &ss) const override;
23 24 
24 private:25 private:
25 int64_t GetTmpBufIdByLifeTime(int64_t life_time, const std::string &api_name) const;26 int64_t GetTmpBufIdByLifeTime(int64_t life_time, const std::string &api_name) const;
@@ -317,17 +317,30 @@ static void ReplaceSS(std::string &str, const std::string &oldSubStr, const std:
317 return;317 return;
318}318}
319 319 
320-static void ReplaceSSWithSwappingFirstAndLast(std::string firstAndFirst_actual, std::string lastAndLast_actual,320+static void ReplaceSSWithSwappingFirstAndLast(const std::string &first, const std::string &first_actual,
321- const bool &isAllAxisReduce, std::stringstream &ss) {321+ const std::string &last, const std::string &last_actual,
322+ const bool &isAllAxisReduce, std::vector<std::string> &lines)
323+{
324+ std::string f = first;
325+ std::string fa = first_actual;
326+ std::string l = last;
327+ std::string la = last_actual;
322 if (isAllAxisReduce) {328 if (isAllAxisReduce) {
323- ReplaceSS(firstAndFirst_actual, "first", "last");329+ ReplaceSS(f, "first", "last");
324- ReplaceSS(lastAndLast_actual, "last", "first");330+ ReplaceSS(fa, "first", "last");
331+ ReplaceSS(l, "last", "first");
332+ ReplaceSS(la, "last", "first");
325 }333 }
326- ss << firstAndFirst_actual << ";\n" << lastAndLast_actual << ";\n";334+ // 添加四条独立语句,每条语句末尾加分号和换行符
335+ lines.emplace_back(f + ";\n");
336+ lines.emplace_back(fa + ";\n");
337+ lines.emplace_back(l + ";\n");
338+ lines.emplace_back(la + ";\n");
327 return;339 return;
328}340}
329 341 
330-size_t GetAxesNumExceptZeroTail(const Tensor &src, const Tensor &dst) {342+size_t GetAxesNumExceptZeroTail(const Tensor &src, const Tensor &dst)
343+{
331 size_t num_axes = src.vectorized_axis.size();344 size_t num_axes = src.vectorized_axis.size();
332 for (; num_axes > 0; num_axes--) {345 for (; num_axes > 0; num_axes--) {
333 if (src.vectorized_strides[num_axes - 1] != 0 || dst.vectorized_strides[num_axes - 1] != 0) {346 if (src.vectorized_strides[num_axes - 1] != 0 || dst.vectorized_strides[num_axes - 1] != 0) {
@@ -341,13 +354,13 @@ size_t GetAxesNumExceptZeroTail(const Tensor &src, const Tensor &dst) {
341 为了避免由于存在src[i].axis_size=1(此时strides=0)导致误判为R轴,所以在遍历过程中过滤掉了src[i].axis_size为1的情况;354 为了避免由于存在src[i].axis_size=1(此时strides=0)导致误判为R轴,所以在遍历过程中过滤掉了src[i].axis_size为1的情况;
342 用last_not_1_axis_size_index来记录上一次的axis_size != 1的位置。355 用last_not_1_axis_size_index来记录上一次的axis_size != 1的位置。
343*/356*/
344-void ReduceMergedSizeCodeGen(const TPipe &tpipe, std::stringstream &ss, const Tensor &src, const Tensor &dst,357+void ReduceMergedSizeCodeGen(const TPipe &tpipe, std::vector<std::string> &lines, const Tensor &src, const Tensor &dst,
345 bool is_tail) {358 bool is_tail) {
346 std::stringstream first;359 std::stringstream first;
347 std::stringstream first_actual;360 std::stringstream first_actual;
348 std::stringstream last;361 std::stringstream last;
349 std::stringstream last_actual;362 std::stringstream last_actual;
350- first << "{\nuint32_t " << (is_tail ? "first_tail" : "first") << " = 1";363+ first << "uint32_t " << (is_tail ? "first_tail" : "first") << " = 1";
351 first_actual << "uint32_t " << (is_tail ? "first_tail_actual" : "first_actual") << " = 1";364 first_actual << "uint32_t " << (is_tail ? "first_tail_actual" : "first_actual") << " = 1";
352 last << "uint32_t " << (is_tail ? "last_tail" : "last") << " = 1";365 last << "uint32_t " << (is_tail ? "last_tail" : "last") << " = 1";
353 last_actual << "uint32_t " << (is_tail ? "last_tail_actual" : "last_actual") << " = 1";366 last_actual << "uint32_t " << (is_tail ? "last_tail_actual" : "last_actual") << " = 1";
@@ -397,8 +410,9 @@ void ReduceMergedSizeCodeGen(const TPipe &tpipe, std::stringstream &ss, const Te
397 last_not_1_axis_size_index = i;410 last_not_1_axis_size_index = i;
398 }411 }
399 }412 }
400- ReplaceSSWithSwappingFirstAndLast(first.str() + ";\n" + first_actual.str(), last.str() + ";\n" + last_actual.str(),413+ // 先添加代码块开始符号
401- isAllAxisReduce, ss);414+ lines.emplace_back("{\n");
415+ ReplaceSSWithSwappingFirstAndLast(first.str(), first_actual.str(), last.str(), last_actual.str(), isAllAxisReduce, lines);
402}416}
403 417 
404bool IsNeedMultiReduce(const Tiler &tiler, const Tensor &input, const Tensor &output, ascir::AxisId axis_id) {418bool IsNeedMultiReduce(const Tiler &tiler, const Tensor &input, const Tensor &output, ascir::AxisId axis_id) {
@@ -438,7 +452,7 @@ bool IsNeedMultiReduce(const Tiler &tiler, const Tensor &input, const Tensor &ou
438}452}
439 453 
440void ReduceMeanCodeGen(std::string &dtype_name, const TPipe &tpipe, const Tensor &src, const Tensor &dst,454void ReduceMeanCodeGen(std::string &dtype_name, const TPipe &tpipe, const Tensor &src, const Tensor &dst,
441- std::stringstream &ss) {455+ std::vector<std::string> &lines) {
442 std::set<ascir::AxisId> r_from_axis;456 std::set<ascir::AxisId> r_from_axis;
443 for (size_t i = 0; i < dst.axis_strides.size(); i++) {457 for (size_t i = 0; i < dst.axis_strides.size(); i++) {
444 if ((src.axis_strides[i] != 0 || src.axis_size[i] != 1) && dst.axis_strides[i] == 0) { // 如果目标张量的轴步长为0458 if ((src.axis_strides[i] != 0 || src.axis_size[i] != 1) && dst.axis_strides[i] == 0) { // 如果目标张量的轴步长为0
@@ -459,18 +473,19 @@ void ReduceMeanCodeGen(std::string &dtype_name, const TPipe &tpipe, const Tensor
459 collect_original_axes(axis_id); // 从当前轴开始递归收集473 collect_original_axes(axis_id); // 从当前轴开始递归收集
460 }474 }
461 }475 }
462- ss << "const float dimr_recip = 1.0f / (";476+ std::string dimr_recip_line = "const float dimr_recip = 1.0f / (";
463 uint32_t count = 0;477 uint32_t count = 0;
464 for (auto axis_id : r_from_axis) {478 for (auto axis_id : r_from_axis) {
465 if (count++ == 0) {479 if (count++ == 0) {
466- ss << tpipe.tiler.AxisSize(axis_id);480+ dimr_recip_line += tpipe.tiler.AxisSize(axis_id);
467 } else {481 } else {
468- ss << " * " << tpipe.tiler.AxisSize(axis_id);482+ dimr_recip_line += " * " + tpipe.tiler.AxisSize(axis_id);
469 }483 }
470 }484 }
471- ss << ");" << std::endl;485+ dimr_recip_line += ");\n";
472- ss << "Muls(" << dst << ", " << dst << ", " << "dimr_recip, " << KernelUtils::SizeAlign() << "(" << "reduce_dim_a"486+ lines.emplace_back(dimr_recip_line);
473- << ", 32 / sizeof(" << dtype_name << ")));" << std::endl;487+ lines.emplace_back("Muls(" + dst.Str() + ", " + dst.Str() + ", dimr_recip, " + KernelUtils::SizeAlign()
488+ + "(reduce_dim_a, 32 / sizeof(" + dtype_name + ")));\n");
474 return;489 return;
475}490}
476 491 
@@ -524,31 +539,35 @@ bool IsTilerLastReduceAxis(const Tensor &tensor) {
524 return count == 1;539 return count == 1;
525}540}
526 541 
527-void ReduceInitCodeGen(const Tensor &x, const Tensor &y, const int &type_value, std::stringstream &ss,542+void ReduceInitCodeGen(const Tensor &x, const Tensor &y, const int &type_value,
528- const TPipe &tpipe, const std::string &dtype_name) {543+ std::vector<std::string> &lines, const TPipe &tpipe, const std::string &dtype_name)
544+{
529 if (x.isAr) {545 if (x.isAr) {
530 std::string is_last_axis_str = IsTilerLastReduceAxis(y) ? "true" : "false";546 std::string is_last_axis_str = IsTilerLastReduceAxis(y) ? "true" : "false";
547+ std::stringstream ss;
531 ss << "ReduceInit<" << dtype_name << ", " << type_value << ", " << is_last_axis_str << ">(" << x << ", "548 ss << "ReduceInit<" << dtype_name << ", " << type_value << ", " << is_last_axis_str << ">(" << x << ", "
532 << "first_actual" << ", last" << ", last_actual, " << tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size549 << "first_actual" << ", last" << ", last_actual, " << tpipe.tiler.GetAxis(x.vectorized_axis.back()).actual_size
533 << ");" << std::endl;550 << ");" << std::endl;
534- 551+ lines.emplace_back(ss.str());
535- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;552+ lines.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
536 }553 }
537 return;554 return;
538}555}
539 556 
540-void ReduceDimACodeGen(const Tensor &x, const std::string &apiName, std::stringstream &ss) {557+void ReduceDimACodeGen(const Tensor &x, const std::string &apiName, std::vector<std::string> &lines)
541- if (apiName == "Mean") {558+{
559+ if (apiName == "ReduceMean") {
542 if (x.isAr) {560 if (x.isAr) {
543- ss << "reduce_dim_a = first_actual;" << std::endl;561+ lines.emplace_back("reduce_dim_a = first_actual;\n");
544 } else {562 } else {
545- ss << "reduce_dim_a = last_actual;" << std::endl;563+ lines.emplace_back("reduce_dim_a = last_actual;\n");
546 }564 }
547 }565 }
548 return;566 return;
549}567}
550 568 
551-void GenLastTwoRAxisSizeProductCode(const Tensor &x, const Tensor &y, const TPipe &tpipe, std::stringstream &ss) {569+void GenLastTwoRAxisSizeProductCode(const Tensor &x, const Tensor &y,
570+ const TPipe &tpipe, std::vector<std::string> &lines) {
552 // 收集所有R轴571 // 收集所有R轴
553 std::vector<std::pair<ascir::AxisId, size_t>> r_axes;572 std::vector<std::pair<ascir::AxisId, size_t>> r_axes;
554 573 
@@ -565,17 +584,21 @@ void GenLastTwoRAxisSizeProductCode(const Tensor &x, const Tensor &y, const TPip
565 ascir::AxisId last_r_axis = r_axes[r_axes.size() - 1].first;584 ascir::AxisId last_r_axis = r_axes[r_axes.size() - 1].first;
566 ascir::AxisId second_last_r_axis = r_axes[r_axes.size() - 2].first;585 ascir::AxisId second_last_r_axis = r_axes[r_axes.size() - 2].first;
567 586 
568- ss << "// 最后两个R轴大小的乘积,作为每个核处理的R轴块大小" << std::endl;587+ lines.emplace_back("// 最后两个R轴大小的乘积,作为每个核处理的R轴块大小\n");
588+ std::stringstream ss;
569 ss << "int64_t r_axis_block_size = " << tpipe.tiler.AxisSize(last_r_axis) << " * "589 ss << "int64_t r_axis_block_size = " << tpipe.tiler.AxisSize(last_r_axis) << " * "
570 << tpipe.tiler.AxisSize(second_last_r_axis) << ";" << std::endl;590 << tpipe.tiler.AxisSize(second_last_r_axis) << ";" << std::endl;
591+ lines.emplace_back(ss.str());
571 } else if (r_axes.size() == 1) {592 } else if (r_axes.size() == 1) {
572 // 只有一个R轴593 // 只有一个R轴
573- ss << "// 只有一个R轴,使用其大小作为块大小" << std::endl;594+ lines.emplace_back("// 只有一个R轴,使用其大小作为块大小\n");
595+ std::stringstream ss;
574 ss << "int64_t r_axis_block_size = " << tpipe.tiler.AxisSize(r_axes[0].first) << ";" << std::endl;596 ss << "int64_t r_axis_block_size = " << tpipe.tiler.AxisSize(r_axes[0].first) << ";" << std::endl;
597+ lines.emplace_back(ss.str());
575 } else {598 } else {
576 // 没有R轴(特殊情况)599 // 没有R轴(特殊情况)
577- ss << "// 没有R轴,使用默认值" << std::endl;600+ lines.emplace_back("// 没有R轴,使用默认值\n");
578- ss << "int64_t r_axis_block_size = 1;" << std::endl;601+ lines.emplace_back("int64_t r_axis_block_size = 1;\n");
579 }602 }
580}603}
581 604 
@@ -593,15 +616,15 @@ Status GetDtypeNameForReduce(const std::string &api_name, const Tensor &x, const
593}616}
594 617 
595void GenAccumulatedOffsetDeclForArgMax(const std::string &api_name, const Tensor &x, const Tensor &y,618void GenAccumulatedOffsetDeclForArgMax(const std::string &api_name, const Tensor &x, const Tensor &y,
596- const TPipe &tpipe, std::stringstream &ss) {619+ const TPipe &tpipe, std::vector<std::string> &lines) {
597 // ArgMax 和 ArgMaxMultiRPhase1 需要在循环外声明累加的 offset 变量(使用 static 保存状态)620 // ArgMax 和 ArgMaxMultiRPhase1 需要在循环外声明累加的 offset 变量(使用 static 保存状态)
598 if (api_name == "ArgMax") {621 if (api_name == "ArgMax") {
599- ss << "static int64_t accumulated_offset = 0;" << std::endl;622+ lines.emplace_back("static int64_t accumulated_offset = 0;\n");
600 } else if (api_name == "ArgMaxMultiRPhase1") {623 } else if (api_name == "ArgMaxMultiRPhase1") {
601 // ArgMaxMultiRPhase1的初始offset = block_dim * 最后两个R轴大小的乘积624 // ArgMaxMultiRPhase1的初始offset = block_dim * 最后两个R轴大小的乘积
602 // 使用辅助函数生成计算最后两个R轴大小乘积的代码625 // 使用辅助函数生成计算最后两个R轴大小乘积的代码
603- GenLastTwoRAxisSizeProductCode(x, y, tpipe, ss);626+ GenLastTwoRAxisSizeProductCode(x, y, tpipe, lines);
604- ss << "static int64_t accumulated_offset = 0;" << std::endl;627+ lines.emplace_back("static int64_t accumulated_offset = 0;\n");
605 }628 }
606}629}
607 630 
@@ -43,38 +43,40 @@ struct ReduceCodegenShadowCheckInput {
43};43};
44 44 
45static std::map<std::string, std::pair<int, std::string>> reduce_type_map = {45static std::map<std::string, std::pair<int, std::string>> reduce_type_map = {
46- {"Min", {ReduceOpType::kMin, "Min"}},46+ {"ReduceMin", {ReduceOpType::kMin, "Min"}},
47- {"Max", {ReduceOpType::kMax, "Max"}},47+ {"ReduceMax", {ReduceOpType::kMax, "Max"}},
48- {"ArgMax", {ReduceOpType::kMax, "Max"}},48+ {"ArgMax", {ReduceOpType::kMax, "Max"}},
49- {"ArgMaxMultiRPhase1", {ReduceOpType::kMax, "Max"}},49+ {"ArgMaxMultiRPhase1", {ReduceOpType::kMax, "Max"}},
50- {"ArgMaxMultiRPhase2", {ReduceOpType::kMax, "Max"}},50+ {"ArgMaxMultiRPhase2", {ReduceOpType::kMax, "Max"}},
51- {"Any", {ReduceOpType::kAny, "Max"}},51+ {"ReduceAny", {ReduceOpType::kAny, "Max"}},
52- {"All", {ReduceOpType::kAll, "Min"}},52+ {"ReduceAll", {ReduceOpType::kAll, "Min"}},
53- {"Sum", {ReduceOpType::kSum, "Add"}},53+ {"ReduceSum", {ReduceOpType::kSum, "Add"}},
54- {"Prod", {ReduceOpType::kProd, "Mul"}},54+ {"ReduceProd", {ReduceOpType::kProd, "Mul"}},
55- {"Mean", {ReduceOpType::kMean, "Add"}}};55+ {"ReduceMean", {ReduceOpType::kMean, "Add"}},
56+};
56 57 
57void GetIsArAndPattern(const Tensor &y, bool &isAr, std::string &reduce_pattern);58void GetIsArAndPattern(const Tensor &y, bool &isAr, std::string &reduce_pattern);
58void CheckReduceSpecificParamsForCodegen(const ReduceCodegenShadowCheckInput &input);59void CheckReduceSpecificParamsForCodegen(const ReduceCodegenShadowCheckInput &input);
59-void ReduceMergedSizeCodeGen(const TPipe &tpipe, std::stringstream &ss, const Tensor &src, const Tensor &dst,60+void ReduceMergedSizeCodeGen(const TPipe &tpipe, std::vector<std::string> &lines, const Tensor &src, const Tensor &dst,
60 bool is_tail = false);61 bool is_tail = false);
61bool IsNeedMultiReduce(const Tiler &tiler, const Tensor &input, const Tensor &output, ascir::AxisId axis_id);62bool IsNeedMultiReduce(const Tiler &tiler, const Tensor &input, const Tensor &output, ascir::AxisId axis_id);
62void ReduceMeanCodeGen(std::string &dtype_name, const TPipe &tpipe, const Tensor &src, const Tensor &dst,63void ReduceMeanCodeGen(std::string &dtype_name, const TPipe &tpipe, const Tensor &src, const Tensor &dst,
63- std::stringstream &ss);64+ std::vector<std::string> &lines);
64-void ReduceInitCodeGen(const Tensor &x, const Tensor &y, const int &type_value, std::stringstream &ss,65+void ReduceInitCodeGen(const Tensor &x, const Tensor &y, const int &type_value,
65- const TPipe &tpipe, const std::string &dtype_name);66+ std::vector<std::string> &lines, const TPipe &tpipe, const std::string &dtype_name);
66-void ReduceDimACodeGen(const Tensor &x, const std::string &apiName, std::stringstream &ss);67+void ReduceDimACodeGen(const Tensor &x, const std::string &apiName, std::vector<std::string> &lines);
67Status GetDtypeNameForReduce(const std::string &api_name, const Tensor &x, const Tensor &y, std::string &dtype_name);68Status GetDtypeNameForReduce(const std::string &api_name, const Tensor &x, const Tensor &y, std::string &dtype_name);
68void GenAccumulatedOffsetDeclForArgMax(const std::string &api_name, const Tensor &x, const Tensor &y,69void GenAccumulatedOffsetDeclForArgMax(const std::string &api_name, const Tensor &x, const Tensor &y,
69- const TPipe &tpipe, std::stringstream &ss);70+ const TPipe &tpipe, std::vector<std::string> &lines);
70 71 
71/**72/**
72 * @brief 生成获取最后两个R轴大小乘积的代码字符串73 * @brief 生成获取最后两个R轴大小乘积的代码字符串
73 * @param x 输入张量74 * @param x 输入张量
74 * @param y 输出张量75 * @param y 输出张量
75 * @param tpipe Tiler对象76 * @param tpipe Tiler对象
76- * @param ss 输出字符串流77+ * @param lines 输出代码行集合,每条语句一个 emplace_back
77 */78 */
78-void GenLastTwoRAxisSizeProductCode(const Tensor &x, const Tensor &y, const TPipe &tpipe, std::stringstream &ss);79+void GenLastTwoRAxisSizeProductCode(const Tensor &x, const Tensor &y,
80+ const TPipe &tpipe, std::vector<std::string> &lines);
79} // namespace reduce_base81} // namespace reduce_base
80#endif // __AUTOFUSE_REDUCE_API_CALL_BASE_H__82#endif // __AUTOFUSE_REDUCE_API_CALL_BASE_H__
@@ -19,6 +19,17 @@ using namespace codegen;
19using namespace af::ascir_op;19using namespace af::ascir_op;
20using namespace testing;20using namespace testing;
21 21 
22+namespace {
23+void CheckReduceTailBoolParam(const std::string &result) {
24+ const bool has_argmax_call = (result.find("ArgMaxExtend") != std::string::npos) ||
25+ (result.find("ArgMaxWithValueExtend") != std::string::npos);
26+ const std::string expected_tail = has_argmax_call ? "tmp_reduce_shape, false);" : "tmp_reduce_shape, true);";
27+ const std::string forbidden_tail = has_argmax_call ? "tmp_reduce_shape, true);" : "tmp_reduce_shape, false);";
28+ EXPECT_NE(result.find(expected_tail), std::string::npos);
29+ EXPECT_EQ(result.find(forbidden_tail), std::string::npos);
30+}
31+} // namespace
32+ 
22class ArgMaxApicallTest : public ::testing::Test {33class ArgMaxApicallTest : public ::testing::Test {
23 protected:34 protected:
24 void SetUp() override {}35 void SetUp() override {}
@@ -53,10 +64,13 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMax) {
53 af::AscGraph graph("test");64 af::AscGraph graph("test");
54 af::ascir_op::Data x("x", graph);65 af::ascir_op::Data x("x", graph);
55 af::ascir_op::Data y("y", graph);66 af::ascir_op::Data y("y", graph);
67+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
68+ graph.AddNode(reduce); // 将Reduce节点添加到图中
56 69 
57 auto nodex = graph.FindNode("x");70 auto nodex = graph.FindNode("x");
58 af::AscTensor tensorx = nodex->outputs[0];71 af::AscTensor tensorx = nodex->outputs[0];
59 auto nodey = graph.FindNode("y");72 auto nodey = graph.FindNode("y");
73+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
60 af::AscTensor tensory = nodey->outputs[0];74 af::AscTensor tensory = nodey->outputs[0];
61 75 
62 tensorx.attr.axis = {z0.id, z1.id, z2.id};76 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -111,6 +125,8 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMax) {
111 codegen::ReduceApiCall call(api_name);125 codegen::ReduceApiCall call(api_name);
112 call.unit = af::ComputeUnit::kUnitVector;126 call.unit = af::ComputeUnit::kUnitVector;
113 call.type = "ArgMax";127 call.type = "ArgMax";
128+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
129+ call.node_name = reduce_node->GetName();
114 y_tensor.write = &call;130 y_tensor.write = &call;
115 call.inputs.push_back(&x_tensor);131 call.inputs.push_back(&x_tensor);
116 call.outputs.push_back(y_tensor);132 call.outputs.push_back(y_tensor);
@@ -124,6 +140,7 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMax) {
124 Status status = call.Generate(tpipe, current_axis, result);140 Status status = call.Generate(tpipe, current_axis, result);
125 // Check the result141 // Check the result
126 EXPECT_EQ(status, ge::SUCCESS);142 EXPECT_EQ(status, ge::SUCCESS);
143+ CheckReduceTailBoolParam(result);
127}144}
128 145 
129TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase1) {146TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase1) {
@@ -154,10 +171,13 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase1) {
154 af::AscGraph graph("test");171 af::AscGraph graph("test");
155 af::ascir_op::Data x("x", graph);172 af::ascir_op::Data x("x", graph);
156 af::ascir_op::Data y("y", graph);173 af::ascir_op::Data y("y", graph);
174+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
175+ graph.AddNode(reduce); // 将Reduce节点添加到图中
157 176 
158 auto nodex = graph.FindNode("x");177 auto nodex = graph.FindNode("x");
159 af::AscTensor tensorx = nodex->outputs[0];178 af::AscTensor tensorx = nodex->outputs[0];
160 auto nodey = graph.FindNode("y");179 auto nodey = graph.FindNode("y");
180+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
161 af::AscTensor tensory = nodey->outputs[0];181 af::AscTensor tensory = nodey->outputs[0];
162 182 
163 tensorx.attr.axis = {z0.id, z1.id, z2.id};183 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -236,6 +256,8 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase1) {
236 codegen::ReduceApiCall call(api_name);256 codegen::ReduceApiCall call(api_name);
237 call.unit = af::ComputeUnit::kUnitVector;257 call.unit = af::ComputeUnit::kUnitVector;
238 call.type = "ArgMaxMultiRPhase1";258 call.type = "ArgMaxMultiRPhase1";
259+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
260+ call.node_name = reduce_node->GetName();
239 y_tensor.write = &call;261 y_tensor.write = &call;
240 z_tensor.write = &call;262 z_tensor.write = &call;
241 call.inputs.push_back(&x_tensor);263 call.inputs.push_back(&x_tensor);
@@ -252,6 +274,7 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase1) {
252 Status status = call.Generate(tpipe, current_axis, result);274 Status status = call.Generate(tpipe, current_axis, result);
253 // Check the result275 // Check the result
254 EXPECT_EQ(status, ge::SUCCESS);276 EXPECT_EQ(status, ge::SUCCESS);
277+ CheckReduceTailBoolParam(result);
255}278}
256 279 
257TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase2) {280TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase2) {
@@ -282,10 +305,13 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase2) {
282 af::AscGraph graph("test");305 af::AscGraph graph("test");
283 af::ascir_op::Data x("x", graph);306 af::ascir_op::Data x("x", graph);
284 af::ascir_op::Data y("y", graph);307 af::ascir_op::Data y("y", graph);
308+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
309+ graph.AddNode(reduce); // 将Reduce节点添加到图中
285 310 
286 auto nodex = graph.FindNode("x");311 auto nodex = graph.FindNode("x");
287 af::AscTensor tensorx = nodex->outputs[0];312 af::AscTensor tensorx = nodex->outputs[0];
288 auto nodey = graph.FindNode("y");313 auto nodey = graph.FindNode("y");
314+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
289 af::AscTensor tensory = nodey->outputs[0];315 af::AscTensor tensory = nodey->outputs[0];
290 316 
291 tensorx.attr.axis = {z0.id, z1.id, z2.id};317 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -364,6 +390,8 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase2) {
364 codegen::ReduceApiCall call(api_name);390 codegen::ReduceApiCall call(api_name);
365 call.unit = af::ComputeUnit::kUnitVector;391 call.unit = af::ComputeUnit::kUnitVector;
366 call.type = "ArgMaxMultiRPhase2";392 call.type = "ArgMaxMultiRPhase2";
393+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
394+ call.node_name = reduce_node->GetName();
367 y_tensor.write = &call;395 y_tensor.write = &call;
368 call.inputs.push_back(&x_tensor);396 call.inputs.push_back(&x_tensor);
369 call.inputs.push_back(&z_tensor);397 call.inputs.push_back(&z_tensor);
@@ -379,6 +407,7 @@ TEST_F(ArgMaxApicallTest, ReduceApi_Test_ArgMaxMultiRPhase2) {
379 Status status = call.Generate(tpipe, current_axis, result);407 Status status = call.Generate(tpipe, current_axis, result);
380 // Check the result408 // Check the result
381 EXPECT_EQ(status, ge::SUCCESS);409 EXPECT_EQ(status, ge::SUCCESS);
410+ CheckReduceTailBoolParam(result);
382}411}
383 412 
384TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMax_NoNeed_MultiReduce_Int32) {413TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMax_NoNeed_MultiReduce_Int32) {
@@ -409,10 +438,13 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMax_NoNeed_MultiReduce_Int32) {
409 af::AscGraph graph("test");438 af::AscGraph graph("test");
410 af::ascir_op::Data x("x", graph);439 af::ascir_op::Data x("x", graph);
411 af::ascir_op::Data y("y", graph);440 af::ascir_op::Data y("y", graph);
441+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
442+ graph.AddNode(reduce); // 将Reduce节点添加到图中
412 443 
413 auto nodex = graph.FindNode("x");444 auto nodex = graph.FindNode("x");
414 af::AscTensor tensorx = nodex->outputs[0];445 af::AscTensor tensorx = nodex->outputs[0];
415 auto nodey = graph.FindNode("y");446 auto nodey = graph.FindNode("y");
447+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
416 af::AscTensor tensory = nodey->outputs[0];448 af::AscTensor tensory = nodey->outputs[0];
417 449 
418 tensorx.attr.axis = {z0.id, z1.id, z2.id};450 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -466,6 +498,8 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMax_NoNeed_MultiReduce_Int32) {
466 codegen::ReduceApiCall call(api_name);498 codegen::ReduceApiCall call(api_name);
467 call.unit = af::ComputeUnit::kUnitVector;499 call.unit = af::ComputeUnit::kUnitVector;
468 call.type = "ArgMax";500 call.type = "ArgMax";
501+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
502+ call.node_name = reduce_node->GetName();
469 y_tensor.write = &call;503 y_tensor.write = &call;
470 call.inputs.push_back(&x_tensor);504 call.inputs.push_back(&x_tensor);
471 call.outputs.push_back(y_tensor);505 call.outputs.push_back(y_tensor);
@@ -479,6 +513,7 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMax_NoNeed_MultiReduce_Int32) {
479 Status status = call.Generate(tpipe, current_axis, result);513 Status status = call.Generate(tpipe, current_axis, result);
480 // Check the result514 // Check the result
481 EXPECT_EQ(status, ge::SUCCESS);515 EXPECT_EQ(status, ge::SUCCESS);
516+ CheckReduceTailBoolParam(result);
482}517}
483 518 
484TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase1_NoNeed_MultiReduce_Int32) {519TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase1_NoNeed_MultiReduce_Int32) {
@@ -509,10 +544,13 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase1_NoNeed_MultiReduc
509 af::AscGraph graph("test");544 af::AscGraph graph("test");
510 af::ascir_op::Data x("x", graph);545 af::ascir_op::Data x("x", graph);
511 af::ascir_op::Data y("y", graph);546 af::ascir_op::Data y("y", graph);
547+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
548+ graph.AddNode(reduce); // 将Reduce节点添加到图中
512 549 
513 auto nodex = graph.FindNode("x");550 auto nodex = graph.FindNode("x");
514 af::AscTensor tensorx = nodex->outputs[0];551 af::AscTensor tensorx = nodex->outputs[0];
515 auto nodey = graph.FindNode("y");552 auto nodey = graph.FindNode("y");
553+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
516 af::AscTensor tensory = nodey->outputs[0];554 af::AscTensor tensory = nodey->outputs[0];
517 555 
518 tensorx.attr.axis = {z0.id, z1.id, z2.id};556 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -590,6 +628,8 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase1_NoNeed_MultiReduc
590 codegen::ReduceApiCall call(api_name);628 codegen::ReduceApiCall call(api_name);
591 call.unit = af::ComputeUnit::kUnitVector;629 call.unit = af::ComputeUnit::kUnitVector;
592 call.type = "ArgMaxMultiRPhase1";630 call.type = "ArgMaxMultiRPhase1";
631+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
632+ call.node_name = reduce_node->GetName();
593 y_tensor.write = &call;633 y_tensor.write = &call;
594 z_tensor.write = &call;634 z_tensor.write = &call;
595 call.inputs.push_back(&x_tensor);635 call.inputs.push_back(&x_tensor);
@@ -606,6 +646,7 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase1_NoNeed_MultiReduc
606 Status status = call.Generate(tpipe, current_axis, result);646 Status status = call.Generate(tpipe, current_axis, result);
607 // Check the result647 // Check the result
608 EXPECT_EQ(status, ge::SUCCESS);648 EXPECT_EQ(status, ge::SUCCESS);
649+ CheckReduceTailBoolParam(result);
609}650}
610 651 
611TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase2_NoNeed_MultiReduce_Int32) {652TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase2_NoNeed_MultiReduce_Int32) {
@@ -636,10 +677,13 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase2_NoNeed_MultiReduc
636 af::AscGraph graph("test");677 af::AscGraph graph("test");
637 af::ascir_op::Data x("x", graph);678 af::ascir_op::Data x("x", graph);
638 af::ascir_op::Data y("y", graph);679 af::ascir_op::Data y("y", graph);
680+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
681+ graph.AddNode(reduce); // 将Reduce节点添加到图中
639 682 
640 auto nodex = graph.FindNode("x");683 auto nodex = graph.FindNode("x");
641 af::AscTensor tensorx = nodex->outputs[0];684 af::AscTensor tensorx = nodex->outputs[0];
642 auto nodey = graph.FindNode("y");685 auto nodey = graph.FindNode("y");
686+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
643 af::AscTensor tensory = nodey->outputs[0];687 af::AscTensor tensory = nodey->outputs[0];
644 688 
645 tensorx.attr.axis = {z0.id, z1.id, z2.id};689 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -717,6 +761,8 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase2_NoNeed_MultiReduc
717 codegen::ReduceApiCall call(api_name);761 codegen::ReduceApiCall call(api_name);
718 call.unit = af::ComputeUnit::kUnitVector;762 call.unit = af::ComputeUnit::kUnitVector;
719 call.type = "ArgMaxMultiRPhase2";763 call.type = "ArgMaxMultiRPhase2";
764+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
765+ call.node_name = reduce_node->GetName();
720 y_tensor.write = &call;766 y_tensor.write = &call;
721 call.inputs.push_back(&x_tensor);767 call.inputs.push_back(&x_tensor);
722 call.inputs.push_back(&z_tensor);768 call.inputs.push_back(&z_tensor);
@@ -732,4 +778,5 @@ TEST_F(ArgMaxApicallTest, ReduceApicallTest_ArgMaxMultiRPhase2_NoNeed_MultiReduc
732 Status status = call.Generate(tpipe, current_axis, result);778 Status status = call.Generate(tpipe, current_axis, result);
733 // Check the result779 // Check the result
734 EXPECT_EQ(status, ge::SUCCESS);780 EXPECT_EQ(status, ge::SUCCESS);
781+ CheckReduceTailBoolParam(result);
735}782}
@@ -223,7 +223,7 @@ void SetAscirNodeParamsForTest(const af::AscNodePtr &node, const ascir_param::As
223} // namespace223} // namespace
224 224 
225TEST_F(ReduceApicallTest, ReduceApi_Test_001) {225TEST_F(ReduceApicallTest, ReduceApi_Test_001) {
226- std::string api_name = "Max";226+ std::string api_name = "ReduceMax";
227 227 
228 std::vector<ascir::AxisId> current_axis;228 std::vector<ascir::AxisId> current_axis;
229 std::vector<std::reference_wrapper<const Tensor>> inputs;229 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -250,10 +250,13 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_001) {
250 af::AscGraph graph("test");250 af::AscGraph graph("test");
251 af::ascir_op::Data x("x", graph);251 af::ascir_op::Data x("x", graph);
252 af::ascir_op::Data y("y", graph);252 af::ascir_op::Data y("y", graph);
253+ af::ascir_op::Max reduce("reduce");
254+ graph.AddNode(reduce);
253 255 
254 auto nodex = graph.FindNode("x");256 auto nodex = graph.FindNode("x");
255 af::AscTensor tensorx = nodex->outputs[0];257 af::AscTensor tensorx = nodex->outputs[0];
256 auto nodey = graph.FindNode("y");258 auto nodey = graph.FindNode("y");
259+ auto reduce_node = graph.FindNode("reduce");
257 af::AscTensor tensory = nodey->outputs[0];260 af::AscTensor tensory = nodey->outputs[0];
258 261 
259 tensorx.attr.axis = {z0.id, z1.id, z2.id};262 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -306,6 +309,8 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_001) {
306 codegen::ReduceApiCall call(api_name);309 codegen::ReduceApiCall call(api_name);
307 call.unit = af::ComputeUnit::kUnitVector;310 call.unit = af::ComputeUnit::kUnitVector;
308 call.type = "Max";311 call.type = "Max";
312+ call.node = reduce_node;
313+ call.node_name = reduce_node->GetName();
309 y_tensor.write = &call;314 y_tensor.write = &call;
310 call.inputs.push_back(&x_tensor);315 call.inputs.push_back(&x_tensor);
311 call.outputs.push_back(y_tensor);316 call.outputs.push_back(y_tensor);
@@ -322,7 +327,7 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_001) {
322}327}
323 328 
324TEST_F(ReduceApicallTest, ReduceApi_Test_002) {329TEST_F(ReduceApicallTest, ReduceApi_Test_002) {
325- std::string api_name = "Max";330+ std::string api_name = "ReduceMax";
326 331 
327 std::vector<ascir::AxisId> current_axis;332 std::vector<ascir::AxisId> current_axis;
328 std::vector<std::reference_wrapper<const Tensor>> inputs;333 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -349,10 +354,13 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_002) {
349 af::AscGraph graph("test");354 af::AscGraph graph("test");
350 af::ascir_op::Data x("x", graph);355 af::ascir_op::Data x("x", graph);
351 af::ascir_op::Data y("y", graph);356 af::ascir_op::Data y("y", graph);
357+ af::ascir_op::Max reduce("reduce");
358+ graph.AddNode(reduce);
352 359 
353 auto nodex = graph.FindNode("x");360 auto nodex = graph.FindNode("x");
354 af::AscTensor tensorx = nodex->outputs[0];361 af::AscTensor tensorx = nodex->outputs[0];
355 auto nodey = graph.FindNode("y");362 auto nodey = graph.FindNode("y");
363+ auto reduce_node = graph.FindNode("reduce");
356 af::AscTensor tensory = nodey->outputs[0];364 af::AscTensor tensory = nodey->outputs[0];
357 365 
358 tensorx.attr.axis = {z0.id, z1.id, z2.id};366 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -404,6 +412,8 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_002) {
404 codegen::ReduceApiCall call(api_name);412 codegen::ReduceApiCall call(api_name);
405 call.unit = af::ComputeUnit::kUnitVector;413 call.unit = af::ComputeUnit::kUnitVector;
406 call.type = "Max";414 call.type = "Max";
415+ call.node = reduce_node;
416+ call.node_name = reduce_node->GetName();
407 y_tensor.write = &call;417 y_tensor.write = &call;
408 call.inputs.push_back(&x_tensor);418 call.inputs.push_back(&x_tensor);
409 call.outputs.push_back(y_tensor);419 call.outputs.push_back(y_tensor);
@@ -420,7 +430,7 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_002) {
420}430}
421 431 
422TEST_F(ReduceApicallTest, ReduceApi_Test_003) {432TEST_F(ReduceApicallTest, ReduceApi_Test_003) {
423- std::string api_name = "Max";433+ std::string api_name = "ReduceMax";
424 434 
425 std::vector<ascir::AxisId> current_axis;435 std::vector<ascir::AxisId> current_axis;
426 std::vector<std::reference_wrapper<const Tensor>> inputs;436 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -451,10 +461,13 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_003) {
451 af::AscGraph graph("test");461 af::AscGraph graph("test");
452 af::ascir_op::Data x("x", graph);462 af::ascir_op::Data x("x", graph);
453 af::ascir_op::Data y("y", graph);463 af::ascir_op::Data y("y", graph);
464+ af::ascir_op::Max reduce("reduce");
465+ graph.AddNode(reduce);
454 466 
455 auto nodex = graph.FindNode("x");467 auto nodex = graph.FindNode("x");
456 af::AscTensor tensorx = nodex->outputs[0];468 af::AscTensor tensorx = nodex->outputs[0];
457 auto nodey = graph.FindNode("y");469 auto nodey = graph.FindNode("y");
470+ auto reduce_node = graph.FindNode("reduce");
458 af::AscTensor tensory = nodey->outputs[0];471 af::AscTensor tensory = nodey->outputs[0];
459 472 
460 tensorx.attr.axis = {z0.id, z1.id, z2.id, z3.id};473 tensorx.attr.axis = {z0.id, z1.id, z2.id, z3.id};
@@ -507,6 +520,8 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_003) {
507 codegen::ReduceApiCall call(api_name);520 codegen::ReduceApiCall call(api_name);
508 call.unit = af::ComputeUnit::kUnitVector;521 call.unit = af::ComputeUnit::kUnitVector;
509 call.type = "Max";522 call.type = "Max";
523+ call.node = reduce_node;
524+ call.node_name = reduce_node->GetName();
510 y_tensor.write = &call;525 y_tensor.write = &call;
511 call.inputs.push_back(&x_tensor);526 call.inputs.push_back(&x_tensor);
512 call.outputs.push_back(y_tensor);527 call.outputs.push_back(y_tensor);
@@ -523,7 +538,7 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_003) {
523}538}
524 539 
525TEST_F(ReduceApicallTest, ReduceApi_Test_004) {540TEST_F(ReduceApicallTest, ReduceApi_Test_004) {
526- std::string api_name = "Max";541+ std::string api_name = "ReduceMax";
527 542 
528 std::vector<ascir::AxisId> current_axis;543 std::vector<ascir::AxisId> current_axis;
529 std::vector<std::reference_wrapper<const Tensor>> inputs;544 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -550,10 +565,13 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_004) {
550 af::AscGraph graph("test");565 af::AscGraph graph("test");
551 af::ascir_op::Data x("x", graph);566 af::ascir_op::Data x("x", graph);
552 af::ascir_op::Data y("y", graph);567 af::ascir_op::Data y("y", graph);
568+ af::ascir_op::Max reduce("reduce");
569+ graph.AddNode(reduce);
553 570 
554 auto nodex = graph.FindNode("x");571 auto nodex = graph.FindNode("x");
555 af::AscTensor tensorx = nodex->outputs[0];572 af::AscTensor tensorx = nodex->outputs[0];
556 auto nodey = graph.FindNode("y");573 auto nodey = graph.FindNode("y");
574+ auto reduce_node = graph.FindNode("reduce");
557 af::AscTensor tensory = nodey->outputs[0];575 af::AscTensor tensory = nodey->outputs[0];
558 576 
559 tensorx.attr.axis = {z0.id, z1.id, z2.id};577 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -606,6 +624,8 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_004) {
606 codegen::ReduceApiCall call(api_name);624 codegen::ReduceApiCall call(api_name);
607 call.unit = af::ComputeUnit::kUnitVector;625 call.unit = af::ComputeUnit::kUnitVector;
608 call.type = "Max";626 call.type = "Max";
627+ call.node = reduce_node;
628+ call.node_name = reduce_node->GetName();
609 y_tensor.write = &call;629 y_tensor.write = &call;
610 call.inputs.push_back(&x_tensor);630 call.inputs.push_back(&x_tensor);
611 call.outputs.push_back(y_tensor);631 call.outputs.push_back(y_tensor);
@@ -622,7 +642,7 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_004) {
622}642}
623 643 
624TEST_F(ReduceApicallTest, ReduceApi_Test_All_Reduce) {644TEST_F(ReduceApicallTest, ReduceApi_Test_All_Reduce) {
625- std::string api_name = "Max";645+ std::string api_name = "ReduceMax";
626 646 
627 std::vector<ascir::AxisId> current_axis;647 std::vector<ascir::AxisId> current_axis;
628 std::vector<std::reference_wrapper<const Tensor>> inputs;648 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -649,11 +669,14 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_All_Reduce) {
649 af::AscGraph graph("test");669 af::AscGraph graph("test");
650 af::ascir_op::Data x("x", graph);670 af::ascir_op::Data x("x", graph);
651 af::ascir_op::Data y("y", graph);671 af::ascir_op::Data y("y", graph);
672+ af::ascir_op::Max reduce("reduce");
673+ graph.AddNode(reduce);
652 674 
653 auto nodex = graph.FindNode("x");675 auto nodex = graph.FindNode("x");
654 nodex->attr.tmp_buffers = {{{af::Symbol(8192), -1}, af::MemAttr(), 0}};676 nodex->attr.tmp_buffers = {{{af::Symbol(8192), -1}, af::MemAttr(), 0}};
655 af::AscTensor tensorx = nodex->outputs[0];677 af::AscTensor tensorx = nodex->outputs[0];
656 auto nodey = graph.FindNode("y");678 auto nodey = graph.FindNode("y");
679+ auto reduce_node = graph.FindNode("reduce");
657 af::AscTensor tensory = nodey->outputs[0];680 af::AscTensor tensory = nodey->outputs[0];
658 681 
659 tensorx.attr.axis = {z0.id, z1.id, z2.id};682 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -706,6 +729,8 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_All_Reduce) {
706 codegen::ReduceApiCall call(api_name);729 codegen::ReduceApiCall call(api_name);
707 call.unit = af::ComputeUnit::kUnitVector;730 call.unit = af::ComputeUnit::kUnitVector;
708 call.type = "Max";731 call.type = "Max";
732+ call.node = reduce_node;
733+ call.node_name = reduce_node->GetName();
709 y_tensor.write = &call;734 y_tensor.write = &call;
710 call.inputs.push_back(&x_tensor);735 call.inputs.push_back(&x_tensor);
711 call.outputs.push_back(y_tensor);736 call.outputs.push_back(y_tensor);
@@ -730,7 +755,7 @@ TEST_F(ReduceApicallTest, ReduceApi_Test_All_Reduce) {
730}755}
731 756 
732TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Inner) {757TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Inner) {
733- std::string api_name = "Sum";758+ std::string api_name = "ReduceSum";
734 759 
735 std::vector<ascir::AxisId> current_axis;760 std::vector<ascir::AxisId> current_axis;
736 std::vector<std::reference_wrapper<const Tensor>> inputs;761 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -757,10 +782,13 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Inner) {
757 af::AscGraph graph("test");782 af::AscGraph graph("test");
758 af::ascir_op::Data x("x", graph);783 af::ascir_op::Data x("x", graph);
759 af::ascir_op::Data y("y", graph);784 af::ascir_op::Data y("y", graph);
785+ af::ascir_op::Sum reduce("reduce");
786+ graph.AddNode(reduce);
760 787 
761 auto nodex = graph.FindNode("x");788 auto nodex = graph.FindNode("x");
762 af::AscTensor tensorx = nodex->outputs[0];789 af::AscTensor tensorx = nodex->outputs[0];
763 auto nodey = graph.FindNode("y");790 auto nodey = graph.FindNode("y");
791+ auto reduce_node = graph.FindNode("reduce");
764 af::AscTensor tensory = nodey->outputs[0];792 af::AscTensor tensory = nodey->outputs[0];
765 793 
766 tensorx.attr.axis = {z0.id, z1.id, z2.id};794 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -815,6 +843,8 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Inner) {
815 codegen::ReduceApiCall call(api_name);843 codegen::ReduceApiCall call(api_name);
816 call.unit = af::ComputeUnit::kUnitVector;844 call.unit = af::ComputeUnit::kUnitVector;
817 call.type = "Sum";845 call.type = "Sum";
846+ call.node = reduce_node;
847+ call.node_name = reduce_node->GetName();
818 y_tensor.write = &call;848 y_tensor.write = &call;
819 call.inputs.push_back(&x_tensor);849 call.inputs.push_back(&x_tensor);
820 call.outputs.push_back(y_tensor);850 call.outputs.push_back(y_tensor);
@@ -831,7 +861,7 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Inner) {
831}861}
832 862 
833TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Outer) {863TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Outer) {
834- std::string api_name = "Sum";864+ std::string api_name = "ReduceSum";
835 865 
836 std::vector<ascir::AxisId> current_axis;866 std::vector<ascir::AxisId> current_axis;
837 std::vector<std::reference_wrapper<const Tensor>> inputs;867 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -858,10 +888,13 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Outer) {
858 af::AscGraph graph("test");888 af::AscGraph graph("test");
859 af::ascir_op::Data x("x", graph);889 af::ascir_op::Data x("x", graph);
860 af::ascir_op::Data y("y", graph);890 af::ascir_op::Data y("y", graph);
891+ af::ascir_op::Sum reduce("reduce");
892+ graph.AddNode(reduce);
861 893 
862 auto nodex = graph.FindNode("x");894 auto nodex = graph.FindNode("x");
863 af::AscTensor tensorx = nodex->outputs[0];895 af::AscTensor tensorx = nodex->outputs[0];
864 auto nodey = graph.FindNode("y");896 auto nodey = graph.FindNode("y");
897+ auto reduce_node = graph.FindNode("reduce");
865 af::AscTensor tensory = nodey->outputs[0];898 af::AscTensor tensory = nodey->outputs[0];
866 899 
867 tensorx.attr.axis = {z0.id, z1.id, z2.id};900 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -916,6 +949,8 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Outer) {
916 codegen::ReduceApiCall call(api_name);949 codegen::ReduceApiCall call(api_name);
917 call.unit = af::ComputeUnit::kUnitVector;950 call.unit = af::ComputeUnit::kUnitVector;
918 call.type = "Sum";951 call.type = "Sum";
952+ call.node = reduce_node;
953+ call.node_name = reduce_node->GetName();
919 y_tensor.write = &call;954 y_tensor.write = &call;
920 call.inputs.push_back(&x_tensor);955 call.inputs.push_back(&x_tensor);
921 call.outputs.push_back(y_tensor);956 call.outputs.push_back(y_tensor);
@@ -932,7 +967,7 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_Int32_Outer) {
932}967}
933 968 
934TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32) {969TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32) {
935- std::string api_name = "Mean";970+ std::string api_name = "ReduceMean";
936 971 
937 std::vector<ascir::AxisId> current_axis;972 std::vector<ascir::AxisId> current_axis;
938 std::vector<std::reference_wrapper<const Tensor>> inputs;973 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -959,10 +994,13 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32)
959 af::AscGraph graph("test");994 af::AscGraph graph("test");
960 af::ascir_op::Data x("x", graph);995 af::ascir_op::Data x("x", graph);
961 af::ascir_op::Data y("y", graph);996 af::ascir_op::Data y("y", graph);
997+ af::ascir_op::Sum reduce("reduce");
998+ graph.AddNode(reduce);
962 999 
963 auto nodex = graph.FindNode("x");1000 auto nodex = graph.FindNode("x");
964 af::AscTensor tensorx = nodex->outputs[0];1001 af::AscTensor tensorx = nodex->outputs[0];
965 auto nodey = graph.FindNode("y");1002 auto nodey = graph.FindNode("y");
1003+ auto reduce_node = graph.FindNode("reduce");
966 af::AscTensor tensory = nodey->outputs[0];1004 af::AscTensor tensory = nodey->outputs[0];
967 1005 
968 tensorx.attr.axis = {z0.id, z1.id, z2.id};1006 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -1017,6 +1055,8 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32)
1017 codegen::ReduceApiCall call(api_name);1055 codegen::ReduceApiCall call(api_name);
1018 call.unit = af::ComputeUnit::kUnitVector;1056 call.unit = af::ComputeUnit::kUnitVector;
1019 call.type = "Mean";1057 call.type = "Mean";
1058+ call.node = reduce_node;
1059+ call.node_name = reduce_node->GetName();
1020 y_tensor.write = &call;1060 y_tensor.write = &call;
1021 call.inputs.push_back(&x_tensor);1061 call.inputs.push_back(&x_tensor);
1022 call.outputs.push_back(y_tensor);1062 call.outputs.push_back(y_tensor);
@@ -1033,7 +1073,7 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32)
1033}1073}
1034 1074 
1035TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float) {1075TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float) {
1036- std::string api_name = "Mean";1076+ std::string api_name = "ReduceMean";
1037 1077 
1038 std::vector<ascir::AxisId> current_axis;1078 std::vector<ascir::AxisId> current_axis;
1039 std::vector<std::reference_wrapper<const Tensor>> inputs;1079 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -1060,10 +1100,13 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float)
1060 af::AscGraph graph("test");1100 af::AscGraph graph("test");
1061 af::ascir_op::Data x("x", graph);1101 af::ascir_op::Data x("x", graph);
1062 af::ascir_op::Data y("y", graph);1102 af::ascir_op::Data y("y", graph);
1103+ af::ascir_op::Sum reduce("reduce");
1104+ graph.AddNode(reduce);
1063 1105 
1064 auto nodex = graph.FindNode("x");1106 auto nodex = graph.FindNode("x");
1065 af::AscTensor tensorx = nodex->outputs[0];1107 af::AscTensor tensorx = nodex->outputs[0];
1066 auto nodey = graph.FindNode("y");1108 auto nodey = graph.FindNode("y");
1109+ auto reduce_node = graph.FindNode("reduce");
1067 af::AscTensor tensory = nodey->outputs[0];1110 af::AscTensor tensory = nodey->outputs[0];
1068 1111 
1069 tensorx.attr.axis = {z0.id, z1.id, z2.id};1112 tensorx.attr.axis = {z0.id, z1.id, z2.id};
@@ -1118,6 +1161,8 @@ TEST_F(ReduceApicallTest, ReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float)
1118 codegen::ReduceApiCall call(api_name);1161 codegen::ReduceApiCall call(api_name);
1119 call.unit = af::ComputeUnit::kUnitVector;1162 call.unit = af::ComputeUnit::kUnitVector;
1120 call.type = "Mean";1163 call.type = "Mean";
1164+ call.node = reduce_node;
1165+ call.node_name = reduce_node->GetName();
1121 y_tensor.write = &call;1166 y_tensor.write = &call;
1122 call.inputs.push_back(&x_tensor);1167 call.inputs.push_back(&x_tensor);
1123 call.outputs.push_back(y_tensor);1168 call.outputs.push_back(y_tensor);
@@ -37,7 +37,7 @@ class RegReduceApicallTest : public ::testing::Test {
37};37};
38 38 
39TEST_F(RegReduceApicallTest, RegReduceApi_Test_001) {39TEST_F(RegReduceApicallTest, RegReduceApi_Test_001) {
40- std::string api_name = "Max";40+ std::string api_name = "ReduceMax";
41 41 
42 std::vector<ascir::AxisId> current_axis;42 std::vector<ascir::AxisId> current_axis;
43 std::vector<std::reference_wrapper<const Tensor>> inputs;43 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -64,11 +64,14 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_001) {
64 af::AscGraph graph("test");64 af::AscGraph graph("test");
65 af::ascir_op::Data x("x", graph);65 af::ascir_op::Data x("x", graph);
66 af::ascir_op::Data y("y", graph);66 af::ascir_op::Data y("y", graph);
67+ af::ascir_op::Max reduce("reduce");
68+ graph.AddNode(reduce);
67 69 
68 auto nodex = graph.FindNode("x");70 auto nodex = graph.FindNode("x");
69 af::AscTensor tensorx = nodex->outputs[0];71 af::AscTensor tensorx = nodex->outputs[0];
70 auto nodey = graph.FindNode("y");72 auto nodey = graph.FindNode("y");
71 af::AscTensor tensory = nodey->outputs[0];73 af::AscTensor tensory = nodey->outputs[0];
74+ auto reduce_node = graph.FindNode("reduce");
72 75 
73 tensorx.attr.axis = {z0.id, z1.id, z2.id};76 tensorx.attr.axis = {z0.id, z1.id, z2.id};
74 tensorx.attr.vectorized_axis = {z0.id, z2.id};77 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -120,6 +123,8 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_001) {
120 codegen::RegReduceApiCall call(api_name);123 codegen::RegReduceApiCall call(api_name);
121 call.unit = af::ComputeUnit::kUnitVector;124 call.unit = af::ComputeUnit::kUnitVector;
122 call.type = "Max";125 call.type = "Max";
126+ call.node = reduce_node;
127+ call.node_name = reduce_node->GetName();
123 y_tensor.write = &call;128 y_tensor.write = &call;
124 call.inputs.push_back(&x_tensor);129 call.inputs.push_back(&x_tensor);
125 call.outputs.push_back(y_tensor);130 call.outputs.push_back(y_tensor);
@@ -141,7 +146,7 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_001) {
141}146}
142 147 
143TEST_F(RegReduceApicallTest, RegReduceApi_Test_002) {148TEST_F(RegReduceApicallTest, RegReduceApi_Test_002) {
144- std::string api_name = "Max";149+ std::string api_name = "ReduceMax";
145 150 
146 std::vector<ascir::AxisId> current_axis;151 std::vector<ascir::AxisId> current_axis;
147 std::vector<std::reference_wrapper<const Tensor>> inputs;152 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -168,11 +173,14 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_002) {
168 af::AscGraph graph("test");173 af::AscGraph graph("test");
169 af::ascir_op::Data x("x", graph);174 af::ascir_op::Data x("x", graph);
170 af::ascir_op::Data y("y", graph);175 af::ascir_op::Data y("y", graph);
176+ af::ascir_op::Max reduce("reduce");
177+ graph.AddNode(reduce);
171 178 
172 auto nodex = graph.FindNode("x");179 auto nodex = graph.FindNode("x");
173 af::AscTensor tensorx = nodex->outputs[0];180 af::AscTensor tensorx = nodex->outputs[0];
174 auto nodey = graph.FindNode("y");181 auto nodey = graph.FindNode("y");
175 af::AscTensor tensory = nodey->outputs[0];182 af::AscTensor tensory = nodey->outputs[0];
183+ auto reduce_node = graph.FindNode("reduce");
176 184 
177 tensorx.attr.axis = {z0.id, z1.id, z2.id};185 tensorx.attr.axis = {z0.id, z1.id, z2.id};
178 tensorx.attr.vectorized_axis = {z0.id, z2.id};186 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -223,6 +231,8 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_002) {
223 codegen::RegReduceApiCall call(api_name);231 codegen::RegReduceApiCall call(api_name);
224 call.unit = af::ComputeUnit::kUnitVector;232 call.unit = af::ComputeUnit::kUnitVector;
225 call.type = "Max";233 call.type = "Max";
234+ call.node = reduce_node;
235+ call.node_name = reduce_node->GetName();
226 y_tensor.write = &call;236 y_tensor.write = &call;
227 call.inputs.push_back(&x_tensor);237 call.inputs.push_back(&x_tensor);
228 call.outputs.push_back(y_tensor);238 call.outputs.push_back(y_tensor);
@@ -239,7 +249,7 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_002) {
239}249}
240 250 
241TEST_F(RegReduceApicallTest, RegReduceApi_Test_003) {251TEST_F(RegReduceApicallTest, RegReduceApi_Test_003) {
242- std::string api_name = "Max";252+ std::string api_name = "ReduceMax";
243 253 
244 std::vector<ascir::AxisId> current_axis;254 std::vector<ascir::AxisId> current_axis;
245 std::vector<std::reference_wrapper<const Tensor>> inputs;255 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -270,11 +280,14 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_003) {
270 af::AscGraph graph("test");280 af::AscGraph graph("test");
271 af::ascir_op::Data x("x", graph);281 af::ascir_op::Data x("x", graph);
272 af::ascir_op::Data y("y", graph);282 af::ascir_op::Data y("y", graph);
283+ af::ascir_op::Max reduce("reduce");
284+ graph.AddNode(reduce);
273 285 
274 auto nodex = graph.FindNode("x");286 auto nodex = graph.FindNode("x");
275 af::AscTensor tensorx = nodex->outputs[0];287 af::AscTensor tensorx = nodex->outputs[0];
276 auto nodey = graph.FindNode("y");288 auto nodey = graph.FindNode("y");
277 af::AscTensor tensory = nodey->outputs[0];289 af::AscTensor tensory = nodey->outputs[0];
290+ auto reduce_node = graph.FindNode("reduce");
278 291 
279 tensorx.attr.axis = {z0.id, z1.id, z2.id, z3.id};292 tensorx.attr.axis = {z0.id, z1.id, z2.id, z3.id};
280 tensorx.attr.vectorized_axis = {z0.id, z2.id, z3.id};293 tensorx.attr.vectorized_axis = {z0.id, z2.id, z3.id};
@@ -326,6 +339,8 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_003) {
326 codegen::RegReduceApiCall call(api_name);339 codegen::RegReduceApiCall call(api_name);
327 call.unit = af::ComputeUnit::kUnitVector;340 call.unit = af::ComputeUnit::kUnitVector;
328 call.type = "Max";341 call.type = "Max";
342+ call.node = reduce_node;
343+ call.node_name = reduce_node->GetName();
329 y_tensor.write = &call;344 y_tensor.write = &call;
330 call.inputs.push_back(&x_tensor);345 call.inputs.push_back(&x_tensor);
331 call.outputs.push_back(y_tensor);346 call.outputs.push_back(y_tensor);
@@ -342,7 +357,7 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_003) {
342}357}
343 358 
344TEST_F(RegReduceApicallTest, RegReduceApi_Test_004) {359TEST_F(RegReduceApicallTest, RegReduceApi_Test_004) {
345- std::string api_name = "Max";360+ std::string api_name = "ReduceMax";
346 361 
347 std::vector<ascir::AxisId> current_axis;362 std::vector<ascir::AxisId> current_axis;
348 std::vector<std::reference_wrapper<const Tensor>> inputs;363 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -369,11 +384,13 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_004) {
369 af::AscGraph graph("test");384 af::AscGraph graph("test");
370 af::ascir_op::Data x("x", graph);385 af::ascir_op::Data x("x", graph);
371 af::ascir_op::Data y("y", graph);386 af::ascir_op::Data y("y", graph);
387+ af::ascir_op::Max reduce("reduce"); graph.AddNode(reduce);
372 388 
373 auto nodex = graph.FindNode("x");389 auto nodex = graph.FindNode("x");
374 af::AscTensor tensorx = nodex->outputs[0];390 af::AscTensor tensorx = nodex->outputs[0];
375 auto nodey = graph.FindNode("y");391 auto nodey = graph.FindNode("y");
376 af::AscTensor tensory = nodey->outputs[0];392 af::AscTensor tensory = nodey->outputs[0];
393+ auto reduce_node = graph.FindNode("reduce");
377 394 
378 tensorx.attr.axis = {z0.id, z1.id, z2.id};395 tensorx.attr.axis = {z0.id, z1.id, z2.id};
379 tensorx.attr.vectorized_axis = {z0.id, z2.id};396 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -425,6 +442,8 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_004) {
425 codegen::RegReduceApiCall call(api_name);442 codegen::RegReduceApiCall call(api_name);
426 call.unit = af::ComputeUnit::kUnitVector;443 call.unit = af::ComputeUnit::kUnitVector;
427 call.type = "Max";444 call.type = "Max";
445+ call.node = reduce_node;
446+ call.node_name = reduce_node->GetName();
428 y_tensor.write = &call;447 y_tensor.write = &call;
429 call.inputs.push_back(&x_tensor);448 call.inputs.push_back(&x_tensor);
430 call.outputs.push_back(y_tensor);449 call.outputs.push_back(y_tensor);
@@ -441,7 +460,7 @@ TEST_F(RegReduceApicallTest, RegReduceApi_Test_004) {
441}460}
442 461 
443TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Inner) {462TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Inner) {
444- std::string api_name = "Sum";463+ std::string api_name = "ReduceSum";
445 464 
446 std::vector<ascir::AxisId> current_axis;465 std::vector<ascir::AxisId> current_axis;
447 std::vector<std::reference_wrapper<const Tensor>> inputs;466 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -468,11 +487,13 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Inner) {
468 af::AscGraph graph("test");487 af::AscGraph graph("test");
469 af::ascir_op::Data x("x", graph);488 af::ascir_op::Data x("x", graph);
470 af::ascir_op::Data y("y", graph);489 af::ascir_op::Data y("y", graph);
490+ af::ascir_op::Sum reduce("reduce"); graph.AddNode(reduce);
471 491 
472 auto nodex = graph.FindNode("x");492 auto nodex = graph.FindNode("x");
473 af::AscTensor tensorx = nodex->outputs[0];493 af::AscTensor tensorx = nodex->outputs[0];
474 auto nodey = graph.FindNode("y");494 auto nodey = graph.FindNode("y");
475 af::AscTensor tensory = nodey->outputs[0];495 af::AscTensor tensory = nodey->outputs[0];
496+ auto reduce_node = graph.FindNode("reduce");
476 497 
477 tensorx.attr.axis = {z0.id, z1.id, z2.id};498 tensorx.attr.axis = {z0.id, z1.id, z2.id};
478 tensorx.attr.vectorized_axis = {z0.id, z2.id};499 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -526,6 +547,8 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Inner) {
526 codegen::RegReduceApiCall call(api_name);547 codegen::RegReduceApiCall call(api_name);
527 call.unit = af::ComputeUnit::kUnitVector;548 call.unit = af::ComputeUnit::kUnitVector;
528 call.type = "Sum";549 call.type = "Sum";
550+ call.node = reduce_node;
551+ call.node_name = reduce_node->GetName();
529 y_tensor.write = &call;552 y_tensor.write = &call;
530 call.inputs.push_back(&x_tensor);553 call.inputs.push_back(&x_tensor);
531 call.outputs.push_back(y_tensor);554 call.outputs.push_back(y_tensor);
@@ -542,7 +565,7 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Inner) {
542}565}
543 566 
544TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Outer) {567TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Outer) {
545- std::string api_name = "Sum";568+ std::string api_name = "ReduceSum";
546 569 
547 std::vector<ascir::AxisId> current_axis;570 std::vector<ascir::AxisId> current_axis;
548 std::vector<std::reference_wrapper<const Tensor>> inputs;571 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -569,11 +592,13 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Outer) {
569 af::AscGraph graph("test");592 af::AscGraph graph("test");
570 af::ascir_op::Data x("x", graph);593 af::ascir_op::Data x("x", graph);
571 af::ascir_op::Data y("y", graph);594 af::ascir_op::Data y("y", graph);
595+ af::ascir_op::Sum reduce("reduce"); graph.AddNode(reduce);
572 596 
573 auto nodex = graph.FindNode("x");597 auto nodex = graph.FindNode("x");
574 af::AscTensor tensorx = nodex->outputs[0];598 af::AscTensor tensorx = nodex->outputs[0];
575 auto nodey = graph.FindNode("y");599 auto nodey = graph.FindNode("y");
576 af::AscTensor tensory = nodey->outputs[0];600 af::AscTensor tensory = nodey->outputs[0];
601+ auto reduce_node = graph.FindNode("reduce");
577 602 
578 tensorx.attr.axis = {z0.id, z1.id, z2.id};603 tensorx.attr.axis = {z0.id, z1.id, z2.id};
579 tensorx.attr.vectorized_axis = {z0.id, z2.id};604 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -627,6 +652,8 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Outer) {
627 codegen::RegReduceApiCall call(api_name);652 codegen::RegReduceApiCall call(api_name);
628 call.unit = af::ComputeUnit::kUnitVector;653 call.unit = af::ComputeUnit::kUnitVector;
629 call.type = "Sum";654 call.type = "Sum";
655+ call.node = reduce_node;
656+ call.node_name = reduce_node->GetName();
630 y_tensor.write = &call;657 y_tensor.write = &call;
631 call.inputs.push_back(&x_tensor);658 call.inputs.push_back(&x_tensor);
632 call.outputs.push_back(y_tensor);659 call.outputs.push_back(y_tensor);
@@ -643,7 +670,7 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_Int32_Outer) {
643}670}
644 671 
645TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32) {672TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Int32) {
646- std::string api_name = "Mean";673+ std::string api_name = "ReduceMean";
647 674 
648 std::vector<ascir::AxisId> current_axis;675 std::vector<ascir::AxisId> current_axis;
649 std::vector<std::reference_wrapper<const Tensor>> inputs;676 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -670,11 +697,13 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_
670 af::AscGraph graph("test");697 af::AscGraph graph("test");
671 af::ascir_op::Data x("x", graph);698 af::ascir_op::Data x("x", graph);
672 af::ascir_op::Data y("y", graph);699 af::ascir_op::Data y("y", graph);
700+ af::ascir_op::Sum reduce("reduce"); graph.AddNode(reduce);
673 701 
674 auto nodex = graph.FindNode("x");702 auto nodex = graph.FindNode("x");
675 af::AscTensor tensorx = nodex->outputs[0];703 af::AscTensor tensorx = nodex->outputs[0];
676 auto nodey = graph.FindNode("y");704 auto nodey = graph.FindNode("y");
677 af::AscTensor tensory = nodey->outputs[0];705 af::AscTensor tensory = nodey->outputs[0];
706+ auto reduce_node = graph.FindNode("reduce");
678 707 
679 tensorx.attr.axis = {z0.id, z1.id, z2.id};708 tensorx.attr.axis = {z0.id, z1.id, z2.id};
680 tensorx.attr.vectorized_axis = {z1.id, z2.id};709 tensorx.attr.vectorized_axis = {z1.id, z2.id};
@@ -728,6 +757,8 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_
728 codegen::RegReduceApiCall call(api_name);757 codegen::RegReduceApiCall call(api_name);
729 call.unit = af::ComputeUnit::kUnitVector;758 call.unit = af::ComputeUnit::kUnitVector;
730 call.type = "Mean";759 call.type = "Mean";
760+ call.node = reduce_node;
761+ call.node_name = reduce_node->GetName();
731 y_tensor.write = &call;762 y_tensor.write = &call;
732 call.inputs.push_back(&x_tensor);763 call.inputs.push_back(&x_tensor);
733 call.outputs.push_back(y_tensor);764 call.outputs.push_back(y_tensor);
@@ -744,7 +775,7 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_
744}775}
745 776 
746TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float) {777TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_Float) {
747- std::string api_name = "Mean";778+ std::string api_name = "ReduceMean";
748 779 
749 std::vector<ascir::AxisId> current_axis;780 std::vector<ascir::AxisId> current_axis;
750 std::vector<std::reference_wrapper<const Tensor>> inputs;781 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -771,11 +802,13 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_
771 af::AscGraph graph("test");802 af::AscGraph graph("test");
772 af::ascir_op::Data x("x", graph);803 af::ascir_op::Data x("x", graph);
773 af::ascir_op::Data y("y", graph);804 af::ascir_op::Data y("y", graph);
805+ af::ascir_op::Sum reduce("reduce"); graph.AddNode(reduce);
774 806 
775 auto nodex = graph.FindNode("x");807 auto nodex = graph.FindNode("x");
776 af::AscTensor tensorx = nodex->outputs[0];808 af::AscTensor tensorx = nodex->outputs[0];
777 auto nodey = graph.FindNode("y");809 auto nodey = graph.FindNode("y");
778 af::AscTensor tensory = nodey->outputs[0];810 af::AscTensor tensory = nodey->outputs[0];
811+ auto reduce_node = graph.FindNode("reduce");
779 812 
780 tensorx.attr.axis = {z0.id, z1.id, z2.id};813 tensorx.attr.axis = {z0.id, z1.id, z2.id};
781 tensorx.attr.vectorized_axis = {z1.id, z2.id};814 tensorx.attr.vectorized_axis = {z1.id, z2.id};
@@ -829,6 +862,8 @@ TEST_F(RegReduceApicallTest, RegReduceApicallTest_ReduceMean_NoNeed_MultiReduce_
829 codegen::RegReduceApiCall call(api_name);862 codegen::RegReduceApiCall call(api_name);
830 call.unit = af::ComputeUnit::kUnitVector;863 call.unit = af::ComputeUnit::kUnitVector;
831 call.type = "Mean";864 call.type = "Mean";
865+ call.node = reduce_node;
866+ call.node_name = reduce_node->GetName();
832 y_tensor.write = &call;867 y_tensor.write = &call;
833 call.inputs.push_back(&x_tensor);868 call.inputs.push_back(&x_tensor);
834 call.outputs.push_back(y_tensor);869 call.outputs.push_back(y_tensor);
@@ -37,7 +37,7 @@ class RegReduceMaxApicallTest : public ::testing::Test {
37 37 
38// Test Max with INT8 type38// Test Max with INT8 type
39TEST_F(RegReduceMaxApicallTest, Max_INT8) {39TEST_F(RegReduceMaxApicallTest, Max_INT8) {
40- std::string api_name = "Max";40+ std::string api_name = "ReduceMax";
41 41 
42 std::vector<ascir::AxisId> current_axis;42 std::vector<ascir::AxisId> current_axis;
43 std::vector<std::reference_wrapper<const Tensor>> inputs;43 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -64,11 +64,14 @@ TEST_F(RegReduceMaxApicallTest, Max_INT8) {
64 af::AscGraph graph("test");64 af::AscGraph graph("test");
65 af::ascir_op::Data x("x", graph);65 af::ascir_op::Data x("x", graph);
66 af::ascir_op::Data y("y", graph);66 af::ascir_op::Data y("y", graph);
67+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
68+ graph.AddNode(reduce); // 将Reduce节点添加到图中
67 69 
68 auto nodex = graph.FindNode("x");70 auto nodex = graph.FindNode("x");
69 af::AscTensor tensorx = nodex->outputs[0];71 af::AscTensor tensorx = nodex->outputs[0];
70 auto nodey = graph.FindNode("y");72 auto nodey = graph.FindNode("y");
71 af::AscTensor tensory = nodey->outputs[0];73 af::AscTensor tensory = nodey->outputs[0];
74+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
72 75 
73 tensorx.attr.axis = {z0.id, z1.id, z2.id};76 tensorx.attr.axis = {z0.id, z1.id, z2.id};
74 tensorx.attr.vectorized_axis = {z0.id, z2.id};77 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -121,6 +124,8 @@ TEST_F(RegReduceMaxApicallTest, Max_INT8) {
121 codegen::RegReduceApiCall call(api_name);124 codegen::RegReduceApiCall call(api_name);
122 call.unit = af::ComputeUnit::kUnitVector;125 call.unit = af::ComputeUnit::kUnitVector;
123 call.type = "Max";126 call.type = "Max";
127+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
128+ call.node_name = reduce_node->GetName();
124 y_tensor.write = &call;129 y_tensor.write = &call;
125 call.inputs.push_back(&x_tensor);130 call.inputs.push_back(&x_tensor);
126 call.outputs.push_back(y_tensor);131 call.outputs.push_back(y_tensor);
@@ -138,7 +143,7 @@ TEST_F(RegReduceMaxApicallTest, Max_INT8) {
138 143 
139// Test Max with INT16 type144// Test Max with INT16 type
140TEST_F(RegReduceMaxApicallTest, Max_INT16) {145TEST_F(RegReduceMaxApicallTest, Max_INT16) {
141- std::string api_name = "Max";146+ std::string api_name = "ReduceMax";
142 147 
143 std::vector<ascir::AxisId> current_axis;148 std::vector<ascir::AxisId> current_axis;
144 std::vector<std::reference_wrapper<const Tensor>> inputs;149 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -165,11 +170,14 @@ TEST_F(RegReduceMaxApicallTest, Max_INT16) {
165 af::AscGraph graph("test");170 af::AscGraph graph("test");
166 af::ascir_op::Data x("x", graph);171 af::ascir_op::Data x("x", graph);
167 af::ascir_op::Data y("y", graph);172 af::ascir_op::Data y("y", graph);
173+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
174+ graph.AddNode(reduce); // 将Reduce节点添加到图中
168 175 
169 auto nodex = graph.FindNode("x");176 auto nodex = graph.FindNode("x");
170 af::AscTensor tensorx = nodex->outputs[0];177 af::AscTensor tensorx = nodex->outputs[0];
171 auto nodey = graph.FindNode("y");178 auto nodey = graph.FindNode("y");
172 af::AscTensor tensory = nodey->outputs[0];179 af::AscTensor tensory = nodey->outputs[0];
180+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
173 181 
174 tensorx.attr.axis = {z0.id, z1.id, z2.id};182 tensorx.attr.axis = {z0.id, z1.id, z2.id};
175 tensorx.attr.vectorized_axis = {z0.id, z2.id};183 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -222,6 +230,8 @@ TEST_F(RegReduceMaxApicallTest, Max_INT16) {
222 codegen::RegReduceApiCall call(api_name);230 codegen::RegReduceApiCall call(api_name);
223 call.unit = af::ComputeUnit::kUnitVector;231 call.unit = af::ComputeUnit::kUnitVector;
224 call.type = "Max";232 call.type = "Max";
233+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
234+ call.node_name = reduce_node->GetName();
225 y_tensor.write = &call;235 y_tensor.write = &call;
226 call.inputs.push_back(&x_tensor);236 call.inputs.push_back(&x_tensor);
227 call.outputs.push_back(y_tensor);237 call.outputs.push_back(y_tensor);
@@ -239,7 +249,7 @@ TEST_F(RegReduceMaxApicallTest, Max_INT16) {
239 249 
240// Test Max with BF16 type250// Test Max with BF16 type
241TEST_F(RegReduceMaxApicallTest, Max_BF16) {251TEST_F(RegReduceMaxApicallTest, Max_BF16) {
242- std::string api_name = "Max";252+ std::string api_name = "ReduceMax";
243 253 
244 std::vector<ascir::AxisId> current_axis;254 std::vector<ascir::AxisId> current_axis;
245 std::vector<std::reference_wrapper<const Tensor>> inputs;255 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -266,11 +276,14 @@ TEST_F(RegReduceMaxApicallTest, Max_BF16) {
266 af::AscGraph graph("test");276 af::AscGraph graph("test");
267 af::ascir_op::Data x("x", graph);277 af::ascir_op::Data x("x", graph);
268 af::ascir_op::Data y("y", graph);278 af::ascir_op::Data y("y", graph);
279+ af::ascir_op::Max reduce("reduce"); // 创建Reduce类型的节点
280+ graph.AddNode(reduce); // 将Reduce节点添加到图中
269 281 
270 auto nodex = graph.FindNode("x");282 auto nodex = graph.FindNode("x");
271 af::AscTensor tensorx = nodex->outputs[0];283 af::AscTensor tensorx = nodex->outputs[0];
272 auto nodey = graph.FindNode("y");284 auto nodey = graph.FindNode("y");
273 af::AscTensor tensory = nodey->outputs[0];285 af::AscTensor tensory = nodey->outputs[0];
286+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
274 287 
275 tensorx.attr.axis = {z0.id, z1.id, z2.id};288 tensorx.attr.axis = {z0.id, z1.id, z2.id};
276 tensorx.attr.vectorized_axis = {z0.id, z2.id};289 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -323,6 +336,8 @@ TEST_F(RegReduceMaxApicallTest, Max_BF16) {
323 codegen::RegReduceApiCall call(api_name);336 codegen::RegReduceApiCall call(api_name);
324 call.unit = af::ComputeUnit::kUnitVector;337 call.unit = af::ComputeUnit::kUnitVector;
325 call.type = "Max";338 call.type = "Max";
339+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
340+ call.node_name = reduce_node->GetName();
326 y_tensor.write = &call;341 y_tensor.write = &call;
327 call.inputs.push_back(&x_tensor);342 call.inputs.push_back(&x_tensor);
328 call.outputs.push_back(y_tensor);343 call.outputs.push_back(y_tensor);
@@ -37,7 +37,7 @@ class RegReduceMinApicallTest : public ::testing::Test {
37 37 
38// Test Min with INT8 type38// Test Min with INT8 type
39TEST_F(RegReduceMinApicallTest, Min_INT8) {39TEST_F(RegReduceMinApicallTest, Min_INT8) {
40- std::string api_name = "Min";40+ std::string api_name = "ReduceMin";
41 41 
42 std::vector<ascir::AxisId> current_axis;42 std::vector<ascir::AxisId> current_axis;
43 std::vector<std::reference_wrapper<const Tensor>> inputs;43 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -64,11 +64,14 @@ TEST_F(RegReduceMinApicallTest, Min_INT8) {
64 af::AscGraph graph("test");64 af::AscGraph graph("test");
65 af::ascir_op::Data x("x", graph);65 af::ascir_op::Data x("x", graph);
66 af::ascir_op::Data y("y", graph);66 af::ascir_op::Data y("y", graph);
67+ af::ascir_op::Min reduce("reduce"); // 创建Reduce类型的节点
68+ graph.AddNode(reduce); // 将Reduce节点添加到图中
67 69 
68 auto nodex = graph.FindNode("x");70 auto nodex = graph.FindNode("x");
69 af::AscTensor tensorx = nodex->outputs[0];71 af::AscTensor tensorx = nodex->outputs[0];
70 auto nodey = graph.FindNode("y");72 auto nodey = graph.FindNode("y");
71 af::AscTensor tensory = nodey->outputs[0];73 af::AscTensor tensory = nodey->outputs[0];
74+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
72 75 
73 tensorx.attr.axis = {z0.id, z1.id, z2.id};76 tensorx.attr.axis = {z0.id, z1.id, z2.id};
74 tensorx.attr.vectorized_axis = {z0.id, z2.id};77 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -121,6 +124,8 @@ TEST_F(RegReduceMinApicallTest, Min_INT8) {
121 codegen::RegReduceApiCall call(api_name);124 codegen::RegReduceApiCall call(api_name);
122 call.unit = af::ComputeUnit::kUnitVector;125 call.unit = af::ComputeUnit::kUnitVector;
123 call.type = "Min";126 call.type = "Min";
127+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
128+ call.node_name = reduce_node->GetName();
124 y_tensor.write = &call;129 y_tensor.write = &call;
125 call.inputs.push_back(&x_tensor);130 call.inputs.push_back(&x_tensor);
126 call.outputs.push_back(y_tensor);131 call.outputs.push_back(y_tensor);
@@ -138,7 +143,7 @@ TEST_F(RegReduceMinApicallTest, Min_INT8) {
138 143 
139// Test Min with INT16 type144// Test Min with INT16 type
140TEST_F(RegReduceMinApicallTest, Min_INT16) {145TEST_F(RegReduceMinApicallTest, Min_INT16) {
141- std::string api_name = "Min";146+ std::string api_name = "ReduceMin";
142 147 
143 std::vector<ascir::AxisId> current_axis;148 std::vector<ascir::AxisId> current_axis;
144 std::vector<std::reference_wrapper<const Tensor>> inputs;149 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -165,11 +170,14 @@ TEST_F(RegReduceMinApicallTest, Min_INT16) {
165 af::AscGraph graph("test");170 af::AscGraph graph("test");
166 af::ascir_op::Data x("x", graph);171 af::ascir_op::Data x("x", graph);
167 af::ascir_op::Data y("y", graph);172 af::ascir_op::Data y("y", graph);
173+ af::ascir_op::Min reduce("reduce"); // 创建Reduce类型的节点
174+ graph.AddNode(reduce); // 将Reduce节点添加到图中
168 175 
169 auto nodex = graph.FindNode("x");176 auto nodex = graph.FindNode("x");
170 af::AscTensor tensorx = nodex->outputs[0];177 af::AscTensor tensorx = nodex->outputs[0];
171 auto nodey = graph.FindNode("y");178 auto nodey = graph.FindNode("y");
172 af::AscTensor tensory = nodey->outputs[0];179 af::AscTensor tensory = nodey->outputs[0];
180+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
173 181 
174 tensorx.attr.axis = {z0.id, z1.id, z2.id};182 tensorx.attr.axis = {z0.id, z1.id, z2.id};
175 tensorx.attr.vectorized_axis = {z0.id, z2.id};183 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -222,6 +230,8 @@ TEST_F(RegReduceMinApicallTest, Min_INT16) {
222 codegen::RegReduceApiCall call(api_name);230 codegen::RegReduceApiCall call(api_name);
223 call.unit = af::ComputeUnit::kUnitVector;231 call.unit = af::ComputeUnit::kUnitVector;
224 call.type = "Min";232 call.type = "Min";
233+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
234+ call.node_name = reduce_node->GetName();
225 y_tensor.write = &call;235 y_tensor.write = &call;
226 call.inputs.push_back(&x_tensor);236 call.inputs.push_back(&x_tensor);
227 call.outputs.push_back(y_tensor);237 call.outputs.push_back(y_tensor);
@@ -239,7 +249,7 @@ TEST_F(RegReduceMinApicallTest, Min_INT16) {
239 249 
240// Test Min with BF16 type250// Test Min with BF16 type
241TEST_F(RegReduceMinApicallTest, Min_BF16) {251TEST_F(RegReduceMinApicallTest, Min_BF16) {
242- std::string api_name = "Min";252+ std::string api_name = "ReduceMin";
243 253 
244 std::vector<ascir::AxisId> current_axis;254 std::vector<ascir::AxisId> current_axis;
245 std::vector<std::reference_wrapper<const Tensor>> inputs;255 std::vector<std::reference_wrapper<const Tensor>> inputs;
@@ -266,11 +276,14 @@ TEST_F(RegReduceMinApicallTest, Min_BF16) {
266 af::AscGraph graph("test");276 af::AscGraph graph("test");
267 af::ascir_op::Data x("x", graph);277 af::ascir_op::Data x("x", graph);
268 af::ascir_op::Data y("y", graph);278 af::ascir_op::Data y("y", graph);
279+ af::ascir_op::Min reduce("reduce"); // 创建Reduce类型的节点
280+ graph.AddNode(reduce); // 将Reduce节点添加到图中
269 281 
270 auto nodex = graph.FindNode("x");282 auto nodex = graph.FindNode("x");
271 af::AscTensor tensorx = nodex->outputs[0];283 af::AscTensor tensorx = nodex->outputs[0];
272 auto nodey = graph.FindNode("y");284 auto nodey = graph.FindNode("y");
273 af::AscTensor tensory = nodey->outputs[0];285 af::AscTensor tensory = nodey->outputs[0];
286+ auto reduce_node = graph.FindNode("reduce"); // 获取Reduce节点
274 287 
275 tensorx.attr.axis = {z0.id, z1.id, z2.id};288 tensorx.attr.axis = {z0.id, z1.id, z2.id};
276 tensorx.attr.vectorized_axis = {z0.id, z2.id};289 tensorx.attr.vectorized_axis = {z0.id, z2.id};
@@ -323,6 +336,8 @@ TEST_F(RegReduceMinApicallTest, Min_BF16) {
323 codegen::RegReduceApiCall call(api_name);336 codegen::RegReduceApiCall call(api_name);
324 call.unit = af::ComputeUnit::kUnitVector;337 call.unit = af::ComputeUnit::kUnitVector;
325 call.type = "Min";338 call.type = "Min";
339+ call.node = reduce_node; // 设置Reduce节点,BuildApiParam需要有效的node
340+ call.node_name = reduce_node->GetName();
326 y_tensor.write = &call;341 y_tensor.write = &call;
327 call.inputs.push_back(&x_tensor);342 call.inputs.push_back(&x_tensor);
328 call.outputs.push_back(y_tensor);343 call.outputs.push_back(y_tensor);
@@ -1269,7 +1269,7 @@ class MaxAscIrCodegenImplV2 : public AscIrCodegenV2 {
1269 return "RegReduceApiCall";1269 return "RegReduceApiCall";
1270 }1270 }
1271 [[nodiscard]] std::string GetApiName() const override {1271 [[nodiscard]] std::string GetApiName() const override {
1272- return "Max";1272+ return "ReduceMax";
1273 }1273 }
1274 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1274 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1275 return {"reduce_init_reg_base.h"};1275 return {"reduce_init_reg_base.h"};
@@ -1303,7 +1303,7 @@ class SumAscIrCodegenImplV2 : public AscIrCodegenV2 {
1303 return "RegReduceApiCall";1303 return "RegReduceApiCall";
1304 }1304 }
1305 [[nodiscard]] std::string GetApiName() const override {1305 [[nodiscard]] std::string GetApiName() const override {
1306- return "Sum";1306+ return "ReduceSum";
1307 }1307 }
1308 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1308 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1309 return {"reduce_init_reg_base.h"};1309 return {"reduce_init_reg_base.h"};
@@ -1340,7 +1340,7 @@ class MinAscIrCodegenImplV2 : public AscIrCodegenV2 {
1340 return "RegReduceApiCall";1340 return "RegReduceApiCall";
1341 }1341 }
1342 [[nodiscard]] std::string GetApiName() const override {1342 [[nodiscard]] std::string GetApiName() const override {
1343- return "Min";1343+ return "ReduceMin";
1344 }1344 }
1345 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1345 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1346 return {"reduce_init_reg_base.h"};1346 return {"reduce_init_reg_base.h"};
@@ -1374,7 +1374,7 @@ class MeanAscIrCodegenImplV2 : public AscIrCodegenV2 {
1374 return "RegReduceApiCall";1374 return "RegReduceApiCall";
1375 }1375 }
1376 [[nodiscard]] std::string GetApiName() const override {1376 [[nodiscard]] std::string GetApiName() const override {
1377- return "Mean";1377+ return "ReduceMean";
1378 }1378 }
1379 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1379 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1380 return {"reduce_init_reg_base.h"};1380 return {"reduce_init_reg_base.h"};
@@ -1403,7 +1403,7 @@ class ProdAscIrCodegenImplV2 : public AscIrCodegenV2 {
1403 return "RegReduceApiCall";1403 return "RegReduceApiCall";
1404 }1404 }
1405 [[nodiscard]] std::string GetApiName() const override {1405 [[nodiscard]] std::string GetApiName() const override {
1406- return "Prod";1406+ return "ReduceProd";
1407 }1407 }
1408 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1408 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1409 return {"reduce_init_reg_base.h"};1409 return {"reduce_init_reg_base.h"};
@@ -1432,7 +1432,7 @@ class AnyAscIrCodegenImplV2 : public AscIrCodegenV2 {
1432 return "RegReduceApiCall";1432 return "RegReduceApiCall";
1433 }1433 }
1434 [[nodiscard]] std::string GetApiName() const override {1434 [[nodiscard]] std::string GetApiName() const override {
1435- return "Any";1435+ return "ReduceAny";
1436 }1436 }
1437 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1437 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1438 return {"reduce_init_reg_base.h"};1438 return {"reduce_init_reg_base.h"};
@@ -1461,7 +1461,7 @@ class AllAscIrCodegenImplV2 : public AscIrCodegenV2 {
1461 return "RegReduceApiCall";1461 return "RegReduceApiCall";
1462 }1462 }
1463 [[nodiscard]] std::string GetApiName() const override {1463 [[nodiscard]] std::string GetApiName() const override {
1464- return "All";1464+ return "ReduceAll";
1465 }1465 }
1466 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {1466 [[nodiscard]] std::vector<std::string> LoadApiHeaderFiles([[maybe_unused]] bool is_dynamic) const override {
1467 return {"reduce_init_reg_base.h"};1467 return {"reduce_init_reg_base.h"};
@@ -20,6 +20,7 @@
20#include "api_call/utils/api_call_factory.h"20#include "api_call/utils/api_call_factory.h"
21#include "codegen/expression_convert_struct.h"21#include "codegen/expression_convert_struct.h"
22#include "reg_api_call_utils.h"22#include "reg_api_call_utils.h"
23+#include "codegen_api_param/codegen_api_param.h"
23 24 
24namespace codegen {25namespace codegen {
25using namespace af::ops;26using namespace af::ops;
@@ -41,10 +42,9 @@ Status RegReduceApiCall::ParseAttr(const ascir::NodeView &node) {
41 return ge::SUCCESS;42 return ge::SUCCESS;
42}43}
43 44 
44-Status RegReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,45+Status RegReduceApiCall::BuildApiParam(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,
45- const std::vector<std::reference_wrapper<const Tensor>> &inputs,46+ const std::vector<std::reference_wrapper<const Tensor>> &inputs,
46- const std::vector<std::reference_wrapper<const Tensor>> &outputs,47+ const std::vector<std::reference_wrapper<const Tensor>> &outputs) const {
47- std::string &result) const {
48 // 获取tmp_buf复用TBuf的id48 // 获取tmp_buf复用TBuf的id
49 int64_t life_time_axis_id = -1L;49 int64_t life_time_axis_id = -1L;
50 int64_t id = -1L;50 int64_t id = -1L;
@@ -62,7 +62,6 @@ Status RegReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::A
62 62 
63 auto x = inputs[0].get();63 auto x = inputs[0].get();
64 auto y = outputs[0].get();64 auto y = outputs[0].get();
65- (void)RegisterBasicDumpParam(this->api_name_, inputs, outputs);
66 65 
67 std::string reduce_pattern;66 std::string reduce_pattern;
68 GetIsArAndPattern(y, x.isAr, reduce_pattern);67 GetIsArAndPattern(y, x.isAr, reduce_pattern);
@@ -74,53 +73,84 @@ Status RegReduceApiCall::Generate(const TPipe &tpipe, const std::vector<ascir::A
74 static_cast<int32_t>(y.dtype));73 static_cast<int32_t>(y.dtype));
75 GELOGI("Tensor::DtypeName(y.dtype) == %s", dtype_name.c_str());74 GELOGI("Tensor::DtypeName(y.dtype) == %s", dtype_name.c_str());
76 75 
77- std::stringstream ss;76+ auto api_param = af::ComGraphMakeShared<CodegenApiParam>();
77+ GE_ASSERT_NOTNULL(api_param);
78+
79+ ReduceMergedSizeCodeGen(tpipe, api_param->api_pre_process, x, y);
78 80 
79- ReduceMergedSizeCodeGen(tpipe, ss, x, y);81+ ReduceDimACodeGen(x, this->api_name_, api_param->api_pre_process);
80 82 
81- ReduceDimACodeGen(x, this->api_name_, ss);83+ ReduceInitCodeGen(x, y, type_value, api_param->api_pre_process, tpipe, dtype_name);
84+ api_param->api_pre_process.emplace_back("uint32_t tmp_reduce_shape[] = {first_actual, last};\n");
85+ std::string new_api_name = this->api_name_ == "ReduceMean" ? "ReduceSum" : this->api_name_;
86+ api_param->api_name = new_api_name;
87+ api_param->template_params.emplace_back(dtype_name);
88+ api_param->template_params.emplace_back(reduce_pattern);
89+ api_param->template_params.emplace_back(is_reuse_source_);
82 90 
83- ReduceInitCodeGen(x, y, type_value, ss, tpipe, dtype_name);91+ bool need_multi_reduce = IsNeedMultiReduce(tpipe.tiler, x, y, current_axis.back());
84 92 
85- ss << "uint32_t tmp_reduce_shape[] = {first_actual, last};" << std::endl;93+ if (need_multi_reduce) {
86- 
87- std::string new_api_name = this->api_name_ == "Mean" ? "Sum" : this->api_name_;
88- if (!IsNeedMultiReduce(tpipe.tiler, x, y, current_axis.back())) {
89- ss << "Reduce" << new_api_name << "<" << dtype_name << ", " << reduce_pattern << ", " << is_reuse_source_ << ">("
90- << y << "[" << tpipe.tiler.TensorVectorizedOffset(current_axis, y) << "], " << x << "["
91- << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], ";
92- is_reuse_source_ == "true" ? ss << "" : ss << tpipe.tmp_buf << "_" << std::to_string(id) << ", ";
93- ss << "tmp_reduce_shape, true);" << std::endl;
94- 
95- if (this->api_name_ == "Mean") {
96- ReduceMeanCodeGen(dtype_name, tpipe, x, y, ss);
97- }
98- } else {
99 life_time_axis_id = 0L;94 life_time_axis_id = 0L;
100 int64_t tmp_reduce_id = -1L;95 int64_t tmp_reduce_id = -1L;
101- auto it = this->tmp_buf_id.find(life_time_axis_id);96+ auto it_tmp = this->tmp_buf_id.find(life_time_axis_id);
102- GE_ASSERT_TRUE(it != this->tmp_buf_id.end(), "RegReduceApiCall(tmp_reduce_id) cannot find tmp buffer id to use.");97+ GE_ASSERT_TRUE(it_tmp != this->tmp_buf_id.end(), "RegReduceApiCall(tmp_reduce_id) cannot find tmp buffer id to use.");
103- tmp_reduce_id = it->second;98+ tmp_reduce_id = it_tmp->second;
104- ss << "LocalTensor<" << dtype_name << "> tmp_reduce;" << std::endl;99+ api_param->api_pre_process.emplace_back("LocalTensor<" + dtype_name + "> tmp_reduce;\n");
105- ss << "tmp_reduce = " << tpipe.tmp_buf << "_" << std::to_string(tmp_reduce_id) << ".template ReinterpretCast<"100+ api_param->api_pre_process.emplace_back(
106- << dtype_name << ">();" << std::endl;101+ "tmp_reduce = " + tpipe.tmp_buf.name + "_" + std::to_string(tmp_reduce_id) +
107- ss << "Reduce" << new_api_name << "<" << dtype_name << "," << reduce_pattern << ", " << is_reuse_source_ << ">"102+ ".template ReinterpretCast<" + dtype_name + ">();\n");
108- << "(tmp_reduce[0], " << x << "[" << tpipe.tiler.TensorVectorizedOffset(current_axis, x) << "], ";
109- is_reuse_source_ == "true" ? ss << "" : ss << tpipe.tmp_buf << "_" << std::to_string(id) << ", ";
110- ss << "tmp_reduce_shape, true);" << std::endl;
111- ss << "AscendC::PipeBarrier<PIPE_V>();" << std::endl;
112- ss << "uint32_t temp_size = " << KernelUtils::SizeAlign() << "(" << y.actual_size << ", 32/sizeof(" << dtype_name
113- << "));" << std::endl;
114- ss << "if (" << tpipe.tiler.GetAxis(current_axis.back()) << " == 0) {" << std::endl;
115- ss << "DataCopyExtend(" << y << "[0], " << "tmp_reduce[0], " << "temp_size);" << std::endl;
116- ss << "} else {" << std::endl;
117- ss << "AscendC::" << instr_type << "(" << y << "[0], " << "tmp_reduce[0], " << y << "[0], temp_size);\n"
118- << "}" << std::endl;
119 }103 }
120 104 
121- ss << "}" << std::endl;105+ if (need_multi_reduce) {
122- result = ss.str();106+ // need_multi_reduce 时输出到 tmp_reduce[0]
123- return ge::SUCCESS;107+ api_param->output_params.emplace_back("tmp_reduce", true, CombinedExprFactory::Constant(0));
108+ api_param->input_params.emplace_back(
109+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
110+ } else {
111+ api_param->output_params.emplace_back(
112+ y.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, y)));
113+ api_param->input_params.emplace_back(
114+ x.Str(), true, CombinedExprFactory::SymbolVar(tpipe.tiler.TensorVectorizedOffset(current_axis, x)));
115+ }
116+ 
117+ // 设置tmp_buf_name(如果不是reuse_source)
118+ if (is_reuse_source_ != "true") {
119+ api_param->tmp_buf_name = tpipe.tmp_buf.name + "_" + std::to_string(id);
120+ }
121+ api_param->cal_count = CombinedExprFactory::SymbolVar("tmp_reduce_shape");
122+ 
123+ // 后处理代码
124+ if (!need_multi_reduce && this->api_name_ == "ReduceMean") {
125+ // Mean算子在非multi_reduce时需要额外的后处理(除法)
126+ ReduceMeanCodeGen(dtype_name, tpipe, x, y, api_param->api_post_process);
127+ }
128+ 
129+ if (need_multi_reduce) {
130+ api_param->api_post_process.emplace_back("AscendC::PipeBarrier<PIPE_V>();\n");
131+ api_param->api_post_process.emplace_back(
132+ "uint32_t temp_size = " + KernelUtils::SizeAlign() + "(" + y.actual_size.Str() +
133+ ", 32/sizeof(" + dtype_name + "));\n");
134+ api_param->api_post_process.emplace_back(
135+ "if (" + tpipe.tiler.GetAxis(current_axis.back()).Str() + " == 0) {\n");
136+ api_param->api_post_process.emplace_back(
137+ "DataCopyExtend(" + y.Str() + "[0], tmp_reduce[0], temp_size);\n");
138+ api_param->api_post_process.emplace_back("} else {\n");
139+ api_param->api_post_process.emplace_back(
140+ "AscendC::" + instr_type + "(" + y.Str() + "[0], tmp_reduce[0], " + y.Str() + "[0], temp_size);\n");
141+ api_param->api_post_process.emplace_back("}\n");
142+ }
143+ // 结束代码块(与ReduceMergedSizeCodeGen生成的 { 对应)
144+ api_param->api_post_process.emplace_back("}\n");
145+ 
146+ GE_CHK_STATUS_RET(CodegenApiParam::Register(this->node, api_param),
147+ "CodegenApiParam Register failed for node %s", this->node_name.c_str());
148+ return af::SUCCESS;
149+}
150+ 
151+Status RegReduceApiCall::GenDimensionParam(const CodegenApiParam &api_param, const Tiler &tiler, std::stringstream &ss) const {
152+ ss << api_param.cal_count.ToStr(tiler) << ", true);" << std::endl;
153+ return af::SUCCESS;
124}154}
125 155 
126static ApiCallRegister<RegReduceApiCall> register_reduce_api_call("RegReduceApiCall");156static ApiCallRegister<RegReduceApiCall> register_reduce_api_call("RegReduceApiCall");
@@ -17,9 +17,10 @@ class RegReduceApiCall : public ApiCall {
17 using ApiCall::Generate;17 using ApiCall::Generate;
18 explicit RegReduceApiCall(const std::string &api_name) : ApiCall(api_name) {}18 explicit RegReduceApiCall(const std::string &api_name) : ApiCall(api_name) {}
19 ~RegReduceApiCall() final = default;19 ~RegReduceApiCall() final = default;
20- Status Generate(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,20+ Status BuildApiParam(const TPipe &tpipe, const std::vector<ascir::AxisId> &current_axis,
21- const std::vector<std::reference_wrapper<const Tensor>> &inputs,21+ const std::vector<std::reference_wrapper<const Tensor>> &inputs,
22- const std::vector<std::reference_wrapper<const Tensor>> &outputs, std::string &result) const override;22+ const std::vector<std::reference_wrapper<const Tensor>> &outputs) const override;
23+ Status GenDimensionParam(const CodegenApiParam &api_param, const Tiler &tiler, std::stringstream &ss) const override;
23 Status CallParseAttr(const ascir::NodeView &node) {24 Status CallParseAttr(const ascir::NodeView &node) {
24 return ParseAttr(node);25 return ParseAttr(node);
25 }26 }