已合并
整改TopK算子重复定义问题 #5211
整改TopK算子重复定义问题 #5211
已合并
cy_hw创建于 8月29日
共 1 个文件变更+138-0
@@ -0,0 +1,138 @@
1+/**
2+ * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#include "onnx_common.h"
12+#include "math/topk/op_graph/topk_proto.h"
13+ 
14+using namespace std;
15+using namespace ge;
16+using ge::Operator;
17+ 
18+namespace domi {
19+static Status ParseParamsTopK(const Message* op_src, ge::Operator& op_dest)
20+{
21+ const ge::onnx::NodeProto* node = reinterpret_cast<const ge::onnx::NodeProto*>(op_src);
22+ if (node == nullptr) {
23+ OP_LOGE("TopK", "Dynamic cast op_src to NodeProto failed.");
24+ return FAILED;
25+ }
26+ 
27+ int axis = -1;
28+ bool sorted = true;
29+ bool largest = true;
30+ for (const auto& attr : node->attribute()) {
31+ if (attr.name() == "sorted" && attr.type() == ge::onnx::AttributeProto::INT) {
32+ sorted = static_cast<bool>(attr.i());
33+ } else if (attr.name() == "largest" && attr.type() == ge::onnx::AttributeProto::INT) {
34+ largest = static_cast<bool>(attr.i());
35+ } else if (attr.name() == "axis" && attr.type() == ge::onnx::AttributeProto::INT) {
36+ axis = attr.i();
37+ }
38+ }
39+ 
40+ op_dest.SetAttr("name", node->name());
41+ op_dest.SetAttr("sorted", sorted);
42+ op_dest.SetAttr("dim", axis);
43+ op_dest.SetAttr("largest", largest);
44+ 
45+ return SUCCESS;
46+}
47+ 
48+static Status ParseParamsTopKV9(const Message* op_src, ge::Operator& op_dest)
49+{
50+ const ge::onnx::NodeProto* node = reinterpret_cast<const ge::onnx::NodeProto*>(op_src);
51+ if (node == nullptr) {
52+ OP_LOGE("TopK", "Dynamic cast op_src to NodeProto failed.");
53+ return FAILED;
54+ }
55+ 
56+ // 1.add dynamic input and out
57+ int op_input_size = node->input_size();
58+ int op_output_size = node->output_size();
59+ op_dest.DynamicInputRegister("x", op_input_size);
60+ op_dest.DynamicOutputRegister("y", op_output_size);
61+ 
62+ // 2.set original_type
63+ op_dest.SetAttr("original_type", "ai.onnx::9::TopK");
64+ 
65+ int axis = -1;
66+ int64_t data = -1;
67+ 
68+ // 3.set attr if needed
69+ for (const auto& attr : node->attribute()) {
70+ if (attr.name() == "k" && attr.type() == ge::onnx::AttributeProto::INT) {
71+ data = attr.i();
72+ }
73+ if (attr.name() == "axis" && attr.type() == ge::onnx::AttributeProto::INT) {
74+ axis = attr.i();
75+ }
76+ }
77+ if (data == -1) {
78+ OP_LOGE("TopK", "onnx TopK has no K attr.");
79+ return PARAM_INVALID;
80+ }
81+ 
82+ const ge::Tensor scalar_k = CreateScalar(data, ge::DT_INT32);
83+ op_dest.SetAttr("k", scalar_k);
84+ op_dest.SetAttr("dim", axis);
85+ op_dest.SetAttr("name", node->name());
86+ return SUCCESS;
87+}
88+ 
89+static Status ParseOpToGraphTopKV9(const ge::Operator& op, ge::Graph& graph)
90+{
91+ std::string ori_name;
92+ if (op.GetAttr("name", ori_name) != SUCCESS) {
93+ OP_LOGE(GetOpName(op).c_str(), "get name from op failed.");
94+ return FAILED;
95+ }
96+ 
97+ auto data0 = op::Data((ori_name + "_data0").c_str()).set_attr_index(0);
98+ ge::Tensor k_value;
99+ if (op.GetAttr("k", k_value) != SUCCESS) {
100+ OP_LOGE("TopK", "get value from op failed");
101+ return FAILED;
102+ }
103+ 
104+ int dim = -1;
105+ if (op.GetAttr("dim", dim) != SUCCESS) {
106+ OP_LOGE("TopK", "get dim from op failed");
107+ return FAILED;
108+ }
109+ 
110+ auto data1 = op::Const((ori_name + "_data1").c_str()).set_attr_value(k_value);
111+ auto topk = op::TopK((ori_name + "_TopK").c_str()).set_input_x(data0).set_input_k(data1).set_attr_dim(dim);
112+ std::vector<Operator> inputs{data0};
113+ std::vector<std::pair<Operator, std::vector<size_t> > > output_indexs;
114+ output_indexs.emplace_back(topk, vector<std::size_t>{0});
115+ output_indexs.emplace_back(topk, vector<std::size_t>{1});
116+ graph.SetInputs(inputs).SetOutputs(output_indexs);
117+ return SUCCESS;
118+}
119+ 
120+REGISTER_CUSTOM_OP("PartitionedCall")
121+ .FrameworkType(ONNX)
122+ .OriginOpType(std::vector<ge::AscendString>{ge::AscendString("ai.onnx::8::TopK"),
123+ ge::AscendString("ai.onnx::9::TopK")})
124+ .ParseParamsFn(ParseParamsTopKV9)
125+ .ParseOpToGraphFn(ParseOpToGraphTopKV9)
126+ .ImplyType(ImplyType::TVM);
127+ 
128+REGISTER_CUSTOM_OP("TopK")
129+ .FrameworkType(ONNX)
130+ .OriginOpType({ge::AscendString("ai.onnx::10::TopK"), ge::AscendString("ai.onnx::11::TopK"),
131+ ge::AscendString("ai.onnx::12::TopK"), ge::AscendString("ai.onnx::13::TopK"),
132+ ge::AscendString("ai.onnx::14::TopK"), ge::AscendString("ai.onnx::15::TopK"),
133+ ge::AscendString("ai.onnx::16::TopK"), ge::AscendString("ai.onnx::17::TopK"),
134+ ge::AscendString("ai.onnx::18::TopK")})
135+ .ParseParamsFn(ParseParamsTopK)
136+ .ImplyType(ImplyType::TVM);
137+ 
138+} // namespace domi