已合并
fusion pass兼容性问题修复 #3908
pengyiming7创建于 7月8日
fusion pass兼容性问题修复 #3908
已合并
pengyiming7创建于 7月8日
3 个文件变更+161-105
@@ -39,6 +39,7 @@ namespace ops {
39// D1 scenario: uses kCompatibleInherited stage (9.0.0+).39// D1 scenario: uses kCompatibleInherited stage (9.0.0+).
40// Strategy: compile-time macro guard + runtime version check + overall silence.40// Strategy: compile-time macro guard + runtime version check + overall silence.
41#define GE_COMPILER_VERSION_900 9000000041#define GE_COMPILER_VERSION_900 90000000
42+#define GE_COMPILER_VERSION_910 90100000
42#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_90043#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900
43 44 
44// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.45// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.
@@ -197,11 +198,28 @@ static es::EsTensorHolder BuildTransposeNode(es::EsGraphBuilder& replaceGraphBui
197 return es::EsTensorHolder(output);198 return es::EsTensorHolder(output);
198}199}
199 200 
201+static bool IsTargetVersion()
202+{
203+ int32_t version = 0;
204+ char pkgName[] = "ge_compiler";
205+ if (aclsysGetVersionNum) {
206+ aclsysGetVersionNum(pkgName, &version);
207+ }
208+ if (version >= GE_COMPILER_VERSION_910) {
209+ return true;
210+ }
211+ return false;
212+}
213+ 
200std::vector<PatternUniqPtr> PermuteFusionPass::Patterns()214std::vector<PatternUniqPtr> PermuteFusionPass::Patterns()
201{215{
202 OP_LOGD(kFusionPassName.c_str(), "Enter Patterns for PermuteFusionPass.");216 OP_LOGD(kFusionPassName.c_str(), "Enter Patterns for PermuteFusionPass.");
203 std::vector<PatternUniqPtr> patternGraphs;217 std::vector<PatternUniqPtr> patternGraphs;
204 218 
219+ if (!IsTargetVersion()) {
220+ return patternGraphs;
221+ }
222+ 
205 auto graphBuilder = es::EsGraphBuilder("PermuteFusionPass");223 auto graphBuilder = es::EsGraphBuilder("PermuteFusionPass");
206 224 
207 // Create input node225 // Create input node
@@ -238,8 +256,9 @@ bool PermuteFusionPass::MeetRequirements(const std::unique_ptr<MatchResult>& mat
238 256 
239 // Runtime version check: on GE 8.5.0, return false to no-op.257 // Runtime version check: on GE 8.5.0, return false to no-op.
240 int32_t version = 0;258 int32_t version = 0;
259+ char pkgName[] = "ge_compiler";
241 if (aclsysGetVersionNum) {260 if (aclsysGetVersionNum) {
242- aclsysGetVersionNum(const_cast<char*>("ge_compiler"), &version);261+ aclsysGetVersionNum(pkgName, &version);
243 }262 }
244 if (version < GE_COMPILER_VERSION_900) {263 if (version < GE_COMPILER_VERSION_900) {
245 OP_LOGD(kFusionPassName.c_str(), "GE runtime version %d < 90000000, skip pass.", version);264 OP_LOGD(kFusionPassName.c_str(), "GE runtime version %d < 90000000, skip pass.", version);
@@ -25,13 +25,13 @@ namespace ops {
25// D1 scenario: uses kCompatibleInherited stage (9.0.0+).25// D1 scenario: uses kCompatibleInherited stage (9.0.0+).
26// Strategy: compile-time macro guard + runtime version check + overall silence.26// Strategy: compile-time macro guard + runtime version check + overall silence.
27#define GE_COMPILER_VERSION_900 9000000027#define GE_COMPILER_VERSION_900 90000000
28+#define GE_COMPILER_VERSION_910 90100000
28#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_90029#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900
29 30 
30// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.31// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.
31// At runtime: if GE >= 9.0.0, symbol resolves normally; if GE 8.5.0, pointer is NULL.32// At runtime: if GE >= 9.0.0, symbol resolves normally; if GE 8.5.0, pointer is NULL.
32extern "C" {33extern "C" {
33-__attribute__((weak))34+__attribute__((weak)) int32_t aclsysGetVersionNum(char* pkgName, int32_t* versionNum);
34-int32_t aclsysGetVersionNum(char* pkgName, int32_t* versionNum);
35}35}
36 36 
37const std::string FUSION_PASS_NAME = "GlobalavgpoolPass";37const std::string FUSION_PASS_NAME = "GlobalavgpoolPass";
@@ -53,13 +53,12 @@ CustomPassStage GetGlobalavgpoolPassStage()
53 if (version >= GE_COMPILER_VERSION_900) {53 if (version >= GE_COMPILER_VERSION_900) {
54 return CustomPassStage::kCompatibleInherited;54 return CustomPassStage::kCompatibleInherited;
55 }55 }
56- return CustomPassStage::kBeforeInferShape; // fallback to old stage for 8.5.056+ return CustomPassStage::kBeforeInferShape; // fallback to old stage for 8.5.0
57}57}
58-} // anonymous namespace58+} // anonymous namespace
59 59 
60-static void GetInputsInfo(60+static void GetInputsInfo(const std::vector<SubgraphInput>& subGraphInputs, std::vector<Shape>& inputShapes,
61- const std::vector<SubgraphInput>& subGraphInputs, std::vector<Shape>& inputShapes,61+ std::vector<DataType>& inputDtypes, std::vector<Format>& inputFormats)
62- std::vector<DataType>& inputDtypes, std::vector<Format>& inputFormats)
63{62{
64 for (const auto& subGraphInput : subGraphInputs) {63 for (const auto& subGraphInput : subGraphInputs) {
65 auto matchNode = subGraphInput.GetAllInputs().at(0);64 auto matchNode = subGraphInput.GetAllInputs().at(0);
@@ -72,12 +71,13 @@ static void GetInputsInfo(
72 // 如果失败,尝试获取输出描述71 // 如果失败,尝试获取输出描述
73 status = matchNode.node.GetOutputDesc(matchNode.index, tensorDesc);72 status = matchNode.node.GetOutputDesc(matchNode.index, tensorDesc);
74 if (status != GRAPH_SUCCESS) {73 if (status != GRAPH_SUCCESS) {
75- OP_LOGE("GlobalavgpoolPass", "Failed to get output desc from GlobalAveragePool node, status: %u", status);74+ OP_LOGE("GlobalavgpoolPass", "Failed to get output desc from GlobalAveragePool node, status: %u",
75+ status);
76 // 使用默认值76 // 使用默认值
77 tensorDesc.SetDataType(DT_FLOAT);77 tensorDesc.SetDataType(DT_FLOAT);
78 tensorDesc.SetFormat(FORMAT_ND);78 tensorDesc.SetFormat(FORMAT_ND);
79 // 使用合理的默认形状79 // 使用合理的默认形状
80- Shape defaultShape({1, 1, 1}); // 3D默认形状80+ Shape defaultShape({1, 1, 1}); // 3D默认形状
81 tensorDesc.SetShape(defaultShape);81 tensorDesc.SetShape(defaultShape);
82 }82 }
83 }83 }
@@ -96,7 +96,8 @@ static Status InferShape(const GraphUniqPtr& replaceGraph, const std::vector<Sub
96 // matchNode.node是GlobalAveragePool节点,matchNode.index是输出索引(0)96 // matchNode.node是GlobalAveragePool节点,matchNode.index是输出索引(0)
97 // 我们需要获取GlobalAveragePool的输入描述(索引0)97 // 我们需要获取GlobalAveragePool的输入描述(索引0)
98 if (matchNode.node.GetInputDesc(0, tensorDesc) != GRAPH_SUCCESS) {98 if (matchNode.node.GetInputDesc(0, tensorDesc) != GRAPH_SUCCESS) {
99- OP_LOGE_WITHOUT_REPORT("GlobalavgpoolPass", "Failed to get input desc from GlobalAveragePool node in InferShape");99+ OP_LOGE_WITHOUT_REPORT("GlobalavgpoolPass",
100+ "Failed to get input desc from GlobalAveragePool node in InferShape");
100 // 如果失败,尝试获取输出描述101 // 如果失败,尝试获取输出描述
101 matchNode.node.GetOutputDesc(matchNode.index, tensorDesc);102 matchNode.node.GetOutputDesc(matchNode.index, tensorDesc);
102 }103 }
@@ -105,35 +106,52 @@ static Status InferShape(const GraphUniqPtr& replaceGraph, const std::vector<Sub
105 return GeUtils::InferShape(*replaceGraph, inputShapes);106 return GeUtils::InferShape(*replaceGraph, inputShapes);
106}107}
107 108 
109+static bool IsTargetVersion()
110+{
111+ int32_t version = 0;
112+ char pkgName[] = "ge_compiler";
113+ if (aclsysGetVersionNum) {
114+ aclsysGetVersionNum(pkgName, &version);
115+ }
116+ if (version >= GE_COMPILER_VERSION_910) {
117+ return true;
118+ }
119+ return false;
120+}
121+ 
108std::vector<PatternUniqPtr> GlobalavgpoolPass::Patterns()122std::vector<PatternUniqPtr> GlobalavgpoolPass::Patterns()
109{123{
110 OP_LOGD(FUSION_PASS_NAME.c_str(), "Enter Patterns for GlobalavgpoolPass");124 OP_LOGD(FUSION_PASS_NAME.c_str(), "Enter Patterns for GlobalavgpoolPass");
111 std::vector<PatternUniqPtr> patternGraphs;125 std::vector<PatternUniqPtr> patternGraphs;
126+ if (!IsTargetVersion()) {
127+ return patternGraphs;
128+ }
112 auto graphBuilder = es::EsGraphBuilder(FUSION_PASS_NAME.c_str());129 auto graphBuilder = es::EsGraphBuilder(FUSION_PASS_NAME.c_str());
113 130 
114 // 创建输入131 // 创建输入
115 auto x = graphBuilder.CreateInput(0);132 auto x = graphBuilder.CreateInput(0);
116 OP_LOGD(FUSION_PASS_NAME.c_str(), "Created input node");133 OP_LOGD(FUSION_PASS_NAME.c_str(), "Created input node");
117- 134+ 
118 // 构建 GlobalAveragePool 节点135 // 构建 GlobalAveragePool 节点
119 // 注意:我们需要获取Graph对象来构建CompliantNode136 // 注意:我们需要获取Graph对象来构建CompliantNode
120 auto* graph = graphBuilder.GetCGraphBuilder()->GetGraph();137 auto* graph = graphBuilder.GetCGraphBuilder()->GetGraph();
121 OP_LOGD(FUSION_PASS_NAME.c_str(), "Got graph pointer: %p", graph);138 OP_LOGD(FUSION_PASS_NAME.c_str(), "Got graph pointer: %p", graph);
122 auto globalAvgPool = es::CompliantNodeBuilder(graph)139 auto globalAvgPool = es::CompliantNodeBuilder(graph)
123- .OpType("GlobalAveragePool")140+ .OpType("GlobalAveragePool")
124- .Name("global_avg_pool")141+ .Name("global_avg_pool")
125- .IrDefInputs({{"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""}})142+ .IrDefInputs({{"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""}})
126- .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})143+ .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})
127- .Build();144+ .Build();
128 OP_LOGD(FUSION_PASS_NAME.c_str(), "Built GlobalAveragePool node");145 OP_LOGD(FUSION_PASS_NAME.c_str(), "Built GlobalAveragePool node");
129- 146+ 
130 // 连接输入 - 使用正确的Graph参数147 // 连接输入 - 使用正确的Graph参数
131- if (es::AddEdgeAndUpdatePeerDesc(*graph, *x.GetProducer(), x.GetProducerOutIndex(), globalAvgPool, 0) != GRAPH_SUCCESS) {148+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *x.GetProducer(), x.GetProducerOutIndex(), globalAvgPool, 0) !=
149+ GRAPH_SUCCESS) {
132 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge in pattern");150 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge in pattern");
133 return patternGraphs;151 return patternGraphs;
134 }152 }
135 OP_LOGD(FUSION_PASS_NAME.c_str(), "Added edge successfully");153 OP_LOGD(FUSION_PASS_NAME.c_str(), "Added edge successfully");
136- 154+ 
137 // 获取输出并构建图155 // 获取输出并构建图
138 // 注意:GetTensorHolderFromNode需要EsCGraphBuilder和节点156 // 注意:GetTensorHolderFromNode需要EsCGraphBuilder和节点
139 auto y = graphBuilder.GetCGraphBuilder()->GetTensorHolderFromNode(globalAvgPool, 0);157 auto y = graphBuilder.GetCGraphBuilder()->GetTensorHolderFromNode(globalAvgPool, 0);
@@ -148,7 +166,7 @@ std::vector<PatternUniqPtr> GlobalavgpoolPass::Patterns()
148 NodeIo nodeIo = {y->GetProducer(), 0};166 NodeIo nodeIo = {y->GetProducer(), 0};
149 pattern->CaptureTensor(nodeIo);167 pattern->CaptureTensor(nodeIo);
150 OP_LOGD(FUSION_PASS_NAME.c_str(), "Pattern created and tensor captured");168 OP_LOGD(FUSION_PASS_NAME.c_str(), "Pattern created and tensor captured");
151- 169+ 
152 patternGraphs.emplace_back(std::move(pattern));170 patternGraphs.emplace_back(std::move(pattern));
153 return patternGraphs;171 return patternGraphs;
154}172}
@@ -156,11 +174,12 @@ std::vector<PatternUniqPtr> GlobalavgpoolPass::Patterns()
156bool GlobalavgpoolPass::MeetRequirements(const std::unique_ptr<MatchResult>& match_result)174bool GlobalavgpoolPass::MeetRequirements(const std::unique_ptr<MatchResult>& match_result)
157{175{
158 OP_LOGD(FUSION_PASS_NAME.c_str(), "=== Enter MeetRequirements for GlobalavgpoolPass ===");176 OP_LOGD(FUSION_PASS_NAME.c_str(), "=== Enter MeetRequirements for GlobalavgpoolPass ===");
159- 177+ 
160 // Runtime version check: on GE 8.5.0, return false to no-op.178 // Runtime version check: on GE 8.5.0, return false to no-op.
161 int32_t version = 0;179 int32_t version = 0;
180+ char pkgName[] = "ge_compiler";
162 if (aclsysGetVersionNum) {181 if (aclsysGetVersionNum) {
163- aclsysGetVersionNum(const_cast<char*>("ge_compiler"), &version);182+ aclsysGetVersionNum(pkgName, &version);
164 }183 }
165 if (version < GE_COMPILER_VERSION_900) {184 if (version < GE_COMPILER_VERSION_900) {
166 OP_LOGD(FUSION_PASS_NAME.c_str(), "GE runtime version %d < 90000000, skip pass.", version);185 OP_LOGD(FUSION_PASS_NAME.c_str(), "GE runtime version %d < 90000000, skip pass.", version);
@@ -175,7 +194,7 @@ bool GlobalavgpoolPass::MeetRequirements(const std::unique_ptr<MatchResult>& mat
175 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to GetCaptrue tensor");194 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to GetCaptrue tensor");
176 return false;195 return false;
177 }196 }
178- 197+ 
179 auto node = matchedNode.node;198 auto node = matchedNode.node;
180 AscendString nodeType;199 AscendString nodeType;
181 node.GetType(nodeType);200 node.GetType(nodeType);
@@ -221,7 +240,8 @@ GraphUniqPtr GlobalavgpoolPass::Replacement(const std::unique_ptr<MatchResult>&
221 auto replaceGraphBuilder = es::EsGraphBuilder("replacement");240 auto replaceGraphBuilder = es::EsGraphBuilder("replacement");
222 241 
223 // 创建输入节点 - 使用带有数据类型和形状的重载版本242 // 创建输入节点 - 使用带有数据类型和形状的重载版本
224- auto reduceMeanInput = replaceGraphBuilder.CreateInput(0, "x", inputDtypes[0], inputFormats[0], inputShapes[0].GetDims());243+ auto reduceMeanInput = replaceGraphBuilder.CreateInput(0, "x", inputDtypes[0], inputFormats[0],
244+ inputShapes[0].GetDims());
225 245 
226 // 根据输入维度计算axes246 // 根据输入维度计算axes
227 int64_t inputDim = inputShapes[0].GetDims().size();247 int64_t inputDim = inputShapes[0].GetDims().size();
@@ -244,28 +264,32 @@ GraphUniqPtr GlobalavgpoolPass::Replacement(const std::unique_ptr<MatchResult>&
244 // 使用CompliantNodeBuilder创建ReduceMean节点264 // 使用CompliantNodeBuilder创建ReduceMean节点
245 auto* graph = replaceGraphBuilder.GetCGraphBuilder()->GetGraph();265 auto* graph = replaceGraphBuilder.GetCGraphBuilder()->GetGraph();
246 auto reduceMeanNode = es::CompliantNodeBuilder(graph)266 auto reduceMeanNode = es::CompliantNodeBuilder(graph)
247- .OpType("ReduceMean")267+ .OpType("ReduceMean")
248- .Name("reduce_mean")268+ .Name("reduce_mean")
249- .IrDefInputs({269+ .IrDefInputs({
250- {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},270+ {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
251- {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},271+ {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
252- })272+ })
253- .IrDefOutputs({273+ .IrDefOutputs({
254- {"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""},274+ {"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""},
255- })275+ })
256- .IrDefAttrs({276+ .IrDefAttrs({
257- {"keep_dims", es::CompliantNodeBuilder::kEsAttrRequired, "Bool", es::CreateFrom(true)},277+ {"keep_dims", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",
258- {"noop_with_empty_axes", es::CompliantNodeBuilder::kEsAttrRequired, "Bool", es::CreateFrom(true)},278+ es::CreateFrom(true)},
259- })279+ {"noop_with_empty_axes", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",
260- .Build();280+ es::CreateFrom(true)},
281+ })
282+ .Build();
261 // 连接输入283 // 连接输入
262- if (es::AddEdgeAndUpdatePeerDesc(*graph, *reduceMeanInput.GetProducer(), reduceMeanInput.GetProducerOutIndex(), reduceMeanNode, 0) != GRAPH_SUCCESS) {284+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *reduceMeanInput.GetProducer(), reduceMeanInput.GetProducerOutIndex(),
285+ reduceMeanNode, 0) != GRAPH_SUCCESS) {
263 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge for reduceMean input");286 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge for reduceMean input");
264 return nullptr;287 return nullptr;
265 }288 }
266 289 
267 // 连接axes常量节点290 // 连接axes常量节点
268- if (es::AddEdgeAndUpdatePeerDesc(*graph, *axesConst.GetProducer(), axesConst.GetProducerOutIndex(), reduceMeanNode, 1) != GRAPH_SUCCESS) {291+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *axesConst.GetProducer(), axesConst.GetProducerOutIndex(), reduceMeanNode,
292+ 1) != GRAPH_SUCCESS) {
269 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge for axes constant");293 OP_LOGE_WITHOUT_REPORT(FUSION_PASS_NAME.c_str(), "Failed to add edge for axes constant");
270 return nullptr;294 return nullptr;
271 }295 }
@@ -288,6 +312,6 @@ GraphUniqPtr GlobalavgpoolPass::Replacement(const std::unique_ptr<MatchResult>&
288 312 
289REG_FUSION_PASS(GlobalavgpoolPass).Stage(GetGlobalavgpoolPassStage());313REG_FUSION_PASS(GlobalavgpoolPass).Stage(GetGlobalavgpoolPassStage());
290 314 
291-#endif // GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900315+#endif // GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900
292 316 
293-} // namespace ops317+} // namespace ops
@@ -27,13 +27,13 @@ namespace ops {
27// D1 scenario: uses kCompatibleInherited stage (9.0.0+).27// D1 scenario: uses kCompatibleInherited stage (9.0.0+).
28// Strategy: compile-time macro guard + runtime version check + overall silence.28// Strategy: compile-time macro guard + runtime version check + overall silence.
29#define GE_COMPILER_VERSION_900 9000000029#define GE_COMPILER_VERSION_900 90000000
30+#define GE_COMPILER_VERSION_910 90100000
30#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_90031#if GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900
31 32 
32// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.33// Weak declare aclsysGetVersionNum to avoid hard link dependency on libascendcl.
33// At runtime: if GE >= 9.0.0, symbol resolves normally; if GE 8.5.0, pointer is NULL.34// At runtime: if GE >= 9.0.0, symbol resolves normally; if GE 8.5.0, pointer is NULL.
34extern "C" {35extern "C" {
35-__attribute__((weak))36+__attribute__((weak)) int32_t aclsysGetVersionNum(char* pkgName, int32_t* versionNum);
36-int32_t aclsysGetVersionNum(char* pkgName, int32_t* versionNum);
37}37}
38 38 
39const std::string kPassName = "ReduceMeanWithCastFusionPass";39const std::string kPassName = "ReduceMeanWithCastFusionPass";
@@ -50,13 +50,12 @@ CustomPassStage GetReduceMeanWithCastPassStage()
50 if (version >= GE_COMPILER_VERSION_900) {50 if (version >= GE_COMPILER_VERSION_900) {
51 return CustomPassStage::kCompatibleInherited;51 return CustomPassStage::kCompatibleInherited;
52 }52 }
53- return CustomPassStage::kBeforeInferShape; // fallback to old stage for 8.5.053+ return CustomPassStage::kBeforeInferShape; // fallback to old stage for 8.5.0
54}54}
55-} // anonymous namespace55+} // anonymous namespace
56 56 
57-static void GetInputsInfo(57+static void GetInputsInfo(const std::vector<SubgraphInput>& subgraphInputs, std::vector<Shape>& inputShapes,
58- const std::vector<SubgraphInput>& subgraphInputs, std::vector<Shape>& inputShapes,58+ std::vector<DataType>& inputDtypes, std::vector<Format>& inputFormats)
59- std::vector<DataType>& inputDtypes, std::vector<Format>& inputFormats)
60{59{
61 for (const auto& subgraphInput : subgraphInputs) {60 for (const auto& subgraphInput : subgraphInputs) {
62 auto matchNode = subgraphInput.GetAllInputs().at(0);61 auto matchNode = subgraphInput.GetAllInputs().at(0);
@@ -68,8 +67,7 @@ static void GetInputsInfo(
68 }67 }
69}68}
70 69 
71-static Status InferShape(const GraphUniqPtr& replaceGraph,70+static Status InferShape(const GraphUniqPtr& replaceGraph, const std::vector<SubgraphInput>& subgraphInputs)
72- const std::vector<SubgraphInput>& subgraphInputs)
73{71{
74 OP_LOGD(kPassName.c_str(), "Begin InferShape for replacement.");72 OP_LOGD(kPassName.c_str(), "Begin InferShape for replacement.");
75 std::vector<Shape> inputShapes;73 std::vector<Shape> inputShapes;
@@ -82,11 +80,28 @@ static Status InferShape(const GraphUniqPtr& replaceGraph,
82 return GeUtils::InferShape(*replaceGraph, inputShapes);80 return GeUtils::InferShape(*replaceGraph, inputShapes);
83}81}
84 82 
83+static bool IsTargetVersion()
84+{
85+ int32_t version = 0;
86+ char pkgName[] = "ge_compiler";
87+ if (aclsysGetVersionNum) {
88+ aclsysGetVersionNum(pkgName, &version);
89+ }
90+ if (version >= GE_COMPILER_VERSION_910) {
91+ return true;
92+ }
93+ return false;
94+}
95+ 
85std::vector<PatternUniqPtr> ReduceMeanWithCastFusionPass::Patterns()96std::vector<PatternUniqPtr> ReduceMeanWithCastFusionPass::Patterns()
86{97{
87 OP_LOGD(kPassName.c_str(), "Enter Patterns for ReduceMeanWithCastFusionPass");98 OP_LOGD(kPassName.c_str(), "Enter Patterns for ReduceMeanWithCastFusionPass");
88 std::vector<PatternUniqPtr> patternGraphs;99 std::vector<PatternUniqPtr> patternGraphs;
89 100 
101+ if (!IsTargetVersion()) {
102+ return patternGraphs;
103+ }
104+ 
90 auto graphBuilder = es::EsGraphBuilder(kPassName.c_str());105 auto graphBuilder = es::EsGraphBuilder(kPassName.c_str());
91 106 
92 // Create input x (index 0)107 // Create input x (index 0)
@@ -97,24 +112,24 @@ std::vector<PatternUniqPtr> ReduceMeanWithCastFusionPass::Patterns()
97 // Build ReduceMeanWithCast node using CompliantNodeBuilder (no ES API available)112 // Build ReduceMeanWithCast node using CompliantNodeBuilder (no ES API available)
98 auto* graph = graphBuilder.GetCGraphBuilder()->GetGraph();113 auto* graph = graphBuilder.GetCGraphBuilder()->GetGraph();
99 auto reduceMeanWithCast = es::CompliantNodeBuilder(graph)114 auto reduceMeanWithCast = es::CompliantNodeBuilder(graph)
100- .OpType("ReduceMeanWithCast")115+ .OpType("ReduceMeanWithCast")
101- .Name("reduce_mean_with_cast")116+ .Name("reduce_mean_with_cast")
102- .IrDefInputs({117+ .IrDefInputs({
103- {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},118+ {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
104- {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},119+ {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
105- })120+ })
106- .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})121+ .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})
107- .Build();122+ .Build();
108 // Connect x to ReduceMeanWithCast input 0123 // Connect x to ReduceMeanWithCast input 0
109- if (es::AddEdgeAndUpdatePeerDesc(*graph, *x.GetProducer(), x.GetProducerOutIndex(),124+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *x.GetProducer(), x.GetProducerOutIndex(), reduceMeanWithCast, 0) !=
110- reduceMeanWithCast, 0) != GRAPH_SUCCESS) {125+ GRAPH_SUCCESS) {
111 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for x input in pattern");126 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for x input in pattern");
112 return patternGraphs;127 return patternGraphs;
113 }128 }
114 129 
115 // Connect axes to ReduceMeanWithCast input 1130 // Connect axes to ReduceMeanWithCast input 1
116- if (es::AddEdgeAndUpdatePeerDesc(*graph, *axes.GetProducer(), axes.GetProducerOutIndex(),131+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *axes.GetProducer(), axes.GetProducerOutIndex(), reduceMeanWithCast, 1) !=
117- reduceMeanWithCast, 1) != GRAPH_SUCCESS) {132+ GRAPH_SUCCESS) {
118 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for axes input in pattern");133 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for axes input in pattern");
119 return patternGraphs;134 return patternGraphs;
120 }135 }
@@ -143,8 +158,9 @@ bool ReduceMeanWithCastFusionPass::MeetRequirements(const std::unique_ptr<MatchR
143 158 
144 // Runtime version check: on GE 8.5.0, return false to no-op.159 // Runtime version check: on GE 8.5.0, return false to no-op.
145 int32_t version = 0;160 int32_t version = 0;
161+ char pkgName[] = "ge_compiler";
146 if (aclsysGetVersionNum) {162 if (aclsysGetVersionNum) {
147- aclsysGetVersionNum(const_cast<char*>("ge_compiler"), &version);163+ aclsysGetVersionNum(pkgName, &version);
148 }164 }
149 if (version < GE_COMPILER_VERSION_900) {165 if (version < GE_COMPILER_VERSION_900) {
150 OP_LOGD(kPassName.c_str(), "GE runtime version %d < 90000000, skip pass.", version);166 OP_LOGD(kPassName.c_str(), "GE runtime version %d < 90000000, skip pass.", version);
@@ -200,18 +216,16 @@ GraphUniqPtr ReduceMeanWithCastFusionPass::Replacement(const std::unique_ptr<Mat
200 }216 }
201 217 
202 OP_LOGD(kPassName.c_str(), "hasDtype=%d, dataType=%d, keep_dims=%d, noop_with_empty_axes=%d",218 OP_LOGD(kPassName.c_str(), "hasDtype=%d, dataType=%d, keep_dims=%d, noop_with_empty_axes=%d",
203- static_cast<int>(hasDtype), static_cast<int>(dataType),219+ static_cast<int>(hasDtype), static_cast<int>(dataType), static_cast<int>(keepDims),
204- static_cast<int>(keepDims), static_cast<int>(noopWithEmptyAxes));220+ static_cast<int>(noopWithEmptyAxes));
205 221 
206 // Build replacement graph222 // Build replacement graph
207 auto replaceBuilder = es::EsGraphBuilder("replacement");223 auto replaceBuilder = es::EsGraphBuilder("replacement");
208 224 
209 // Create input x225 // Create input x
210- auto rX = replaceBuilder.CreateInput(0, "x", inputDtypes[0], inputFormats[0],226+ auto rX = replaceBuilder.CreateInput(0, "x", inputDtypes[0], inputFormats[0], inputShapes[0].GetDims());
211- inputShapes[0].GetDims());
212 // Create input axes227 // Create input axes
213- auto rAxes = replaceBuilder.CreateInput(1, "axes", inputDtypes[1], inputFormats[1],228+ auto rAxes = replaceBuilder.CreateInput(1, "axes", inputDtypes[1], inputFormats[1], inputShapes[1].GetDims());
214- inputShapes[1].GetDims());
215 229 
216 auto* graph = replaceBuilder.GetCGraphBuilder()->GetGraph();230 auto* graph = replaceBuilder.GetCGraphBuilder()->GetGraph();
217 231 
@@ -223,18 +237,18 @@ GraphUniqPtr ReduceMeanWithCastFusionPass::Replacement(const std::unique_ptr<Mat
223 if (hasDtype) {237 if (hasDtype) {
224 // Build Cast node238 // Build Cast node
225 auto castNode = es::CompliantNodeBuilder(graph)239 auto castNode = es::CompliantNodeBuilder(graph)
226- .OpType("Cast")240+ .OpType("Cast")
227- .Name("cast_node")241+ .Name("cast_node")
228- .IrDefInputs({{"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""}})242+ .IrDefInputs({{"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""}})
229- .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})243+ .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})
230- .IrDefAttrs({244+ .IrDefAttrs({
231- {"dst_type", es::CompliantNodeBuilder::kEsAttrRequired, "Int",245+ {"dst_type", es::CompliantNodeBuilder::kEsAttrRequired, "Int",
232- es::CreateFrom(static_cast<int64_t>(dataType))},246+ es::CreateFrom(static_cast<int64_t>(dataType))},
233- })247+ })
234- .Build();248+ .Build();
235 // Connect x to Cast input 0249 // Connect x to Cast input 0
236- if (es::AddEdgeAndUpdatePeerDesc(*graph, *rX.GetProducer(), rX.GetProducerOutIndex(),250+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *rX.GetProducer(), rX.GetProducerOutIndex(), castNode, 0) !=
237- castNode, 0) != GRAPH_SUCCESS) {251+ GRAPH_SUCCESS) {
238 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for Cast input");252 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for Cast input");
239 return nullptr;253 return nullptr;
240 }254 }
@@ -242,47 +256,46 @@ GraphUniqPtr ReduceMeanWithCastFusionPass::Replacement(const std::unique_ptr<Mat
242 reduceMeanInputNode = castNode;256 reduceMeanInputNode = castNode;
243 reduceMeanInputIdx = 0;257 reduceMeanInputIdx = 0;
244 useCast = true;258 useCast = true;
245- OP_LOGD(kPassName.c_str(), "Cast node built and connected, dst_type=%d",259+ OP_LOGD(kPassName.c_str(), "Cast node built and connected, dst_type=%d", static_cast<int>(dataType));
246- static_cast<int>(dataType));
247 }260 }
248 261 
249 // Build ReduceMean node262 // Build ReduceMean node
250 auto reduceMeanNode = es::CompliantNodeBuilder(graph)263 auto reduceMeanNode = es::CompliantNodeBuilder(graph)
251- .OpType("ReduceMean")264+ .OpType("ReduceMean")
252- .Name("reduce_mean")265+ .Name("reduce_mean")
253- .IrDefInputs({266+ .IrDefInputs({
254- {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},267+ {"x", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
255- {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},268+ {"axes", es::CompliantNodeBuilder::kEsIrInputRequired, ""},
256- })269+ })
257- .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})270+ .IrDefOutputs({{"y", es::CompliantNodeBuilder::kEsIrOutputRequired, ""}})
258- .IrDefAttrs({271+ .IrDefAttrs({
259- {"keep_dims", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",272+ {"keep_dims", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",
260- es::CreateFrom(keepDims)},273+ es::CreateFrom(keepDims)},
261- {"noop_with_empty_axes", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",274+ {"noop_with_empty_axes", es::CompliantNodeBuilder::kEsAttrRequired, "Bool",
262- es::CreateFrom(noopWithEmptyAxes)},275+ es::CreateFrom(noopWithEmptyAxes)},
263- })276+ })
264- .Build();277+ .Build();
265 278 
266 // Connect data input to ReduceMean279 // Connect data input to ReduceMean
267 if (useCast) {280 if (useCast) {
268 // Connect Cast output to ReduceMean input 0281 // Connect Cast output to ReduceMean input 0
269- if (es::AddEdgeAndUpdatePeerDesc(*graph, reduceMeanInputNode, reduceMeanInputIdx,282+ if (es::AddEdgeAndUpdatePeerDesc(*graph, reduceMeanInputNode, reduceMeanInputIdx, reduceMeanNode, 0) !=
270- reduceMeanNode, 0) != GRAPH_SUCCESS) {283+ GRAPH_SUCCESS) {
271 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for Cast->ReduceMean");284 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for Cast->ReduceMean");
272 return nullptr;285 return nullptr;
273 }286 }
274 } else {287 } else {
275 // Connect x directly to ReduceMean input 0288 // Connect x directly to ReduceMean input 0
276- if (es::AddEdgeAndUpdatePeerDesc(*graph, *rX.GetProducer(), rX.GetProducerOutIndex(),289+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *rX.GetProducer(), rX.GetProducerOutIndex(), reduceMeanNode, 0) !=
277- reduceMeanNode, 0) != GRAPH_SUCCESS) {290+ GRAPH_SUCCESS) {
278 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for x->ReduceMean");291 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for x->ReduceMean");
279 return nullptr;292 return nullptr;
280 }293 }
281 }294 }
282 295 
283 // Connect axes to ReduceMean input 1296 // Connect axes to ReduceMean input 1
284- if (es::AddEdgeAndUpdatePeerDesc(*graph, *rAxes.GetProducer(), rAxes.GetProducerOutIndex(),297+ if (es::AddEdgeAndUpdatePeerDesc(*graph, *rAxes.GetProducer(), rAxes.GetProducerOutIndex(), reduceMeanNode, 1) !=
285- reduceMeanNode, 1) != GRAPH_SUCCESS) {298+ GRAPH_SUCCESS) {
286 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for axes->ReduceMean");299 OP_LOGE_WITHOUT_REPORT(kPassName.c_str(), "Failed to add edge for axes->ReduceMean");
287 return nullptr;300 return nullptr;
288 }301 }
@@ -307,6 +320,6 @@ GraphUniqPtr ReduceMeanWithCastFusionPass::Replacement(const std::unique_ptr<Mat
307 320 
308REG_FUSION_PASS(ReduceMeanWithCastFusionPass).Stage(GetReduceMeanWithCastPassStage());321REG_FUSION_PASS(ReduceMeanWithCastFusionPass).Stage(GetReduceMeanWithCastPassStage());
309 322 
310-#endif // GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900323+#endif // GE_COMPILER_VERSION_NUM >= GE_COMPILER_VERSION_900
311 324 
312} // namespace ops325} // namespace ops