已合并
回退TriluFusionPass-商分 #3229
回退TriluFusionPass-商分 #3229
已合并
Wangdongxu_mj007创建于 6月9日
4 个文件变更+1-572
@@ -12,4 +12,4 @@
12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62cm12a")12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62cm12a")
13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
14set(SUPPORT_TILING_DIR "arch35" "arch35")14set(SUPPORT_TILING_DIR "arch35" "arch35")
15-add_all_modules_sources(OPTYPE triu ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE DEPENDENCIES tril)15+add_all_modules_sources(OPTYPE triu ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)
@@ -1,273 +0,0 @@
1-/**
2- * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.
9- */
10- 
11-/**
12- * @brief Trilu fusion pass (Trilu --> Tril/Triu)
13- * @details
14- * upper?
15- * x, k(input), upper(attr) 0 / \ 1
16- * | / \
17- * Trilu ==> x, diagonal(attr) x, diagonal(attr)
18- * | | |
19- * y Tril Triu
20- * | |
21- * y y
22- *
23- * The key transformation:
24- * - Trilu has optional input k (diagonal offset) and attribute upper
25- * - Tril/Triu have attribute diagonal instead of input k
26- * - upper=0 -> Tril, upper=1 -> Triu
27- * - k input value is extracted and converted to diagonal attribute
28- */
29- 
30-#include <vector>
31-#include <string>
32-#include "es_math_ops.h"
33-#include "platform/platform_info.h"
34-#include "ge/ge_utils.h"
35-#include "ge/compliant_node_builder.h"
36-#include "log/log.h"
37-#include "trilu_fusion_pass.h"
38- 
39-using namespace ge;
40-using namespace fe;
41-using namespace ge::fusion;
42- 
43-namespace ops {
44- 
45-const std::string kFusionPassName = "TriluFusionPass";
46-const int64_t kCaptureIdxTriluNode = 0L;
47- 
48-const std::set<std::string> kTriluSupportSocList = {
49- "Ascend310B", "Ascend310P", "Ascend910", "Ascend910B", "Ascend910_93", "Ascend950"};
50- 
51-static bool IsSupportSoc()
52-{
53- PlatformInfo platformInfo;
54- OptionalInfo optionalInfo;
55- if (unlikely(PlatformInfoManager::Instance().GetPlatformInfoWithOutSocVersion(platformInfo, optionalInfo) != SUCCESS)) {
56- OP_LOGE(kFusionPassName.c_str(), "Get platform_info failed.");
57- return false;
58- }
59- const std::string soc = platformInfo.str_info.short_soc_version;
60- if (kTriluSupportSocList.count(soc) == 0) {
61- OP_LOGE(kFusionPassName.c_str(), "SoC %s is not supported by this fusion pass.", soc.c_str());
62- return false;
63- }
64- return true;
65-}
66- 
67-static bool GetDiagonalValue(const GNode& triluNode, int32_t& diagonalValue)
68-{
69- if (triluNode.GetInputsSize() < 2) {
70- diagonalValue = 0;
71- OP_LOGD(kFusionPassName.c_str(), "No k input, set diagonal to default value 0.");
72- return true;
73- }
74- 
75- auto srcInfo = triluNode.GetInDataNodesAndPortIndexs(1);
76- auto srcNodePtr = srcInfo.first;
77- if (srcNodePtr == nullptr) {
78- diagonalValue = 0;
79- OP_LOGD(kFusionPassName.c_str(), "k input source node is null, set diagonal to default value 0.");
80- return true;
81- }
82- 
83- GNode srcNode = *srcNodePtr;
84- AscendString nodeType;
85- srcNode.GetType(nodeType);
86- std::string typeStr = nodeType.GetString();
87- 
88- if (typeStr != "Const" && typeStr != "Constant") {
89- OP_LOGE(kFusionPassName.c_str(), "k input is not a constant, cannot extract diagonal value.");
90- return false;
91- }
92- 
93- Tensor tensor;
94- if (srcNode.GetAttr("value", tensor) != GRAPH_SUCCESS) {
95- OP_LOGE(kFusionPassName.c_str(), "Failed to get value attr from Const node.");
96- return false;
97- }
98- 
99- auto tensorDesc = tensor.GetTensorDesc();
100- auto shape = tensorDesc.GetShape();
101- auto dims = shape.GetDims();
102- 
103- if (dims.size() > 1 || (dims.size() == 1 && dims[0] != 1)) {
104- OP_LOGE(kFusionPassName.c_str(), "Invalid k shape, expected scalar or 1D with size 1.");
105- return false;
106- }
107- 
108- DataType dtype = tensorDesc.GetDataType();
109- const uint8_t* dataPtr = tensor.GetData();
110- if (dataPtr == nullptr) {
111- OP_LOGE(kFusionPassName.c_str(), "k tensor data is null.");
112- return false;
113- }
114- 
115- if (dtype == DT_INT32) {
116- diagonalValue = *reinterpret_cast<const int32_t*>(dataPtr);
117- } else if (dtype == DT_INT64) {
118- diagonalValue = static_cast<int32_t>(*reinterpret_cast<const int64_t*>(dataPtr));
119- } else {
120- OP_LOGE(kFusionPassName.c_str(), "k tensor dtype %d not supported, only int32/int64.", dtype);
121- return false;
122- }
123- 
124- OP_LOGD(kFusionPassName.c_str(), "Extracted diagonal value: %d", diagonalValue);
125- return true;
126-}
127- 
128-static Status InferShape(const GraphUniqPtr& replaceGraph, const std::vector<SubgraphInput>& subgraphInputs)
129-{
130- OP_LOGD(kFusionPassName.c_str(), "Begin infershape for replacement.");
131- std::vector<Shape> inputShapes;
132- for (const auto& subgraphInput : subgraphInputs) {
133- auto matchNode = subgraphInput.GetAllInputs().at(0);
134- TensorDesc tensorDesc;
135- matchNode.node.GetInputDesc(matchNode.index, tensorDesc);
136- inputShapes.emplace_back(tensorDesc.GetShape());
137- }
138- return GeUtils::InferShape(*replaceGraph, inputShapes);
139-}
140- 
141-static void GetInputsInfo(const std::vector<SubgraphInput> &subGraphInputs, std::vector<Shape> &inputShapes,
142- std::vector<DataType> &inputDtpyes, std::vector<Format> &inputFormats)
143- {
144- for (const auto& subGraphInput : subGraphInputs) {
145- auto matchNode = subGraphInput.GetAllInputs().at(0);
146- TensorDesc tensorDesc;
147- AscendString nodeType;
148- matchNode.node.GetType(nodeType);
149- matchNode.node.GetInputDesc(matchNode.index, tensorDesc);
150- inputShapes.emplace_back(tensorDesc.GetShape());
151- inputDtpyes.emplace_back(tensorDesc.GetDataType());
152- inputFormats.emplace_back(tensorDesc.GetFormat());
153- }
154-}
155- 
156-std::vector<PatternUniqPtr> TriluFusionPass::Patterns()
157-{
158- OP_LOGD(kFusionPassName.c_str(), "Enter Patterns for TriluFusionPass");
159- std::vector<PatternUniqPtr> patternGraphs;
160- 
161- auto graphBuilder0 = es::EsGraphBuilder("TriluXFusionPass");
162- auto x0 = graphBuilder0.CreateInput(0);
163- auto output0 = es::Trilu(x0);
164- auto graph0 = graphBuilder0.BuildAndReset(std::vector<es::EsTensorHolder>{output0});
165- auto pattern0 = std::make_unique<Pattern>(std::move(*graph0));
166- pattern0->CaptureTensor({*output0.GetProducer(), 0}); // Capture the Trilu node
167- patternGraphs.emplace_back(std::move(pattern0));
168- 
169- auto graphBuilder1 = es::EsGraphBuilder("TriluXKConstFusionPass");
170- auto x1 = graphBuilder1.CreateInput(0);
171- auto k0 = graphBuilder1.CreateConst(std::vector<int32_t>{0},std::vector<int64_t>{0});
172- auto output1 = es::Trilu(x1, k0);
173- auto graph1 = graphBuilder1.BuildAndReset(std::vector<es::EsTensorHolder>{output1});
174- auto pattern1 = std::make_unique<Pattern>(std::move(*graph1));
175- pattern1->CaptureTensor({*output1.GetProducer(), 0}); // Capture the Trilu node
176- patternGraphs.emplace_back(std::move(pattern1));
177- return patternGraphs;
178-}
179- 
180-bool TriluFusionPass::MeetRequirements(const std::unique_ptr<MatchResult>& matchResult)
181-{
182- OP_LOGD(kFusionPassName.c_str(), "Enter MeetRequirements for TriluFusionPass");
183- auto patternGraph = matchResult->GetPatternGraph();
184- AscendString patternName;
185- 
186- if (patternGraph.GetName(patternName) != GRAPH_SUCCESS){
187- OP_LOGE(kFusionPassName.c_str(), "Failed to get patternName.");
188- return false;
189- }
190- 
191- if (!IsSupportSoc()) {
192- OP_LOGE(kFusionPassName.c_str(), "Platform not supported.");
193- return false;
194- }
195- 
196- NodeIo triluNodeIo;
197- if (unlikely(matchResult->GetCapturedTensor(kCaptureIdxTriluNode, triluNodeIo) != SUCCESS)) {
198- OP_LOGE(kFusionPassName.c_str(), "Failed to get captured tensor.");
199- return false;
200- }
201- AscendString nodeType;
202- triluNodeIo.node.GetType(nodeType);
203- std::string typeStr = nodeType.GetString();
204- if (typeStr != "Trilu") {
205- OP_LOGE(kFusionPassName.c_str(), "Node type %s is not Trilu, skip.", typeStr.c_str());
206- return false;
207- }
208- 
209- int32_t upper = 0;
210- if (triluNodeIo.node.GetAttr("upper", upper) != GRAPH_SUCCESS) {
211- // Attribute not set, use default value 0
212- upper = 0;
213- OP_LOGE(kFusionPassName.c_str(), "upper attribute not set, use default value 0.");
214- }
215- if (upper != 0 && upper != 1) {
216- OP_LOGE(kFusionPassName.c_str(), "upper value %d is not 0 or 1, skip.", upper);
217- return false;
218- }
219- 
220- // 4. Check and extract diagonal value from k input
221- int32_t diagonal = 0;
222- if (!GetDiagonalValue(triluNodeIo.node, diagonal)) {
223- OP_LOGE(kFusionPassName.c_str(), "Failed to get diagonal value from k input, skip.");
224- return false;
225- }
226- 
227- return true;
228-}
229- 
230-GraphUniqPtr TriluFusionPass::Replacement(const std::unique_ptr<MatchResult>& matchResult)
231-{
232- OP_LOGD(kFusionPassName.c_str(), "Enter Replacement for TriluFusionPass");
233- AscendString patternName;
234- auto patternGraph = matchResult->GetPatternGraph();
235- patternGraph.GetName(patternName);
236- 
237- NodeIo triluNodeIo;
238- matchResult->GetCapturedTensor(kCaptureIdxTriluNode, triluNodeIo);
239- int32_t upper = 0;
240- triluNodeIo.node.GetAttr("upper", upper);
241- int32_t diagonal = 0;
242- GetDiagonalValue(triluNodeIo.node, diagonal);
243-
244- std::vector<SubgraphInput> subGraphInputs;
245- matchResult->ToSubgraphBoundary()->GetAllInputs(subGraphInputs);
246- std::vector<Shape> inputShapes;
247- std::vector<DataType> inputDtpyes;
248- std::vector<Format> inputFormats;
249- GetInputsInfo(subGraphInputs, inputShapes, inputDtpyes, inputFormats);
250- 
251- auto replaceGraphBuilder = es::EsGraphBuilder("replacement");
252- auto xTensor = replaceGraphBuilder.CreateInput(0, "x", inputDtpyes[0], inputFormats[0], inputShapes[0].GetDims());
253- auto res = (upper == 0) ? es::Tril(xTensor, diagonal) : es::Triu(xTensor, diagonal);
254- 
255- GNode triluNode = *res.GetProducer();
256- auto triluNodeFormat = inputFormats[0];
257- TensorDesc triluInputDesc;
258- triluNode.GetInputDesc(0, triluInputDesc);
259- triluInputDesc.SetFormat(triluNodeFormat);
260- triluNode.UpdateInputDesc(0, triluInputDesc);
261-
262- auto replaceGraph = replaceGraphBuilder.BuildAndReset({res});
263- 
264- 
265- if (InferShape(replaceGraph, subGraphInputs) != SUCCESS) {
266- OP_LOGE(kFusionPassName.c_str(), "Infershape for replacement failed.");
267- return nullptr;
268- }
269- 
270- return replaceGraph;
271-}
272-REG_FUSION_PASS(TriluFusionPass).Stage(CustomPassStage::kCompatibleInherited);
273-} // namespace ops
@@ -1,34 +0,0 @@
1-/**
2- * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.
9- */
10- 
11-#include "ge/fusion/pass/pattern_fusion_pass.h"
12- 
13-#ifndef OPS_MATH_CONVERSION_TRIU_FUSION_PASS_TRILU_FUSION_PASS_H_
14-#define OPS_MATH_CONVERSION_TRIU_FUSION_PASS_TRILU_FUSION_PASS_H_
15- 
16-namespace ops {
17-using namespace ge;
18-using namespace ge::fusion;
19- 
20-class __attribute__((visibility("default"))) TriluFusionPass : public PatternFusionPass {
21-protected:
22- std::vector<PatternUniqPtr> Patterns() override;
23- 
24- bool MeetRequirements(const std::unique_ptr<MatchResult>& matchResult) override;
25- 
26- GraphUniqPtr Replacement(const std::unique_ptr<MatchResult>& matchResult) override;
27-};
28- 
29-static void GetInputsInfo(const std::vector<SubgraphInput> &subgraphInputs, std::vector<Shape> &inputShapes,
30- std::vector<DataType> &inputDtypes, std::vector<Format> &inputFormats);
31-static Status InferShape(const GraphUniqPtr &replaceGraph, const std::vector<SubgraphInput> &subgraphInputs);
32- 
33-} // namespace ops
34-#endif // OPS_MATH_CONVERSION_TRIU_FUSION_PASS_TRILU_FUSION_PASS_H_
@@ -1,264 +0,0 @@
1-/**
2- * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3- * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4- * CANN Open Software License Agreement Version 2.0 (the "License").
5- * Please refer to the License for details. You may not use this file except in compliance with the License.
6- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7- * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8- * See LICENSE in the root of the software repository for the full text of the License.
9- */
10- 
11-#include <iostream>
12-#include <vector>
13-#include "gtest/gtest.h"
14-#include "platform/platform_infos_def.h"
15-#include "platform/platform_info.h"
16-#include "ge/es_graph_builder.h"
17-#include "es_math_ops.h"
18-#include "log/log.h"
19-#include "../../../op_graph/fusion_pass/trilu_fusion_pass.h"
20- 
21-using namespace std;
22-using namespace ge;
23-using namespace fe;
24-using namespace fusion;
25-using namespace ops;
26- 
27-namespace {
28-const std::string kPassName = "TriluFusionPass";
29-}
30- 
31-class TriluFusionPassTest : public testing::Test {
32-protected:
33- static void SetUpTestCase()
34- {
35- PlatformInfo platformInfo;
36- OptionalInfo optiCompilationInfo;
37- platformInfo.soc_info.ai_core_cnt = 64;
38- platformInfo.str_info.short_soc_version = "Ascend910_93";
39- optiCompilationInfo.soc_version = "Ascend910_93";
40- PlatformInfoManager::Instance().platform_info_map_["Ascend910_93"] = platformInfo;
41- PlatformInfoManager::Instance().SetOptionalCompilationInfo(optiCompilationInfo);
42- }
43- 
44- void SetUp() override
45- {
46- PlatformInfo platformInfo;
47- OptionalInfo optiCompilationInfo;
48- platformInfo.soc_info.ai_core_cnt = 64;
49- platformInfo.str_info.short_soc_version = "Ascend910_93";
50- optiCompilationInfo.soc_version = "Ascend910_93";
51- PlatformInfoManager::Instance().platform_info_map_["Ascend910_93"] = platformInfo;
52- PlatformInfoManager::Instance().SetOptionalCompilationInfo(optiCompilationInfo);
53- }
54- 
55- void SetPlatform(const std::string& soc)
56- {
57- PlatformInfo platformInfo;
58- OptionalInfo optiCompilationInfo;
59- platformInfo.soc_info.ai_core_cnt = 64;
60- platformInfo.str_info.short_soc_version = soc;
61- optiCompilationInfo.soc_version = soc;
62- PlatformInfoManager::Instance().platform_info_map_[soc] = platformInfo;
63- PlatformInfoManager::Instance().SetOptionalCompilationInfo(optiCompilationInfo);
64- }
65-};
66- 
67-TEST_F(TriluFusionPassTest, patternTest)
68-{
69- TriluFusionPass pass;
70- std::vector<PatternUniqPtr> patterns = pass.Patterns();
71- EXPECT_GT(patterns.size(), 0);
72-}
73- 
74-TEST_F(TriluFusionPassTest, fusionSuccessUpper0NoK)
75-{
76- std::vector<int64_t> dimsX{10, 10};
77- Shape shapeX(dimsX);
78- 
79- auto graphBuilder = es::EsGraphBuilder("test");
80- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT16, FORMAT_ND, shapeX.GetDims());
81- auto output = es::Trilu(x, nullptr, 0);
82- 
83- TensorDesc xDesc;
84- x.GetProducer()->GetOutputDesc(0, xDesc);
85- xDesc.SetDataType(DT_FLOAT16);
86- xDesc.SetShape(shapeX);
87- xDesc.SetFormat(FORMAT_ND);
88- x.GetProducer()->UpdateOutputDesc(0, xDesc);
89- 
90- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
91- 
92- CustomPassContext passContext;
93- TriluFusionPass pass;
94- Status status = pass.Run(graph, passContext);
95- 
96- EXPECT_TRUE(status == SUCCESS || status == GRAPH_NOT_CHANGED);
97- 
98- bool foundTril = false;
99- bool foundTriu = false;
100- for (auto node : graph->GetAllNodes()) {
101- AscendString type;
102- node.GetType(type);
103- if (type == "Tril") {
104- foundTril = true;
105- }
106- if (type == "Triu") {
107- foundTriu = true;
108- }
109- }
110- EXPECT_TRUE(foundTril || foundTriu);
111-}
112- 
113-TEST_F(TriluFusionPassTest, fusionSuccessUpper1NoK)
114-{
115- std::vector<int64_t> dimsX{10, 10};
116- Shape shapeX(dimsX);
117- 
118- auto graphBuilder = es::EsGraphBuilder("test");
119- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT16, FORMAT_ND, shapeX.GetDims());
120- auto output = es::Trilu(x, nullptr, 1);
121- 
122- TensorDesc xDesc;
123- x.GetProducer()->GetOutputDesc(0, xDesc);
124- xDesc.SetDataType(DT_FLOAT16);
125- xDesc.SetShape(shapeX);
126- xDesc.SetFormat(FORMAT_ND);
127- x.GetProducer()->UpdateOutputDesc(0, xDesc);
128- 
129- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
130- 
131- CustomPassContext passContext;
132- TriluFusionPass pass;
133- Status status = pass.Run(graph, passContext);
134- 
135- EXPECT_TRUE(status == SUCCESS);
136-}
137- 
138-TEST_F(TriluFusionPassTest, fusionSuccessFp32)
139-{
140- std::vector<int64_t> dimsX{10, 10};
141- Shape shapeX(dimsX);
142- 
143- auto graphBuilder = es::EsGraphBuilder("test");
144- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT, FORMAT_ND, shapeX.GetDims());
145- 
146- auto output = es::Trilu(x, nullptr, 0);
147- 
148- TensorDesc xDesc;
149- x.GetProducer()->GetOutputDesc(0, xDesc);
150- xDesc.SetDataType(DT_FLOAT);
151- xDesc.SetShape(shapeX);
152- xDesc.SetFormat(FORMAT_ND);
153- x.GetProducer()->UpdateOutputDesc(0, xDesc);
154- 
155- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
156- 
157- CustomPassContext passContext;
158- TriluFusionPass pass;
159- Status status = pass.Run(graph, passContext);
160- 
161- EXPECT_TRUE(status == SUCCESS);
162- 
163- bool found = false;
164- for (auto node : graph->GetAllNodes()) {
165- AscendString type;
166- node.GetType(type);
167- if (type == "Tril" || type == "Triu") {
168- found = true;
169- break;
170- }
171- }
172- EXPECT_TRUE(found);
173-}
174- 
175-TEST_F(TriluFusionPassTest, fusionSuccess3dShape)
176-{
177- std::vector<int64_t> dimsX{2, 10, 10};
178- Shape shapeX(dimsX);
179- 
180- auto graphBuilder = es::EsGraphBuilder("test");
181- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT16, FORMAT_ND, shapeX.GetDims());
182- 
183- auto output = es::Trilu(x, nullptr, 1);
184- 
185- TensorDesc xDesc;
186- x.GetProducer()->GetOutputDesc(0, xDesc);
187- xDesc.SetDataType(DT_FLOAT16);
188- xDesc.SetShape(shapeX);
189- xDesc.SetFormat(FORMAT_ND);
190- x.GetProducer()->UpdateOutputDesc(0, xDesc);
191- 
192- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
193- 
194- CustomPassContext passContext;
195- TriluFusionPass pass;
196- Status status = pass.Run(graph, passContext);
197- 
198- EXPECT_TRUE(status == SUCCESS);
199-}
200- 
201-TEST_F(TriluFusionPassTest, unsupportedPlatformFail)
202-{
203- // Set unsupported platform (not in kTriluSupportSocList and not bf16 capable)
204- SetPlatform("Ascend310");
205- 
206- std::vector<int64_t> dimsX{10, 10};
207- Shape shapeX(dimsX);
208- 
209- auto graphBuilder = es::EsGraphBuilder("test");
210- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT16, FORMAT_ND, shapeX.GetDims());
211- auto output = es::Trilu(x, nullptr, 0);
212- 
213- TensorDesc xDesc;
214- x.GetProducer()->GetOutputDesc(0, xDesc);
215- xDesc.SetDataType(DT_FLOAT16);
216- xDesc.SetShape(shapeX);
217- xDesc.SetFormat(FORMAT_ND);
218- x.GetProducer()->UpdateOutputDesc(0, xDesc);
219- 
220- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
221- 
222- CustomPassContext passContext;
223- TriluFusionPass pass;
224- Status status = pass.Run(graph, passContext);
225- 
226- EXPECT_EQ(status, GRAPH_NOT_CHANGED);
227-}
228- 
229-TEST_F(TriluFusionPassTest, fusionSuccessAscend950)
230-{
231- SetPlatform("Ascend950");
232- 
233- std::vector<int64_t> dimsX{10, 10};
234- Shape shapeX(dimsX);
235- 
236- auto graphBuilder = es::EsGraphBuilder("test");
237- auto x = graphBuilder.CreateInput(0, "x", DT_FLOAT16, FORMAT_ND, shapeX.GetDims());
238- auto output = es::Trilu(x, nullptr, 0);
239- 
240- TensorDesc xDesc;
241- x.GetProducer()->GetOutputDesc(0, xDesc);
242- xDesc.SetDataType(DT_FLOAT16);
243- xDesc.SetShape(shapeX);
244- xDesc.SetFormat(FORMAT_ND);
245- x.GetProducer()->UpdateOutputDesc(0, xDesc);
246- std::shared_ptr<Graph> graph = graphBuilder.BuildAndReset(std::vector<es::EsTensorHolder>{output});
247- 
248- CustomPassContext passContext;
249- TriluFusionPass pass;
250- Status status = pass.Run(graph, passContext);
251- 
252- EXPECT_TRUE(status == SUCCESS);
253- 
254- bool found = false;
255- for (auto node : graph->GetAllNodes()) {
256- AscendString type;
257- node.GetType(type);
258- if (type == "Tril" || type == "Triu") {
259- found = true;
260- break;
261- }
262- }
263- EXPECT_TRUE(found);
264-}