已合并
feat: 自定义算子多模型支持 #3026
Chang-an-HW创建于 5月20日
feat: 自定义算子多模型支持 #3026
已合并
Chang-an-HW创建于 5月20日
88 个文件变更+3316-615
@@ -541,7 +541,8 @@ elseif (BUILD_OPEN_PROJECT OR ENABLE_OPEN_SRC)
541 541 
542 add_custom_target(ge-executor)542 add_custom_target(ge-executor)
543 add_dependencies(ge-executor ge_common ge_executor_shared ge_common_base davinci_executor hybrid_executor gert om2_executor register543 add_dependencies(ge-executor ge_common ge_executor_shared ge_common_base davinci_executor hybrid_executor gert om2_executor register
544- graph npu_sched_model_loader lowering register_static graph_base model_deployer data_flow_base hcom_executor)544+ graph custom_op_registry_static npu_sched_model_loader lowering register_static graph_base model_deployer
545+ data_flow_base hcom_executor)
545 add_dependencies(ge-executor acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl acl_cblas)546 add_dependencies(ge-executor acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl acl_cblas)
546 add_dependencies(ge-executor ge_common_stub stub_lowering atc_stub_graph gert_stub hybrid_executor_stub stub_register stub_acl_mdl547 add_dependencies(ge-executor ge_common_stub stub_lowering atc_stub_graph gert_stub hybrid_executor_stub stub_register stub_acl_mdl
547 stub_acl_cblas stub_acl_op_executor)548 stub_acl_cblas stub_acl_op_executor)
@@ -556,7 +557,8 @@ elseif (BUILD_OPEN_PROJECT OR ENABLE_OPEN_SRC)
556 add_dependencies(ge-compiler flow_graph)557 add_dependencies(ge-compiler flow_graph)
557 558 
558 add_custom_target(ge-executor)559 add_custom_target(ge-executor)
559- add_dependencies(ge-executor ge_common ge_common_base davinci_executor hybrid_executor gert register graph graph_base acl_cblas)560+ add_dependencies(ge-executor ge_common ge_common_base davinci_executor hybrid_executor gert register graph
561+ custom_op_registry_static graph_base acl_cblas)
560 add_dependencies(ge-executor acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl om2_executor ge_executor_shared hcom_executor lowering)562 add_dependencies(ge-executor acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl om2_executor ge_executor_shared hcom_executor lowering)
561 endif ()563 endif ()
562 564 
@@ -84,6 +84,7 @@ set(SRC_BASE_LIST
84 "common/plugin/op_tiling_manager.cc"84 "common/plugin/op_tiling_manager.cc"
85 "common/ge_inner_error_codes.cc"85 "common/ge_inner_error_codes.cc"
86 "common/helper/model_helper.cc"86 "common/helper/model_helper.cc"
87+ "common/helper/custom_op_registry_builder.cc"
87 "common/helper/custom_op_so_loader.cc"88 "common/helper/custom_op_so_loader.cc"
88 "common/helper/model_custom_kernels_helper.cc"89 "common/helper/model_custom_kernels_helper.cc"
89 "common/helper/pre_model_helper.cc"90 "common/helper/pre_model_helper.cc"
@@ -0,0 +1,151 @@
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 "common/helper/custom_op_registry_builder.h"
12+ 
13+#include <memory>
14+#include <set>
15+#include <string>
16+#include <vector>
17+ 
18+#include "common/helper/custom_op_so_loader.h"
19+#include "framework/common/debug/log.h"
20+#include "graph_metadef/common/ge_common/util.h"
21+#include "graph/custom_op_pull_registry.h"
22+#include "mmpa/mmpa_api.h"
23+ 
24+namespace ge {
25+namespace {
26+constexpr const char *kGetCreatorAbiVersionSymbol = "GetRegisteredCustomOpCreatorAbiVersion";
27+constexpr const char *kGetCreatorNumSymbol = "GetRegisteredCustomOpCreatorNum";
28+constexpr const char *kGetCreatorsSymbol = "GetRegisteredCustomOpCreators";
29+ 
30+using GetCreatorAbiVersionFunc = uint32_t (*)();
31+using GetCreatorNumFunc = size_t (*)();
32+using GetCreatorsFunc = int32_t (*)(CustomOpTypeToCreator *, size_t, size_t);
33+ 
34+struct PullCreatorSymbols {
35+ GetCreatorAbiVersionFunc get_abi_version = nullptr;
36+ GetCreatorNumFunc get_creator_num = nullptr;
37+ GetCreatorsFunc get_creators = nullptr;
38+};
39+ 
40+struct PendingCreator {
41+ std::string op_type;
42+ CustomOpCreateFunc creator = nullptr;
43+};
44+ 
45+Status ResolvePullCreatorSymbols(void *const so_handle, const CustomOpRegistryBuilder::DlsymFunc dlsym_func,
46+ PullCreatorSymbols &symbols) {
47+ symbols.get_abi_version =
48+ reinterpret_cast<GetCreatorAbiVersionFunc>(dlsym_func(so_handle, kGetCreatorAbiVersionSymbol));
49+ symbols.get_creator_num = reinterpret_cast<GetCreatorNumFunc>(dlsym_func(so_handle, kGetCreatorNumSymbol));
50+ symbols.get_creators = reinterpret_cast<GetCreatorsFunc>(dlsym_func(so_handle, kGetCreatorsSymbol));
51+ if ((symbols.get_abi_version == nullptr) || (symbols.get_creator_num == nullptr) ||
52+ (symbols.get_creators == nullptr)) {
53+ GELOGE(FAILED, "[CUSTOM OP] pull creator ABI symbols are incomplete.");
54+ return FAILED;
55+ }
56+ return SUCCESS;
57+}
58+ 
59+Status LoadRawCreators(const PullCreatorSymbols &symbols, std::vector<CustomOpTypeToCreator> &raw_creators) {
60+ const uint32_t abi_version = symbols.get_abi_version();
61+ if (abi_version != kCustomOpCreatorPullAbiVersion) {
62+ GELOGE(FAILED, "[CUSTOM OP] pull creator ABI version %u does not match expected %u.",
63+ abi_version, kCustomOpCreatorPullAbiVersion);
64+ return FAILED;
65+ }
66+ 
67+ const size_t creator_num = symbols.get_creator_num();
68+ raw_creators.resize(creator_num);
69+ const auto ret = symbols.get_creators(raw_creators.empty() ? nullptr : raw_creators.data(),
70+ raw_creators.size(), sizeof(CustomOpTypeToCreator));
71+ if (ret != 0) {
72+ GELOGE(FAILED, "[CUSTOM OP] get registered custom op creators failed, ret:%d.", ret);
73+ return FAILED;
74+ }
75+ return SUCCESS;
76+}
77+ 
78+Status ValidateAndCollectCreator(const CustomOpTypeToCreator &raw_creator, const CustomOpRegistryPtr &registry,
79+ std::set<std::string> &pending_op_types,
80+ std::vector<PendingCreator> &pending_creators) {
81+ if ((raw_creator.struct_size != sizeof(CustomOpTypeToCreator)) || (raw_creator.op_type == nullptr) ||
82+ (raw_creator.op_type[0] == '\0') || (raw_creator.creator == nullptr)) {
83+ GELOGE(FAILED, "[CUSTOM OP] invalid custom op pull creator entry.");
84+ return FAILED;
85+ }
86+ 
87+ const std::string op_type(raw_creator.op_type);
88+ if (registry->HasCreator(AscendString(op_type.c_str())) ||
89+ (pending_op_types.find(op_type) != pending_op_types.end())) {
90+ GELOGE(FAILED, "[CUSTOM OP] duplicate custom op creator for %s in model registry.", op_type.c_str());
91+ return FAILED;
92+ }
93+ 
94+ (void)pending_op_types.insert(op_type);
95+ pending_creators.push_back({op_type, raw_creator.creator});
96+ return SUCCESS;
97+}
98+ 
99+Status CollectCreatorsFromSoHandle(const CustomOpSoHandlePtr &so_handle, const CustomOpRegistryPtr &registry,
100+ const CustomOpRegistryBuilder::DlsymFunc dlsym_func,
101+ std::set<std::string> &pending_op_types,
102+ std::vector<PendingCreator> &pending_creators) {
103+ if ((so_handle == nullptr) || (so_handle->GetHandle() == nullptr)) {
104+ GELOGE(FAILED, "[CUSTOM OP] custom op so handle is null.");
105+ return FAILED;
106+ }
107+ 
108+ PullCreatorSymbols symbols;
109+ GE_CHK_STATUS_RET(ResolvePullCreatorSymbols(so_handle->GetHandle(), dlsym_func, symbols),
110+ "[CUSTOM OP] resolve pull creator symbols failed.");
111+ std::vector<CustomOpTypeToCreator> raw_creators;
112+ GE_CHK_STATUS_RET(LoadRawCreators(symbols, raw_creators), "[CUSTOM OP] load raw pull creators failed.");
113+ for (const auto &raw_creator : raw_creators) {
114+ GE_CHK_STATUS_RET(ValidateAndCollectCreator(raw_creator, registry, pending_op_types, pending_creators),
115+ "[CUSTOM OP] validate pull creator failed.");
116+ }
117+ return SUCCESS;
118+}
119+} // namespace
120+ 
121+Status CustomOpRegistryBuilder::AddCreatorsFromSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles,
122+ const CustomOpRegistryPtr &registry) {
123+ return AddCreatorsFromSoHandles(so_handles, registry, mmDlsym);
124+}
125+ 
126+Status CustomOpRegistryBuilder::AddCreatorsFromSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles,
127+ const CustomOpRegistryPtr &registry,
128+ const DlsymFunc dlsym_func) {
129+ if ((registry == nullptr) || (dlsym_func == nullptr)) {
130+ GELOGE(FAILED, "[CUSTOM OP] registry or dlsym function is null.");
131+ return FAILED;
132+ }
133+ 
134+ std::set<std::string> pending_op_types;
135+ std::vector<PendingCreator> pending_creators;
136+ for (const auto &so_handle : so_handles) {
137+ GE_CHK_STATUS_RET(CollectCreatorsFromSoHandle(so_handle, registry, dlsym_func, pending_op_types, pending_creators),
138+ "[CUSTOM OP] collect creators from custom op so handle failed.");
139+ }
140+ 
141+ for (const auto &pending_creator : pending_creators) {
142+ const auto register_ret = registry->RegisterCreator(AscendString(pending_creator.op_type.c_str()),
143+ [creator = pending_creator.creator]() {
144+ return std::unique_ptr<BaseCustomOp>(creator());
145+ });
146+ GE_CHK_STATUS_RET(register_ret, "[CUSTOM OP] register pull creator to model registry failed.");
147+ }
148+ registry->AddSoHandles(so_handles);
149+ return SUCCESS;
150+}
151+} // namespace ge
@@ -0,0 +1,33 @@
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+#ifndef BASE_COMMON_HELPER_CUSTOM_OP_REGISTRY_BUILDER_H_
12+#define BASE_COMMON_HELPER_CUSTOM_OP_REGISTRY_BUILDER_H_
13+ 
14+#include <vector>
15+ 
16+#include "external/ge_common/ge_api_types.h"
17+#include "graph/custom_op_registry.h"
18+ 
19+namespace ge {
20+class CustomOpRegistryBuilder {
21+ public:
22+ using DlsymFunc = void *(*)(void *handle, const char *symbol);
23+ 
24+ static Status AddCreatorsFromSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles,
25+ const CustomOpRegistryPtr &registry);
26+ 
27+ private:
28+ static Status AddCreatorsFromSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles,
29+ const CustomOpRegistryPtr &registry, DlsymFunc dlsym_func);
30+};
31+} // namespace ge
32+ 
33+#endif // BASE_COMMON_HELPER_CUSTOM_OP_REGISTRY_BUILDER_H_
@@ -11,9 +11,13 @@
11#include "common/helper/custom_op_so_loader.h"11#include "common/helper/custom_op_so_loader.h"
12 12 
13#include <cerrno>13#include <cerrno>
14+#include <cinttypes>
14#include <cstddef>15#include <cstddef>
15#include <cstdint>16#include <cstdint>
16#include <dlfcn.h>17#include <dlfcn.h>
18+#include <iomanip>
19+#include <functional>
20+#include <sstream>
17#include <unistd.h>21#include <unistd.h>
18#include <sys/syscall.h>22#include <sys/syscall.h>
19#include <utility>23#include <utility>
@@ -21,6 +25,7 @@
21 25 
22#include "common/checker.h"26#include "common/checker.h"
23#include "framework/common/debug/log.h"27#include "framework/common/debug/log.h"
28+#include "graph/custom_op_load_context.h"
24#include "graph/utils/file_utils.h"29#include "graph/utils/file_utils.h"
25#include "mmpa/mmpa_api.h"30#include "mmpa/mmpa_api.h"
26 31 
@@ -29,20 +34,17 @@
29 * 本文件实现 CustomOpSoLoader,用于将 OM 中携带的自定义算子 so 二进制以“仅内存”方式加载到当前进程。34 * 本文件实现 CustomOpSoLoader,用于将 OM 中携带的自定义算子 so 二进制以“仅内存”方式加载到当前进程。
30 *35 *
31 * 核心流程:36 * 核心流程:
32- * 1) 生成稳定标识:使用 vendor_name + so_name 生成 so_key,并计算内容指纹(bin_size + FNV1a64)37+ * 1) 生成稳定标识:使用 so 二进制内容的 hash hex 字符串作为 fingerprint key
33 * 2) 内存加载:通过 memfd_create 创建匿名 fd,写入 so 数据,再以 /proc/self/fd/<fd> 调用 mmDlopen。38 * 2) 内存加载:通过 memfd_create 创建匿名 fd,写入 so 数据,再以 /proc/self/fd/<fd> 调用 mmDlopen。
34- * 3) 状态去重:以 so_key 缓存 {fingerprint, handle, mem_fd}:39+ * 3) 状态去重:以 fingerprint key 缓存 weak lease;同内容复用存活 lease,同名不同内容互不冲突。
35- * - key 且同内容:跳过重复加载;40+ * 4) 生命周期管理:CustomOpSoHandle 析构执行 mmDlclose + mmClose,loader 仅维护 weak cache,
36- * - key 但内容不同:直接报错失败,避免运行时行为不确定41+ * 长期强引用由模型级 CustomOpRegistry 持有
37- * 4) 生命周期管理:Cleanup 中统一执行 mmDlclose + mmClose,确保句柄和 fd 被可靠释放。
38 *42 *
39 * 设计约束:43 * 设计约束:
40 * 严格禁止任何“回退落盘”路径;当 memfd_create 或 /proc/self/fd 路径不可用时,直接返回失败。44 * 严格禁止任何“回退落盘”路径;当 memfd_create 或 /proc/self/fd 路径不可用时,直接返回失败。
41 */45 */
42namespace ge {46namespace ge {
43namespace {47namespace {
44-constexpr uint64_t kFnvOffsetBasis = 14695981039346656037ULL;
45-constexpr uint64_t kFnvPrime = 1099511628211ULL;
46constexpr int32_t kInvalidFd = -1;48constexpr int32_t kInvalidFd = -1;
47constexpr const char_t *kProcFdPrefix = "/proc/self/fd/";49constexpr const char_t *kProcFdPrefix = "/proc/self/fd/";
48constexpr const char_t *kNoDiskFallbackHint = "strict no-disk-fallback is enabled.";50constexpr const char_t *kNoDiskFallbackHint = "strict no-disk-fallback is enabled.";
@@ -50,13 +52,55 @@ constexpr const char *kReleaseOpsRegInfoSymbol = "ReleaseOpsRegInfo";
50 52 
51using ReleaseOpsRegInfoFunc = void (*)();53using ReleaseOpsRegInfoFunc = void (*)();
52 54 
53-uint64_t CalculateFnv1a64(const uint8_t *data, const size_t data_len) {55+class PendingSoResource {
C
CChang-an-HW5月27日

查看一下现有管理机制,是否能够复用或者收编

likedislike
Chang-an-HW
5月28日 评论:
Chang-an-HW
5月28日 评论:
Chang-an-HW
5月29日 评论:
Chang-an-HW
5月29日 评论:
Chang-an-HW
5月29日 评论:
54- uint64_t hash = kFnvOffsetBasis;56+ public:
55- for (size_t i = 0U; i < data_len; ++i) {57+ ~PendingSoResource() {
56- hash ^= static_cast<uint64_t>(data[i]);58+ if ((handle_ != nullptr) && (mmDlclose(handle_) != 0)) {
57- hash *= kFnvPrime;59+ GELOGW("[CustomOpSoLoader] dlclose pending custom op so failed, errmsg:%s", mmDlerror());
60+ }
61+ handle_ = nullptr;
62+ if ((mem_fd_ != kInvalidFd) && (mmClose(mem_fd_) != EN_OK)) {
63+ GELOGW("[CustomOpSoLoader] close pending mem fd failed, errno:%d", errno);
64+ }
65+ mem_fd_ = kInvalidFd;
58 }66 }
59- return hash;67+ 
68+ PendingSoResource() = default;
69+ PendingSoResource(const PendingSoResource &) = delete;
70+ PendingSoResource &operator=(const PendingSoResource &) = delete;
71+ 
72+ int32_t &MutableFd() noexcept {
73+ return mem_fd_;
74+ }
75+ 
76+ int32_t GetFd() const noexcept {
77+ return mem_fd_;
78+ }
79+ 
80+ void *&MutableHandle() noexcept {
81+ return handle_;
82+ }
83+ 
84+ void *GetHandle() const noexcept {
85+ return handle_;
86+ }
87+ 
88+ void Release() noexcept {
89+ handle_ = nullptr;
90+ mem_fd_ = kInvalidFd;
91+ }
92+ 
93+ private:
94+ int32_t mem_fd_ = kInvalidFd;
95+ void *handle_ = nullptr;
96+};
97+ 
98+std::string CalculateBinHash(const uint8_t *data, const size_t data_len) {
99+ const size_t hash_val = std::hash<std::string>{}(
100+ std::string(reinterpret_cast<const char *>(data), data_len));
101+ std::ostringstream oss;
102+ oss << std::hex << std::setfill('0') << std::setw(sizeof(size_t) * 2) << hash_val;
103+ return oss.str();
60}104}
61 105 
62int32_t CreateMemFdBySyscall(const std::string &name) {106int32_t CreateMemFdBySyscall(const std::string &name) {
@@ -74,19 +118,72 @@ ReleaseOpsRegInfoFunc GetReleaseOpsRegInfoFunc() {
74}118}
75}119}
76 120 
121+CustomOpSoLoader::CustomOpSoLoader() = default;
122+ 
123+CustomOpSoHandle::CustomOpSoHandle(std::string fingerprint_key, void *handle, std::string so_name,
124+ const size_t bin_size, const int32_t mem_fd)
125+ : fingerprint_key_(std::move(fingerprint_key)),
126+ handle_(handle),
127+ so_name_(std::move(so_name)),
128+ bin_size_(bin_size),
129+ mem_fd_(mem_fd) {}
130+ 
131+CustomOpSoHandle::~CustomOpSoHandle() {
132+ if ((handle_ != nullptr) && (mmDlclose(handle_) != 0)) {
133+ GELOGW("[CustomOpSoLoader] dlclose custom op so[%s] fingerprint[%s] failed, errmsg:%s",
134+ so_name_.c_str(), fingerprint_key_.c_str(), mmDlerror());
135+ }
136+ handle_ = nullptr;
137+ if ((mem_fd_ != kInvalidFd) && (mmClose(mem_fd_) != EN_OK)) {
138+ GELOGW("[CustomOpSoLoader] close mem fd for custom op so[%s] fingerprint[%s] failed, errno:%d",
139+ so_name_.c_str(), fingerprint_key_.c_str(), errno);
140+ }
141+ mem_fd_ = kInvalidFd;
142+}
143+ 
144+void CustomOpSoHandle::AdoptResource(void *handle, const int32_t mem_fd) noexcept {
145+ handle_ = handle;
146+ mem_fd_ = mem_fd;
147+}
148+ 
149+void *CustomOpSoHandle::GetHandle() const {
150+ return handle_;
151+}
152+ 
153+const std::string &CustomOpSoHandle::GetFingerprintKey() const {
154+ return fingerprint_key_;
155+}
156+ 
157+const std::string &CustomOpSoHandle::GetSoName() const {
158+ return so_name_;
159+}
160+ 
77CustomOpSoLoader &CustomOpSoLoader::GetInstance() {161CustomOpSoLoader &CustomOpSoLoader::GetInstance() {
78 static CustomOpSoLoader instance;162 static CustomOpSoLoader instance;
79 return instance;163 return instance;
80}164}
81 165 
82-CustomOpSoLoader::~CustomOpSoLoader() {166+CustomOpSoLoader::~CustomOpSoLoader() = default;
83- if (!loaded_states_.empty()) {167+ 
168+void CustomOpSoLoader::Finalize() {
169+ auto &loader = GetInstance();
170+ bool any_alive = false;
171+ {
172+ std::lock_guard<std::mutex> lock(loader.mutex_);
173+ for (const auto &entry : loader.loaded_states_) {
174+ if (!entry.second.expired()) {
175+ any_alive = true;
176+ break;
177+ }
178+ }
179+ }
180+ if (any_alive) {
84 const auto release_ops_reg_info = GetReleaseOpsRegInfoFunc();181 const auto release_ops_reg_info = GetReleaseOpsRegInfoFunc();
85 if (release_ops_reg_info != nullptr) {182 if (release_ops_reg_info != nullptr) {
86 release_ops_reg_info();183 release_ops_reg_info();
87 }184 }
88 }185 }
89- Cleanup();186+ loader.Cleanup();
90}187}
91 188 
92Status CustomOpSoLoader::GetSoKey(const OpSoBinPtr &op_so_bin, std::string &so_key) const {189Status CustomOpSoLoader::GetSoKey(const OpSoBinPtr &op_so_bin, std::string &so_key) const {
@@ -97,14 +194,16 @@ Status CustomOpSoLoader::GetSoKey(const OpSoBinPtr &op_so_bin, std::string &so_k
97}194}
98 195 
99Status CustomOpSoLoader::CalculateSoBinFingerprint(const OpSoBinPtr &op_so_bin,196Status CustomOpSoLoader::CalculateSoBinFingerprint(const OpSoBinPtr &op_so_bin,
100- SoBinFingerprint &fingerprint) const {197+ std::string &fingerprint_key) const {
101 GE_ASSERT_NOTNULL(op_so_bin);198 GE_ASSERT_NOTNULL(op_so_bin);
102 GE_ASSERT_TRUE(op_so_bin->GetBinData() != nullptr, "so[%s] bin data is null.", op_so_bin->GetSoName().c_str());199 GE_ASSERT_TRUE(op_so_bin->GetBinData() != nullptr, "so[%s] bin data is null.", op_so_bin->GetSoName().c_str());
103 GE_ASSERT_TRUE(op_so_bin->GetBinDataSize() > 0U, "so[%s] bin data size is zero.", op_so_bin->GetSoName().c_str());200 GE_ASSERT_TRUE(op_so_bin->GetBinDataSize() > 0U, "so[%s] bin data size is zero.", op_so_bin->GetSoName().c_str());
104 201 
105 const auto *bin_data = op_so_bin->GetBinData();202 const auto *bin_data = op_so_bin->GetBinData();
106- fingerprint.bin_size = op_so_bin->GetBinDataSize();203+ fingerprint_key = CalculateBinHash(bin_data, op_so_bin->GetBinDataSize());
107- fingerprint.content_hash = CalculateFnv1a64(bin_data, fingerprint.bin_size);204+ GE_ASSERT_TRUE(!fingerprint_key.empty(),
205+ "so[%s] fingerprint hash is empty.",
206+ op_so_bin->GetSoName().c_str());
108 return SUCCESS;207 return SUCCESS;
109}208}
110 209 
@@ -141,6 +240,10 @@ Status CustomOpSoLoader::WriteSoBinToFd(const OpSoBinPtr &op_so_bin, const int32
141 op_so_bin->GetSoName().c_str(), errno);240 op_so_bin->GetSoName().c_str(), errno);
142 written_len += static_cast<size_t>(current_write_len);241 written_len += static_cast<size_t>(current_write_len);
143 }242 }
243+ const off_t actual_fd_size = lseek(mem_fd, 0, SEEK_END);
244+ GE_ASSERT_TRUE((actual_fd_size >= 0) && (static_cast<size_t>(actual_fd_size) == bin_size),
245+ "[CustomOpSoLoader] memfd size[%jd] does not match declared so[%s] bin size[%zu].",
246+ static_cast<intmax_t>(actual_fd_size), op_so_bin->GetSoName().c_str(), bin_size);
144 GE_ASSERT_TRUE(lseek(mem_fd, 0, SEEK_SET) != -1,247 GE_ASSERT_TRUE(lseek(mem_fd, 0, SEEK_SET) != -1,
145 "[CustomOpSoLoader] reset memfd for custom op so[%s] failed, errno:%d",248 "[CustomOpSoLoader] reset memfd for custom op so[%s] failed, errno:%d",
146 op_so_bin->GetSoName().c_str(), errno);249 op_so_bin->GetSoName().c_str(), errno);
@@ -150,71 +253,119 @@ Status CustomOpSoLoader::WriteSoBinToFd(const OpSoBinPtr &op_so_bin, const int32
150Status CustomOpSoLoader::DlopenSoByFd(const int32_t mem_fd, void *&handle) const {253Status CustomOpSoLoader::DlopenSoByFd(const int32_t mem_fd, void *&handle) const {
C
CChang-an-HW5月25日

改命名:表示只能offline场景使用

likedislike
Chang-an-HW
5月25日 评论:
151 GE_ASSERT_TRUE(mem_fd != kInvalidFd, "mem fd is invalid when loading custom op so.");254 GE_ASSERT_TRUE(mem_fd != kInvalidFd, "mem fd is invalid when loading custom op so.");
152 const std::string so_path = std::string(kProcFdPrefix) + std::to_string(mem_fd);255 const std::string so_path = std::string(kProcFdPrefix) + std::to_string(mem_fd);
153- const int32_t open_flag =256+ const int32_t open_flag = static_cast<int32_t>(MMPA_RTLD_NOW);
154- static_cast<int32_t>(static_cast<uint32_t>(MMPA_RTLD_NOW) | static_cast<uint32_t>(MMPA_RTLD_GLOBAL));257+ ScopedOfflineCustomOpSoLoadGuard offline_custom_op_so_load_guard;
155 handle = mmDlopen(so_path.c_str(), open_flag);258 handle = mmDlopen(so_path.c_str(), open_flag);
156 GE_ASSERT_TRUE(handle != nullptr, "dlopen custom op so[%s] failed, errmsg:%s", so_path.c_str(), mmDlerror());259 GE_ASSERT_TRUE(handle != nullptr, "dlopen custom op so[%s] failed, errmsg:%s", so_path.c_str(), mmDlerror());
157 GELOGI("[CustomOpSoLoader] dlopen custom op so[%s] success.", so_path.c_str());260 GELOGI("[CustomOpSoLoader] dlopen custom op so[%s] success.", so_path.c_str());
158 return SUCCESS;261 return SUCCESS;
159}262}
160 263 
161-Status CustomOpSoLoader::LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins) {264+Status CustomOpSoLoader::LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins,
265+ std::vector<CustomOpSoHandlePtr> &loaded_handles) {
162 if (custom_so_bins.empty()) {266 if (custom_so_bins.empty()) {
163 return SUCCESS;267 return SUCCESS;
164 }268 }
165- std::lock_guard<std::mutex> lock(mutex_);269+ std::vector<CustomOpSoHandlePtr> current_loaded_handles;
166 for (const auto &so_bin : custom_so_bins) {270 for (const auto &so_bin : custom_so_bins) {
167- std::string so_key;271+ GE_ASSERT_SUCCESS(LoadSingleCustomOpSoBin(so_bin, current_loaded_handles));
168- GE_ASSERT_SUCCESS(GetSoKey(so_bin, so_key));
169- SoBinFingerprint current_fingerprint;
170- GE_ASSERT_SUCCESS(CalculateSoBinFingerprint(so_bin, current_fingerprint));
171- const auto loaded_state_it = loaded_states_.find(so_key);
172- if (loaded_state_it != loaded_states_.end()) {
173- if (loaded_state_it->second.fingerprint == current_fingerprint) {
174- GELOGI("[CustomOpSoLoader] custom op so key[%s] already loaded with same content, skip reload.",
175- so_key.c_str());
176- continue;
177- }
178- GELOGE(FAILED, "[CustomOpSoLoader] custom op so key[%s] already loaded with different content.",
179- so_key.c_str());
180- return FAILED;
181- }
182- int32_t mem_fd = kInvalidFd;
183- GE_ASSERT_SUCCESS(CreateSoMemFd(so_key, mem_fd));
184- if (WriteSoBinToFd(so_bin, mem_fd) != SUCCESS) {
185- (void)mmClose(mem_fd);
186- return FAILED;
187- }
188- void *handle = nullptr;
189- if (DlopenSoByFd(mem_fd, handle) != SUCCESS) {
190- (void)mmClose(mem_fd);
191- return FAILED;
192- }
193- const auto emplace_ret = loaded_states_.emplace(so_key, LoadedSoState{current_fingerprint, handle, mem_fd});
194- if (!emplace_ret.second) {
195- if (handle != nullptr) {
196- (void)mmDlclose(handle);
197- }
198- (void)mmClose(mem_fd);
199- GELOGE(FAILED, "[CustomOpSoLoader] emplace loaded custom op so key[%s] failed.", so_key.c_str());
200- return FAILED;
201- }
202 }272 }
273+ loaded_handles.insert(loaded_handles.end(), current_loaded_handles.begin(), current_loaded_handles.end());
203 return SUCCESS;274 return SUCCESS;
204}275}
205 276 
277+Status CustomOpSoLoader::LoadSingleCustomOpSoBin(const OpSoBinPtr &so_bin,
278+ std::vector<CustomOpSoHandlePtr> &loaded_handles) {
279+ GE_ASSERT_NOTNULL(so_bin);
280+ std::string diagnostic_so_key;
281+ GE_ASSERT_SUCCESS(GetSoKey(so_bin, diagnostic_so_key));
282+ std::string fingerprint_key;
283+ GE_ASSERT_SUCCESS(CalculateSoBinFingerprint(so_bin, fingerprint_key));
284+ 
285+ auto loaded_handle = GetLoadedHandle(fingerprint_key);
286+ if (loaded_handle != nullptr) {
287+ GELOGI("[CustomOpSoLoader] custom op so[%s] fingerprint[%s] already loaded, reuse lease.",
288+ so_bin->GetSoName().c_str(), fingerprint_key.c_str());
289+ loaded_handles.emplace_back(loaded_handle);
290+ return SUCCESS;
291+ }
292+ 
293+ CustomOpSoHandlePtr candidate_handle;
294+ const Status load_status = LoadCustomOpSoBinCandidate(so_bin, diagnostic_so_key, fingerprint_key, candidate_handle);
295+ if (load_status != SUCCESS) {
296+ loaded_handle = GetLoadedHandle(fingerprint_key);
297+ if (loaded_handle != nullptr) {
298+ GELOGI("[CustomOpSoLoader] custom op so[%s] fingerprint[%s] was published after local load failure, reuse lease.",
299+ so_bin->GetSoName().c_str(), fingerprint_key.c_str());
300+ loaded_handles.emplace_back(loaded_handle);
301+ return SUCCESS;
302+ }
303+ return load_status;
304+ }
305+ PublishOrReuseLoadedHandle(fingerprint_key, candidate_handle, loaded_handle);
306+ GE_ASSERT_NOTNULL(loaded_handle);
307+ loaded_handles.emplace_back(loaded_handle);
308+ return SUCCESS;
309+}
310+ 
311+CustomOpSoHandlePtr CustomOpSoLoader::GetLoadedHandle(const std::string &fingerprint_key) {
312+ std::lock_guard<std::mutex> lock(mutex_);
313+ const auto loaded_state_it = loaded_states_.find(fingerprint_key);
314+ if (loaded_state_it == loaded_states_.end()) {
315+ return nullptr;
316+ }
317+ const auto loaded_handle = loaded_state_it->second.lock();
318+ if (loaded_handle == nullptr) {
319+ (void)loaded_states_.erase(loaded_state_it);
320+ }
321+ return loaded_handle;
322+}
323+ 
324+Status CustomOpSoLoader::LoadCustomOpSoBinCandidate(const OpSoBinPtr &so_bin, const std::string &diagnostic_so_key,
325+ const std::string &fingerprint_key,
326+ CustomOpSoHandlePtr &candidate_handle) {
327+ auto new_handle = std::make_shared<CustomOpSoHandle>(fingerprint_key, nullptr, so_bin->GetSoName(),
328+ so_bin->GetBinDataSize(), kInvalidFd);
329+ PendingSoResource pending_resource;
330+ Status load_status = CreateSoMemFd(fingerprint_key, pending_resource.MutableFd());
331+ if (load_status == SUCCESS) {
332+ load_status = WriteSoBinToFd(so_bin, pending_resource.GetFd());
333+ }
334+ if (load_status == SUCCESS) {
335+ load_status = DlopenSoByFd(pending_resource.GetFd(), pending_resource.MutableHandle());
336+ }
337+ if (load_status != SUCCESS) {
338+ return load_status;
339+ }
340+ 
341+ new_handle->AdoptResource(pending_resource.GetHandle(), pending_resource.GetFd());
342+ pending_resource.Release();
343+ GELOGI("[CustomOpSoLoader] custom op so[%s] diagnostic key[%s] fingerprint[%s] candidate loaded.",
344+ so_bin->GetSoName().c_str(), diagnostic_so_key.c_str(), fingerprint_key.c_str());
345+ candidate_handle = new_handle;
346+ return SUCCESS;
347+}
348+ 
349+void CustomOpSoLoader::PublishOrReuseLoadedHandle(const std::string &fingerprint_key,
350+ const CustomOpSoHandlePtr &candidate_handle,
351+ CustomOpSoHandlePtr &loaded_handle) {
352+ std::lock_guard<std::mutex> lock(mutex_);
353+ const auto loaded_state_it = loaded_states_.find(fingerprint_key);
354+ if (loaded_state_it != loaded_states_.end()) {
355+ loaded_handle = loaded_state_it->second.lock();
356+ if (loaded_handle != nullptr) {
357+ GELOGI("[CustomOpSoLoader] custom op so fingerprint[%s] was published concurrently, reuse lease.",
358+ fingerprint_key.c_str());
359+ return;
360+ }
361+ (void)loaded_states_.erase(loaded_state_it);
362+ }
363+ loaded_states_[fingerprint_key] = candidate_handle;
364+ loaded_handle = candidate_handle;
365+}
366+ 
206void CustomOpSoLoader::Cleanup() {367void CustomOpSoLoader::Cleanup() {
207 std::lock_guard<std::mutex> lock(mutex_);368 std::lock_guard<std::mutex> lock(mutex_);
208- for (const auto &loaded_state : loaded_states_) {
209- if ((loaded_state.second.handle != nullptr) && (mmDlclose(loaded_state.second.handle) != 0)) {
210- GELOGW("[CustomOpSoLoader] dlclose custom op so key[%s] failed, errmsg:%s",
211- loaded_state.first.c_str(), mmDlerror());
212- }
213- if ((loaded_state.second.mem_fd != kInvalidFd) && (mmClose(loaded_state.second.mem_fd) != EN_OK)) {
214- GELOGW("[CustomOpSoLoader] close mem fd for custom op so key[%s] failed, errno:%d",
215- loaded_state.first.c_str(), errno);
216- }
217- }
218 loaded_states_.clear();369 loaded_states_.clear();
219}370}
220} // namespace ge371} // namespace ge
@@ -11,51 +11,74 @@
11#ifndef BASE_COMMON_HELPER_CUSTOM_OP_SO_LOADER_H_11#ifndef BASE_COMMON_HELPER_CUSTOM_OP_SO_LOADER_H_
12#define BASE_COMMON_HELPER_CUSTOM_OP_SO_LOADER_H_12#define BASE_COMMON_HELPER_CUSTOM_OP_SO_LOADER_H_
13 13 
14+#include <cstddef>
14#include <cstdint>15#include <cstdint>
16+#include <map>
17+#include <memory>
15#include <string>18#include <string>
16-#include <unordered_map>
17#include <vector>19#include <vector>
18#include <mutex>20#include <mutex>
19 21 
20#include "external/ge_common/ge_common_api_types.h"22#include "external/ge_common/ge_common_api_types.h"
23+#include "ge/ge_api_error_codes.h"
21#include "graph/op_so_bin.h"24#include "graph/op_so_bin.h"
22 25 
23namespace ge {26namespace ge {
27+class CustomOpSoHandle {
28+ public:
29+ CustomOpSoHandle(std::string fingerprint_key, void *handle, std::string so_name, size_t bin_size, int32_t mem_fd);
30+ ~CustomOpSoHandle();
31+ CustomOpSoHandle(const CustomOpSoHandle &) = delete;
32+ CustomOpSoHandle &operator=(const CustomOpSoHandle &) = delete;
33+ CustomOpSoHandle(CustomOpSoHandle &&) = delete;
34+ CustomOpSoHandle &operator=(CustomOpSoHandle &&) = delete;
35+ 
36+ void *GetHandle() const;
37+ const std::string &GetFingerprintKey() const;
38+ const std::string &GetSoName() const;
39+ 
40+ private:
41+ friend class CustomOpSoLoader;
42+ void AdoptResource(void *handle, int32_t mem_fd) noexcept;
43+ 
44+ std::string fingerprint_key_;
45+ void *handle_;
46+ std::string so_name_;
47+ size_t bin_size_;
48+ int32_t mem_fd_;
49+};
50+ 
51+using CustomOpSoHandlePtr = std::shared_ptr<CustomOpSoHandle>;
52+ 
24class CustomOpSoLoader {53class CustomOpSoLoader {
25 public:54 public:
26 static CustomOpSoLoader &GetInstance();55 static CustomOpSoLoader &GetInstance();
27- Status LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins);56+ static void Finalize();
57+ Status LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins,
58+ std::vector<CustomOpSoHandlePtr> &loaded_handles);
28 59 
29 private:60 private:
30- CustomOpSoLoader() = default;61+ CustomOpSoLoader();
31 ~CustomOpSoLoader();62 ~CustomOpSoLoader();
32 CustomOpSoLoader(const CustomOpSoLoader &) = delete;63 CustomOpSoLoader(const CustomOpSoLoader &) = delete;
33 CustomOpSoLoader &operator=(const CustomOpSoLoader &) = delete;64 CustomOpSoLoader &operator=(const CustomOpSoLoader &) = delete;
34 65 
35- struct SoBinFingerprint {
36- uint32_t bin_size;
37- uint64_t content_hash;
38- 
39- bool operator==(const SoBinFingerprint &other) const {
40- return (bin_size == other.bin_size) && (content_hash == other.content_hash);
41- }
42- };
43- 
44- struct LoadedSoState {
45- SoBinFingerprint fingerprint;
46- void *handle;
47- int32_t mem_fd;
48- };
49- 
50 Status GetSoKey(const OpSoBinPtr &op_so_bin, std::string &so_key) const;66 Status GetSoKey(const OpSoBinPtr &op_so_bin, std::string &so_key) const;
51- Status CalculateSoBinFingerprint(const OpSoBinPtr &op_so_bin, SoBinFingerprint &fingerprint) const;67+ Status CalculateSoBinFingerprint(const OpSoBinPtr &op_so_bin, std::string &fingerprint_key) const;
52 Status CreateSoMemFd(const std::string &so_key, int32_t &mem_fd) const;68 Status CreateSoMemFd(const std::string &so_key, int32_t &mem_fd) const;
53 Status WriteSoBinToFd(const OpSoBinPtr &op_so_bin, const int32_t mem_fd) const;69 Status WriteSoBinToFd(const OpSoBinPtr &op_so_bin, const int32_t mem_fd) const;
54 Status DlopenSoByFd(const int32_t mem_fd, void *&handle) const;70 Status DlopenSoByFd(const int32_t mem_fd, void *&handle) const;
71+ Status LoadSingleCustomOpSoBin(const OpSoBinPtr &so_bin, std::vector<CustomOpSoHandlePtr> &loaded_handles);
72+ CustomOpSoHandlePtr GetLoadedHandle(const std::string &fingerprint_key);
73+ Status LoadCustomOpSoBinCandidate(const OpSoBinPtr &so_bin, const std::string &diagnostic_so_key,
74+ const std::string &fingerprint_key,
75+ CustomOpSoHandlePtr &candidate_handle);
76+ void PublishOrReuseLoadedHandle(const std::string &fingerprint_key, const CustomOpSoHandlePtr &candidate_handle,
77+ CustomOpSoHandlePtr &loaded_handle);
55 void Cleanup();78 void Cleanup();
56 79 
57 mutable std::mutex mutex_;80 mutable std::mutex mutex_;
58- std::unordered_map<std::string, LoadedSoState> loaded_states_;81+ std::map<std::string, std::weak_ptr<CustomOpSoHandle>> loaded_states_;
59};82};
60} // namespace ge83} // namespace ge
61 84 
@@ -9,21 +9,97 @@
9 */9 */
10 10 
11#include "framework/common/helper/model_helper.h"11#include "framework/common/helper/model_helper.h"
12+ 
13+#include <cinttypes>
14+#include <map>
15+#include <set>
16+#include <string>
17+#include <vector>
18+ 
19+#include "common/helper/custom_op_registry_builder.h"
20+#include "common/helper/custom_op_so_loader.h"
21+#include "common/model/ge_root_model.h"
12#include "external/graph/custom_op.h"22#include "external/graph/custom_op.h"
13-#include "graph/custom_op_factory.h"23+#include "graph/custom_op_registry.h"
24+#include "graph/debug/ge_attr_define.h"
25+#include "graph/utils/attr_utils.h"
14 26 
15namespace ge {27namespace ge {
16-Status ModelHelper::CollectUsedCustomOpTypes(const GeRootModelPtr &ge_root_model,28+namespace {
17- std::set<std::string> &used_custom_op_types) const {29+Status ValidateCustomOpNodeDeserialized(const NodePtr &node, const CustomOpRegistryPtr &registry) {
18- if (ge_root_model->GetRootGraph() != nullptr) {30+ if (node == nullptr) {
19- const auto &root_graph = ge_root_model->GetRootGraph();31+ return SUCCESS;
20- for (const auto &node : root_graph->GetAllNodes()) {32+ }
21- const std::string op_type = node->GetType();33+ 
22- if (CustomOpFactory::IsExistOp(AscendString(op_type.c_str()))) {34+ const std::string op_type = node->GetType();
23- used_custom_op_types.insert(op_type);35+ const AscendString ascend_op_type(op_type.c_str());
24- }36+ if (!registry->HasCreator(ascend_op_type)) {
37+ GELOGD("[CUSTOM OP] op %s is not found in registry.", op_type.c_str());
38+ return SUCCESS;
39+ }
40+ 
41+ if (!registry->HasCustomOp(ascend_op_type)) {
42+ GELOGE(FAILED, "[CUSTOM OP] custom op %s is used by model but not deserialized.", op_type.c_str());
43+ return FAILED;
44+ }
45+ return SUCCESS;
46+}
47+ 
48+Status ValidateCustomOpsInGraphDeserialized(const ComputeGraphPtr &graph, const CustomOpRegistryPtr &registry,
49+ std::set<ComputeGraph *> &visited_graphs) {
50+ if (graph == nullptr) {
51+ return SUCCESS;
52+ }
53+ if (!visited_graphs.insert(graph.get()).second) {
54+ return SUCCESS;
55+ }
56+ 
57+ for (const auto &node : graph->GetAllNodes()) {
58+ GE_ASSERT_SUCCESS(ValidateCustomOpNodeDeserialized(node, registry));
59+ }
60+ return SUCCESS;
61+}
62+ 
63+bool HasNonEmptyCustomOpsPartition(const OmFileLoadHelper &om_load_helper) {
64+ ModelPartition custom_ops_partition;
65+ if (om_load_helper.GetModelPartition(ModelPartitionType::CUSTOM_OPS, custom_ops_partition, 0U) != SUCCESS) {
66+ return false;
67+ }
68+ return (custom_ops_partition.data != nullptr) && (custom_ops_partition.size > 0U);
69+}
70+ 
71+Status CollectCustomOpTypesFromGraph(const ComputeGraphPtr &graph, const CustomOpRegistryPtr &registry,
72+ std::set<std::string> &used_custom_op_types) {
73+ if (graph == nullptr) {
74+ return SUCCESS;
75+ }
76+ GE_ASSERT_NOTNULL(registry);
77+ for (const auto &node : graph->GetAllNodes()) {
78+ const std::string op_type = node->GetType();
79+ if (registry->HasCreator(AscendString(op_type.c_str()))) {
80+ used_custom_op_types.insert(op_type);
25 }81 }
26 }82 }
83+ return SUCCESS;
84+}
85+} // namespace
86+ 
87+Status LoadCustomOpsToRegistry(const uint8_t *data, const size_t len, const CustomOpRegistryPtr &registry) {
88+ if (registry == nullptr) {
89+ GELOGE(FAILED, "[CUSTOM OP] model custom op registry is null.");
90+ return FAILED;
91+ }
92+ GE_CHK_STATUS_RET(registry->LoadCustomOpsPartition(data, len),
93+ "[CUSTOM OP] Load custom ops partition to model registry failed.");
94+ return SUCCESS;
95+}
96+ 
97+Status ModelHelper::CollectUsedCustomOpTypes(const GeRootModelPtr &ge_root_model,
98+ std::set<std::string> &used_custom_op_types) const {
99+ GE_ASSERT_NOTNULL(ge_root_model);
100+ const auto &registry = ge_root_model->GetCustomOpRegistry();
101+ GE_ASSERT_NOTNULL(registry);
102+ GE_ASSERT_SUCCESS(CollectCustomOpTypesFromGraph(ge_root_model->GetRootGraph(), registry, used_custom_op_types));
27 103 
28 // subgraph_instance_name_to_model_ 中的 GeModel 可能持有独立的 ComputeGraph 对象,104 // subgraph_instance_name_to_model_ 中的 GeModel 可能持有独立的 ComputeGraph 对象,
29 // 这些子图未必通过 AddSubgraph 挂入 root_graph 的子图树,因此无法被上方 GetAllNodes() 遍历到。105 // 这些子图未必通过 AddSubgraph 挂入 root_graph 的子图树,因此无法被上方 GetAllNodes() 遍历到。
@@ -39,12 +115,7 @@ Status ModelHelper::CollectUsedCustomOpTypes(const GeRootModelPtr &ge_root_model
39 if (graph == ge_root_model->GetRootGraph()) {115 if (graph == ge_root_model->GetRootGraph()) {
40 continue;116 continue;
41 }117 }
42- for (const auto &node : graph->GetAllNodes()) {118+ GE_ASSERT_SUCCESS(CollectCustomOpTypesFromGraph(graph, registry, used_custom_op_types));
43- const std::string op_type = node->GetType();
44- if (CustomOpFactory::IsExistOp(AscendString(op_type.c_str()))) {
45- used_custom_op_types.insert(op_type);
46- }
47- }
48 }119 }
49 return SUCCESS;120 return SUCCESS;
50}121}
@@ -64,8 +135,8 @@ Status ModelHelper::SerializeCustomOpKernel(PortableOp *serializable_op, const s
64 }135 }
65 136 
66 if (buffer.empty()) {137 if (buffer.empty()) {
67- GELOGW("[CUSTOM OP] serialized buffer is empty, skip, op_type:%s", op_type_str.c_str());138+ GELOGE(FAILED, "[CUSTOM OP] serialized buffer is empty, op_type:%s", op_type_str.c_str());
68- return SUCCESS;139+ return FAILED;
69 }140 }
70 141 
71 CustomKernelItemHeader header;142 CustomKernelItemHeader header;
@@ -83,6 +154,13 @@ Status ModelHelper::SerializeCustomOpKernel(PortableOp *serializable_op, const s
83 154 
84Status ModelHelper::SaveCustomOpsPartition(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper,155Status ModelHelper::SaveCustomOpsPartition(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper,
85 const GeRootModelPtr &ge_root_model) const {156 const GeRootModelPtr &ge_root_model) const {
157+ GE_ASSERT_NOTNULL(ge_root_model);
158+ const auto &registry = ge_root_model->GetCustomOpRegistry();
159+ if (registry == nullptr) {
160+ GELOGI("[CUSTOM OP] model custom op registry is null, skip saving custom ops partition.");
161+ return SUCCESS;
162+ }
163+ 
86 std::set<std::string> used_custom_op_types;164 std::set<std::string> used_custom_op_types;
87 GE_ASSERT_SUCCESS(CollectUsedCustomOpTypes(ge_root_model, used_custom_op_types));165 GE_ASSERT_SUCCESS(CollectUsedCustomOpTypes(ge_root_model, used_custom_op_types));
88 166 
@@ -96,7 +174,7 @@ Status ModelHelper::SaveCustomOpsPartition(std::shared_ptr<OmFileSaveHelper> &om
96 std::vector<std::pair<std::string, PortableOp *>> serializable_ops;174 std::vector<std::pair<std::string, PortableOp *>> serializable_ops;
97 serializable_ops.reserve(used_custom_op_types.size());175 serializable_ops.reserve(used_custom_op_types.size());
98 for (const auto &op_type_str : used_custom_op_types) {176 for (const auto &op_type_str : used_custom_op_types) {
99- auto op = CustomOpFactory::CreateOrGetCustomOp(AscendString(op_type_str.c_str()));177+ auto op = registry->CreateOrGetCustomOp(AscendString(op_type_str.c_str()));
100 if (op == nullptr) {178 if (op == nullptr) {
101 GELOGE(FAILED, "[CUSTOM OP] create custom op failed, op_type:%s", op_type_str.c_str());179 GELOGE(FAILED, "[CUSTOM OP] create custom op failed, op_type:%s", op_type_str.c_str());
102 return FAILED;180 return FAILED;
@@ -129,7 +207,26 @@ Status ModelHelper::SaveCustomOpsPartition(std::shared_ptr<OmFileSaveHelper> &om
129 return om_file_save_helper->AddOwnedPartition(ModelPartitionType::CUSTOM_OPS, std::move(merged_buffers), 0U);207 return om_file_save_helper->AddOwnedPartition(ModelPartitionType::CUSTOM_OPS, std::move(merged_buffers), 0U);
130}208}
131 209 
132-Status ModelHelper::LoadCustomOps(const OmFileLoadHelper &om_load_helper) const {210+Status ModelHelper::ValidateCustomOpsDeserialized(const GeRootModelPtr &ge_root_model,
211+ const CustomOpRegistryPtr &registry) const {
212+ GE_ASSERT_NOTNULL(ge_root_model);
213+ GE_ASSERT_NOTNULL(registry);
214+ 
215+ std::set<ComputeGraph *> visited_graphs;
216+ GE_ASSERT_SUCCESS(ValidateCustomOpsInGraphDeserialized(ge_root_model->GetRootGraph(), registry, visited_graphs));
217+ 
218+ const auto &subgraph_map = ge_root_model->GetSubgraphInstanceNameToModel();
219+ for (const auto &subgraph_pair : subgraph_map) {
220+ const auto &ge_model = subgraph_pair.second;
221+ if (ge_model == nullptr) {
222+ continue;
223+ }
224+ GE_ASSERT_SUCCESS(ValidateCustomOpsInGraphDeserialized(ge_model->GetGraph(), registry, visited_graphs));
225+ }
226+ return SUCCESS;
227+}
228+ 
229+Status ModelHelper::LoadCustomOps(const OmFileLoadHelper &om_load_helper, const CustomOpRegistryPtr &registry) const {
133 ModelPartition custom_ops_partition;230 ModelPartition custom_ops_partition;
134 if (om_load_helper.GetModelPartition(ModelPartitionType::CUSTOM_OPS, custom_ops_partition, 0U) != SUCCESS) {231 if (om_load_helper.GetModelPartition(ModelPartitionType::CUSTOM_OPS, custom_ops_partition, 0U) != SUCCESS) {
135 GELOGI("[CUSTOM OP] custom ops partition not found, skip load.");232 GELOGI("[CUSTOM OP] custom ops partition not found, skip load.");
@@ -141,9 +238,93 @@ Status ModelHelper::LoadCustomOps(const OmFileLoadHelper &om_load_helper) const
141 return SUCCESS;238 return SUCCESS;
142 }239 }
143 240 
144- GE_CHK_STATUS_RET(CustomOpFactory::LoadCustomOpsPartition(custom_ops_partition.data,241+ GE_CHK_STATUS_RET(LoadCustomOpsToRegistry(custom_ops_partition.data, custom_ops_partition.size, registry),
145- custom_ops_partition.size),242+ "[CUSTOM OP] Load custom ops partition to model registry failed.");
146- "[CUSTOM OP] Load custom ops partition failed.");
147 return SUCCESS;243 return SUCCESS;
148}244}
245+ 
246+Status ModelHelper::LoadCustomOpRegistry(const OmFileLoadHelper &om_load_helper,
247+ const GeRootModelPtr &ge_root_model) const {
248+ GE_ASSERT_NOTNULL(ge_root_model);
249+ std::vector<CustomOpSoHandlePtr> loaded_handles;
250+ GE_CHK_STATUS_RET(LoadOpSoBin(om_load_helper, ge_root_model, loaded_handles), "[CUSTOM OP] Load so bins failed.");
251+ auto registry = std::make_shared<CustomOpRegistry>();
252+ GE_ASSERT_NOTNULL(registry);
253+ if (loaded_handles.empty()) {
254+ GE_ASSERT_TRUE(!HasNonEmptyCustomOpsPartition(om_load_helper),
255+ "[CUSTOM OP] custom ops partition exists but no custom op so is loaded.");
256+ ge_root_model->SetCustomOpRegistry(registry);
257+ GELOGI("[CUSTOM OP] no custom op so loaded, set empty model custom op registry.");
258+ return SUCCESS;
259+ }
260+ 
261+ GE_CHK_STATUS_RET(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(loaded_handles, registry),
262+ "[CUSTOM OP] Build model custom op registry failed.");
263+ GE_CHK_STATUS_RET(LoadCustomOps(om_load_helper, registry), "[CUSTOM OP] Load custom ops to registry failed.");
264+ GE_CHK_STATUS_RET(ValidateCustomOpsDeserialized(ge_root_model, registry),
265+ "[CUSTOM OP] Validate model custom ops deserialized failed.");
266+ ge_root_model->SetCustomOpRegistry(registry);
267+ return SUCCESS;
268+}
269+ 
270+Status ModelHelper::LoadOpSoBin(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model,
271+ std::vector<CustomOpSoHandlePtr> &loaded_handles) const {
272+ ModelPartition partition_kernel_def;
273+ if (om_load_helper.GetModelPartition(ModelPartitionType::SO_BINS, partition_kernel_def, 0U) == SUCCESS) {
274+ GELOGD("Kernels partition size:%" PRIu64 "", partition_kernel_def.size);
275+ if (ge_root_model->LoadSoBinData(partition_kernel_def.data, partition_kernel_def.size)) {
276+ auto root_graph = ge_root_model->GetRootGraph();
277+ GE_ASSERT_NOTNULL(root_graph);
278+ std::map<std::string, ge::OpSoBinPtr> bin_file_buffer;
279+ auto all_so_bin = ge_root_model->GetAllSoBin();
280+ std::vector<OpSoBinPtr> custom_op_so_bins;
281+ for (const auto &op_so_bin_ptr : all_so_bin) {
282+ if (op_so_bin_ptr == nullptr) {
283+ continue;
284+ }
285+ if (op_so_bin_ptr->GetSoBinType() == SoBinType::kAutofuse) {
286+ std::string so_path = op_so_bin_ptr->GetVendorName() + "/" + op_so_bin_ptr->GetSoName();
287+ bin_file_buffer[so_path] = op_so_bin_ptr;
288+ GELOGD("Added autofuse so_path:%s", so_path.c_str());
289+ } else if (op_so_bin_ptr->GetSoBinType() == SoBinType::kCustomOp) {
290+ custom_op_so_bins.emplace_back(op_so_bin_ptr);
291+ }
292+ }
293+ if (!bin_file_buffer.empty()) {
294+ root_graph->SetExtAttr<std::map<std::string, ge::OpSoBinPtr>>("bin_file_buffer", bin_file_buffer);
295+ }
296+ GE_ASSERT_SUCCESS(LoadCustomOpSoBins(custom_op_so_bins, loaded_handles));
297+ SaveOpSoInfo(ge_root_model);
298+ GELOGD("Load so bin store success");
299+ } else {
300+ GELOGW("Load so bin store unsuccessful");
301+ GE_ASSERT_TRUE(partition_kernel_def.size == 0U,
302+ "Load so bin store failed when SO_BINS partition is non-empty, size:%" PRIu64,
303+ partition_kernel_def.size);
304+ }
305+ }
306+ return SUCCESS;
307+}
308+ 
309+Status ModelHelper::LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins,
310+ std::vector<CustomOpSoHandlePtr> &loaded_handles) const {
311+ if (custom_so_bins.empty()) {
312+ return SUCCESS;
313+ }
314+ GE_ASSERT_SUCCESS(CustomOpSoLoader::GetInstance().LoadCustomOpSoBins(custom_so_bins, loaded_handles),
315+ "Load custom op so bins from SO_BINS failed.");
316+ return SUCCESS;
317+}
318+ 
319+void ModelHelper::SaveOpSoInfo(const GeRootModelPtr &ge_root_model) const {
320+ SoInOmInfo so_info;
321+ (void) ge::AttrUtils::GetStr(*(model_.get()), "host_env_os", so_info.os_info);
322+ (void) ge::AttrUtils::GetStr(*(model_.get()), "host_env_cpu", so_info.cpu_info);
323+ (void) ge::AttrUtils::GetStr(*(model_.get()), ATTR_MODEL_OPP_VERSION, so_info.opp_version);
324+ (void) ge::AttrUtils::GetStr(*(model_.get()), ATTR_MODEL_COMPILER_VERSION, so_info.compiler_version);
325+ GELOGD("Save so info with host_env_os:%s, host_env_cpu:%s, opp_version:%s, compiler_version:%s",
326+ so_info.os_info.c_str(), so_info.cpu_info.c_str(), so_info.opp_version.c_str(),
327+ so_info.compiler_version.c_str());
328+ ge_root_model->SetSoInOmInfo(so_info);
329+}
149} // namespace ge330} // namespace ge
@@ -12,7 +12,6 @@
12#include "framework/common/helper/model_helper.h"12#include "framework/common/helper/model_helper.h"
13#include "common/checker.h"13#include "common/checker.h"
14#include "common/helper/model_parser_base.h"14#include "common/helper/model_parser_base.h"
15-#include "common/helper/custom_op_so_loader.h"
16#include "common/model/ge_model.h"15#include "common/model/ge_model.h"
17#include "common/model/ge_root_model.h"16#include "common/model/ge_root_model.h"
18#include "common/op_so_store/op_so_store_utils.h"17#include "common/op_so_store/op_so_store_utils.h"
@@ -1336,8 +1335,7 @@ Status ModelHelper::GenerateGeRootModel(const OmFileLoadHelper &om_load_helper,
1336 GE_CHECK_NOTNULL(model_);1335 GE_CHECK_NOTNULL(model_);
1337 GE_ASSERT_SUCCESS(root_model_->Initialize(model_->GetGraph()));1336 GE_ASSERT_SUCCESS(root_model_->Initialize(model_->GetGraph()));
1338 root_model_->SetModelName(model_->GetName());1337 root_model_->SetModelName(model_->GetName());
1339- GE_CHK_STATUS_RET(LoadOpSoBin(om_load_helper, root_model_), "[Generate][LoadOpSoBin]Failed");1338+ GE_CHK_STATUS_RET(LoadCustomOpRegistry(om_load_helper, root_model_), "[Generate][LoadCustomOpRegistry]Failed");
1340- GE_CHK_STATUS_RET(LoadCustomOps(om_load_helper), "[Generate][LoadCustomOps]Failed");
1341 GE_CHK_STATUS_RET(LoadTilingData(om_load_helper, root_model_), "[Generate][LoadTilingData]Failed");1339 GE_CHK_STATUS_RET(LoadTilingData(om_load_helper, root_model_), "[Generate][LoadTilingData]Failed");
1342 root_model_->SetSubgraphInstanceNameToModel(model_->GetGraph()->GetName(), model_);1340 root_model_->SetSubgraphInstanceNameToModel(model_->GetGraph()->GetName(), model_);
1343 return SUCCESS;1341 return SUCCESS;
@@ -1350,8 +1348,7 @@ Status ModelHelper::GenerateGeRootModel(const OmFileLoadHelper &om_load_helper,
1350 GE_ASSERT_SUCCESS(root_model_->Initialize(cur_model->GetGraph()));1348 GE_ASSERT_SUCCESS(root_model_->Initialize(cur_model->GetGraph()));
1351 root_model_->SetModelName(cur_model->GetName());1349 root_model_->SetModelName(cur_model->GetName());
1352 model_ = cur_model;1350 model_ = cur_model;
1353- GE_CHK_STATUS_RET(LoadOpSoBin(om_load_helper, root_model_), "[Generate][LoadOpSoBin]Failed");1351+ GE_CHK_STATUS_RET(LoadCustomOpRegistry(om_load_helper, root_model_), "[Generate][LoadCustomOpRegistry]Failed");
1354- GE_CHK_STATUS_RET(LoadCustomOps(om_load_helper), "[Generate][LoadCustomOps]Failed");
1355 GE_CHK_STATUS_RET(LoadTilingData(om_load_helper, root_model_), "[Generate][LoadTilingData]Failed");1352 GE_CHK_STATUS_RET(LoadTilingData(om_load_helper, root_model_), "[Generate][LoadTilingData]Failed");
1356 if (IsPartitionedGraph(cur_model)) {1353 if (IsPartitionedGraph(cur_model)) {
1357 if (!gert::GraphUnfolder::IsGraphNeedUnfold(cur_model->GetGraph())) {1354 if (!gert::GraphUnfolder::IsGraphNeedUnfold(cur_model->GetGraph())) {
@@ -1498,56 +1495,6 @@ Status ModelHelper::LoadCustAICPUKernelStore(const OmFileLoadHelper &om_load_hel
1498 return SUCCESS;1495 return SUCCESS;
1499}1496}
1500 1497 
1501-Status ModelHelper::LoadOpSoBin(const OmFileLoadHelper &om_load_helper,
1502- const GeRootModelPtr &ge_root_model) const {
1503- ModelPartition partition_kernel_def;
1504- if (om_load_helper.GetModelPartition(ModelPartitionType::SO_BINS, partition_kernel_def, 0U)
1505- == SUCCESS) {
1506- GELOGD("Kernels partition size:%" PRIu64 "", partition_kernel_def.size);
1507- if (ge_root_model->LoadSoBinData(partition_kernel_def.data, partition_kernel_def.size)) {
1508- // 取出AutofuseSo并存放到扩展属性
1509- auto root_graph = ge_root_model->GetRootGraph();
1510- GE_ASSERT_NOTNULL(root_graph);
1511- std::map<std::string, ge::OpSoBinPtr> bin_file_buffer;
1512- auto all_so_bin = ge_root_model->GetAllSoBin();
1513- std::vector<OpSoBinPtr> custom_op_so_bins;
1514- for (const auto &op_so_bin_ptr : all_so_bin) {
1515- if (op_so_bin_ptr == nullptr) {
1516- continue;
1517- }
1518- if (op_so_bin_ptr->GetSoBinType() == SoBinType::kAutofuse) {
1519- std::string so_path = op_so_bin_ptr->GetVendorName() + "/" + op_so_bin_ptr->GetSoName();
1520- bin_file_buffer[so_path] = op_so_bin_ptr;
1521- GELOGD("Added autofuse so_path:%s", so_path.c_str());
1522- } else if (op_so_bin_ptr->GetSoBinType() == SoBinType::kCustomOp) {
1523- custom_op_so_bins.emplace_back(op_so_bin_ptr);
1524- }
1525- }
1526- if (!bin_file_buffer.empty()) {
1527- root_graph->SetExtAttr<std::map<std::string, ge::OpSoBinPtr>>("bin_file_buffer", bin_file_buffer);
1528- }
1529- GE_ASSERT_SUCCESS(LoadCustomOpSoBins(custom_op_so_bins));
1530- SaveOpSoInfo(ge_root_model);
1531- GELOGD("Load so bin store success");
1532- } else {
1533- GELOGW("Load so bin store unsuccessful");
1534- GE_ASSERT_TRUE(partition_kernel_def.size == 0U,
1535- "Load so bin store failed when SO_BINS partition is non-empty, size:%" PRIu64,
1536- partition_kernel_def.size);
1537- }
1538- }
1539- return SUCCESS;
1540-}
1541- 
1542-Status ModelHelper::LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins) const {
1543- if (custom_so_bins.empty()) {
1544- return SUCCESS;
1545- }
1546- GE_ASSERT_SUCCESS(CustomOpSoLoader::GetInstance().LoadCustomOpSoBins(custom_so_bins),
1547- "Load custom op so bins from SO_BINS failed.");
1548- return SUCCESS;
1549-}
1550- 
1551Status ModelHelper::LoadTilingData(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const {1498Status ModelHelper::LoadTilingData(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const {
1552 ModelPartition partition_kernel_def;1499 ModelPartition partition_kernel_def;
1553 (void)om_load_helper.GetModelPartition(ModelPartitionType::TILING_DATA, partition_kernel_def, 0U);1500 (void)om_load_helper.GetModelPartition(ModelPartitionType::TILING_DATA, partition_kernel_def, 0U);
@@ -1564,18 +1511,6 @@ Status ModelHelper::LoadTilingData(const OmFileLoadHelper &om_load_helper, const
1564 return SUCCESS;1511 return SUCCESS;
1565}1512}
1566 1513 
1567-void ModelHelper::SaveOpSoInfo(const GeRootModelPtr &ge_root_model) const {
1568- SoInOmInfo so_info;
1569- (void) ge::AttrUtils::GetStr(*(model_.get()), "host_env_os", so_info.os_info);
1570- (void) ge::AttrUtils::GetStr(*(model_.get()), "host_env_cpu", so_info.cpu_info);
1571- (void) ge::AttrUtils::GetStr(*(model_.get()), ATTR_MODEL_OPP_VERSION, so_info.opp_version);
1572- (void) ge::AttrUtils::GetStr(*(model_.get()), ATTR_MODEL_COMPILER_VERSION, so_info.compiler_version);
1573- GELOGD("Save so info with host_env_os:%s, host_env_cpu:%s, opp_version:%s, compiler_version:%s",
1574- so_info.os_info.c_str(), so_info.cpu_info.c_str(), so_info.opp_version.c_str(),
1575- so_info.compiler_version.c_str());
1576- ge_root_model->SetSoInOmInfo(so_info);
1577-}
1578- 
1579GeModelPtr ModelHelper::GetGeModel() {1514GeModelPtr ModelHelper::GetGeModel() {
1580 if (model_ != nullptr) {1515 if (model_ != nullptr) {
1581 return model_;1516 return model_;
@@ -31,7 +31,6 @@
31#include "common/opskernel/ops_kernel_info_types.h"31#include "common/opskernel/ops_kernel_info_types.h"
32#include "external/ge_common/ge_common_api_types.h"32#include "external/ge_common/ge_common_api_types.h"
33#include "external/graph/custom_op.h"33#include "external/graph/custom_op.h"
34-#include "graph/custom_op_factory.h"
35 34 
36namespace ge {35namespace ge {
37namespace {36namespace {
@@ -155,16 +154,19 @@ Status GetP2pFixedFeatureMemorySize(const GeRootModel *ge_root_model, size_t &p2
155 return SUCCESS;154 return SUCCESS;
156}155}
157 156 
158-void CollectCustomOpTypesFromGraph(const ComputeGraphPtr &graph, std::set<std::string> &used_custom_op_types) {157+Status CollectCustomOpTypesFromGraph(const ComputeGraphPtr &graph, const CustomOpRegistryPtr &custom_op_registry,
158+ std::set<std::string> &used_custom_op_types) {
159 if (graph == nullptr) {159 if (graph == nullptr) {
160- return;160+ return SUCCESS;
161 }161 }
162+ GE_ASSERT_NOTNULL(custom_op_registry);
162 for (const auto &node : graph->GetAllNodes()) {163 for (const auto &node : graph->GetAllNodes()) {
163 const auto &op_type = node->GetType();164 const auto &op_type = node->GetType();
164- if (CustomOpFactory::IsExistOp(AscendString(op_type.c_str()))) {165+ if (custom_op_registry->HasCreator(AscendString(op_type.c_str()))) {
165 (void)used_custom_op_types.insert(op_type);166 (void)used_custom_op_types.insert(op_type);
166 }167 }
167 }168 }
169+ return SUCCESS;
168}170}
169}171}
170Status GeRootModel::Initialize(const ComputeGraphPtr &root_graph) {172Status GeRootModel::Initialize(const ComputeGraphPtr &root_graph) {
@@ -373,23 +375,25 @@ Status GeRootModel::ResolvePortableOpSoPath(const std::string &op_type, Portable
373 375 
374Status GeRootModel::CheckAndSetCustomOpSo() {376Status GeRootModel::CheckAndSetCustomOpSo() {
375 GE_ASSERT_NOTNULL(root_graph_);377 GE_ASSERT_NOTNULL(root_graph_);
378+ GE_ASSERT_NOTNULL(custom_op_registry_);
376 std::string target_os;379 std::string target_os;
377 std::string target_cpu;380 std::string target_cpu;
378 GE_ASSERT_SUCCESS(GetTargetHostEnv(target_os, target_cpu), "Get target host env failed.");381 GE_ASSERT_SUCCESS(GetTargetHostEnv(target_os, target_cpu), "Get target host env failed.");
379 const bool is_cross_compile = IsCrossCompileTarget(target_os, target_cpu);382 const bool is_cross_compile = IsCrossCompileTarget(target_os, target_cpu);
380 std::set<std::string> used_custom_op_types;383 std::set<std::string> used_custom_op_types;
381- CollectCustomOpTypesFromGraph(root_graph_, used_custom_op_types);384+ GE_ASSERT_SUCCESS(CollectCustomOpTypesFromGraph(root_graph_, custom_op_registry_, used_custom_op_types));
382 for (const auto &item : subgraph_instance_name_to_model_) {385 for (const auto &item : subgraph_instance_name_to_model_) {
383 const auto &ge_model = item.second;386 const auto &ge_model = item.second;
384 if (ge_model == nullptr || ge_model->GetGraph() == nullptr || ge_model->GetGraph() == root_graph_) {387 if (ge_model == nullptr || ge_model->GetGraph() == nullptr || ge_model->GetGraph() == root_graph_) {
385 continue;388 continue;
386 }389 }
387- CollectCustomOpTypesFromGraph(ge_model->GetGraph(), used_custom_op_types);390+ GE_ASSERT_SUCCESS(CollectCustomOpTypesFromGraph(ge_model->GetGraph(), custom_op_registry_,
391+ used_custom_op_types));
388 }392 }
389 393 
390 bool has_portable_custom_op = false;394 bool has_portable_custom_op = false;
391 for (const auto &op_type : used_custom_op_types) {395 for (const auto &op_type : used_custom_op_types) {
392- auto op = CustomOpFactory::CreateOrGetCustomOp(AscendString(op_type.c_str()));396+ auto op = custom_op_registry_->CreateOrGetCustomOp(AscendString(op_type.c_str()));
393 GE_ASSERT_NOTNULL(op);397 GE_ASSERT_NOTNULL(op);
394 auto *portable_op = dynamic_cast<PortableOp *>(op);398 auto *portable_op = dynamic_cast<PortableOp *>(op);
395 if (portable_op == nullptr) {399 if (portable_op == nullptr) {
@@ -634,6 +638,7 @@ std::shared_ptr<GeRootModel> GeRootModel::Fork() {
634 ge_root_model->op_master_device_so_set_ = this->op_master_device_so_set_;638 ge_root_model->op_master_device_so_set_ = this->op_master_device_so_set_;
635 ge_root_model->autofuse_so_set_ = this->autofuse_so_set_;639 ge_root_model->autofuse_so_set_ = this->autofuse_so_set_;
636 ge_root_model->custom_op_so_set_ = this->custom_op_so_set_;640 ge_root_model->custom_op_so_set_ = this->custom_op_so_set_;
641+ ge_root_model->custom_op_registry_ = this->custom_op_registry_;
637 return ge_root_model;642 return ge_root_model;
638}643}
639} // namespace ge644} // namespace ge
@@ -24,6 +24,7 @@
24#include "common/memory/feature_memory_impl.h"24#include "common/memory/feature_memory_impl.h"
25#include "common/host_resource_center/host_resource_center.h"25#include "common/host_resource_center/host_resource_center.h"
26#include "ge/ge_ir_build.h"26#include "ge/ge_ir_build.h"
27+#include "graph/custom_op_registry.h"
27 28 
28namespace ge {29namespace ge {
29class PortableOp;30class PortableOp;
@@ -161,6 +162,14 @@ struct FixedFeatureMemory {
161 return custom_op_so_set_;162 return custom_op_so_set_;
162 }163 }
163 164 
165+ void SetCustomOpRegistry(const CustomOpRegistryPtr &registry) {
166+ custom_op_registry_ = registry;
167+ }
168+ 
169+ const CustomOpRegistryPtr &GetCustomOpRegistry() const {
170+ return custom_op_registry_;
171+ }
172+ 
164 std::shared_ptr<GeRootModel> Fork();173 std::shared_ptr<GeRootModel> Fork();
165 174 
166 inline void SetRootGraph(const ComputeGraphPtr &graph) {175 inline void SetRootGraph(const ComputeGraphPtr &graph) {
@@ -219,6 +228,7 @@ struct FixedFeatureMemory {
219 std::unordered_set<std::string> op_master_device_so_set_{};228 std::unordered_set<std::string> op_master_device_so_set_{};
220 std::unordered_set<std::string> autofuse_so_set_{};229 std::unordered_set<std::string> autofuse_so_set_{};
221 std::unordered_set<std::string> custom_op_so_set_{};230 std::unordered_set<std::string> custom_op_so_set_{};
231+ CustomOpRegistryPtr custom_op_registry_ = nullptr;
222};232};
223using GeRootModelPtr = std::shared_ptr<ge::GeRootModel>;233using GeRootModelPtr = std::shared_ptr<ge::GeRootModel>;
224} // namespace ge234} // namespace ge
@@ -220,8 +220,10 @@ if("ge-executor" IN_LIST BUILD_COMPONENT)
220 message(STATUS "************Install ge-executor packages***************")220 message(STATUS "************Install ge-executor packages***************")
221 install_public_packages(ge-executor)221 install_public_packages(ge-executor)
222 if(NOT MDC_COMPILE_RUNTIME)222 if(NOT MDC_COMPILE_RUNTIME)
223- install(TARGETS ge_common ge_executor_shared ge_common_base davinci_executor hybrid_executor gert om2_executor register223+ install(TARGETS ge_common ge_executor_shared ge_common_base davinci_executor hybrid_executor gert om2_executor
224- graph lowering register_static graph_base model_deployer npu_sched_model_loader data_flow_base hcom_executor224+ register graph lowering register_static graph_base custom_op_registry_static model_deployer
225+ npu_sched_model_loader
226+ data_flow_base hcom_executor
225 acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl acl_cblas227 acl_mdl acl_mdl_impl acl_mdl_impl_om2 acl_op_executor acl_op_executor_impl acl_cblas
226 LIBRARY DESTINATION ${ARCH_LINUX_PATH}/lib64 COMPONENT ge-executor228 LIBRARY DESTINATION ${ARCH_LINUX_PATH}/lib64 COMPONENT ge-executor
227 ARCHIVE DESTINATION ${ARCH_LINUX_PATH}/lib64 COMPONENT ge-executor229 ARCHIVE DESTINATION ${ARCH_LINUX_PATH}/lib64 COMPONENT ge-executor
@@ -38,6 +38,7 @@
38#include "graph/unfold/graph_unfolder.h"38#include "graph/unfold/graph_unfolder.h"
39#include "graph/passes/feature/super_kernel_pass.h"39#include "graph/passes/feature/super_kernel_pass.h"
40#include "common/compile_profiling/ge_trace_wrapper.h"40#include "common/compile_profiling/ge_trace_wrapper.h"
41+#include "graph/custom_op_factory.h"
41 42 
42using domi::BuildMode;43using domi::BuildMode;
43 44 
@@ -287,6 +288,7 @@ Status GraphBuilder::Build(ComputeGraphPtr &comp_graph, GeRootModelPtr &ge_root_
287 if (ge_root_model_ptr == nullptr) {288 if (ge_root_model_ptr == nullptr) {
288 return MEMALLOC_FAILED;289 return MEMALLOC_FAILED;
289 }290 }
291+ ge_root_model_ptr->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
290 292 
291 // when Constant's memory is large, can be converted to Const,293 // when Constant's memory is large, can be converted to Const,
292 // because Const's memory can be released when model is unload294 // because Const's memory can be released when model is unload
@@ -349,6 +349,8 @@ InferStorageShape() 分发入口
3493. 算子 InferShape 函数通过 `InferShapeContext` 接口读取输入 Shape、写入输出 OriginShape3493. 算子 InferShape 函数通过 `InferShapeContext` 接口读取输入 Shape、写入输出 OriginShape
3504. `TransformAllOutputsShape()` 自动将输出 OriginShape 转换为 StorageShape(维度扩展 + 格式转换)3504. `TransformAllOutputsShape()` 自动将输出 OriginShape 转换为 StorageShape(维度扩展 + 格式转换)
351 351 
352+`FindInferShapeFunc` 仅服务于 `OpImplSpaceRegistryV2` 路径。lowering 阶段只有在 `IsInferShapeRegistered()` 已确认当前 op type 存在 v2 infer_shape 时才会构造该节点,因此运行期再次查找失败代表 registry/type/version 前后不一致,应直接失败。自定义算子的 ShapeInferOp 不通过该节点回退到进程级 `CustomOpFactory`,而是走 `LoweringCustomNode -> InferCustomOpShape -> FindCustomOp -> InferCustomOpShapeFromInput`,并使用 `GeRootModel` 注入到 `LoweringGlobalData` 的模型级 `CustomOpRegistry`。
353+ 
352### 6.2 执行图优化354### 6.2 执行图优化
353 355 
354#### FindInferShapeFunc 去重356#### FindInferShapeFunc 去重
@@ -120,7 +120,7 @@ GenerateOfflineModel()
120 120 
121**文件路径**: `base/common/model/ge_root_model.cc`121**文件路径**: `base/common/model/ge_root_model.cc`
122 122 
123-检测逻辑分为个独立的检查函数:123+检测逻辑分为个独立的检查函数:
124 124 
125#### 3.2.1 CheckAndSetSpaceRegistry125#### 3.2.1 CheckAndSetSpaceRegistry
126 126 
@@ -142,6 +142,12 @@ GenerateOfflineModel()
142 142 
143**说明**:Autofuse 是 GE 的算子自动融合优化特性,融合后的算子会生成独立的 .so 文件,需要随模型一起分发。143**说明**:Autofuse 是 GE 的算子自动融合优化特性,融合后的算子会生成独立的 .so 文件,需要随模型一起分发。
144 144 
145+#### 3.2.4 CheckAndSetCustomOpSo
146+ 
147+**触发条件**:图中存在当前 `GeRootModel` 持有的 `CustomOpRegistry` 能识别的 `PortableOp` 自定义算子。
148+ 
149+**说明**`GraphManager::PreRun()``BuildModel()` 返回后会把编译期进程级全局 `CustomOpRegistry` 显式绑定到当前 `GeRootModel`。后续自定义算子 SO 收集和 `CUSTOM_OPS` 分区序列化均通过 `ge_root_model->GetCustomOpRegistry()` 访问自定义算子,保存流程不再直接访问 `CustomOpFactory`。已有 OM 重新打包时如果模型未携带 custom op registry,则仅跳过 custom op 分区处理,不回退到进程级全局 registry。
150+ 
145### 3.3 收集阶段:LoadAndStoreOppSo151### 3.3 收集阶段:LoadAndStoreOppSo
146 152 
147确定需要打包的 SO 类型后,`ModelHelper` 调用 `LoadAndStoreOppSo()` 将 .so 文件从磁盘加载到内存中的 `OpSoStore` 对象。153确定需要打包的 SO 类型后,`ModelHelper` 调用 `LoadAndStoreOppSo()` 将 .so 文件从磁盘加载到内存中的 `OpSoStore` 对象。
@@ -238,7 +244,13 @@ OpMasterDevice SO 的加载采用两套去重策略:
238- **内置 SO**:通过 so 名称去重(类型+版本号保证唯一),相同名称的 SO 只保留一份244- **内置 SO**:通过 so 名称去重(类型+版本号保证唯一),相同名称的 SO 只保留一份
239- **自定义 SO**:通过二进制内容去重,将完整 SO 数据作为 key 建立映射。当多个模型引用内容相同但文件名不同的自定义算子时,系统能识别并复用已有 SO,避免重复加载245- **自定义 SO**:通过二进制内容去重,将完整 SO 数据作为 key 建立映射。当多个模型引用内容相同但文件名不同的自定义算子时,系统能识别并复用已有 SO,避免重复加载
240 246 
241-#### 4.2.3 兼容性校验247+#### 4.2.3 CUSTOM_OPS 分区加载
248+ 
249+**文件路径**: `base/common/helper/model_custom_kernels_helper.cc`
250+ 
251+离线 OM 中的 `CUSTOM_OPS` 分区承载自定义算子实例序列化数据。离线加载 root model 时,即使 OM 未携带自定义算子 SO 或非空 `CUSTOM_OPS` 分区,也会创建模型级空 `CustomOpRegistry` 并注入 `GeRootModel`,用于标识该模型的自定义算子查找域。加载非空 `CUSTOM_OPS` 分区时必须写入当前模型持有的 `CustomOpRegistry`,禁止回退到进程级全局 `CustomOpFactory`,避免多模型私有自定义算子状态互相污染。RT2 `ModelConverter::ConvertGeModelToExecuteGraph()` 只消费 `GeRootModel` 已注入的 registry;若 registry 为空则视为上游构造异常,不在 Convert 阶段回退全局 registry。
252+ 
253+#### 4.2.4 兼容性校验
242 254 
243**文件路径**: `base/common/helper/model_helper.cc`255**文件路径**: `base/common/helper/model_helper.cc`
244 256 
@@ -89,6 +89,7 @@ if(COMPILABLE_ADD_BUILD_CUSTOM_OP)
89 lowering89 lowering
90 register90 register
91 gert91 gert
92+ custom_op_registry_static
92 dl93 dl
93 -Wl,--as-needed94 -Wl,--as-needed
94 )95 )
@@ -96,8 +96,10 @@ SET(GRAPH_SOURCE_LIST
96 "type/ascend_string.cc"96 "type/ascend_string.cc"
97 "attr/attr_value.cc"97 "attr/attr_value.cc"
98 "type/axis_type_info.cc"98 "type/axis_type_info.cc"
99+ "normal_graph/custom_op_creator_register.cc"
99 "normal_graph/custom_op_factory.cc"100 "normal_graph/custom_op_factory.cc"
100- "normal_graph/custom_op_factory_impl.cc"101+ "normal_graph/custom_op_pull_registry.cc"
102+ "normal_graph/custom_op_registry.cc"
101 "normal_graph/operator_factory.cc"103 "normal_graph/operator_factory.cc"
102 "normal_graph/operator_factory_impl.cc"104 "normal_graph/operator_factory_impl.cc"
103 "normal_graph/graph.cc"105 "normal_graph/graph.cc"
@@ -227,6 +229,7 @@ target_compile_options(graph PRIVATE
227 229 
228target_compile_definitions(graph PRIVATE230target_compile_definitions(graph PRIVATE
229 $<$<OR:$<STREQUAL:${PRODUCT_SIDE},host>,$<STREQUAL:${ENABLE_OPEN_SRC},True>>:FMK_SUPPORT_DUMP>231 $<$<OR:$<STREQUAL:${PRODUCT_SIDE},host>,$<STREQUAL:${ENABLE_OPEN_SRC},True>>:FMK_SUPPORT_DUMP>
232+ CUSTOM_OP_PULL_REGISTRY_HIDDEN_EXPORT
230 google=ascend_private233 google=ascend_private
231 $<IF:$<STREQUAL:${TARGET_SYSTEM_NAME},Windows>,OS_TYPE=WIN,OS_TYPE=0>234 $<IF:$<STREQUAL:${TARGET_SYSTEM_NAME},Windows>,OS_TYPE=WIN,OS_TYPE=0>
232 $<$<STREQUAL:${TARGET_SYSTEM_NAME},Windows>:SECUREC_USING_STD_SECURE_LIB=0 NOMINMAX>235 $<$<STREQUAL:${TARGET_SYSTEM_NAME},Windows>:SECUREC_USING_STD_SECURE_LIB=0 NOMINMAX>
@@ -237,6 +240,9 @@ target_include_directories(graph PRIVATE
237 ${CMAKE_BINARY_DIR}240 ${CMAKE_BINARY_DIR}
238 ${CMAKE_BINARY_DIR}/proto/metadef_protos241 ${CMAKE_BINARY_DIR}/proto/metadef_protos
239 ${AIR_CODE_DIR}/inc/graph_metadef242 ${AIR_CODE_DIR}/inc/graph_metadef
243+ ${AIR_CODE_DIR}/inc/graph_metadef/external
244+ ${ASCEND_INSTALL_PATH}/include/graph
245+ ${ASCEND_INSTALL_PATH}/include
240 ${TOP_DIR}/runtime/include/external246 ${TOP_DIR}/runtime/include/external
241 ${TOP_DIR}/runtime/include/external/acl247 ${TOP_DIR}/runtime/include/external/acl
242)248)
@@ -267,6 +273,31 @@ target_link_libraries(graph
267target_link_libraries(graph PRIVATE graph_base error_manager runtime_headers)273target_link_libraries(graph PRIVATE graph_base error_manager runtime_headers)
268target_compile_options(graph PRIVATE ${OPTIMIZE_OPTION})274target_compile_options(graph PRIVATE ${OPTIMIZE_OPTION})
269 275 
276+add_library(custom_op_registry_static STATIC
277+ "normal_graph/custom_op_creator_register.cc"
278+ "normal_graph/custom_op_pull_registry.cc"
279+)
280+ 
281+target_compile_options(custom_op_registry_static PRIVATE
282+ $<$<STREQUAL:${TARGET_SYSTEM_NAME},Linux>:-fPIC -fvisibility=hidden -fvisibility-inlines-hidden>
283+)
284+ 
285+target_include_directories(custom_op_registry_static PRIVATE
286+ ${CMAKE_CURRENT_LIST_DIR}
287+ ${CMAKE_BINARY_DIR}
288+ ${CMAKE_BINARY_DIR}/proto/metadef_protos
289+ ${AIR_CODE_DIR}/inc/graph_metadef
290+ ${AIR_CODE_DIR}/inc/graph_metadef/external
291+ ${ASCEND_INSTALL_PATH}/include/graph
292+ ${ASCEND_INSTALL_PATH}/include
293+ ${TOP_DIR}/runtime/include/external
294+ ${TOP_DIR}/runtime/include/external/acl
295+)
296+ 
297+target_link_libraries(custom_op_registry_static
298+ PRIVATE intf_pub
299+ PUBLIC metadef_headers)
300+ 
270if (${ENABLE_OPEN_SRC} STREQUAL "True")301if (${ENABLE_OPEN_SRC} STREQUAL "True")
271else()302else()
272 ######### libgraph.a #############303 ######### libgraph.a #############
@@ -375,6 +406,8 @@ endif ()
375if (NOT "${PRODUCT}" STREQUAL "ascend031")406if (NOT "${PRODUCT}" STREQUAL "ascend031")
376 list(APPEND STUB_HEADER_LIST407 list(APPEND STUB_HEADER_LIST
377 ${GE_METADEF_INC_DIR}/external/graph/operator.h408 ${GE_METADEF_INC_DIR}/external/graph/operator.h
409+ ${GE_METADEF_INC_DIR}/graph/custom_op_pull_registry.h
410+ ${GE_METADEF_INC_DIR}/graph/custom_op_registry.h
378 ${GE_METADEF_INC_DIR}/graph/ge_tensor.h411 ${GE_METADEF_INC_DIR}/graph/ge_tensor.h
379 )412 )
380 if (BUILD_OPEN_PROJECT OR ENABLE_OPEN_SRC)413 if (BUILD_OPEN_PROJECT OR ENABLE_OPEN_SRC)
@@ -0,0 +1,30 @@
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 "graph/custom_op.h"
12+ 
13+#include <memory>
14+ 
15+#include "graph/custom_op_factory.h"
16+#include "graph/custom_op_load_context.h"
17+#include "graph/custom_op_pull_registry.h"
18+ 
19+namespace ge {
20+CustomOpCreatorRegister::CustomOpCreatorRegister(const AscendString &operator_type,
C
CChang-an-HW6月8日

两个构造函数放一起

likedislike
Chang-an-HW
6月8日 评论:
21+ const CustomOpCreateFunc op_creator) {
22+ RegisterCustomOpLocalCreator(operator_type.GetString(), op_creator);
23+ if ((op_creator == nullptr) || IsOfflineCustomOpSoLoading()) {
24+ return;
25+ }
26+ CustomOpFactory::RegisterCustomOpCreator(operator_type, [op_creator]() -> std::unique_ptr<BaseCustomOp> {
27+ return std::unique_ptr<BaseCustomOp>(op_creator());
28+ });
29+}
30+} // namespace ge
@@ -10,34 +10,68 @@
10 10 
11#include "graph/custom_op_factory.h"11#include "graph/custom_op_factory.h"
12#include "graph/custom_op.h"12#include "graph/custom_op.h"
13-#include "graph/custom_op_factory_impl.h"13+#include "graph/custom_op_load_context.h"
14+#include "graph/custom_op_registry.h"
14#include "debug/ge_log.h"15#include "debug/ge_log.h"
15 16 
17+#include <cstdint>
18+#include <memory>
19+ 
16namespace ge {20namespace ge {
21+namespace {
22+thread_local uint32_t g_offline_custom_op_so_loading_depth = 0U;
23+} // namespace
24+ 
25+CustomOpRegistry &CustomOpFactory::GetGlobalRegistry() {
26+ return *GetGlobalRegistryPtr();
27+}
28+ 
29+CustomOpRegistryPtr CustomOpFactory::GetGlobalRegistryPtr() {
30+ static CustomOpRegistryPtr registry = std::make_shared<CustomOpRegistry>();
31+ return registry;
32+}
33+ 
17graphStatus CustomOpFactory::RegisterCustomOpCreator(const AscendString &op_type, const BaseOpCreator &op_creator) {34graphStatus CustomOpFactory::RegisterCustomOpCreator(const AscendString &op_type, const BaseOpCreator &op_creator) {
18- return CustomOpFactoryImpl::GetInstance().RegisterCustomOpCreator(op_type, op_creator);35+ return GetGlobalRegistry().RegisterCreator(op_type, op_creator);
19}36}
20 37 
21BaseCustomOp *CustomOpFactory::CreateOrGetCustomOp(const AscendString &op_type) {38BaseCustomOp *CustomOpFactory::CreateOrGetCustomOp(const AscendString &op_type) {
22- return CustomOpFactoryImpl::GetInstance().CreateOrGetCustomOp(op_type);39+ return GetGlobalRegistry().CreateOrGetCustomOp(op_type);
23}40}
24 41 
25graphStatus CustomOpFactory::GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops) {42graphStatus CustomOpFactory::GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops) {
26- return CustomOpFactoryImpl::GetInstance().GetAllRegisteredOps(all_registered_ops);43+ return GetGlobalRegistry().GetAllRegisteredOps(all_registered_ops);
27}44}
28bool CustomOpFactory::IsExistOp(const AscendString &op_type) {45bool CustomOpFactory::IsExistOp(const AscendString &op_type) {
29- return CustomOpFactoryImpl::GetInstance().IsExistOp(op_type);46+ return GetGlobalRegistry().HasCreator(op_type);
30}47}
31 48 
32bool CustomOpFactory::IsAddressRefreshable(const AscendString &op_type) {49bool CustomOpFactory::IsAddressRefreshable(const AscendString &op_type) {
33- return CustomOpFactoryImpl::GetInstance().IsAddressRefreshable(op_type);50+ return GetGlobalRegistry().IsAddressRefreshable(op_type);
34}51}
35 52 
36graphStatus CustomOpFactory::LoadCustomOpsPartition(const uint8_t *data, size_t len) {53graphStatus CustomOpFactory::LoadCustomOpsPartition(const uint8_t *data, size_t len) {
37- return CustomOpFactoryImpl::GetInstance().LoadCustomOpsPartition(data, len);54+ return GetGlobalRegistry().LoadCustomOpsPartition(data, len);
38}55}
39 56 
40CustomOpCreatorRegister::CustomOpCreatorRegister(const AscendString &operator_type, BaseOpCreator const &op_creator) {57CustomOpCreatorRegister::CustomOpCreatorRegister(const AscendString &operator_type, BaseOpCreator const &op_creator) {
41- CustomOpFactoryImpl::GetInstance().RegisterCustomOpCreator(operator_type, op_creator);58+ if (IsOfflineCustomOpSoLoading()) {
59+ return;
60+ }
61+ CustomOpFactory::RegisterCustomOpCreator(operator_type, op_creator);
62+}
63+ 
64+ScopedOfflineCustomOpSoLoadGuard::ScopedOfflineCustomOpSoLoadGuard() {
65+ ++g_offline_custom_op_so_loading_depth;
66+}
67+ 
68+ScopedOfflineCustomOpSoLoadGuard::~ScopedOfflineCustomOpSoLoadGuard() {
69+ if (g_offline_custom_op_so_loading_depth > 0U) {
70+ --g_offline_custom_op_so_loading_depth;
71+ }
72+}
73+ 
74+bool IsOfflineCustomOpSoLoading() {
75+ return g_offline_custom_op_so_loading_depth > 0U;
42}76}
43} // namespace ge77} // namespace ge
@@ -0,0 +1,80 @@
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 "graph/custom_op_pull_registry.h"
12+ 
13+#include <cstdint>
14+#include <mutex>
15+#include <string>
16+#include <vector>
17+ 
18+#ifdef __GNUC__
19+#ifdef CUSTOM_OP_PULL_REGISTRY_HIDDEN_EXPORT
20+#define CUSTOM_OP_PULL_REGISTRY_EXPORT __attribute__((visibility("hidden")))
21+#else
22+#define CUSTOM_OP_PULL_REGISTRY_EXPORT __attribute__((visibility("default")))
23+#endif
24+#else
25+#define CUSTOM_OP_PULL_REGISTRY_EXPORT
26+#endif
27+ 
28+namespace ge {
29+namespace {
30+struct LocalCreator {
31+ std::string op_type;
32+ CustomOpCreateFunc creator;
33+};
34+ 
35+std::mutex &GetCustomOpLocalCreatorMutex() {
36+ static std::mutex mu;
37+ return mu;
38+}
39+ 
40+std::vector<LocalCreator> &GetCustomOpLocalCreators() {
41+ static std::vector<LocalCreator> creators;
42+ return creators;
43+}
44+} // namespace
45+ 
46+void RegisterCustomOpLocalCreator(const char *const op_type, const CustomOpCreateFunc creator) {
47+ if ((op_type == nullptr) || (op_type[0] == '\0') || (creator == nullptr)) {
48+ return;
49+ }
50+ const std::lock_guard<std::mutex> lock(GetCustomOpLocalCreatorMutex());
51+ GetCustomOpLocalCreators().push_back({op_type, creator});
52+}
53+} // namespace ge
54+ 
55+extern "C" CUSTOM_OP_PULL_REGISTRY_EXPORT uint32_t GetRegisteredCustomOpCreatorAbiVersion() {
56+ return ge::kCustomOpCreatorPullAbiVersion;
57+}
58+ 
59+extern "C" CUSTOM_OP_PULL_REGISTRY_EXPORT size_t GetRegisteredCustomOpCreatorNum() {
60+ const std::lock_guard<std::mutex> lock(ge::GetCustomOpLocalCreatorMutex());
61+ return ge::GetCustomOpLocalCreators().size();
62+}
63+ 
64+extern "C" CUSTOM_OP_PULL_REGISTRY_EXPORT int32_t GetRegisteredCustomOpCreators(
65+ ge::CustomOpTypeToCreator *creators, const size_t creator_num, const size_t creator_struct_size) {
66+ const std::lock_guard<std::mutex> lock(ge::GetCustomOpLocalCreatorMutex());
67+ const auto &local_creators = ge::GetCustomOpLocalCreators();
68+ if ((creator_num < local_creators.size()) || ((creator_num > 0U) && (creators == nullptr)) ||
69+ (creator_struct_size < sizeof(ge::CustomOpTypeToCreator))) {
70+ return -1;
71+ }
72+ for (size_t i = 0U; i < local_creators.size(); ++i) {
73+ auto *creator_addr = reinterpret_cast<uint8_t *>(creators) + (i * creator_struct_size);
74+ auto *creator = reinterpret_cast<ge::CustomOpTypeToCreator *>(creator_addr);
75+ *creator = {sizeof(ge::CustomOpTypeToCreator), local_creators[i].op_type.c_str(), local_creators[i].creator};
76+ }
77+ return 0;
78+}
79+ 
80+#undef CUSTOM_OP_PULL_REGISTRY_EXPORT
Rgraph_metadef/graph/normal_graph/custom_op_factory_impl.ccgraph_metadef/graph/normal_graph/custom_op_registry.cc+142-82
@@ -1,5 +1,5 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.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 of3 * 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").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.5 * Please refer to the License for details. You may not use this file except in compliance with the License.
@@ -8,37 +8,133 @@
8 * See LICENSE in the root of the software repository for the full text of the License.8 * See LICENSE in the root of the software repository for the full text of the License.
9 */9 */
10 10 
11-#include "graph/custom_op_factory_impl.h"11+#include "graph/custom_op_registry.h"
12+ 
13+#include <limits>
14+#include <string>
15+#include <utility>
12 16 
13-#include "external/graph/custom_op.h"
14#include "debug/ge_log.h"17#include "debug/ge_log.h"
15-#include "common/util/mem_utils.h"
16#include "framework/common/framework_types_internal.h"18#include "framework/common/framework_types_internal.h"
19+#include "graph/operator_factory_impl.h"
17 20 
18namespace ge {21namespace ge {
19-Status CustomOpFactoryImpl::RegisterCustomOpCreator(const AscendString &op_type, const BaseOpCreator &op_creator) {22+namespace {
23+struct ParsedCustomKernelItem {
24+ std::string op_type;
25+ const uint8_t *kernel_bin;
26+ size_t bin_len;
27+ size_t entry_size;
28+};
29+ 
30+graphStatus ParseCustomKernelItem(const uint8_t *data, const size_t len, const size_t offset,
31+ ParsedCustomKernelItem &item) {
32+ const size_t header_size = sizeof(CustomKernelItemHeader);
33+ if (header_size > (len - offset)) {
34+ GELOGE(GRAPH_FAILED, "[CUSTOM OP] Insufficient data for CustomKernelItemHeader at offset %zu", offset);
35+ return GRAPH_FAILED;
36+ }
37+ 
38+ const auto *header = reinterpret_cast<const CustomKernelItemHeader *>(data + offset);
39+ if (header->magic != kCustomKernelItemMagic) {
40+ GELOGE(GRAPH_FAILED, "[CUSTOM OP] Invalid magic in CustomKernelItemHeader: 0x%X, expected 0x%X",
41+ header->magic, kCustomKernelItemMagic);
42+ return GRAPH_FAILED;
43+ }
44+ 
45+ const size_t name_len = static_cast<size_t>(header->name_len);
46+ const size_t bin_len = static_cast<size_t>(header->bin_len);
47+ if ((name_len > (std::numeric_limits<size_t>::max() - header_size)) ||
48+ (bin_len > (std::numeric_limits<size_t>::max() - header_size - name_len))) {
49+ GELOGE(GRAPH_FAILED, "[CUSTOM OP] Invalid kernel entry size at offset %zu, name len %zu, bin len %zu", offset,
50+ name_len, bin_len);
51+ return GRAPH_FAILED;
52+ }
53+ 
54+ const size_t entry_size = header_size + name_len + bin_len;
55+ if (entry_size > (len - offset)) {
56+ GELOGE(GRAPH_FAILED, "[CUSTOM OP] Insufficient data for kernel entry at offset %zu, need %zu bytes", offset,
57+ entry_size);
58+ return GRAPH_FAILED;
59+ }
60+ 
61+ const char *op_type_ptr = reinterpret_cast<const char *>(data + offset + header_size);
62+ item.op_type = std::string(op_type_ptr, name_len);
63+ item.kernel_bin = data + offset + header_size + name_len;
64+ item.bin_len = bin_len;
65+ item.entry_size = entry_size;
66+ return GRAPH_SUCCESS;
67+}
68+ 
69+graphStatus DeserializeCustomKernelItem(CustomOpRegistry &registry, const ParsedCustomKernelItem &item) {
70+ auto op = registry.CreateOrGetCustomOp(AscendString(item.op_type.c_str()));
71+ if (op == nullptr) {
72+ GELOGE(GRAPH_FAILED, "[CUSTOM OP] Custom op '%s' not found in registry, environment mismatch detected",
73+ item.op_type.c_str());
74+ return GRAPH_FAILED;
75+ }
76+ 
77+ auto *serializable_op = dynamic_cast<PortableOp *>(op);
78+ if (serializable_op == nullptr) {
79+ GELOGE(GRAPH_FAILED,
80+ "[CUSTOM OP] Custom op '%s' is not PortableOp, type mismatch or version inconsistency detected",
81+ item.op_type.c_str());
82+ return GRAPH_FAILED;
83+ }
84+ 
85+ const std::vector<uint8_t> kernel_bin_buffer(item.kernel_bin, item.kernel_bin + item.bin_len);
86+ const auto ret = serializable_op->Deserialize(kernel_bin_buffer);
87+ if (ret != GRAPH_SUCCESS) {
88+ GELOGE(ret, "[CUSTOM OP] Failed to deserialize custom op '%s'", item.op_type.c_str());
89+ return ret;
90+ }
91+ 
92+ GELOGI("[CUSTOM OP] Successfully deserialized custom op '%s'", item.op_type.c_str());
93+ return GRAPH_SUCCESS;
94+}
95+} // namespace
96+ 
97+CustomOpRegistry::~CustomOpRegistry() {
98+ std::vector<std::string> op_types;
99+ {
100+ const std::lock_guard<std::mutex> lock(mu_);
101+ for (const auto &entry : creators_) {
102+ op_types.push_back(entry.first.GetString());
103+ }
104+ }
105+ if (!op_types.empty()) {
106+ OperatorFactoryImpl::RemoveCustomOpCreators(op_types);
107+ }
108+}
109+ 
110+graphStatus CustomOpRegistry::RegisterCreator(const AscendString &op_type, const BaseOpCreator &creator) {
20 const std::lock_guard<std::mutex> lock(mu_);111 const std::lock_guard<std::mutex> lock(mu_);
21- if (op_creator == nullptr) {112+ if (creator == nullptr) {
22 GELOGE(GRAPH_PARAM_INVALID, "[Check][Param] custom op creator for %s is null.", op_type.GetString());113 GELOGE(GRAPH_PARAM_INVALID, "[Check][Param] custom op creator for %s is null.", op_type.GetString());
23 return GRAPH_PARAM_INVALID;114 return GRAPH_PARAM_INVALID;
24 }115 }
25- const auto it = custom_op_creators_.find(op_type);116+ const auto it = creators_.find(op_type);
26- if (it != custom_op_creators_.cend()) {117+ if (it != creators_.cend()) {
27 GELOGW("[CUSTOM OP] custom op creator for %s already exist.", op_type.GetString());118 GELOGW("[CUSTOM OP] custom op creator for %s already exist.", op_type.GetString());
28 return GRAPH_FAILED;119 return GRAPH_FAILED;
29 }120 }
30- (void)custom_op_creators_.emplace(op_type, op_creator);121+ (void)creators_.emplace(op_type, creator);
31 GELOGI("[CUSTOM OP] register custom operator creator for %s.", op_type.GetString());122 GELOGI("[CUSTOM OP] register custom operator creator for %s.", op_type.GetString());
32 return GRAPH_SUCCESS;123 return GRAPH_SUCCESS;
33}124}
34 125 
35-BaseCustomOp *CustomOpFactoryImpl::CreateOrGetCustomOp(const AscendString &op_type) {126+void CustomOpRegistry::AddSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles) {
127+ const std::lock_guard<std::mutex> lock(mu_);
128+ so_handles_.insert(so_handles_.end(), so_handles.begin(), so_handles.end());
129+}
130+ 
131+BaseCustomOp *CustomOpRegistry::CreateOrGetCustomOp(const AscendString &op_type) {
36 const std::lock_guard<std::mutex> lock(mu_);132 const std::lock_guard<std::mutex> lock(mu_);
37 if (const auto it = custom_ops_.find(op_type); it != custom_ops_.cend()) {133 if (const auto it = custom_ops_.find(op_type); it != custom_ops_.cend()) {
38 GELOGD("[CUSTOM OP] custom_op %s already created .", op_type.GetString());134 GELOGD("[CUSTOM OP] custom_op %s already created .", op_type.GetString());
39 return it->second.get();135 return it->second.get();
40 }136 }
41- if (const auto op_creator_it = custom_op_creators_.find(op_type); op_creator_it != custom_op_creators_.cend()) {137+ if (const auto op_creator_it = creators_.find(op_type); op_creator_it != creators_.cend()) {
42 if (op_creator_it->second == nullptr) {138 if (op_creator_it->second == nullptr) {
43 GELOGE(GRAPH_PARAM_INVALID, "[Check][Param] custom op creator for %s is null.", op_type.GetString());139 GELOGE(GRAPH_PARAM_INVALID, "[Check][Param] custom op creator for %s is null.", op_type.GetString());
44 return nullptr;140 return nullptr;
@@ -54,20 +150,7 @@ BaseCustomOp *CustomOpFactoryImpl::CreateOrGetCustomOp(const AscendString &op_ty
54 return nullptr;150 return nullptr;
55}151}
56 152 
57-Status CustomOpFactoryImpl::GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops) {153+bool CustomOpRegistry::IsAddressRefreshable(const AscendString &op_type) {
58- const std::lock_guard<std::mutex> lock(mu_);
59- for (const auto &op_creator : custom_op_creators_) {
60- all_registered_ops.push_back(op_creator.first);
61- }
62- return GRAPH_SUCCESS;
63-}
64- 
65-bool CustomOpFactoryImpl::IsExistOp(const AscendString &op_type) {
66- const std::lock_guard<std::mutex> lock(mu_);
67- return custom_op_creators_.find(op_type) != custom_op_creators_.end();
68-}
69- 
70-bool CustomOpFactoryImpl::IsAddressRefreshable(const AscendString &op_type) {
71 const auto *custom_op = CreateOrGetCustomOp(op_type);154 const auto *custom_op = CreateOrGetCustomOp(op_type);
72 if (custom_op == nullptr) {155 if (custom_op == nullptr) {
73 return false;156 return false;
@@ -75,7 +158,31 @@ bool CustomOpFactoryImpl::IsAddressRefreshable(const AscendString &op_type) {
75 return dynamic_cast<const ArgsUpdater*>(custom_op) != nullptr;158 return dynamic_cast<const ArgsUpdater*>(custom_op) != nullptr;
76}159}
77 160 
78-graphStatus CustomOpFactoryImpl::LoadCustomOpsPartition(const uint8_t *data, size_t len) {161+BaseCustomOp *CustomOpRegistry::FindCustomOp(const AscendString &op_type) const {
162+ const std::lock_guard<std::mutex> lock(mu_);
163+ const auto it = custom_ops_.find(op_type);
164+ return (it == custom_ops_.cend()) ? nullptr : it->second.get();
165+}
166+ 
167+bool CustomOpRegistry::HasCreator(const AscendString &op_type) const {
168+ const std::lock_guard<std::mutex> lock(mu_);
169+ return creators_.find(op_type) != creators_.cend();
170+}
171+ 
172+bool CustomOpRegistry::HasCustomOp(const AscendString &op_type) const {
173+ const std::lock_guard<std::mutex> lock(mu_);
174+ return custom_ops_.find(op_type) != custom_ops_.cend();
175+}
176+ 
177+graphStatus CustomOpRegistry::GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops) const {
178+ const std::lock_guard<std::mutex> lock(mu_);
179+ for (const auto &op_creator : creators_) {
180+ all_registered_ops.push_back(op_creator.first);
181+ }
182+ return GRAPH_SUCCESS;
183+}
184+ 
185+graphStatus CustomOpRegistry::LoadCustomOpsPartition(const uint8_t *data, size_t len) {
79 if ((data == nullptr) || (len == 0U)) {186 if ((data == nullptr) || (len == 0U)) {
80 GELOGE(GRAPH_PARAM_INVALID, "[CUSTOM OP] custom ops partition data is invalid, data %p, len %zu.", data, len);187 GELOGE(GRAPH_PARAM_INVALID, "[CUSTOM OP] custom ops partition data is invalid, data %p, len %zu.", data, len);
81 return GRAPH_PARAM_INVALID;188 return GRAPH_PARAM_INVALID;
@@ -83,66 +190,19 @@ graphStatus CustomOpFactoryImpl::LoadCustomOpsPartition(const uint8_t *data, siz
83 190 
84 size_t offset = 0U;191 size_t offset = 0U;
85 while (offset < len) {192 while (offset < len) {
86- // 1. 检查剩余空间是否足够读取 header193+ ParsedCustomKernelItem item{};
87- if (offset + sizeof(CustomKernelItemHeader) > len) {194+ const auto parse_ret = ParseCustomKernelItem(data, len, offset, item);
88- GELOGE(GRAPH_FAILED, "[CUSTOM OP] Insufficient data for CustomKernelItemHeader at offset %zu", offset);195+ if (parse_ret != GRAPH_SUCCESS) {
89- return GRAPH_FAILED;196+ return parse_ret;
90 }197 }
91- 198+ const auto deserialize_ret = DeserializeCustomKernelItem(*this, item);
92- // 2. 解析 header199+ if (deserialize_ret != GRAPH_SUCCESS) {
93- const auto *header = reinterpret_cast<const CustomKernelItemHeader *>(data + offset);200+ return deserialize_ret;
94- if (header->magic != kCustomKernelItemMagic) {
95- GELOGE(GRAPH_FAILED, "[CUSTOM OP] Invalid magic in CustomKernelItemHeader: 0x%X, expected 0x%X",
96- header->magic, kCustomKernelItemMagic);
97- return GRAPH_FAILED;
98 }201 }
99- 202+ offset += item.entry_size;
100- // 3. 检查剩余空间是否足够读取 name + bin
101- const size_t entry_size = sizeof(CustomKernelItemHeader) + static_cast<size_t>(header->name_len) +
102- static_cast<size_t>(header->bin_len);
103- if (offset + entry_size > len) {
104- GELOGE(GRAPH_FAILED, "[CUSTOM OP] Insufficient data for kernel entry at offset %zu, need %zu bytes", offset, entry_size);
105- return GRAPH_FAILED;
106- }
107- 
108- // 4. 读取 op_type
109- const char *op_type_ptr = reinterpret_cast<const char *>(data + offset + sizeof(CustomKernelItemHeader));
110- const std::string op_type(op_type_ptr, header->name_len);
111- 
112- // 5. 创建算子实例
113- auto op = CreateOrGetCustomOp(AscendString(op_type.c_str()));
114- if (op == nullptr) {
115- GELOGE(GRAPH_FAILED, "[CUSTOM OP] Custom op '%s' not found in registry, "
116- "environment mismatch detected", op_type.c_str());
117- return GRAPH_FAILED;
118- }
119- 
120- // 6. 能力检测
121- auto *serializable_op = dynamic_cast<PortableOp *>(op);
122- if (serializable_op == nullptr) {
123- GELOGE(GRAPH_FAILED, "[CUSTOM OP] Custom op '%s' is not PortableOp, "
124- "type mismatch or version inconsistency detected", op_type.c_str());
125- return GRAPH_FAILED;
126- }
127- 
128- // 7. 调用反序列化
129- const uint8_t *kernel_bin = data + offset + sizeof(CustomKernelItemHeader) + header->name_len;
130- const std::vector<uint8_t> kernel_bin_buffer(kernel_bin, kernel_bin + header->bin_len);
131- const auto ret = serializable_op->Deserialize(kernel_bin_buffer);
132- if (ret != GRAPH_SUCCESS) {
133- GELOGE(ret, "[CUSTOM OP] Failed to deserialize custom op '%s'", op_type.c_str());
134- return ret;
135- }
136- 
137- GELOGI("[CUSTOM OP] Successfully deserialized custom op '%s'", op_type.c_str());
138- 
139- // 8. 推进 offset
140- offset += entry_size;
141 }203 }
142 204 
143 GELOGI("[CUSTOM OP] load custom ops partition success.");205 GELOGI("[CUSTOM OP] load custom ops partition success.");
144 return GRAPH_SUCCESS;206 return GRAPH_SUCCESS;
145}207}
146- 208+} // namespace ge
147-CustomOpFactoryImpl::CustomOpFactoryImpl() = default;
148-} // namespace ge
@@ -498,6 +498,19 @@ void OperatorFactoryImpl::BackupAndClearRegInfoOnce() {
498 });498 });
499}499}
500 500 
501+void OperatorFactoryImpl::RemoveCustomOpCreators(const std::vector<std::string> &op_types) {
502+ if (operator_creators_v2_ != nullptr) {
503+ for (const auto &op_type : op_types) {
504+ operator_creators_v2_->erase(op_type);
505+ }
506+ }
507+ if (operator_creators_ != nullptr) {
508+ for (const auto &op_type : op_types) {
509+ operator_creators_->erase(op_type);
510+ }
511+ }
512+}
513+ 
501void OperatorFactoryImpl::MergeBackupCreatorsOnce() {514void OperatorFactoryImpl::MergeBackupCreatorsOnce() {
502 static std::once_flag flag;515 static std::once_flag flag;
503 std::call_once(flag, []() {516 std::call_once(flag, []() {
@@ -21,9 +21,12 @@
21#include "platform/platform_info.h"21#include "platform/platform_info.h"
22#include "common/op_so_store/op_so_store.h"22#include "common/op_so_store/op_so_store.h"
23#include "common/host_resource_center/host_resource_serializer.h"23#include "common/host_resource_center/host_resource_serializer.h"
24+#include "graph/custom_op_registry.h"
24 25 
25namespace ge {26namespace ge {
26using NodeRefreshInfo = std::map<NodePtr, std::map<NodePtr, std::vector<std::pair<size_t, int64_t>>>>;27using NodeRefreshInfo = std::map<NodePtr, std::map<NodePtr, std::vector<std::pair<size_t, int64_t>>>>;
28+Status LoadCustomOpsToRegistry(const uint8_t *data, size_t len, const CustomOpRegistryPtr &registry);
29+ 
27class GeModel;30class GeModel;
28class GeRootModel;31class GeRootModel;
29class PortableOp;32class PortableOp;
@@ -215,6 +218,7 @@ class GE_FUNC_VISIBILITY ModelHelper : public ModelSaveHelper {
215 const size_t mode_index) const;218 const size_t mode_index) const;
216 Status LoadCustAICPUKernelStore(const OmFileLoadHelper &om_load_helper, const GeModelPtr &cur_model,219 Status LoadCustAICPUKernelStore(const OmFileLoadHelper &om_load_helper, const GeModelPtr &cur_model,
217 const size_t mode_index) const;220 const size_t mode_index) const;
221+ Status LoadCustomOpRegistry(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const;
218 222 
219 Status SaveModelDef(shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeModelPtr &ge_model,223 Status SaveModelDef(shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeModelPtr &ge_model,
220 Buffer &model_buffer, const size_t model_index = 0U) const;224 Buffer &model_buffer, const size_t model_index = 0U) const;
@@ -225,8 +229,11 @@ class GE_FUNC_VISIBILITY ModelHelper : public ModelSaveHelper {
225 Status SaveAllModelPartiton(shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeModelPtr &ge_model,229 Status SaveAllModelPartiton(shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeModelPtr &ge_model,
226 Buffer &model_buffer, Buffer &task_buffer, const size_t model_index = 0U) const;230 Buffer &model_buffer, Buffer &task_buffer, const size_t model_index = 0U) const;
227 231 
228- Status LoadOpSoBin(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const;232+ Status LoadOpSoBin(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model,
229- Status LoadCustomOps(const OmFileLoadHelper &om_load_helper) const;233+ std::vector<CustomOpSoHandlePtr> &loaded_handles) const;
234+ Status ValidateCustomOpsDeserialized(const GeRootModelPtr &ge_root_model,
235+ const CustomOpRegistryPtr &registry) const;
236+ Status LoadCustomOps(const OmFileLoadHelper &om_load_helper, const CustomOpRegistryPtr &registry) const;
230 Status LoadTilingData(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const;237 Status LoadTilingData(const OmFileLoadHelper &om_load_helper, const GeRootModelPtr &ge_root_model) const;
231 Status SaveTilingData(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeRootModelPtr &ge_root_model);238 Status SaveTilingData(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper, const GeRootModelPtr &ge_root_model);
232 void SaveOpSoInfo(const GeRootModelPtr &ge_root_model) const;239 void SaveOpSoInfo(const GeRootModelPtr &ge_root_model) const;
@@ -239,7 +246,8 @@ class GE_FUNC_VISIBILITY ModelHelper : public ModelSaveHelper {
239 Status SaveOpMasterDeviceSoBin(const GeRootModelPtr &ge_root_model);246 Status SaveOpMasterDeviceSoBin(const GeRootModelPtr &ge_root_model);
240 Status SaveAutofuseSoBin(const GeRootModelPtr &ge_root_model);247 Status SaveAutofuseSoBin(const GeRootModelPtr &ge_root_model);
241 Status SaveCustomOpSoBin(const GeRootModelPtr &ge_root_model);248 Status SaveCustomOpSoBin(const GeRootModelPtr &ge_root_model);
242- Status LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins) const;249+ Status LoadCustomOpSoBins(const std::vector<OpSoBinPtr> &custom_so_bins,
250+ std::vector<CustomOpSoHandlePtr> &loaded_handles) const;
243 Status SaveRootModelPartitions(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper,251 Status SaveRootModelPartitions(std::shared_ptr<OmFileSaveHelper> &om_file_save_helper,
244 const GeRootModelPtr &ge_root_model, const GeModelPtr &first_ge_model,252 const GeRootModelPtr &ge_root_model, const GeModelPtr &first_ge_model,
245 string &output_file_name, const bool has_asc_node);253 string &output_file_name, const bool has_asc_node);
@@ -30,11 +30,11 @@
30#include "framework/runtime/stream_allocator.h"30#include "framework/runtime/stream_allocator.h"
31#include "framework/runtime/event_allocator.h"31#include "framework/runtime/event_allocator.h"
32#include "common/host_resource_center/host_resource_center.h"32#include "common/host_resource_center/host_resource_center.h"
33+#include "graph/custom_op_registry.h"
33 34 
34namespace ge {35namespace ge {
35class AicoreKernelHandlesManager;36class AicoreKernelHandlesManager;
36} // namespace ge37} // namespace ge
37- 
38namespace gert {38namespace gert {
39enum class ExecutorState { kInit, kLoaded };39enum class ExecutorState { kInit, kLoaded };
40inline const ge::char_t *GetSubExeGraphTypeStr(const SubExeGraphType type) {40inline const ge::char_t *GetSubExeGraphTypeStr(const SubExeGraphType type) {
@@ -240,6 +240,7 @@ class VISIBILITY_EXPORT ModelV2Executor {
240 // to keep host resource live longer than resource_guard_240 // to keep host resource live longer than resource_guard_
241 // resource guarder may holding pointer from host_resource_center_241 // resource guarder may holding pointer from host_resource_center_
242 ge::HostResourceCenterPtr host_resource_center_;242 ge::HostResourceCenterPtr host_resource_center_;
243+ ge::CustomOpRegistryPtr custom_op_registry_;
243 TopologicalResourceGuard resource_guard_;244 TopologicalResourceGuard resource_guard_;
244 std::array<ExeGraphExecutor, kSubExeGraphTypeEnd> graphs_;245 std::array<ExeGraphExecutor, kSubExeGraphTypeEnd> graphs_;
245 ModelDesc *model_desc_ = nullptr;246 ModelDesc *model_desc_ = nullptr;
@@ -19,6 +19,7 @@
19#include "base/registry/op_impl_space_registry_v2.h"19#include "base/registry/op_impl_space_registry_v2.h"
20#include "exe_graph/lowering/lowering_opt.h"20#include "exe_graph/lowering/lowering_opt.h"
21#include "common/ge_common/ge_types.h"21#include "common/ge_common/ge_types.h"
22+#include "graph/custom_op_registry.h"
22 23 
23namespace ge {24namespace ge {
24class AicoreKernelHandlesManager;25class AicoreKernelHandlesManager;
@@ -183,6 +184,13 @@ class LoweringGlobalData {
183 std::shared_ptr<ge::AicoreKernelHandlesManager> GetAicoreKernelHandlesManager() const {184 std::shared_ptr<ge::AicoreKernelHandlesManager> GetAicoreKernelHandlesManager() const {
184 return aicore_manager_;185 return aicore_manager_;
185 }186 }
187+ void SetCustomOpRegistry(const ge::CustomOpRegistryPtr &registry) {
188+ custom_op_registry_ = registry;
189+ }
190+ 
191+ const ge::CustomOpRegistryPtr &GetCustomOpRegistry() const {
192+ return custom_op_registry_;
193+ }
186 194 
187 private:195 private:
188 struct HolderByGraphs {196 struct HolderByGraphs {
@@ -211,6 +219,7 @@ class LoweringGlobalData {
211 std::map<int64_t, std::pair<const void *, size_t>> fixed_feature_mem_;219 std::map<int64_t, std::pair<const void *, size_t>> fixed_feature_mem_;
212 bool is_single_stream_scene_{true};220 bool is_single_stream_scene_{true};
213 void *host_resource_center_{nullptr};221 void *host_resource_center_{nullptr};
222+ ge::CustomOpRegistryPtr custom_op_registry_{nullptr};
214 // user set file constant device memory, key is file name223 // user set file constant device memory, key is file name
215 std::map<std::string, ge::FileConstantMem> file_constant_mems_;224 std::map<std::string, ge::FileConstantMem> file_constant_mems_;
216 std::shared_ptr<ge::AicoreKernelHandlesManager> aicore_manager_;225 std::shared_ptr<ge::AicoreKernelHandlesManager> aicore_manager_;
@@ -116,6 +116,7 @@ class ShapeInferOp : virtual public BaseCustomOp {
116};116};
117 117 
118using BaseOpCreator = std::function<std::unique_ptr<BaseCustomOp>()>;118using BaseOpCreator = std::function<std::unique_ptr<BaseCustomOp>()>;
119+using CustomOpCreateFunc = ge::BaseCustomOp *(*)();
119 120 
120/**121/**
121 * 自定义算子创建器注册辅助类。122 * 自定义算子创建器注册辅助类。
@@ -124,14 +125,16 @@ using BaseOpCreator = std::function<std::unique_ptr<BaseCustomOp>()>;
124class CustomOpCreatorRegister {125class CustomOpCreatorRegister {
125public:126public:
126 CustomOpCreatorRegister(const AscendString &operator_type, const BaseOpCreator &op_creator);127 CustomOpCreatorRegister(const AscendString &operator_type, const BaseOpCreator &op_creator);
128+ CustomOpCreatorRegister(const AscendString &operator_type, CustomOpCreateFunc op_creator);
127 ~CustomOpCreatorRegister() = default;129 ~CustomOpCreatorRegister() = default;
128};130};
129} // namespace ge131} // namespace ge
130 132 
131#define REG_JOIN(g_register, y) g_register##y133#define REG_JOIN(g_register, y) g_register##y
132#define REG_AUTO_MAPPING_OP(custom_op_class) REG_AUTO_MAPPING_OP_UNIQ(__COUNTER__, custom_op_class)134#define REG_AUTO_MAPPING_OP(custom_op_class) REG_AUTO_MAPPING_OP_UNIQ(__COUNTER__, custom_op_class)
133-#define REG_AUTO_MAPPING_OP_UNIQ(ctr, custom_op_class) \135+#define REG_AUTO_MAPPING_OP_UNIQ(ctr, custom_op_class) \
C
CChang-an-HW6月8日

离线场景老版so不兼容

likedislike
Chang-an-HW
6月8日 评论:
134- static const ge::CustomOpCreatorRegister REG_JOIN(custom_op_register, ctr)( \136+ static ge::BaseCustomOp *REG_JOIN(custom_op_pull_creator, ctr)() { return new custom_op_class(); } \
135- #custom_op_class, []() -> std::unique_ptr<ge::BaseCustomOp> { return std::make_unique<custom_op_class>(); })137+ static const ge::CustomOpCreatorRegister REG_JOIN(custom_op_register, ctr)( \
138+ #custom_op_class, REG_JOIN(custom_op_pull_creator, ctr))
136 139 
137#endif // METADEF_CXX_INC_GRAPH_BASE_CUSTOM_OP_H140#endif // METADEF_CXX_INC_GRAPH_BASE_CUSTOM_OP_H
@@ -10,6 +10,7 @@
10 10 
11#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H11#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H
12#define CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H12#define CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H
13+#include <memory>
13#include <vector>14#include <vector>
14 15 
15#include "graph/custom_op.h"16#include "graph/custom_op.h"
@@ -18,6 +19,8 @@
18 19 
19 20 
20namespace ge {21namespace ge {
22+class CustomOpRegistry;
23+using CustomOpRegistryPtr = std::shared_ptr<CustomOpRegistry>;
21 24 
22class CustomOpFactory {25class CustomOpFactory {
23public:26public:
@@ -25,6 +28,8 @@ public:
25 28 
26 static BaseCustomOp *CreateOrGetCustomOp(const AscendString &op_type);29 static BaseCustomOp *CreateOrGetCustomOp(const AscendString &op_type);
27 30 
31+ static CustomOpRegistryPtr GetGlobalRegistryPtr();
32+ 
28 static graphStatus GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops);33 static graphStatus GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops);
29 34 
30 static bool IsExistOp(const AscendString &op_type);35 static bool IsExistOp(const AscendString &op_type);
@@ -32,6 +37,8 @@ public:
32 static graphStatus LoadCustomOpsPartition(const uint8_t *data, size_t len);37 static graphStatus LoadCustomOpsPartition(const uint8_t *data, size_t len);
33 38 
34 static bool IsAddressRefreshable(const AscendString &op_type);39 static bool IsAddressRefreshable(const AscendString &op_type);
40+ private:
41+ static CustomOpRegistry &GetGlobalRegistry();
35};42};
36} // namespace ge43} // namespace ge
37#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H44#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_H
@@ -0,0 +1,26 @@
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+#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_LOAD_CONTEXT_H
12+#define CANN_GRAPH_ENGINE_CUSTOM_OP_LOAD_CONTEXT_H
13+ 
14+namespace ge {
15+class ScopedOfflineCustomOpSoLoadGuard {
16+ public:
17+ ScopedOfflineCustomOpSoLoadGuard();
18+ ~ScopedOfflineCustomOpSoLoadGuard();
19+ ScopedOfflineCustomOpSoLoadGuard(const ScopedOfflineCustomOpSoLoadGuard &) = delete;
20+ ScopedOfflineCustomOpSoLoadGuard &operator=(const ScopedOfflineCustomOpSoLoadGuard &) = delete;
21+};
22+ 
23+bool IsOfflineCustomOpSoLoading();
24+} // namespace ge
25+ 
26+#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_LOAD_CONTEXT_H
@@ -0,0 +1,39 @@
1+/**
C
CChang-an-HW5月25日

不使用头文件的方式,改为.a静态链接

likedislike
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+#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_PULL_REGISTRY_H
12+#define CANN_GRAPH_ENGINE_CUSTOM_OP_PULL_REGISTRY_H
13+ 
14+#include <cstddef>
15+#include <cstdint>
16+ 
17+namespace ge {
18+class BaseCustomOp;
19+using CustomOpCreateFunc = BaseCustomOp *(*)();
20+ 
21+constexpr uint32_t kCustomOpCreatorPullAbiVersion = 1U;
22+ 
23+struct CustomOpTypeToCreator {
24+ uint32_t struct_size;
25+ const char *op_type;
26+ CustomOpCreateFunc creator;
27+};
28+ 
29+void RegisterCustomOpLocalCreator(const char *op_type, CustomOpCreateFunc creator);
30+} // namespace ge
31+ 
32+extern "C" uint32_t GetRegisteredCustomOpCreatorAbiVersion();
33+ 
34+extern "C" size_t GetRegisteredCustomOpCreatorNum();
35+ 
36+extern "C" int32_t GetRegisteredCustomOpCreators(
37+ ge::CustomOpTypeToCreator *creators, size_t creator_num, size_t creator_struct_size);
38+ 
39+#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_PULL_REGISTRY_H
Rinc/graph_metadef/graph/custom_op_factory_impl.hinc/graph_metadef/graph/custom_op_registry.h+33-25
@@ -1,45 +1,53 @@
1/**1/**
2- * Copyright (c) 2025 Huawei Technologies Co., Ltd.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 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").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.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, 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.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.8 * See LICENSE in the root of the software repository for the full text of the License.
9 */9 */
10 10 
11-#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_FACTORY_IMPL_H11+#ifndef CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_CORE_H
12-#define CANN_GRAPH_ENGINE_CUSTOM_OP_FACTORY_IMPL_H12+#define CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_CORE_H
13+ 
14+#include <cstddef>
15+#include <cstdint>
13#include <map>16#include <map>
14#include <memory>17#include <memory>
15#include <mutex>18#include <mutex>
16-#include "graph/custom_op_factory.h"19+#include <vector>
20+ 
21+#include "graph/ascend_string.h"
22+#include "graph/custom_op.h"
17 23 
18namespace ge {24namespace ge {
19-class CustomOpFactoryImpl {25+class CustomOpSoHandle;
20-public:26+using CustomOpSoHandlePtr = std::shared_ptr<CustomOpSoHandle>;
21- graphStatus RegisterCustomOpCreator(const AscendString &op_type, const BaseOpCreator &op_creator);27+ 
28+class CustomOpRegistry {
29+ public:
30+ ~CustomOpRegistry();
31+ 
32+ graphStatus RegisterCreator(const AscendString &op_type, const BaseOpCreator &creator);
33+ void AddSoHandles(const std::vector<CustomOpSoHandlePtr> &so_handles);
22 34 
23 BaseCustomOp *CreateOrGetCustomOp(const AscendString &op_type);35 BaseCustomOp *CreateOrGetCustomOp(const AscendString &op_type);
24- 
25- graphStatus GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops);
26- 
27- bool IsExistOp(const AscendString &op_type);
28- 
29 bool IsAddressRefreshable(const AscendString &op_type);36 bool IsAddressRefreshable(const AscendString &op_type);
30- 37+ BaseCustomOp *FindCustomOp(const AscendString &op_type) const;
38+ bool HasCreator(const AscendString &op_type) const;
39+ bool HasCustomOp(const AscendString &op_type) const;
40+ graphStatus GetAllRegisteredOps(std::vector<AscendString> &all_registered_ops) const;
31 graphStatus LoadCustomOpsPartition(const uint8_t *data, size_t len);41 graphStatus LoadCustomOpsPartition(const uint8_t *data, size_t len);
32 42 
33- static CustomOpFactoryImpl &GetInstance() {43+ private:
34- static CustomOpFactoryImpl instance;44+ mutable std::mutex mu_;
35- return instance;45+ std::vector<CustomOpSoHandlePtr> so_handles_;
36- }46+ std::map<AscendString, BaseOpCreator> creators_;
37- 
38-private:
39- std::mutex mu_;
40- std::map<AscendString, BaseOpCreator> custom_op_creators_;
41 std::map<AscendString, std::unique_ptr<BaseCustomOp>> custom_ops_;47 std::map<AscendString, std::unique_ptr<BaseCustomOp>> custom_ops_;
42- CustomOpFactoryImpl();
43};48};
49+ 
50+using CustomOpRegistryPtr = std::shared_ptr<CustomOpRegistry>;
44} // namespace ge51} // namespace ge
45-#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_FACTORY_IMPL_H52+ 
53+#endif // CANN_GRAPH_ENGINE_CUSTOM_OP_REGISTRY_CORE_H
@@ -137,6 +137,8 @@ class GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY OperatorFactoryImpl {
137 137 
138 static void ReleaseRegInfo();138 static void ReleaseRegInfo();
139 139 
140+ static void RemoveCustomOpCreators(const std::vector<std::string> &op_types);
141+ 
140 static void BackupAndClearRegInfoOnce();142 static void BackupAndClearRegInfoOnce();
141 143 
142 static void MergeBackupCreatorsOnce();144 static void MergeBackupCreatorsOnce();
@@ -21,7 +21,6 @@
21#include "parser/common/acl_graph_parser_util.h"21#include "parser/common/acl_graph_parser_util.h"
22#include "base/err_msg.h"22#include "base/err_msg.h"
23#include "parser/tensorflow_parser.h"23#include "parser/tensorflow_parser.h"
24-#include "custom_op_factory_impl.h"
25#include "register/scope/scope_fusion_pass_register.h"24#include "register/scope/scope_fusion_pass_register.h"
26#include "framework/common/debug/ge_log.h"25#include "framework/common/debug/ge_log.h"
27#include "graph/debug/ge_attr_define.h"26#include "graph/debug/ge_attr_define.h"
@@ -44,6 +44,7 @@
44#include "common/dump/dump_manager.h"44#include "common/dump/dump_manager.h"
45#include "common/dump/dump_callback.h"45#include "common/dump/dump_callback.h"
46#include "graph/operator_factory_impl.h"46#include "graph/operator_factory_impl.h"
47+#include "common/helper/custom_op_so_loader.h"
47 48 
48namespace {49namespace {
49constexpr size_t kDynamicBatchSizeVecSize = 1U;50constexpr size_t kDynamicBatchSizeVecSize = 1U;
@@ -343,6 +344,7 @@ Status GeExecutor::FinalizeEx() {
343 ProfilingProperties::Instance().ClearProperties();344 ProfilingProperties::Instance().ClearProperties();
344 }345 }
345 346 
347+ CustomOpSoLoader::Finalize();
346 OpsKernelExecutorManager::GetInstance().Finalize();348 OpsKernelExecutorManager::GetInstance().Finalize();
347 HostMemManager::Instance().Finalize();349 HostMemManager::Instance().Finalize();
348 350 
@@ -35,6 +35,7 @@
35#include "graph/model.h"35#include "graph/model.h"
36#include "graph/node.h"36#include "graph/node.h"
37#include "graph/op_desc.h"37#include "graph/op_desc.h"
38+#include "graph/custom_op_registry.h"
38#include "graph/utils/attr_utils.h"39#include "graph/utils/attr_utils.h"
39#include "graph/utils/tensor_utils.h"40#include "graph/utils/tensor_utils.h"
40#include "graph/utils/args_format_desc_utils.h"41#include "graph/utils/args_format_desc_utils.h"
@@ -860,6 +861,22 @@ class DavinciModel {
860 space_registries_ = space_registries;861 space_registries_ = space_registries;
861 }862 }
862 863 
864+ void SetCustomOpRegistry(const CustomOpRegistryPtr &registry) {
865+ custom_op_registry_ = registry;
866+ }
867+ 
868+ void SetCustomOpRegistryRaw(CustomOpRegistry *registry) {
869+ if (registry == nullptr) {
870+ custom_op_registry_ = nullptr;
871+ return;
872+ }
873+ custom_op_registry_ = CustomOpRegistryPtr(registry, [](CustomOpRegistry *) {});
874+ }
875+ 
876+ const CustomOpRegistryPtr &GetCustomOpRegistry() const {
877+ return custom_op_registry_;
878+ }
879+ 
863 ExceptionDumper *MutableExceptionDumper() {880 ExceptionDumper *MutableExceptionDumper() {
864 return &exception_dumper_;881 return &exception_dumper_;
865 }882 }
@@ -1700,6 +1717,7 @@ class DavinciModel {
1700 bool is_stream_sync_timeout_ = false;1717 bool is_stream_sync_timeout_ = false;
1701 1718 
1702 std::shared_ptr<gert::OpImplSpaceRegistryV2Array> space_registries_;1719 std::shared_ptr<gert::OpImplSpaceRegistryV2Array> space_registries_;
1720+ CustomOpRegistryPtr custom_op_registry_{nullptr};
1703 MsprofGeTaskType GetTaskType(const domi::FftsPlusCtxDef &ctx_def) const;1721 MsprofGeTaskType GetTaskType(const domi::FftsPlusCtxDef &ctx_def) const;
1704 uint32_t GetBlockDim(const domi::FftsPlusCtxDef &ctx_def) const;1722 uint32_t GetBlockDim(const domi::FftsPlusCtxDef &ctx_def) const;
1705 uint32_t GetThreadId(const domi::FftsPlusCtxDef &ctx_def) const;1723 uint32_t GetThreadId(const domi::FftsPlusCtxDef &ctx_def) const;
@@ -177,6 +177,19 @@ Status BindOutputMemBlock(const size_t tensor_size, ge::MemBlock *const mem_bloc
177 ge_tensor.MutableTensorDesc().SetPlacement(ge::kPlacementDevice);177 ge_tensor.MutableTensorDesc().SetPlacement(ge::kPlacementDevice);
178 return SUCCESS;178 return SUCCESS;
179}179}
180+ 
181+std::shared_ptr<DavinciModel> CreateDavinciModelFromRootModel(const GeRootModelPtr &root_model,
182+ const GeModelPtr &ge_model,
183+ const int32_t priority) {
184+ const auto davinci_model = MakeShared<DavinciModel>(priority, nullptr);
185+ if ((davinci_model == nullptr) || (root_model == nullptr) || (ge_model == nullptr)) {
186+ return davinci_model;
187+ }
188+ 
189+ davinci_model->Assign(ge_model);
190+ davinci_model->SetCustomOpRegistry(root_model->GetCustomOpRegistry());
191+ return davinci_model;
192+}
180} // namespace193} // namespace
181Status SetNetOutputTensorInfo(const GraphId &graph_id, const GraphNodePtr &graph_node) {194Status SetNetOutputTensorInfo(const GraphId &graph_id, const GraphNodePtr &graph_node) {
182 if (graph_node->IsSavedNetOutputTensorInfoFlag()) {195 if (graph_node->IsSavedNetOutputTensorInfoFlag()) {
@@ -744,6 +757,7 @@ Status ModelManager::LoadModelOnline(uint32_t &model_id, const GeRootModelPtr &g
744 GELOGI("Set graph id to model map, graph id: %u, model id: %u.", graph_node->GetGraphId(), model_id);757 GELOGI("Set graph id to model map, graph id: %u, model id: %u.", graph_node->GetGraphId(), model_id);
745 758 
746 domi::GetContext().is_online_model = true;759 domi::GetContext().is_online_model = true;
760+ GE_ASSERT_NOTNULL(ge_root_model->GetCustomOpRegistry());
747 761 
748 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, ge_root_model), "Init model [%u] op master device failed", model_id);762 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, ge_root_model), "Init model [%u] op master device failed", model_id);
749 763 
@@ -770,6 +784,7 @@ Status ModelManager::LoadModelOnline(uint32_t &model_id, const GeRootModelPtr &g
770 GE_TIMESTAMP_START(Assign);784 GE_TIMESTAMP_START(Assign);
771 davinci_model->Assign(ge_model);785 davinci_model->Assign(ge_model);
772 GE_TIMESTAMP_END(Assign, "GraphLoader::ModelAssign");786 GE_TIMESTAMP_END(Assign, "GraphLoader::ModelAssign");
787+ davinci_model->SetCustomOpRegistry(ge_root_model->GetCustomOpRegistry());
773 const uint64_t session_id = GetContext().SessionId();788 const uint64_t session_id = GetContext().SessionId();
774 789 
775 const DumpProperties &dump_properties = DumpManager::GetInstance().GetDumpProperties(session_id);790 const DumpProperties &dump_properties = DumpManager::GetInstance().GetDumpProperties(session_id);
@@ -1518,6 +1533,7 @@ Status ModelManager::LoadModelOffline(const ModelData &model, const ModelParam &
1518 davinci_model->SetOmName(model.om_name);1533 davinci_model->SetOmName(model.om_name);
1519 const auto &ge_root_model = model_helper.GetGeRootModel();1534 const auto &ge_root_model = model_helper.GetGeRootModel();
1520 GE_CHECK_NOTNULL(ge_root_model);1535 GE_CHECK_NOTNULL(ge_root_model);
1536+ davinci_model->SetCustomOpRegistry(ge_root_model->GetCustomOpRegistry());
1521 davinci_model->SetFileConstantWeightDir(ge_root_model->GetFileConstantWeightDir());1537 davinci_model->SetFileConstantWeightDir(ge_root_model->GetFileConstantWeightDir());
1522 const DumpProperties &dump_properties = DumpManager::GetInstance().GetDumpProperties(kOfflineSessionId);1538 const DumpProperties &dump_properties = DumpManager::GetInstance().GetDumpProperties(kOfflineSessionId);
1523 davinci_model->SetDumpProperties(dump_properties);1539 davinci_model->SetDumpProperties(dump_properties);
@@ -1606,9 +1622,8 @@ Status ModelManager::LoadModelWithQueueParam(uint32_t &model_id,
1606 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, root_model), "Init model [%u] op master device failed", model_id);1622 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, root_model), "Init model [%u] op master device failed", model_id);
1607 const auto &ge_model = it->second;1623 const auto &ge_model = it->second;
1608 GE_CHECK_NOTNULL(ge_model);1624 GE_CHECK_NOTNULL(ge_model);
1609- const auto davinci_model = MakeShared<DavinciModel>(priority, nullptr);1625+ const auto davinci_model = CreateDavinciModelFromRootModel(root_model, ge_model, priority);
1610 GE_CHECK_NOTNULL(davinci_model);1626 GE_CHECK_NOTNULL(davinci_model);
1611- davinci_model->Assign(ge_model);
1612 1627 
1613 Status ret = SUCCESS;1628 Status ret = SUCCESS;
1614 if (need_update_session_id) {1629 if (need_update_session_id) {
@@ -1691,9 +1706,8 @@ Status ModelManager::LoadModelWithoutQ(uint32_t &model_id, const GeRootModelPtr
1691 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, root_model), "Init model [%u] op master device failed", model_id);1706 GE_ASSERT_SUCCESS(InitOpMasterDeviceSo(model_id, root_model), "Init model [%u] op master device failed", model_id);
1692 const auto &ge_model = it->second;1707 const auto &ge_model = it->second;
1693 GE_CHECK_NOTNULL(ge_model);1708 GE_CHECK_NOTNULL(ge_model);
1694- const auto davinci_model = MakeShared<DavinciModel>(priority, nullptr);1709+ const auto davinci_model = CreateDavinciModelFromRootModel(root_model, ge_model, priority);
1695 GE_CHECK_NOTNULL(davinci_model);1710 GE_CHECK_NOTNULL(davinci_model);
1696- davinci_model->Assign(ge_model);
1697 1711 
1698 GenModelId(model_id);1712 GenModelId(model_id);
1699 davinci_model->SetId(model_id);1713 davinci_model->SetId(model_id);
@@ -18,11 +18,13 @@
18#include "exe_graph/runtime/eager_op_execution_context.h"18#include "exe_graph/runtime/eager_op_execution_context.h"
19#include "exe_graph/runtime/update_args_context.h"19#include "exe_graph/runtime/update_args_context.h"
20#include "framework/runtime/args_handler.h"20#include "framework/runtime/args_handler.h"
21-#include "graph/custom_op_factory.h"
22-#include "graph/custom_op.h"
23#include "graph/debug/ge_util.h"21#include "graph/debug/ge_util.h"
24#include "graph/load/model_manager/model_manager.h"22#include "graph/load/model_manager/model_manager.h"
25#include "graph/load/model_manager/model_utils.h"23#include "graph/load/model_manager/model_utils.h"
24+#include "graph/manager/graph_var_manager.h"
25+#include "graph/utils/node_utils.h"
26+#include "graph/custom_op.h"
27+#include "graph/custom_op_registry.h"
26#include "graph/load/model_manager/sink_only_allocator.h"28#include "graph/load/model_manager/sink_only_allocator.h"
27#include "graph/load/model_manager/task_info/ge/sink_op_args_handler.h"29#include "graph/load/model_manager/task_info/ge/sink_op_args_handler.h"
28#include "graph/manager/graph_var_manager.h"30#include "graph/manager/graph_var_manager.h"
@@ -172,7 +174,10 @@ Status CustomTaskInfo::ParseTaskRunParam(const domi::TaskDef &task_def, DavinciM
172 workspace_addrs_ = ModelUtils::GetWorkspaceDataAddrsValue(rts_param, op_desc_, workspace_mem_types_);174 workspace_addrs_ = ModelUtils::GetWorkspaceDataAddrsValue(rts_param, op_desc_, workspace_mem_types_);
173 175 
174 AscendString op_type(op_desc_->GetType().c_str());176 AscendString op_type(op_desc_->GetType().c_str());
175- is_args_refreshable_ = CustomOpFactory::IsAddressRefreshable(op_type);177+ const auto &custom_op_registry = davinci_model->GetCustomOpRegistry();
178+ GE_ASSERT_NOTNULL(custom_op_registry, "[CUSTOM OP] custom op registry is nullptr for op %s.",
179+ op_desc_->GetName().c_str());
180+ is_args_refreshable_ = custom_op_registry->IsAddressRefreshable(op_type);
176 181 
177 for (size_t i = 0UL; i < input_data_addrs_.size(); i++) {182 for (size_t i = 0UL; i < input_data_addrs_.size(); i++) {
178 task_run_param.parsed_input_addrs.push_back({input_data_addrs_[i], input_mem_types_[i], is_args_refreshable_, {0}});183 task_run_param.parsed_input_addrs.push_back({input_data_addrs_[i], input_mem_types_[i], is_args_refreshable_, {0}});
@@ -289,8 +294,13 @@ Status CustomTaskInfo::Distribute() {
289 const TaskProfGuarder prof_guarder(this);294 const TaskProfGuarder prof_guarder(this);
290 295 
291 AscendString op_type(op_desc_->GetType().c_str());296 AscendString op_type(op_desc_->GetType().c_str());
292- auto custom_op_ptr = CustomOpFactory::CreateOrGetCustomOp(op_type);297+ GE_ASSERT_NOTNULL(davinci_model_);
293- GE_ASSERT_NOTNULL(custom_op_ptr);298+ const auto &custom_op_registry = davinci_model_->GetCustomOpRegistry();
299+ GE_ASSERT_NOTNULL(custom_op_registry, "[CUSTOM OP] custom op registry is nullptr for op %s.",
300+ op_desc_->GetName().c_str());
301+ BaseCustomOp *custom_op_ptr = custom_op_registry->CreateOrGetCustomOp(op_type);
302+ GE_ASSERT_NOTNULL(custom_op_ptr, "[CUSTOM OP] custom op %s is not found in registry.",
303+ op_desc_->GetType().c_str());
294 304 
295 args_update_op_ = dynamic_cast<ArgsUpdater*>(custom_op_ptr);305 args_update_op_ = dynamic_cast<ArgsUpdater*>(custom_op_ptr);
296 if (args_update_op_ != nullptr) {306 if (args_update_op_ != nullptr) {
@@ -142,6 +142,7 @@ std::unique_ptr<ModelV2Executor> ModelV2ExecutorBuilder::Build(const ExecutorOpt
142 }142 }
143 GE_TIMESTAMP_EVENT_END(BuildGraph, "ModelV2ExecutorBuilderBuild::BuildGraph");143 GE_TIMESTAMP_EVENT_END(BuildGraph, "ModelV2ExecutorBuilderBuild::BuildGraph");
144 GE_ASSERT_NOTNULL(root_model_);144 GE_ASSERT_NOTNULL(root_model_);
145+ executor->custom_op_registry_ = root_model_->GetCustomOpRegistry();
C
CChang-an-HW6月9日

是否可以直接使用root_model_中的custom_op_registry?

likedislike
Chang-an-HW
6月9日 评论:
Chang-an-HW
6月9日 评论:
145 146 
146 ge::ComputeGraphPtr root_graph = root_model_->GetRootGraph();147 ge::ComputeGraphPtr root_graph = root_model_->GetRootGraph();
147 GE_ASSERT_NOTNULL(root_graph);148 GE_ASSERT_NOTNULL(root_graph);
@@ -15,7 +15,7 @@
15#include "common/checker.h"15#include "common/checker.h"
16#include "exe_graph/lowering/frame_selector.h"16#include "exe_graph/lowering/frame_selector.h"
17#include "kernel/common_kernel_impl/build_tensor.h"17#include "kernel/common_kernel_impl/build_tensor.h"
18-#include "graph/custom_op_factory.h"18+#include "graph/custom_op_registry.h"
19#include "lowering/placement/placed_lowering_result.h"19#include "lowering/placement/placed_lowering_result.h"
20#include "exe_graph/lowering/lowering_definitions.h"20#include "exe_graph/lowering/lowering_definitions.h"
21#include "common/ge_common/ge_types.h"21#include "common/ge_common/ge_types.h"
@@ -23,13 +23,11 @@
23 23 
24namespace gert {24namespace gert {
25namespace {25namespace {
26-bool NeedCustomOpInferShape(const ge::NodePtr &node) {26+bool NeedCustomOpInferShape(const ge::NodePtr &node, const LoweringGlobalData &global_data) {
27 GE_ASSERT_NOTNULL(node);27 GE_ASSERT_NOTNULL(node);
28 const auto op_desc = node->GetOpDesc();28 const auto op_desc = node->GetOpDesc();
29 GE_ASSERT_NOTNULL(op_desc);29 GE_ASSERT_NOTNULL(op_desc);
30- auto custom_op = ge::CustomOpFactory::CreateOrGetCustomOp(node->GetTypePtr());30+ if (bg::FindShapeInferOpInCustomOpRegistry(node->GetTypePtr(), global_data) != nullptr) {
31- auto shape_infer_op = dynamic_cast<ge::ShapeInferOp *>(custom_op);
32- if (shape_infer_op != nullptr) {
33 return true;31 return true;
34 }32 }
35 const std::string infer_rule = ge::InferenceRule::GetInferenceRule(op_desc);33 const std::string infer_rule = ge::InferenceRule::GetInferenceRule(op_desc);
@@ -40,10 +38,13 @@ bool NeedCustomOpInferShape(const ge::NodePtr &node) {
40}38}
41 39 
42bg::ValueHolderPtr FindCustomExecutorFunc(const ge::NodePtr &node, const LowerInput &lower_input) {40bg::ValueHolderPtr FindCustomExecutorFunc(const ge::NodePtr &node, const LowerInput &lower_input) {
43- auto builder = [&node]() -> std::vector<bg::ValueHolderPtr> {41+ auto builder = [&node, &lower_input]() -> std::vector<bg::ValueHolderPtr> {
44- return bg::FrameSelector::OnInitRoot([&]() -> std::vector<bg::ValueHolderPtr> {42+ return bg::FrameSelector::OnInitRoot([&node, &lower_input]() -> std::vector<bg::ValueHolderPtr> {
45 auto node_type = bg::ValueHolder::CreateConst(node->GetTypePtr(), node->GetType().size() + 1, true);43 auto node_type = bg::ValueHolder::CreateConst(node->GetTypePtr(), node->GetType().size() + 1, true);
46- return {bg::ValueHolder::CreateSingleDataOutput("FindCustomOp", {node_type})};44+ ge::CustomOpRegistry *custom_op_registry = lower_input.global_data->GetCustomOpRegistry().get();
45+ auto registry_holder = bg::ValueHolder::CreateConst(&custom_op_registry, sizeof(custom_op_registry));
46+ return {bg::ValueHolder::CreateSingleDataOutput("FindCustomOp",
47+ {node_type, registry_holder})};
47 });48 });
48 };49 };
49 return lower_input.global_data->GetOrCreateUniqueValueHolder(node->GetType() + "_FindCustomOp_", builder)[0];50 return lower_input.global_data->GetOrCreateUniqueValueHolder(node->GetType() + "_FindCustomOp_", builder)[0];
@@ -100,7 +101,7 @@ LowerResult LoweringCustomNode(const ge::NodePtr &node, const LowerInput &lower_
100 LOWER_REQUIRE_NOTNULL(op_desc);101 LOWER_REQUIRE_NOTNULL(op_desc);
101 std::string kernel_type = "ExecuteCustomOp";102 std::string kernel_type = "ExecuteCustomOp";
102 std::vector<bg::ValueHolderPtr> infer_output_shapes;103 std::vector<bg::ValueHolderPtr> infer_output_shapes;
103- if (NeedCustomOpInferShape(node)) {104+ if (NeedCustomOpInferShape(node, *lower_input.global_data)) {
104 kernel_type = "ExecuteCustomOpWithInferShape";105 kernel_type = "ExecuteCustomOpWithInferShape";
105 infer_output_shapes = bg::InferCustomOpShape(node, lower_input.input_shapes, *lower_input.global_data);106 infer_output_shapes = bg::InferCustomOpShape(node, lower_input.input_shapes, *lower_input.global_data);
106 input_holders.insert(input_holders.end(), infer_output_shapes.begin(), infer_output_shapes.end());107 input_holders.insert(input_holders.end(), infer_output_shapes.begin(), infer_output_shapes.end());
@@ -11,8 +11,9 @@
11#include "custom_op_kernel.h"11#include "custom_op_kernel.h"
12#include "register/kernel_registry.h"12#include "register/kernel_registry.h"
13#include "common/checker.h"13#include "common/checker.h"
14-#include "graph/custom_op_factory.h"
15#include "graph/custom_op.h"14#include "graph/custom_op.h"
15+#include "graph/custom_op_factory.h"
16+#include "graph/custom_op_registry.h"
16#include "kernel/memory/multi_stream_mem_block.h"17#include "kernel/memory/multi_stream_mem_block.h"
17#include "graph/def_types.h"18#include "graph/def_types.h"
18#include "graph/utils/type_utils.h"19#include "graph/utils/type_utils.h"
@@ -79,8 +80,10 @@ std::string PrintStreamIdAndTaskId() {
79ge::graphStatus FindCustomOpFunc(KernelContext *context) {80ge::graphStatus FindCustomOpFunc(KernelContext *context) {
80 const char *node_type = context->GetInputValue<char *>(0);81 const char *node_type = context->GetInputValue<char *>(0);
81 GE_ASSERT_NOTNULL(node_type, "Failed to find custom op func, node type is nullptr");82 GE_ASSERT_NOTNULL(node_type, "Failed to find custom op func, node type is nullptr");
82- auto custom_op_ptr = ge::CustomOpFactory::CreateOrGetCustomOp(node_type);83+ auto custom_op_registry = context->GetInputValue<ge::CustomOpRegistry *>(1);
83- GE_ASSERT_NOTNULL(custom_op_ptr);84+ GE_ASSERT_NOTNULL(custom_op_registry, "Failed to find custom op func, custom op registry is nullptr.");
85+ ge::BaseCustomOp *custom_op_ptr = custom_op_registry->CreateOrGetCustomOp(node_type);
86+ GE_ASSERT_NOTNULL(custom_op_ptr, "Failed to find custom op func for op type %s in custom op registry.", node_type);
84 auto chain = context->GetOutput(0);87 auto chain = context->GetOutput(0);
85 GE_ASSERT_NOTNULL(chain);88 GE_ASSERT_NOTNULL(chain);
86 chain->Set(custom_op_ptr, nullptr);89 chain->Set(custom_op_ptr, nullptr);
@@ -261,4 +264,4 @@ REGISTER_KERNEL(ExecuteCustomOpWithInferShape).OutputsCreator(CreateWorkspacesMe
261 .ProfilingInfoFiller(CustomOpProfilingDataFill);264 .ProfilingInfoFiller(CustomOpProfilingDataFill);
262REGISTER_KERNEL(FreeCustomOpWorkspaces).RunFunc(FreeCustomOpWorkspacesFunc);265REGISTER_KERNEL(FreeCustomOpWorkspaces).RunFunc(FreeCustomOpWorkspacesFunc);
263}266}
264-}267+}
@@ -31,9 +31,19 @@
31#include "aicore/converter/autofuse_node_converter.h"31#include "aicore/converter/autofuse_node_converter.h"
32#include "graph/custom_op_factory.h"32#include "graph/custom_op_factory.h"
33#include "graph/custom_op.h"33#include "graph/custom_op.h"
34+#include "graph/custom_op_registry.h"
35+#include "kernel/common_kernel_impl/infer_shape.h"
34 36 
35namespace gert {37namespace gert {
36namespace bg {38namespace bg {
39+ge::ShapeInferOp *FindShapeInferOpInCustomOpRegistry(const ge::AscendString &op_type,
40+ const LoweringGlobalData &global_data) {
41+ ge::BaseCustomOp *custom_op = nullptr;
42+ const auto &custom_op_registry = global_data.GetCustomOpRegistry();
43+ custom_op = (custom_op_registry == nullptr) ? nullptr : custom_op_registry->CreateOrGetCustomOp(op_type);
44+ return dynamic_cast<ge::ShapeInferOp *>(custom_op);
45+}
46+ 
37namespace {47namespace {
38constexpr char const *kRetValType = "_RetVal";48constexpr char const *kRetValType = "_RetVal";
39struct LowerIOShapes {49struct LowerIOShapes {
@@ -120,6 +130,30 @@ std::vector<ValueHolderPtr> BuildInferShapeGraph(const ge::NodePtr &node,
120 return ValueHolder::CreateDataOutput("InferShape", inputs, node->GetAllOutDataAnchorsSize());130 return ValueHolder::CreateDataOutput("InferShape", inputs, node->GetAllOutDataAnchorsSize());
121}131}
122 132 
133+bg::ValueHolderPtr FindCustomOpFunc(const ge::NodePtr &node, LoweringGlobalData &global_data) {
134+ auto builder = [&node, &global_data]() -> std::vector<bg::ValueHolderPtr> {
135+ return bg::FrameSelector::OnInitRoot([&node, &global_data]() -> std::vector<bg::ValueHolderPtr> {
136+ auto node_type = ValueHolder::CreateConst(node->GetTypePtr(), node->GetType().size() + 1, true);
137+ ge::CustomOpRegistry *custom_op_registry = global_data.GetCustomOpRegistry().get();
138+ auto registry_holder = ValueHolder::CreateConst(&custom_op_registry, sizeof(custom_op_registry));
139+ return {ValueHolder::CreateSingleDataOutput("FindCustomOp", {node_type, registry_holder})};
140+ });
141+ };
142+ return global_data.GetOrCreateUniqueValueHolder(node->GetType() + "_FindCustomOp_", builder)[0];
143+}
144+ 
145+std::vector<ValueHolderPtr> BuildCustomOpInferShapeGraph(const ge::NodePtr &node,
146+ const std::vector<ValueHolderPtr> &input_shapes,
147+ LoweringGlobalData &global_data) {
148+ auto custom_op_func = FindCustomOpFunc(node, global_data);
149+ auto infer_shape_func = kernel::InferCustomOpShapeFromInput;
150+ auto infer_shape_func_holder = ValueHolder::CreateConst(&infer_shape_func, sizeof(infer_shape_func));
151+ auto inputs = input_shapes;
152+ inputs.emplace_back(custom_op_func);
153+ inputs.emplace_back(infer_shape_func_holder);
154+ return ValueHolder::CreateDataOutput("InferShape", inputs, node->GetAllOutDataAnchorsSize());
155+}
156+ 
123/*157/*
124 * SymbolInferShape158 * SymbolInferShape
125 * / \159 * / \
@@ -244,10 +278,8 @@ std::vector<ValueHolderPtr> InferCustomOpShape(const ge::NodePtr &node,
244 }278 }
245 const auto op_desc = node->GetOpDesc();279 const auto op_desc = node->GetOpDesc();
246 GE_ASSERT_NOTNULL(op_desc);280 GE_ASSERT_NOTNULL(op_desc);
247- auto custom_op = ge::CustomOpFactory::CreateOrGetCustomOp(node->GetTypePtr());281+ if (FindShapeInferOpInCustomOpRegistry(node->GetTypePtr(), global_data) != nullptr) {
248- auto shape_infer_op = dynamic_cast<ge::ShapeInferOp *>(custom_op);282+ return BuildCustomOpInferShapeGraph(node, input_shapes, global_data);
249- if (shape_infer_op != nullptr) {
250- return BuildInferShapeGraph(node, input_shapes, global_data);
251 }283 }
252 const std::string infer_rule = ge::InferenceRule::GetInferenceRule(op_desc);284 const std::string infer_rule = ge::InferenceRule::GetInferenceRule(op_desc);
253 if (!infer_rule.empty()) {285 if (!infer_rule.empty()) {
@@ -13,6 +13,7 @@
13#include "exe_graph/lowering/value_holder.h"13#include "exe_graph/lowering/value_holder.h"
14#include "graph/node.h"14#include "graph/node.h"
15#include "graph/debug/ge_attr_define.h"15#include "graph/debug/ge_attr_define.h"
16+#include "graph/custom_op.h"
16#include "exe_graph/lowering/lowering_global_data.h"17#include "exe_graph/lowering/lowering_global_data.h"
17 18 
18namespace gert {19namespace gert {
@@ -26,6 +27,8 @@ std::vector<ValueHolderPtr> InferStorageShape(const ge::NodePtr &node, const std
26std::vector<ValueHolderPtr> InferCustomOpShape(const ge::NodePtr &node,27std::vector<ValueHolderPtr> InferCustomOpShape(const ge::NodePtr &node,
27 const std::vector<ValueHolderPtr> &input_shapes,28 const std::vector<ValueHolderPtr> &input_shapes,
28 LoweringGlobalData &global_data);29 LoweringGlobalData &global_data);
30+ge::ShapeInferOp *FindShapeInferOpInCustomOpRegistry(const ge::AscendString &op_type,
31+ const LoweringGlobalData &global_data);
29std::vector<ValueHolderPtr> InferUbGraphShape(const ge::ComputeGraphPtr &compute_graph,32std::vector<ValueHolderPtr> InferUbGraphShape(const ge::ComputeGraphPtr &compute_graph,
30 const std::vector<ValueHolderPtr> &input_shapes,33 const std::vector<ValueHolderPtr> &input_shapes,
31 LoweringGlobalData &global_data);34 LoweringGlobalData &global_data);
@@ -22,8 +22,6 @@
22#include "graph/utils/type_utils.h"22#include "graph/utils/type_utils.h"
23#include "exe_graph/runtime/gert_tensor_data.h"23#include "exe_graph/runtime/gert_tensor_data.h"
24#include "aicore/converter/autofuse_node_converter.h"24#include "aicore/converter/autofuse_node_converter.h"
25-#include "graph/custom_op_factory.h"
26-#include "graph/custom_op.h"
27 25 
28namespace gert {26namespace gert {
29namespace kernel {27namespace kernel {
@@ -100,20 +98,6 @@ ge::graphStatus InferShapeByRule(KernelContext *context) {
100 return ge::GRAPH_SUCCESS;98 return ge::GRAPH_SUCCESS;
101}99}
102 100 
103-ge::graphStatus InferCustomOpShape(InferShapeContext *context) {
104- auto extend_context = reinterpret_cast<ExtendedKernelContext *>(context);
105- GE_ASSERT_NOTNULL(extend_context);
106- auto shape_infer_op = dynamic_cast<ge::ShapeInferOp *>(
107- ge::CustomOpFactory::CreateOrGetCustomOp(extend_context->GetNodeType()));
108- if (shape_infer_op == nullptr) {
109- KLOGE("Failed to find custom ShapeInferOp for node %s(%s)", extend_context->GetNodeName(),
110- extend_context->GetNodeType());
111- return ge::GRAPH_FAILED;
112- }
113- const auto ret = shape_infer_op->InferShape(context);
114- return ret;
115-}
116- 
117ge::graphStatus LoadShapeRuleFromJson(KernelContext *context) {101ge::graphStatus LoadShapeRuleFromJson(KernelContext *context) {
118 const auto input_num = context->GetInputNum();102 const auto input_num = context->GetInputNum();
119 GE_ASSERT_EQ(input_num, 1U);103 GE_ASSERT_EQ(input_num, 1U);
@@ -242,12 +226,6 @@ ge::graphStatus FindInferShapeFunc(KernelContext *context) {
242 226 
243 auto op_funcs = space_registry->GetOpImpl(node_type);227 auto op_funcs = space_registry->GetOpImpl(node_type);
244 if ((op_funcs == nullptr) || (op_funcs->infer_shape == nullptr)) {228 if ((op_funcs == nullptr) || (op_funcs->infer_shape == nullptr)) {
245- auto custom_op = ge::CustomOpFactory::CreateOrGetCustomOp(node_type);
C
CChang-an-HW6月8日
已过期

已经进入SpaceRegistryV2的算子如果(op_funcs == nullptr) || (op_funcs->infer_shape == nullptr)成立显然应该是异常场景,不应该在fallback到CustomOpFactory

likedislike
246- auto shape_infer_op = dynamic_cast<ge::ShapeInferOp *>(custom_op);
247- if (shape_infer_op != nullptr) {
248- *infer_fun_ptr = InferCustomOpShape;
249- return ge::GRAPH_SUCCESS;
250- }
251 KLOGE("Failed to find infer shape kernel, node type %s", node_type);229 KLOGE("Failed to find infer shape kernel, node type %s", node_type);
252 return ge::GRAPH_FAILED;230 return ge::GRAPH_FAILED;
253 }231 }
@@ -16,6 +16,7 @@
16#include "graph/utils/type_utils.h"16#include "graph/utils/type_utils.h"
17#include "common/checker.h"17#include "common/checker.h"
18#include "graph/fast_graph/fast_node.h"18#include "graph/fast_graph/fast_node.h"
19+#include "graph/custom_op.h"
19 20 
20namespace gert {21namespace gert {
21namespace kernel {22namespace kernel {
@@ -68,6 +69,21 @@ inline ge::graphStatus TransformAllOutputsShape(const ComputeNodeInfo *compute_n
68 return ge::GRAPH_SUCCESS;69 return ge::GRAPH_SUCCESS;
69}70}
70 71 
72+inline ge::graphStatus InferCustomOpShapeFromInput(InferShapeContext *context) {
73+ auto kernel_context = reinterpret_cast<KernelContext *>(context);
74+ GE_ASSERT_NOTNULL(kernel_context);
75+ const auto input_num = kernel_context->GetInputNum();
76+ GE_ASSERT(input_num > 1U);
77+ auto custom_op = kernel_context->GetInputValue<ge::BaseCustomOp *>(input_num - 2U);
78+ GE_ASSERT_NOTNULL(custom_op);
79+ auto shape_infer_op = dynamic_cast<ge::ShapeInferOp *>(custom_op);
80+ if (shape_infer_op == nullptr) {
81+ GELOGE(ge::GRAPH_FAILED, "Custom op does not implement ShapeInferOp.");
82+ return ge::GRAPH_FAILED;
83+ }
84+ return shape_infer_op->InferShape(context);
85+}
86+ 
71inline ge::graphStatus BuildInferShapeOutputs(const ge::FastNode *node, KernelContext *context) {87inline ge::graphStatus BuildInferShapeOutputs(const ge::FastNode *node, KernelContext *context) {
72 (void) node;88 (void) node;
73 auto extend_context = reinterpret_cast<ExtendedKernelContext *>(context);89 auto extend_context = reinterpret_cast<ExtendedKernelContext *>(context);
@@ -38,6 +38,8 @@
38namespace gert {38namespace gert {
39namespace kernel {39namespace kernel {
40namespace {40namespace {
41+constexpr size_t kDavinciModelCreateV2OuterFmMemIndex = 8U;
42+ 
41uintptr_t GetRunMemory(const ge::DavinciModel &davinci_model, const MemoryBaseTypeOffset &type_offset_pair) {43uintptr_t GetRunMemory(const ge::DavinciModel &davinci_model, const MemoryBaseTypeOffset &type_offset_pair) {
42 const ge::RuntimeParam &param = davinci_model.GetRuntimeParam();44 const ge::RuntimeParam &param = davinci_model.GetRuntimeParam();
43 switch (type_offset_pair.base_type) {45 switch (type_offset_pair.base_type) {
@@ -70,6 +72,50 @@ ge::GeModelPtr GetGeModel(const KernelContext *const context) {
70 return ge_model_holder->shared_from_this();72 return ge_model_holder->shared_from_this();
71}73}
72 74 
75+ge::graphStatus InitDavinciModelCommon(KernelContext *context, const ge::GeModelPtr &ge_model,
76+ ge::DavinciModel &davinci_model) {
77+ GE_CHECK_NOTNULL(context);
78+ GE_CHECK_NOTNULL(ge_model);
79+ davinci_model.Assign(ge_model);
80+ SetDaviciModel(davinci_model, ge_model);
81+ 
82+ const size_t session_id_index = 1U;
83+ const auto session_id_ptr = context->GetInputPointer<uint64_t>(session_id_index);
84+ GE_CHECK_NOTNULL(session_id_ptr);
85+ (void)davinci_model.UpdateSessionId(*session_id_ptr);
86+ const size_t step_id_index = static_cast<size_t>(DavinciModelCreateInput::kStepId);
87+ davinci_model.SetGlobalStep(ge::PtrToValue(context->GetInputValue<void *>(step_id_index)), sizeof(int64_t));
88+ const uint32_t root_graph_id =
89+ context->GetInputValue<uint32_t>(static_cast<size_t>(DavinciModelCreateInput::kRootGraphId));
90+ davinci_model.SetRootGraphId(root_graph_id);
91+ GE_ASSERT_SUCCESS(davinci_model.InitRuntimeParams());
92+ 
93+ auto space_registries_ptr = context->GetInputValue<gert::OpImplSpaceRegistryV2Array *>(
94+ static_cast<size_t>(DavinciModelCreateInput::kSpaceRegistry));
95+ GE_CHECK_NOTNULL(space_registries_ptr);
96+ davinci_model.SetSpaceRegistries(std::make_shared<OpImplSpaceRegistryV2Array>(*space_registries_ptr));
97+ 
98+ const auto file_constant_weight_dir_holder =
99+ context->GetInputPointer<ge::char_t *>(static_cast<size_t>(DavinciModelCreateInput::kFileConstantWeightDir));
100+ GE_ASSERT_NOTNULL(file_constant_weight_dir_holder);
101+ const std::string file_constant_weight_dir(*file_constant_weight_dir_holder);
102+ GELOGD("Get file constant weight dir [%s] for davinci model.", file_constant_weight_dir.c_str());
103+ davinci_model.SetFileConstantWeightDir(file_constant_weight_dir);
104+ 
105+ const auto reusable_stream_allocator = context->GetInputValue<ge::ReusableStreamAllocator *>(
106+ static_cast<size_t>(DavinciModelCreateInput::kRtStreamReuse));
107+ GE_CHECK_NOTNULL(reusable_stream_allocator);
108+ davinci_model.SetReusableStreamAllocator(reusable_stream_allocator);
109+ return ge::SUCCESS;
110+}
111+ 
112+void SetInferDumpPropertiesIfNeed(ge::DavinciModel &davinci_model) {
113+ const auto dump_properties = ge::DumpManager::GetInstance().GetDumpProperties(ge::kInferSessionId);
114+ if (dump_properties.IsDumpOpen() || dump_properties.IsOpDebugOpen()) {
115+ davinci_model.SetDumpProperties(dump_properties);
116+ }
117+}
118+ 
73ge::Status UpdateModelGraphInputIndex(const ge::ComputeGraphPtr &graph, std::set<uint32_t> &input_index_set) {119ge::Status UpdateModelGraphInputIndex(const ge::ComputeGraphPtr &graph, std::set<uint32_t> &input_index_set) {
74 GE_ASSERT_NOTNULL(graph);120 GE_ASSERT_NOTNULL(graph);
75 for (const auto node : graph->GetDirectNodePtr()) {121 for (const auto node : graph->GetDirectNodePtr()) {
@@ -199,34 +245,10 @@ ge::graphStatus DavinciModelCreate(KernelContext *context) {
199 245 
200 auto davinci_model_ptr = ge::MakeUnique<ge::DavinciModel>(0, nullptr);246 auto davinci_model_ptr = ge::MakeUnique<ge::DavinciModel>(0, nullptr);
201 GE_CHECK_NOTNULL(davinci_model_ptr);247 GE_CHECK_NOTNULL(davinci_model_ptr);
202- davinci_model_ptr->Assign(ge_model);248+ GE_ASSERT_SUCCESS(InitDavinciModelCommon(context, ge_model, *davinci_model_ptr));
203- SetDaviciModel(*davinci_model_ptr.get(), ge_model);249+ const auto custom_op_registry =
204- const size_t session_id_index = 1U;250+ context->GetInputValue<ge::CustomOpRegistry *>(static_cast<size_t>(DavinciModelCreateInput::kCustomOpRegistry));
205- const auto session_id_ptr = context->GetInputPointer<uint64_t>(session_id_index);251+ davinci_model_ptr->SetCustomOpRegistryRaw(custom_op_registry);
206- GE_CHECK_NOTNULL(session_id_ptr);
207- davinci_model_ptr->UpdateSessionId(*session_id_ptr);
208- const size_t step_id_index = static_cast<size_t>(DavinciModelCreateInput::kStepId);
209- davinci_model_ptr->SetGlobalStep(ge::PtrToValue(context->GetInputValue<void *>(step_id_index)), sizeof(int64_t));
210- const uint32_t root_graph_id =
211- context->GetInputValue<uint32_t>(static_cast<size_t>(DavinciModelCreateInput::kRootGraphId));
212- davinci_model_ptr->SetRootGraphId(root_graph_id);
213- GE_ASSERT_SUCCESS(davinci_model_ptr->InitRuntimeParams());
214- auto space_registries_ptr = context->GetInputValue<gert::OpImplSpaceRegistryV2Array *>(
215- static_cast<size_t>(DavinciModelCreateInput::kSpaceRegistry));
216- GE_CHECK_NOTNULL(space_registries_ptr);
217- davinci_model_ptr->SetSpaceRegistries(std::make_shared<OpImplSpaceRegistryV2Array>(*space_registries_ptr));
218- 
219- const auto file_constant_weight_dir_holder =
220- context->GetInputPointer<ge::char_t *>(static_cast<size_t>(DavinciModelCreateInput::kFileConstantWeightDir));
221- GE_ASSERT_NOTNULL(file_constant_weight_dir_holder);
222- std::string file_constant_weight_dir(*file_constant_weight_dir_holder);
223- GELOGD("Get file constant weight dir [%s] for davinci model.", file_constant_weight_dir.c_str());
224- davinci_model_ptr->SetFileConstantWeightDir(file_constant_weight_dir);
225- 
226- const auto reusable_stream_allocator = context->GetInputValue<ge::ReusableStreamAllocator *>(
227- static_cast<size_t>(DavinciModelCreateInput::kRtStreamReuse));
228- GE_CHECK_NOTNULL(reusable_stream_allocator);
229- davinci_model_ptr->SetReusableStreamAllocator(reusable_stream_allocator);
230 252 
231 const auto &file_constant_names_and_mems =253 const auto &file_constant_names_and_mems =
232 context->GetInputPointer<ContinuousVector>(static_cast<size_t>(DavinciModelCreateInput::kFileConstantUserMem));254 context->GetInputPointer<ContinuousVector>(static_cast<size_t>(DavinciModelCreateInput::kFileConstantUserMem));
@@ -247,10 +269,7 @@ ge::graphStatus DavinciModelCreate(KernelContext *context) {
247 GELOGE(ge::GRAPH_FAILED, "davinci model init variable memory failed");269 GELOGE(ge::GRAPH_FAILED, "davinci model init variable memory failed");
248 return ret;270 return ret;
249 }271 }
250- const auto dump_properties = ge::DumpManager::GetInstance().GetDumpProperties(ge::kInferSessionId);272+ SetInferDumpPropertiesIfNeed(*davinci_model_ptr);
251- if (dump_properties.IsDumpOpen() || dump_properties.IsOpDebugOpen()) {
252- davinci_model_ptr->SetDumpProperties(dump_properties);
253- }
254 ge::ModelParam param{};273 ge::ModelParam param{};
255 GE_ASSERT_SUCCESS(InitParam(context, param));274 GE_ASSERT_SUCCESS(InitParam(context, param));
256 const auto frozen_indices_holder = context->GetInputPointer<ge::char_t *>(275 const auto frozen_indices_holder = context->GetInputPointer<ge::char_t *>(
@@ -460,46 +479,16 @@ ge::graphStatus DavinciModelCreateV2(KernelContext *context) {
460 479 
461 auto davinci_model_ptr = ge::MakeUnique<ge::DavinciModel>(0, nullptr);480 auto davinci_model_ptr = ge::MakeUnique<ge::DavinciModel>(0, nullptr);
462 GE_CHECK_NOTNULL(davinci_model_ptr);481 GE_CHECK_NOTNULL(davinci_model_ptr);
463- davinci_model_ptr->Assign(ge_model);482+ GE_ASSERT_SUCCESS(InitDavinciModelCommon(context, ge_model, *davinci_model_ptr));
464- SetDaviciModel(*davinci_model_ptr.get(), ge_model);
465- const size_t session_id_index = 1U;
466- const auto session_id_ptr = context->GetInputPointer<uint64_t>(session_id_index);
467- GE_CHECK_NOTNULL(session_id_ptr);
468- davinci_model_ptr->UpdateSessionId(*session_id_ptr);
469- const size_t step_id_index = static_cast<size_t>(DavinciModelCreateInput::kStepId);
470- davinci_model_ptr->SetGlobalStep(ge::PtrToValue(context->GetInputValue<void *>(step_id_index)), sizeof(int64_t));
471- const uint32_t root_graph_id =
472- context->GetInputValue<uint32_t>(static_cast<size_t>(DavinciModelCreateInput::kRootGraphId));
473- davinci_model_ptr->SetRootGraphId(root_graph_id);
474- GE_ASSERT_SUCCESS(davinci_model_ptr->InitRuntimeParams());
475- auto space_registries_ptr = context->GetInputValue<gert::OpImplSpaceRegistryV2Array *>(
476- static_cast<size_t>(DavinciModelCreateInput::kSpaceRegistry));
477- GE_CHECK_NOTNULL(space_registries_ptr);
478- davinci_model_ptr->SetSpaceRegistries(std::make_shared<OpImplSpaceRegistryV2Array>(*space_registries_ptr));
479- 
480- const auto file_constant_weight_dir_holder =
481- context->GetInputPointer<ge::char_t *>(static_cast<size_t>(DavinciModelCreateInput::kFileConstantWeightDir));
482- GE_ASSERT_NOTNULL(file_constant_weight_dir_holder);
483- std::string file_constant_weight_dir(*file_constant_weight_dir_holder);
484- GELOGD("Get file constant weight dir [%s] for davinci model.", file_constant_weight_dir.c_str());
485- davinci_model_ptr->SetFileConstantWeightDir(file_constant_weight_dir);
486- 
487- const auto reusable_stream_allocator = context->GetInputValue<ge::ReusableStreamAllocator *>(
488- static_cast<size_t>(DavinciModelCreateInput::kRtStreamReuse));
489- GE_CHECK_NOTNULL(reusable_stream_allocator);
490- davinci_model_ptr->SetReusableStreamAllocator(reusable_stream_allocator);
491 483 
492 GE_ASSERT_SUCCESS(davinci_model_ptr->InitVariableMem());484 GE_ASSERT_SUCCESS(davinci_model_ptr->InitVariableMem());
493- const auto dump_properties = ge::DumpManager::GetInstance().GetDumpProperties(ge::kInferSessionId);485+ SetInferDumpPropertiesIfNeed(*davinci_model_ptr);
494- if (dump_properties.IsDumpOpen() || dump_properties.IsOpDebugOpen()) {
495- davinci_model_ptr->SetDumpProperties(dump_properties);
496- }
497 const auto weight_tensor = context->GetInputPointer<GertTensorData>(2U);486 const auto weight_tensor = context->GetInputPointer<GertTensorData>(2U);
498 GE_CHECK_NOTNULL(weight_tensor);487 GE_CHECK_NOTNULL(weight_tensor);
499 ge::ModelParam param{};488 ge::ModelParam param{};
500 param.weight_base = ge::PtrToValue(weight_tensor->GetAddr());489 param.weight_base = ge::PtrToValue(weight_tensor->GetAddr());
501 param.weight_size = weight_tensor->GetSize();490 param.weight_size = weight_tensor->GetSize();
502- const auto outer_fm_mem = context->GetInputPointer<TensorData>(8U);491+ const auto outer_fm_mem = context->GetInputPointer<TensorData>(kDavinciModelCreateV2OuterFmMemIndex);
503 GE_ASSERT_NOTNULL(outer_fm_mem);492 GE_ASSERT_NOTNULL(outer_fm_mem);
504 GE_ASSERT_SUCCESS(davinci_model_ptr->Init(param, outer_fm_mem->GetAddr()));493 GE_ASSERT_SUCCESS(davinci_model_ptr->Init(param, outer_fm_mem->GetAddr()));
505 494 
@@ -69,6 +69,7 @@ enum class DavinciModelCreateInput {
69 kP2pFixedMemTensorFromInit,69 kP2pFixedMemTensorFromInit,
70 kFrozenInputIndicies,70 kFrozenInputIndicies,
71 kFileConstantUserMem,71 kFileConstantUserMem,
72+ kCustomOpRegistry,
72 kDavinciModelCreateInputEnd73 kDavinciModelCreateInputEnd
73};74};
74 75 
@@ -527,9 +527,7 @@ ge::graphStatus SetFixedFeatureMemory(const ge::GeRootModelPtr &root_model, Lowe
527 527 
528ge::ExecuteGraphPtr ModelConverter::ConvertGeModelToExecuteGraph(const ge::GeRootModelPtr &root_model,528ge::ExecuteGraphPtr ModelConverter::ConvertGeModelToExecuteGraph(const ge::GeRootModelPtr &root_model,
529 const Args &args) {529 const Args &args) {
530- if ((root_model == nullptr) || (root_model->GetRootGraph() == nullptr)) {530+ if ((root_model == nullptr) || (root_model->GetRootGraph() == nullptr)) { return nullptr; }
531- return nullptr;
532- }
533 531 
534 GE_ASSERT_SUCCESS(CreateModelDesc(root_model, args.stream_allocator, args.event_allocator, args.notify_allocator));532 GE_ASSERT_SUCCESS(CreateModelDesc(root_model, args.stream_allocator, args.event_allocator, args.notify_allocator));
535 533 
@@ -543,11 +541,7 @@ ge::ExecuteGraphPtr ModelConverter::ConvertGeModelToExecuteGraph(const ge::GeRoo
543 if (flatten_graph == nullptr) {541 if (flatten_graph == nullptr) {
544 GE_ASSERT_GRAPH_SUCCESS(ReadInCompileResults(root_graph, root_model, nodes_to_task_defs, graph_to_static_models));542 GE_ASSERT_GRAPH_SUCCESS(ReadInCompileResults(root_graph, root_model, nodes_to_task_defs, graph_to_static_models));
545 InitConstWeights(root_model, require_weight_size);543 InitConstWeights(root_model, require_weight_size);
546- if (GraphUnfolder::IsGraphNeedUnfold(root_graph)) {544+ flatten_graph = GraphUnfolder::IsGraphNeedUnfold(root_graph) ? FlattenComputeGraph(root_graph) : root_graph;
547- flatten_graph = FlattenComputeGraph(root_graph);
548- } else {
549- flatten_graph = root_graph;
550- }
551 GE_ASSERT_NOTNULL(flatten_graph);545 GE_ASSERT_NOTNULL(flatten_graph);
552 GE_ASSERT_GRAPH_SUCCESS(ge::RecoverIrDefinitions(flatten_graph), "Failed to recover ir definitions");546 GE_ASSERT_GRAPH_SUCCESS(ge::RecoverIrDefinitions(flatten_graph), "Failed to recover ir definitions");
553 root_model->SetFlattenGraph(flatten_graph);547 root_model->SetFlattenGraph(flatten_graph);
@@ -562,6 +556,9 @@ ge::ExecuteGraphPtr ModelConverter::ConvertGeModelToExecuteGraph(const ge::GeRoo
562 LoweringGlobalData global_data =556 LoweringGlobalData global_data =
563 BuildGlobalData(flatten_graph, std::move(nodes_to_task_defs), std::move(graph_to_static_models),557 BuildGlobalData(flatten_graph, std::move(nodes_to_task_defs), std::move(graph_to_static_models),
564 root_model->GetHostResourceCenterPtr().get());558 root_model->GetHostResourceCenterPtr().get());
559+ auto custom_op_registry = root_model->GetCustomOpRegistry();
560+ GE_ASSERT_NOTNULL(custom_op_registry, "Custom op registry of root model is nullptr.");
561+ global_data.SetCustomOpRegistry(custom_op_registry);
565 global_data.SetModelWeightSize(static_cast<size_t>(require_weight_size));562 global_data.SetModelWeightSize(static_cast<size_t>(require_weight_size));
566 auto registries = GetModelDescHolder().GetSpaceRegistries();563 auto registries = GetModelDescHolder().GetSpaceRegistries();
567 GE_ASSERT_NOTNULL(registries);564 GE_ASSERT_NOTNULL(registries);
@@ -572,9 +569,8 @@ ge::ExecuteGraphPtr ModelConverter::ConvertGeModelToExecuteGraph(const ge::GeRoo
572 if (args.file_constant_mems != nullptr) {569 if (args.file_constant_mems != nullptr) {
573 global_data.SetFileConstantMem(*args.file_constant_mems);570 global_data.SetFileConstantMem(*args.file_constant_mems);
574 }571 }
575- auto graph = GraphConverter()572+ auto graph = GraphConverter().SetModelDescHolder(&model_desc_holder_)
576- .SetModelDescHolder(&model_desc_holder_)573+ .ConvertComputeGraphToExecuteGraph(flatten_graph, args.option, global_data);
577- .ConvertComputeGraphToExecuteGraph(flatten_graph, args.option, global_data);
578 GE_ASSERT_NOTNULL(graph, "Failed lowering compute graph %s", flatten_graph->GetName().c_str());574 GE_ASSERT_NOTNULL(graph, "Failed lowering compute graph %s", flatten_graph->GetName().c_str());
579 ge::DumpGraph(graph.get(), "ExecuteGraphAfterSplit");575 ge::DumpGraph(graph.get(), "ExecuteGraphAfterSplit");
580 return graph;576 return graph;
@@ -200,9 +200,12 @@ bg::ValueHolderPtr FileConstantMemToContinuousVecHolder(LoweringGlobalData &glob
200 return bg::CreateContVecHolder(name_and_mems);200 return bg::CreateContVecHolder(name_and_mems);
201}201}
202 202 
203-std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGraphPtr &graph, ge::GeModel *ge_model,203+bg::ValueHolderPtr CreateCustomOpRegistryHolder(LoweringGlobalData &global_data) {
204- LoweringGlobalData &global_data) {204+ ge::CustomOpRegistry *custom_op_registry = global_data.GetCustomOpRegistry().get();
205- // construct DavinciModel Init weight info205+ return bg::ValueHolder::CreateConst(&custom_op_registry, sizeof(custom_op_registry));
206+}
207+ 
208+bg::ValueHolderPtr CreateAssignWeightMemoryHolder(ge::GeModel *ge_model, LoweringGlobalData &global_data) {
206 std::vector<int64_t> flatten_weight = GetFlattenOffsetInfo(ge_model);209 std::vector<int64_t> flatten_weight = GetFlattenOffsetInfo(ge_model);
207 GE_ASSERT_TRUE(flatten_weight.size() == kFlattenKeySize);210 GE_ASSERT_TRUE(flatten_weight.size() == kFlattenKeySize);
208 TensorData weight_tensor;211 TensorData weight_tensor;
@@ -215,7 +218,12 @@ std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGr
215 auto assign_mem_holder = bg::ValueHolder::CreateSingleDataOutput(218 auto assign_mem_holder = bg::ValueHolder::CreateSingleDataOutput(
216 kernel::kAssignWeightMemory,219 kernel::kAssignWeightMemory,
217 {weight_info_holder, bg::HolderOnInit(AssignDeviceMem::GetOrCreateMemAssigner(global_data)), stream_id_holder});220 {weight_info_holder, bg::HolderOnInit(AssignDeviceMem::GetOrCreateMemAssigner(global_data)), stream_id_holder});
221+ return assign_mem_holder;
222+}
218 223 
224+std::vector<bg::ValueHolderPtr> CreateDavinciModelCommonInputs(const ge::ComputeGraphPtr &graph,
225+ ge::GeModel *ge_model,
226+ LoweringGlobalData &global_data) {
219 auto model_holder = bg::ValueHolder::CreateConst(&ge_model, sizeof(uintptr_t));227 auto model_holder = bg::ValueHolder::CreateConst(&ge_model, sizeof(uintptr_t));
220 GE_ASSERT(IsValidHolder(model_holder));228 GE_ASSERT(IsValidHolder(model_holder));
221 // todo rt_session不作为init的输出,而是提供方法获取init图里的节点。这样子DavinciModelCreate可以在init图中229 // todo rt_session不作为init的输出,而是提供方法获取init图里的节点。这样子DavinciModelCreate可以在init图中
@@ -225,6 +233,35 @@ std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGr
225 GE_ASSERT_NOTNULL(root_graph);233 GE_ASSERT_NOTNULL(root_graph);
226 const uint32_t root_graph_id = root_graph->GetGraphID();234 const uint32_t root_graph_id = root_graph->GetGraphID();
227 const auto root_graph_id_holder = bg::ValueHolder::CreateConst(&root_graph_id, sizeof(uint32_t));235 const auto root_graph_id_holder = bg::ValueHolder::CreateConst(&root_graph_id, sizeof(uint32_t));
236+ return {model_holder, session_id, CreateAssignWeightMemoryHolder(ge_model, global_data), step_id,
237+ root_graph_id_holder, bg::HolderOnInit(bg::GetSpaceRegistries(global_data)),
238+ bg::HolderOnInit(bg::GetFileConstantWeightDir(global_data)),
239+ bg::HolderOnInit(bg::ReusableStreamAllocator(global_data))};
240+}
241+ 
242+std::vector<bg::ValueHolderPtr> CreateWorkspaceMemFromInit(LoweringGlobalData &global_data) {
243+ auto builder = [&global_data]() -> std::vector<bg::ValueHolderPtr> {
244+ auto init_outputs = bg::FrameSelector::OnInitRoot(
245+ [&global_data]() -> std::vector<bg::ValueHolderPtr> {
246+ int64_t size = global_data.GetStaticModelWsSize();
247+ const auto memory_size_holder = bg::ValueHolder::CreateConst(&size, sizeof(size));
248+ const auto memory_holder = bg::AllocMem(kOnDeviceHbm, memory_size_holder, global_data, bg::kMainStream);
249+ return {memory_holder};
250+ });
251+ return init_outputs;
252+ };
253+ auto init_outputs = global_data.GetOrCreateUniqueValueHolder("WorkspaceMemFromInit", builder);
254+ GE_ASSERT_TRUE(init_outputs.size() == 1U);
255+ return init_outputs;
256+}
257+ 
258+void AppendCustomOpRegistryInputs(std::vector<bg::ValueHolderPtr> &inputs, LoweringGlobalData &global_data) {
259+ inputs.emplace_back(CreateCustomOpRegistryHolder(global_data));
260+}
261+ 
262+std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGraphPtr &graph, ge::GeModel *ge_model,
263+ LoweringGlobalData &global_data) {
264+ auto davinci_model_inputs = CreateDavinciModelCommonInputs(graph, ge_model, global_data);
228 std::string is_addr_fixed_opt;265 std::string is_addr_fixed_opt;
229 (void)ge::GetContext().GetOption(kStaticModelAddrFixed, is_addr_fixed_opt);266 (void)ge::GetContext().GetOption(kStaticModelAddrFixed, is_addr_fixed_opt);
230 std::string frozen_input;267 std::string frozen_input;
@@ -234,16 +271,13 @@ std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGr
234 GE_ASSERT_SUCCESS(MallocFixedFeatureMemOnInitRootIfNeed(global_data, fixed_holder));271 GE_ASSERT_SUCCESS(MallocFixedFeatureMemOnInitRootIfNeed(global_data, fixed_holder));
235 const auto file_constant_mem_holder = FileConstantMemToContinuousVecHolder(global_data);272 const auto file_constant_mem_holder = FileConstantMemToContinuousVecHolder(global_data);
236 if (is_addr_fixed_opt.empty()) {273 if (is_addr_fixed_opt.empty()) {
237- return bg::ValueHolder::CreateDataOutput(274+ davinci_model_inputs.insert(davinci_model_inputs.end(),
238- "DavinciModelCreate",275+ {fixed_holder[kHbmFixedAddrIndex], fixed_holder[kHbmFixedSizeIndex],
239- {model_holder, session_id, assign_mem_holder, step_id, root_graph_id_holder,276+ bg::HolderOnInit(fixed_holder[kHbmFixedTensorDataIndex]), fixed_holder[kP2pFixedAddrIndex],
240- bg::HolderOnInit(bg::GetSpaceRegistries(global_data)),277+ fixed_holder[kP2pFixedSizeIndex], bg::HolderOnInit(fixed_holder[kP2pFixedTensorDataIndex]), frozen_holder,
241- bg::HolderOnInit(bg::GetFileConstantWeightDir(global_data)),278+ file_constant_mem_holder});
242- bg::HolderOnInit(bg::ReusableStreamAllocator(global_data)), fixed_holder[kHbmFixedAddrIndex],279+ AppendCustomOpRegistryInputs(davinci_model_inputs, global_data);
243- fixed_holder[kHbmFixedSizeIndex], bg::HolderOnInit(fixed_holder[kHbmFixedTensorDataIndex]),280+ return bg::ValueHolder::CreateDataOutput("DavinciModelCreate", davinci_model_inputs, 1U);
244- fixed_holder[kP2pFixedAddrIndex], fixed_holder[kP2pFixedSizeIndex],
245- bg::HolderOnInit(fixed_holder[kP2pFixedTensorDataIndex]), frozen_holder, file_constant_mem_holder},
246- 1U);
247 }281 }
248 282 
249 // 临时方案,解决HCCL算子二级地址拷贝性能问题,待HCCL 1230正式方案上库后删除283 // 临时方案,解决HCCL算子二级地址拷贝性能问题,待HCCL 1230正式方案上库后删除
@@ -257,25 +291,9 @@ std::vector<bg::ValueHolderPtr> CreateDavinciModelOnInitRoot(const ge::ComputeGr
257 *291 *
258 * 正式方案由HCCL模块适配上库。292 * 正式方案由HCCL模块适配上库。
259 */293 */
260- auto builder = [&global_data]() -> std::vector<bg::ValueHolderPtr> {294+ auto init_outputs = CreateWorkspaceMemFromInit(global_data);
261- auto init_outputs = bg::FrameSelector::OnInitRoot(295+ davinci_model_inputs.emplace_back(bg::HolderOnInit(init_outputs[0U]));
262- [&global_data]() -> std::vector<bg::ValueHolderPtr> {296+ return bg::ValueHolder::CreateDataOutput("DavinciModelCreateV2", davinci_model_inputs, 1U);
263- int64_t size = global_data.GetStaticModelWsSize();
264- const auto memory_size_holder = bg::ValueHolder::CreateConst(&size, sizeof(size));
265- const auto memory_holder = bg::AllocMem(kOnDeviceHbm, memory_size_holder, global_data, bg::kMainStream);
266- return {memory_holder};
267- });
268- return init_outputs;
269- };
270- auto init_outputs = global_data.GetOrCreateUniqueValueHolder("WorkspaceMemFromInit", builder);
271- GE_ASSERT_TRUE(init_outputs.size() == 1U);
272- return bg::ValueHolder::CreateDataOutput(
273- "DavinciModelCreateV2",
274- {model_holder, session_id, assign_mem_holder, step_id, root_graph_id_holder,
275- bg::HolderOnInit(bg::GetSpaceRegistries(global_data)),
276- bg::HolderOnInit(bg::GetFileConstantWeightDir(global_data)),
277- bg::HolderOnInit(bg::ReusableStreamAllocator(global_data)), bg::HolderOnInit(init_outputs[0U])},
278- 1U);
279}297}
280 298 
281bg::ValueHolderPtr CreateDavinciModel(const ge::ComputeGraphPtr &graph, ge::GeModel *ge_model,299bg::ValueHolderPtr CreateDavinciModel(const ge::ComputeGraphPtr &graph, ge::GeModel *ge_model,
@@ -16,7 +16,7 @@ GREEN='\033[0;32m'
16YELLOW='\033[1;33m'16YELLOW='\033[1;33m'
17NC='\033[0m'17NC='\033[0m'
18 18 
19-CANN_VERSION="9.0.0"19+CANN_VERSION="9.1.0"
20CHIP_TYPE="910b"20CHIP_TYPE="910b"
21INSTALL_OPS=false21INSTALL_OPS=false
22INSTALL_PATH="${INSTALL_PATH:-/usr/local/Ascend}"22INSTALL_PATH="${INSTALL_PATH:-/usr/local/Ascend}"
@@ -22,6 +22,7 @@
22 <file value="libgraph.so" file_type="shared"/>22 <file value="libgraph.so" file_type="shared"/>
23 <file value="libregister.so" file_type="shared"/>23 <file value="libregister.so" file_type="shared"/>
24 <file value="libregister.a" file_type="static"/>24 <file value="libregister.a" file_type="static"/>
25+ <file value="libcustom_op_registry_static.a" file_type="static"/>
25 <file value="libacl_mdl.so" file_type="shared"/>26 <file value="libacl_mdl.so" file_type="shared"/>
26 <file value="libacl_mdl_impl.so" file_type="shared"/>27 <file value="libacl_mdl_impl.so" file_type="shared"/>
27 <file value="libacl_mdl_impl_om2.so" file_type="shared"/>28 <file value="libacl_mdl_impl_om2.so" file_type="shared"/>
@@ -312,6 +312,11 @@ MockFunctionTest& MockFunctionTest::aclStubInstance()
312 312 
313void MockFunctionTest::ResetToDefaultMock() {313void MockFunctionTest::ResetToDefaultMock() {
314 // delegates the default actions of the RTS methods to aclStub314 // delegates the default actions of the RTS methods to aclStub
315+ ResetRtMocks();
316+ ResetDataBufferMocks();
317+}
318+ 
319+void MockFunctionTest::ResetRtMocks() {
315 ON_CALL(*this, aclrtMalloc)320 ON_CALL(*this, aclrtMalloc)
316 .WillByDefault([this](void **devPtr, size_t size, aclrtMemMallocPolicy policy) {321 .WillByDefault([this](void **devPtr, size_t size, aclrtMemMallocPolicy policy) {
317 return aclStub::aclrtMalloc(devPtr, size, policy);322 return aclStub::aclrtMalloc(devPtr, size, policy);
@@ -324,6 +329,21 @@ void MockFunctionTest::ResetToDefaultMock() {
324 .WillByDefault([this](void *devPtr) {329 .WillByDefault([this](void *devPtr) {
325 return aclStub::aclrtFree(devPtr);330 return aclStub::aclrtFree(devPtr);
326 });331 });
332+ ON_CALL(*this, aclrtFree)
333+ .WillByDefault([this](void *devPtr) {
334+ return aclStub::aclrtFree(devPtr);
335+ });
336+ ON_CALL(*this, aclrtMemcpy)
337+ .WillByDefault([this](void *dst, size_t destMax, const void *src, size_t count, aclrtMemcpyKind kind) {
338+ return aclStub::aclrtMemcpy(dst, destMax, src, count, kind);
339+ });
340+ ON_CALL(*this, aclrtCtxGetCurrentDefaultStream)
341+ .WillByDefault([this](aclrtStream *stream) {
342+ return aclStub::aclrtCtxGetCurrentDefaultStream(stream);
343+ });
344+}
345+ 
346+void MockFunctionTest::ResetDataBufferMocks() {
327 ON_CALL(*this, aclCreateDataBuffer)347 ON_CALL(*this, aclCreateDataBuffer)
328 .WillByDefault([this](void *data, size_t size) {348 .WillByDefault([this](void *data, size_t size) {
329 return aclStub::aclCreateDataBuffer(data, size);349 return aclStub::aclCreateDataBuffer(data, size);
@@ -344,22 +364,6 @@ void MockFunctionTest::ResetToDefaultMock() {
344 .WillByDefault([this](const aclDataBuffer *dataBuffer) {364 .WillByDefault([this](const aclDataBuffer *dataBuffer) {
345 return aclStub::aclGetDataBufferSize(dataBuffer);365 return aclStub::aclGetDataBufferSize(dataBuffer);
346 });366 });
347- ON_CALL(*this, aclrtMemcpy)
348- .WillByDefault([this](void *dst, size_t destMax, const void *src, size_t count, aclrtMemcpyKind kind) {
349- return aclStub::aclrtMemcpy(dst, destMax, src, count, kind);
350- });
351- ON_CALL(*this, aclrtCtxGetCurrentDefaultStream)
352- .WillByDefault([this](aclrtStream *stream) {
353- return aclStub::aclrtCtxGetCurrentDefaultStream(stream);
354- });
355- ON_CALL(*this, SetModelStreamPriority)
356- .WillByDefault([this](uint32_t model_id, uint32_t priority) {
357- return this->aclStub::SetModelStreamPriority(model_id, priority);
358- });
359- ON_CALL(*this, GetModelStreamPriority)
360- .WillByDefault([this](uint32_t model_id, uint32_t &priority) {
361- return this->aclStub::GetModelStreamPriority(model_id, priority);
362- });
363}367}
364 368 
365aclError aclrtCreateEventWithFlag(aclrtEvent *event, uint32_t flag)369aclError aclrtCreateEventWithFlag(aclrtEvent *event, uint32_t flag)
@@ -559,4 +559,8 @@ public:
559 559 
560 // mmpa560 // mmpa
561 MOCK_METHOD0(mmGetTid, INT32());561 MOCK_METHOD0(mmGetTid, INT32());
562+ 
563+private:
564+ void ResetRtMocks();
565+ void ResetDataBufferMocks();
562};566};
@@ -15,6 +15,7 @@
15#include "utils/tensor_utils.h"15#include "utils/tensor_utils.h"
16#include "common/debug/log.h"16#include "common/debug/log.h"
17#include "graph/debug/ge_attr_define.h"17#include "graph/debug/ge_attr_define.h"
18+#include "graph/custom_op_factory.h"
18#include "common/host_resource_center/host_resource_center.h"19#include "common/host_resource_center/host_resource_center.h"
19#include "common/env_path.h"20#include "common/env_path.h"
20#include "common/ge_common/scope_guard.h"21#include "common/ge_common/scope_guard.h"
@@ -294,6 +295,7 @@ ge::GeRootModelPtr GeModelBuilder::BuildGeRootModel() {
294 const auto root_graph = ge_model->GetGraph();295 const auto root_graph = ge_model->GetGraph();
295 if (root_graph != nullptr) {296 if (root_graph != nullptr) {
296 out_model->Initialize(root_graph);297 out_model->Initialize(root_graph);
298+ out_model->SetCustomOpRegistry(ge::CustomOpFactory::GetGlobalRegistryPtr());
297 out_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);299 out_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
298 }300 }
299 301 
@@ -160,6 +160,7 @@ target_link_libraries(graph_engine_test
160 atc_static160 atc_static
161 ge_running_env161 ge_running_env
162 ge_runtime_stub162 ge_runtime_stub
163+ custom_op_registry_static
163 -Wl,--no-whole-archive gert_op_impl164 -Wl,--no-whole-archive gert_op_impl
164 es_ge_test ge_graph_dsl st_stubs GTestShared::gtest GTestShared::gmock GTestShared::gmock_main165 es_ge_test ge_graph_dsl st_stubs GTestShared::gtest GTestShared::gmock GTestShared::gmock_main
165 -ldl166 -ldl
@@ -247,6 +248,7 @@ target_link_libraries(ge_common_atc
247 atc_static248 atc_static
248 ge_running_env249 ge_running_env
249 ge_runtime_stub250 ge_runtime_stub
251+ custom_op_registry_static
250 -Wl,--no-whole-archive gert_op_impl252 -Wl,--no-whole-archive gert_op_impl
251 es_ge_test ge_graph_dsl st_stubs GTestShared::gtest GTestShared::gmock GTestShared::gmock_main253 es_ge_test ge_graph_dsl st_stubs GTestShared::gtest GTestShared::gmock GTestShared::gmock_main
252 -ldl254 -ldl
@@ -381,7 +381,8 @@ TEST_F(TestCustomNodeKernel, custom_op_shape_infer_op_execute_test) {
381 GRAPH_SUCCESS);381 GRAPH_SUCCESS);
382 EXPECT_EQ(custom_shape_infer_count, 1U);382 EXPECT_EQ(custom_shape_infer_count, 1U);
383 EXPECT_EQ(custom_shape_infer_execute_count, 1U);383 EXPECT_EQ(custom_shape_infer_execute_count, 1U);
384- EXPECT_EQ(ess->GetExecuteCountByNodeTypeAndKernelType(op_type, "InferShape"), 1);384+ // 这里没有单独的 "InferShape" kernel 事件;ShapeInferOp::InferShape 是在
385+ // ExecuteCustomOpWithInferShape 内部直接被调用的,所以统计应看执行 kernel。
385 EXPECT_EQ(ess->GetExecuteCountByNodeTypeAndKernelType(op_type, "ExecuteCustomOpWithInferShape"), 1);386 EXPECT_EQ(ess->GetExecuteCountByNodeTypeAndKernelType(op_type, "ExecuteCustomOpWithInferShape"), 1);
386 EXPECT_EQ(model_executor->UnLoad(), GRAPH_SUCCESS);387 EXPECT_EQ(model_executor->UnLoad(), GRAPH_SUCCESS);
387 rtStreamDestroy(stream);388 rtStreamDestroy(stream);
@@ -34,6 +34,7 @@
34#include "graph/args_format_desc.h"34#include "graph/args_format_desc.h"
35#include "common/opskernel/ops_kernel_info_types.h"35#include "common/opskernel/ops_kernel_info_types.h"
36#include "common/tbe_handle_store/tbe_handle_store.h"36#include "common/tbe_handle_store/tbe_handle_store.h"
37+#include "graph/custom_op_factory.h"
37 38 
38using namespace std;39using namespace std;
39using namespace testing;40using namespace testing;
@@ -163,6 +164,7 @@ TEST_F(StestScatteredCollection, mixl2_graph_load_and_success) {
163 {164 {
164 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();165 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
165 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);166 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
167+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
166 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);168 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
167 169 
168 GraphId graph_id = 1001;170 GraphId graph_id = 1001;
@@ -305,6 +307,7 @@ TEST_F(StestScatteredCollection, mixl2_with_args_format_graph_load_and_success)
305 {307 {
306 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();308 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
307 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);309 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
310+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
308 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);311 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
309 312 
310 GraphId graph_id = 1001;313 GraphId graph_id = 1001;
@@ -478,6 +481,7 @@ TEST_F(StestScatteredCollection, mixl2_mem_check_success) {
478 {481 {
479 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();482 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
480 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);483 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
484+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
481 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);485 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
482 486 
483 GraphId graph_id = 1001;487 GraphId graph_id = 1001;
@@ -635,6 +639,7 @@ TEST_F(StestScatteredCollection, ifa_aicore_with_args_format_graph_load_and_succ
635 {639 {
636 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();640 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
637 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);641 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
642+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
638 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);643 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
639 644 
640 GraphId graph_id = 1001;645 GraphId graph_id = 1001;
@@ -805,6 +810,7 @@ TEST_F(StestScatteredCollection, ifa_aicore_with_tiling_sink_graph_load_and_succ
805 {810 {
806 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();811 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
807 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);812 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
813+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
808 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);814 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
809 815 
810 GraphId graph_id = 1001;816 GraphId graph_id = 1001;
@@ -981,6 +987,7 @@ TEST_F(StestScatteredCollection, mc2kernel_runtime_tiling_success) {
981 {987 {
982 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();988 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
983 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);989 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
990+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
984 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);991 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
985 992 
986 GraphId graph_id = 1001;993 GraphId graph_id = 1001;
@@ -1123,6 +1130,7 @@ TEST_F(StestScatteredCollection, mc2kernel_graph_load_and_success) {
1123 {1130 {
1124 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1131 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1125 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);1132 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
1133+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1126 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1134 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1127 1135 
1128 GraphId graph_id = 1001;1136 GraphId graph_id = 1001;
@@ -150,7 +150,8 @@ TEST_F(AutofuseOfflineSt, CheckSaveAutofuseSo) {
150 so_patition.size = so_payload.size();150 so_patition.size = so_payload.size();
151 cur_ctx.partition_datas_.push_back(so_patition);151 cur_ctx.partition_datas_.push_back(so_patition);
152 load_helper.model_contexts_.push_back(cur_ctx);152 load_helper.model_contexts_.push_back(cur_ctx);
153- EXPECT_EQ(model_helper.LoadOpSoBin(load_helper, ge_root_model), SUCCESS);153+ std::vector<CustomOpSoHandlePtr> loaded_handles;
154+ EXPECT_EQ(model_helper.LoadOpSoBin(load_helper, ge_root_model, loaded_handles), SUCCESS);
154}155}
155 156 
156// ge-dev失败,ge仓正常,两个仓合并时,再打开。157// ge-dev失败,ge仓正常,两个仓合并时,再打开。
@@ -18,6 +18,7 @@
18#include "framework/common/helper/model_helper.h"18#include "framework/common/helper/model_helper.h"
19#include "graph_metadef/depends/checker/tensor_check_utils.h"19#include "graph_metadef/depends/checker/tensor_check_utils.h"
20#include "mmpa/mmpa_api.h"20#include "mmpa/mmpa_api.h"
21+#include "graph/custom_op_factory.h"
21 22 
22using namespace std;23using namespace std;
23using namespace testing;24using namespace testing;
@@ -140,6 +141,7 @@ void BuildGraphModel(const ComputeGraphPtr &graph, uint32_t mem_offset, GeModelP
140Status OnlineInferDynamic(ComputeGraphPtr &graph, const GeModelPtr &ge_model) {141Status OnlineInferDynamic(ComputeGraphPtr &graph, const GeModelPtr &ge_model) {
141 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();142 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
142 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);143 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
144+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
143 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);145 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
144 GraphId graph_id = 1001;146 GraphId graph_id = 1001;
145 GraphNodePtr graph_node = MakeShared<GraphNode>(graph_id);147 GraphNodePtr graph_node = MakeShared<GraphNode>(graph_id);
@@ -33,6 +33,7 @@
33#include "graph/manager/mem_manager.h"33#include "graph/manager/mem_manager.h"
34#include "common/profiling/profiling_manager.h"34#include "common/profiling/profiling_manager.h"
35#include "graph/load/model_manager/model_utils.h"35#include "graph/load/model_manager/model_utils.h"
36+#include "graph/custom_op_factory.h"
36#include "common/dump/dump_manager.h"37#include "common/dump/dump_manager.h"
37#include "common/dump/dump_utils.h"38#include "common/dump/dump_utils.h"
38#include "graph/load/model_manager/model_manager.h"39#include "graph/load/model_manager/model_manager.h"
@@ -331,6 +332,7 @@ Status BuildGraphNode(GraphId graph_id, GraphNodePtr &graph_node, GeRootModelPtr
331 332 
332 ge_root_model = MakeShared<GeRootModel>();333 ge_root_model = MakeShared<GeRootModel>();
333 ge_root_model->Initialize(graph);334 ge_root_model->Initialize(graph);
335+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
334 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);336 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
335 337 
336 graph_node = MakeShared<GraphNode>(graph_id);338 graph_node = MakeShared<GraphNode>(graph_id);
@@ -523,6 +525,7 @@ TEST_F(DavinciModelTest, hccl_dump) {
523 // Test LoadModelOnline: RunAsyncListener525 // Test LoadModelOnline: RunAsyncListener
524 const auto ge_root_model = MakeShared<GeRootModel>();526 const auto ge_root_model = MakeShared<GeRootModel>();
525 ge_root_model->Initialize(graph);527 ge_root_model->Initialize(graph);
528+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
526 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());529 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
527 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);530 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
528 graph_node->SetGeRootModel(ge_root_model);531 graph_node->SetGeRootModel(ge_root_model);
@@ -605,6 +608,7 @@ TEST_F(DavinciModelTest, hccl_dump_on_watcher_model) {
605 // Test LoadModelOnline: RunAsyncListener608 // Test LoadModelOnline: RunAsyncListener
606 const auto ge_root_model = MakeShared<GeRootModel>();609 const auto ge_root_model = MakeShared<GeRootModel>();
607 ge_root_model->Initialize(graph);610 ge_root_model->Initialize(graph);
611+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
608 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());612 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
609 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);613 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
610 graph_node->SetGeRootModel(ge_root_model);614 graph_node->SetGeRootModel(ge_root_model);
@@ -683,6 +687,7 @@ TEST_F(DavinciModelTest, sdma_dump) {
683 // Test LoadModelOnline: RunAsyncListener687 // Test LoadModelOnline: RunAsyncListener
684 const auto ge_root_model = MakeShared<GeRootModel>();688 const auto ge_root_model = MakeShared<GeRootModel>();
685 ge_root_model->Initialize(graph);689 ge_root_model->Initialize(graph);
690+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
686 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());691 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
687 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);692 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
688 graph_node->SetGeRootModel(ge_root_model);693 graph_node->SetGeRootModel(ge_root_model);
@@ -758,6 +763,7 @@ TEST_F(DavinciModelTest, sample_davinci_model_static_memory_no_tiling) {
758 // Test LoadModelOnline: RunAsyncListener763 // Test LoadModelOnline: RunAsyncListener
759 const auto ge_root_model = MakeShared<GeRootModel>();764 const auto ge_root_model = MakeShared<GeRootModel>();
760 ge_root_model->Initialize(graph);765 ge_root_model->Initialize(graph);
766+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
761 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());767 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
762 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);768 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
763 graph_node->SetGeRootModel(ge_root_model);769 graph_node->SetGeRootModel(ge_root_model);
@@ -903,6 +909,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_file_constant) {
903 auto runtime_stub = MockForKernelLaunchExFailed();909 auto runtime_stub = MockForKernelLaunchExFailed();
904 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();910 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
905 ge_root_model->Initialize(graph);911 ge_root_model->Initialize(graph);
912+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
906 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);913 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
907 914 
908 GraphId graph_id = 1001;915 GraphId graph_id = 1001;
@@ -968,8 +975,10 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_const_placeholder) {
968 // Test LoadModelOnline975 // Test LoadModelOnline
969 auto runtime_stub = MockForKernelLaunchExFailed();976 auto runtime_stub = MockForKernelLaunchExFailed();
970 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();977 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
971- ge_root_model->Initialize(graph);978+ ge_root_model->Initialize(graph);
972- ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);979+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
980+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
981+ ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
973 982 
974 GraphId graph_id = 1001;983 GraphId graph_id = 1001;
975 GraphNodePtr graph_node = MakeShared<GraphNode>(graph_id);984 GraphNodePtr graph_node = MakeShared<GraphNode>(graph_id);
@@ -1000,6 +1009,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_file_constant_failed) {
1000 auto runtime_stub = MockForKernelLaunchExFailed();1009 auto runtime_stub = MockForKernelLaunchExFailed();
1001 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1010 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1002 ge_root_model->Initialize(graph);1011 ge_root_model->Initialize(graph);
1012+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1003 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1013 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1004 1014 
1005 GraphId graph_id = 1001;1015 GraphId graph_id = 1001;
@@ -1029,6 +1039,7 @@ TEST_F(DavinciModelTest, command_profiling_get_hybrid_model) {
1029 ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test");1039 ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test");
1030 GeRootModelPtr ge_root_model = make_shared<GeRootModel>();1040 GeRootModelPtr ge_root_model = make_shared<GeRootModel>();
1031 ge_root_model->Initialize(graph);1041 ge_root_model->Initialize(graph);
1042+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1032 auto hybrid_model_ptr = ge::hybrid::HybridDavinciModel::Create(ge_root_model);1043 auto hybrid_model_ptr = ge::hybrid::HybridDavinciModel::Create(ge_root_model);
1033 auto shared_model = std::shared_ptr<hybrid::HybridDavinciModel>(hybrid_model_ptr.release());1044 auto shared_model = std::shared_ptr<hybrid::HybridDavinciModel>(hybrid_model_ptr.release());
1034 shared_model->SetDeviceId(0);1045 shared_model->SetDeviceId(0);
@@ -1066,6 +1077,7 @@ TEST_F(DavinciModelTest, unknown_shape_execute_with_file_constant_host) {
1066 // Test LoadModelOnline1077 // Test LoadModelOnline
1067 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1078 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1068 ge_root_model->Initialize(graph);1079 ge_root_model->Initialize(graph);
1080+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1069 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1081 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1070 1082 
1071 GraphId graph_id = 1001;1083 GraphId graph_id = 1001;
@@ -1113,6 +1125,7 @@ TEST_F(DavinciModelTest, unknown_shape_execute_with_file_constant) {
1113 // Test LoadModelOnline1125 // Test LoadModelOnline
1114 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1126 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1115 ge_root_model->Initialize(graph);1127 ge_root_model->Initialize(graph);
1128+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1116 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1129 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1117 1130 
1118 GraphId graph_id = 1001;1131 GraphId graph_id = 1001;
@@ -1211,6 +1224,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_no_tiling_with_sub_mem) {
1211 // Test LoadModelOnline1224 // Test LoadModelOnline
1212 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1225 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1213 ge_root_model->Initialize(graph);1226 ge_root_model->Initialize(graph);
1227+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1214 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1228 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1215 1229 
1216 GraphId graph_id = 1001;1230 GraphId graph_id = 1001;
@@ -1603,6 +1617,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_dumpok) {
1603 {1617 {
1604 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1618 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1605 ge_root_model->Initialize(graph);1619 ge_root_model->Initialize(graph);
1620+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1606 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1621 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1607 1622 
1608 GraphId graph_id = 1001;1623 GraphId graph_id = 1001;
@@ -1720,6 +1735,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_dumpok_with_op_range) {
1720 {1735 {
1721 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1736 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1722 ge_root_model->Initialize(graph);1737 ge_root_model->Initialize(graph);
1738+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1723 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1739 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1724 1740 
1725 GraphId graph_id = 1001;1741 GraphId graph_id = 1001;
@@ -1816,6 +1832,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_exception_dumpok) {
1816 {1832 {
1817 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1833 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1818 ge_root_model->Initialize(graph);1834 ge_root_model->Initialize(graph);
1835+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1819 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1836 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1820 1837 
1821 GraphId graph_id = 1001;1838 GraphId graph_id = 1001;
@@ -2094,6 +2111,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_static_shape_reuse_binary) {
2094 // Test LoadModelOnline2111 // Test LoadModelOnline
2095 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2112 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2096 ge_root_model->Initialize(graph);2113 ge_root_model->Initialize(graph);
2114+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2097 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2115 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2098 2116 
2099 GraphId graph_id = 1001;2117 GraphId graph_id = 1001;
@@ -2165,6 +2183,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_static_shape_ifa_memcheck) {
2165 // Test LoadModelOnline2183 // Test LoadModelOnline
2166 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2184 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2167 ge_root_model->Initialize(graph);2185 ge_root_model->Initialize(graph);
2186+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2168 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2187 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2169 2188 
2170 GraphId graph_id = 1001;2189 GraphId graph_id = 1001;
@@ -2230,6 +2249,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_static_shape_ifa_memcheck_args_li
2230 // Test LoadModelOnline2249 // Test LoadModelOnline
2231 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2250 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2232 ge_root_model->Initialize(graph);2251 ge_root_model->Initialize(graph);
2252+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2233 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2253 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2234 2254 
2235 GraphId graph_id = 1001;2255 GraphId graph_id = 1001;
@@ -2301,6 +2321,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_static_shape_batch_memcheck) {
2301 // Test LoadModelOnline2321 // Test LoadModelOnline
2302 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2322 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2303 ge_root_model->Initialize(graph);2323 ge_root_model->Initialize(graph);
2324+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2304 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2325 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2305 2326 
2306 GraphId graph_id = 1001;2327 GraphId graph_id = 1001;
@@ -2367,6 +2388,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_static_shape_batch_memcheck_no_ar
2367 // Test LoadModelOnline2388 // Test LoadModelOnline
2368 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2389 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2369 ge_root_model->Initialize(graph);2390 ge_root_model->Initialize(graph);
2391+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2370 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2392 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2371 2393 
2372 GraphId graph_id = 1001;2394 GraphId graph_id = 1001;
@@ -2444,6 +2466,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_attached_vector_core) {
2444 // Test LoadModelOnline2466 // Test LoadModelOnline
2445 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2467 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2446 ge_root_model->Initialize(graph);2468 ge_root_model->Initialize(graph);
2469+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2447 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2470 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2448 2471 
2449 GraphId graph_id = 1001;2472 GraphId graph_id = 1001;
@@ -2540,6 +2563,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_atomic_clean_task) {
2540 // Test LoadModelOnline2563 // Test LoadModelOnline
2541 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2564 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2542 ge_root_model->Initialize(graph);2565 ge_root_model->Initialize(graph);
2566+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2543 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2567 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2544 2568 
2545 GraphId graph_id = 1001;2569 GraphId graph_id = 1001;
@@ -2623,6 +2647,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_aicpu_deploy_host) {
2623 // Test LoadModelOnline2647 // Test LoadModelOnline
2624 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2648 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2625 ge_root_model->Initialize(graph);2649 ge_root_model->Initialize(graph);
2650+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2626 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2651 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2627 2652 
2628 GraphId graph_id = 1001;2653 GraphId graph_id = 1001;
@@ -2675,6 +2700,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_with_aicpu_queue) {
2675 // Test LoadModelOnline2700 // Test LoadModelOnline
2676 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2701 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2677 ge_root_model->Initialize(graph);2702 ge_root_model->Initialize(graph);
2703+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2678 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2704 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2679 2705 
2680 GraphId graph_id = 1001;2706 GraphId graph_id = 1001;
@@ -2704,6 +2730,7 @@ TEST_F(DavinciModelTest, sample_davinci_model_execute_reuse_zero_copy_memory) {
2704 2730 
2705 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2731 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2706 ge_root_model->Initialize(graph);2732 ge_root_model->Initialize(graph);
2733+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2707 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2734 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2708 2735 
2709 GraphId graph_id = 1001;2736 GraphId graph_id = 1001;
@@ -2752,6 +2779,7 @@ TEST_F(DavinciModelTest, sample_davinci_model_execute_cmo_offset_invalid) {
2752 2779 
2753 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();2780 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
2754 ge_root_model->Initialize(graph);2781 ge_root_model->Initialize(graph);
2782+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2755 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2783 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2756 2784 
2757 GraphId graph_id = 1001;2785 GraphId graph_id = 1001;
@@ -3069,6 +3097,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_no_tiling_without_q) {
3069 {3097 {
3070 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();3098 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
3071 ge_root_model->Initialize(graph);3099 ge_root_model->Initialize(graph);
3100+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3072 GeExecutor ge_executor;3101 GeExecutor ge_executor;
3073 uint32_t model_id = 0;3102 uint32_t model_id = 0;
3074 EXPECT_NE(ge_executor.LoadModelWithoutQ(model_id, ge_root_model), SUCCESS);3103 EXPECT_NE(ge_executor.LoadModelWithoutQ(model_id, ge_root_model), SUCCESS);
@@ -3078,6 +3107,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_no_tiling_without_q) {
3078 // Test LoadModelOnline3107 // Test LoadModelOnline
3079 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();3108 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
3080 ge_root_model->Initialize(graph);3109 ge_root_model->Initialize(graph);
3110+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3081 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);3111 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
3082 3112 
3083 GraphId graph_id = 1001;3113 GraphId graph_id = 1001;
@@ -3121,6 +3151,7 @@ TEST_F(DavinciModelTest, sdma_dump_with_qos) {
3121 const auto ge_root_model = MakeShared<GeRootModel>();3151 const auto ge_root_model = MakeShared<GeRootModel>();
3122 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());3152 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
3123 ge_root_model->Initialize(graph);3153 ge_root_model->Initialize(graph);
3154+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3124 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);3155 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
3125 graph_node->SetGeRootModel(ge_root_model);3156 graph_node->SetGeRootModel(ge_root_model);
3126 graph_node->IncreaseLoadCount();3157 graph_node->IncreaseLoadCount();
@@ -3247,6 +3278,7 @@ TEST_F(DavinciModelTest, davinci_model_with_non_zero_cpy_inpouts) {
3247 // Test LoadModelOnline3278 // Test LoadModelOnline
3248 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();3279 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
3249 ge_root_model->Initialize(graph);3280 ge_root_model->Initialize(graph);
3281+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3250 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);3282 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
3251 3283 
3252 GraphId graph_id = 1001;3284 GraphId graph_id = 1001;
@@ -3500,6 +3532,7 @@ TEST_F(DavinciModelTest, davinci_model_error_tracking_test) {
3500 // Test LoadModelOnline3532 // Test LoadModelOnline
3501 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();3533 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
3502 ge_root_model->Initialize(graph);3534 ge_root_model->Initialize(graph);
3535+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3503 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);3536 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
3504 3537 
3505 GraphId graph_id = 1001;3538 GraphId graph_id = 1001;
@@ -4048,6 +4081,7 @@ TEST_F(DavinciModelTest, davinci_model_load_check_and_release_model_stream_resou
4048 4081 
4049 auto ge_root_model = MakeShared<GeRootModel>();4082 auto ge_root_model = MakeShared<GeRootModel>();
4050 ge_root_model->Initialize(graph);4083 ge_root_model->Initialize(graph);
4084+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4051 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model_1);4085 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model_1);
4052 4086 
4053 graph_node_1 = MakeShared<GraphNode>(graph_id_1);4087 graph_node_1 = MakeShared<GraphNode>(graph_id_1);
@@ -4198,6 +4232,7 @@ TEST_F(DavinciModelTest, davinci_model_execute_hcom_continuous_input) {
4198 {4232 {
4199 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();4233 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
4200 ge_root_model->Initialize(graph);4234 ge_root_model->Initialize(graph);
4235+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4201 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);4236 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
4202 4237 
4203 GraphId graph_id = 1001;4238 GraphId graph_id = 1001;
@@ -4296,6 +4331,7 @@ TEST_F(DavinciModelTest, DavinciModelExecute_LiteException_Ok) {
4296 // Test LoadModelOnline4331 // Test LoadModelOnline
4297 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();4332 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
4298 ge_root_model->Initialize(graph);4333 ge_root_model->Initialize(graph);
4334+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4299 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);4335 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
4300 4336 
4301 GraphId graph_id = 1001;4337 GraphId graph_id = 1001;
@@ -4372,6 +4408,7 @@ TEST_F(DavinciModelTest, sample_davinci_model_end_sequence) {
4372 // Test LoadModelOnline: RunAsyncListener4408 // Test LoadModelOnline: RunAsyncListener
4373 const auto ge_root_model = MakeShared<GeRootModel>();4409 const auto ge_root_model = MakeShared<GeRootModel>();
4374 ge_root_model->Initialize(graph);4410 ge_root_model->Initialize(graph);
4411+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4375 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());4412 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
4376 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);4413 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
4377 graph_node->SetGeRootModel(ge_root_model);4414 graph_node->SetGeRootModel(ge_root_model);
@@ -4736,6 +4773,7 @@ TEST_F(DavinciModelTest, super_kernel_graph_load_and_success) {
4736 {4773 {
4737 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();4774 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
4738 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);4775 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
4776+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4739 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);4777 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
4740 4778 
4741 GraphId graph_id = 1001;4779 GraphId graph_id = 1001;
@@ -4908,6 +4946,7 @@ TEST_F(DavinciModelTest, ifa_aicore_with_tiling_sink_graph_load_and_success) {
4908 {4946 {
4909 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();4947 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
4910 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);4948 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
4949+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
4911 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);4950 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
4912 4951 
4913 GraphId graph_id = 1001;4952 GraphId graph_id = 1001;
@@ -5092,6 +5131,7 @@ TEST_F(DavinciModelTest, ifa_aicore_with_tiling_sink_graph_load_and_launch_cust_
5092 {5131 {
5093 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5132 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5094 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5133 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5134+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5095 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5135 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5096 5136 
5097 GraphId graph_id = 1001;5137 GraphId graph_id = 1001;
@@ -5281,6 +5321,7 @@ TEST_F(DavinciModelTest, ifa_aicore_with_tiling_sink_graph_load_and_launch_cust_
5281 {5321 {
5282 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5322 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5283 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5323 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5324+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5284 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5325 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5285 5326 
5286 GraphId graph_id = 1001;5327 GraphId graph_id = 1001;
@@ -5460,6 +5501,7 @@ TEST_F(DavinciModelTest, ifa_aicore_with_tiling_sink_graph_load_and_success_with
5460 {5501 {
5461 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5502 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5462 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5503 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5504+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5463 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5505 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5464 5506 
5465 GraphId graph_id = 1001;5507 GraphId graph_id = 1001;
@@ -5500,6 +5542,7 @@ TEST_F(DavinciModelTest, sample_davinci_model_execute_fail) {
5500 // Test LoadModelOnline: RunAsyncListener5542 // Test LoadModelOnline: RunAsyncListener
5501 const auto ge_root_model = MakeShared<GeRootModel>();5543 const auto ge_root_model = MakeShared<GeRootModel>();
5502 ge_root_model->Initialize(graph);5544 ge_root_model->Initialize(graph);
5545+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5503 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());5546 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
5504 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);5547 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
5505 graph_node->SetGeRootModel(ge_root_model);5548 graph_node->SetGeRootModel(ge_root_model);
@@ -5561,6 +5604,7 @@ TEST_F(DavinciModelTest, init_space_registry_with_upgraded_so) {
5561 BuildAddGraph(graph, "file_constant_1", false);5604 BuildAddGraph(graph, "file_constant_1", false);
5562 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5605 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5563 ge_root_model->Initialize(graph);5606 ge_root_model->Initialize(graph);
5607+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5564 5608 
5565 std::vector<OpSoBinPtr> kernels;5609 std::vector<OpSoBinPtr> kernels;
5566 std::string so_name("libopsproto_rt.so");5610 std::string so_name("libopsproto_rt.so");
@@ -5628,6 +5672,7 @@ TEST_F(DavinciModelTest, TilingSink_From_OppPackage_Success) {
5628 {5672 {
5629 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5673 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5630 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5674 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5675+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5631 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5676 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5632 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);5677 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);
5633 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);5678 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);
@@ -5673,6 +5718,7 @@ TEST_F(DavinciModelTest, TilingSink_From_Model_Success) {
5673 {5718 {
5674 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5719 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5675 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5720 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5721+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5676 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5722 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5677 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);5723 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);
5678 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);5724 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);
@@ -5724,6 +5770,7 @@ TEST_F(DavinciModelTest, TilingSink_From_Model_Failed) {
5724 {5770 {
5725 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5771 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5726 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5772 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5773+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5727 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5774 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5728 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);5775 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);
5729 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);5776 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);
@@ -5776,6 +5823,7 @@ TEST_F(DavinciModelTest, FileConstant_Success_UserSetDeviceMem) {
5776 {5823 {
5777 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();5824 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
5778 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);5825 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
5826+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
5779 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);5827 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
5780 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);5828 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);
5781 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);5829 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x4000);
@@ -6094,6 +6142,7 @@ TEST_F(DavinciModelTest, mc2_with_fusion_task_graph_load_and_success) {
6094 {6142 {
6095 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();6143 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
6096 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);6144 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
6145+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
6097 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);6146 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
6098 6147 
6099 GraphId graph_id = 1001;6148 GraphId graph_id = 1001;
@@ -6498,6 +6547,7 @@ TEST_F(DavinciModelTest, Adump_Enable_Success) {
6498 // 加载模型并执行6547 // 加载模型并执行
6499 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();6548 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
6500 ge_root_model->Initialize(graph);6549 ge_root_model->Initialize(graph);
6550+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
6501 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);6551 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
6502 6552 
6503 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());6553 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());
@@ -6636,6 +6686,7 @@ TEST_F(DavinciModelTest, Adump_OverflowNotSupported_NotCalled) {
6636 6686 
6637 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();6687 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
6638 ge_root_model->Initialize(graph);6688 ge_root_model->Initialize(graph);
6689+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
6639 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);6690 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
6640 6691 
6641 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());6692 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());
@@ -6683,6 +6734,7 @@ TEST_F(DavinciModelTest, Adump_WatcherModelEnabled_NotCalled) {
6683 6734 
6684 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();6735 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
6685 ge_root_model->Initialize(graph);6736 ge_root_model->Initialize(graph);
6737+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
6686 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);6738 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
6687 6739 
6688 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());6740 GraphNodePtr graph_node = MakeShared<GraphNode>(graph->GetGraphID());
@@ -7176,6 +7228,7 @@ TEST_F(DavinciModelTest, DavinciModelExecute_SubgraphDump_Blacklist_RootGraph) {
7176 // ========== 创建 GeRootModel 并关联 ==========7228 // ========== 创建 GeRootModel 并关联 ==========
7177 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();7229 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
7178 ge_root_model->Initialize(root_graph);7230 ge_root_model->Initialize(root_graph);
7231+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
7179 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), root_ge_model);7232 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), root_ge_model);
7180 ge_root_model->SetSubgraphInstanceNameToModel(subgraph->GetName(), ge_model);7233 ge_root_model->SetSubgraphInstanceNameToModel(subgraph->GetName(), ge_model);
7181 7234 
@@ -19,6 +19,7 @@
19#include "graph/execute/model_executor.h"19#include "graph/execute/model_executor.h"
20#include "graph_metadef/depends/checker/tensor_check_utils.h"20#include "graph_metadef/depends/checker/tensor_check_utils.h"
21#include "mmpa/mmpa_api.h"21#include "mmpa/mmpa_api.h"
22+#include "graph/custom_op_factory.h"
22 23 
23using namespace std;24using namespace std;
24using namespace testing;25using namespace testing;
@@ -235,6 +236,7 @@ static Status DynamicStackExecute(ComputeGraphPtr &graph, const GeModelPtr &ge_m
235 const int32_t input_num, const size_t output_num, const bool check_output = true) {236 const int32_t input_num, const size_t output_num, const bool check_output = true) {
236 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();237 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
237 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);238 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
239+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
238 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);240 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
239 241 
240 GraphId graph_id = 1001;242 GraphId graph_id = 1001;
@@ -28,6 +28,7 @@
28#include "register/op_impl_kernel_registry.h"28#include "register/op_impl_kernel_registry.h"
29#include "register/kernel_registry.h"29#include "register/kernel_registry.h"
30#include "common/sgt_slice_type.h"30#include "common/sgt_slice_type.h"
31+#include "graph/custom_op_factory.h"
31#include "faker/space_registry_faker.h"32#include "faker/space_registry_faker.h"
32#include "graph/load/model_manager/model_manager.h"33#include "graph/load/model_manager/model_manager.h"
33#include "graph/utils/op_desc_utils.h"34#include "graph/utils/op_desc_utils.h"
@@ -401,6 +402,7 @@ static void RunPureStaticFftsPlusGraph(const ComputeGraphPtr &root_graph, const
401 402 
402 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();403 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
403 ge_root_model->Initialize(root_graph);404 ge_root_model->Initialize(root_graph);
405+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
404 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);406 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
405 407 
406 GraphId graph_id = 1001;408 GraphId graph_id = 1001;
@@ -434,6 +436,7 @@ static void RunDynamicStaticFftsPlusGraph(const ComputeGraphPtr &root_graph,
434 436 
435 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();437 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
436 ge_root_model->Initialize(root_graph);438 ge_root_model->Initialize(root_graph);
439+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
437 ge_root_model->SetModelName(root_graph->GetName());440 ge_root_model->SetModelName(root_graph->GetName());
438 GeModelPtr ge_sub_model = MakeShared<GeModel>();441 GeModelPtr ge_sub_model = MakeShared<GeModel>();
439 ge_sub_model->SetModelTaskDef(model_task_def);442 ge_sub_model->SetModelTaskDef(model_task_def);
@@ -556,6 +559,7 @@ TEST_F(FftsPlusTest, dsa_graph) {
556 // Build GeModel.559 // Build GeModel.
557 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();560 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
558 ge_root_model->Initialize(root_graph);561 ge_root_model->Initialize(root_graph);
562+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
559 563 
560 const auto model_task_def = MakeShared<domi::ModelTaskDef>();564 const auto model_task_def = MakeShared<domi::ModelTaskDef>();
561 const auto ge_model = MakeShared<GeModel>();565 const auto ge_model = MakeShared<GeModel>();
@@ -615,7 +619,8 @@ TEST_F(FftsPlusTest, dsa_graph_set_input1_value) {
615 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);619 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);
616 620 
617 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();621 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
618- ge_root_model->Initialize(root_graph);;622+ ge_root_model->Initialize(root_graph);
623+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
619 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);624 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
620 625 
621 GraphId graph_id = 1001;626 GraphId graph_id = 1001;
@@ -655,6 +660,7 @@ TEST_F(FftsPlusTest, dsa_graph_with_dump) {
655 660 
656 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();661 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
657 ge_root_model->Initialize(root_graph);662 ge_root_model->Initialize(root_graph);
663+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
658 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);664 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
659 665 
660 GraphId graph_id = 1001;666 GraphId graph_id = 1001;
@@ -777,6 +783,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_load_success) {
777 783 
778 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();784 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
779 ge_root_model->Initialize(root_graph);785 ge_root_model->Initialize(root_graph);
786+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
780 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);787 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
781 788 
782 GraphId graph_id = 1001;789 GraphId graph_id = 1001;
@@ -818,6 +825,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_load_success) {
818 825 
819 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();826 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
820 ge_root_model->Initialize(root_graph);827 ge_root_model->Initialize(root_graph);
828+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
821 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);829 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
822 830 
823 GraphId graph_id = 1001;831 GraphId graph_id = 1001;
@@ -921,6 +929,7 @@ TEST_F(FftsPlusTest, ffts_plus_error_tracking_test) {
921 929 
922 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();930 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
923 ge_root_model->Initialize(root_graph);931 ge_root_model->Initialize(root_graph);
932+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
924 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);933 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
925 934 
926 GraphId graph_id = 1001;935 GraphId graph_id = 1001;
@@ -986,6 +995,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_manual_load_success) {
986 995 
987 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();996 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
988 ge_root_model->Initialize(root_graph);997 ge_root_model->Initialize(root_graph);
998+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
989 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);999 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
990 1000 
991 GraphId graph_id = 1001;1001 GraphId graph_id = 1001;
@@ -1052,6 +1062,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_load_success_with_tiling_data) {
1052 1062 
1053 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1063 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1054 ge_root_model->Initialize(root_graph);1064 ge_root_model->Initialize(root_graph);
1065+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1055 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1066 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1056 1067 
1057 GraphId graph_id = 1001;1068 GraphId graph_id = 1001;
@@ -1109,6 +1120,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_load_with_exceptiondump) {
1109 1120 
1110 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1121 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1111 ge_root_model->Initialize(root_graph);1122 ge_root_model->Initialize(root_graph);
1123+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1112 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1124 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1113 1125 
1114 GraphId graph_id = 1001;1126 GraphId graph_id = 1001;
@@ -1186,6 +1198,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_with_aicpu_load_no_block_success) {
1186 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);1198 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);
1187 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1199 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1188 ge_root_model->Initialize(root_graph);1200 ge_root_model->Initialize(root_graph);
1201+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1189 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1202 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1190 1203 
1191 GraphId graph_id = 1001;1204 GraphId graph_id = 1001;
@@ -1233,6 +1246,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_with_aicpu_load_failed) {
1233 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);1246 RTS_STUB_RETURN_VALUE(rtQueryFunctionRegistered, rtError_t, 0x78000001);
1234 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1247 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1235 ge_root_model->Initialize(root_graph);1248 ge_root_model->Initialize(root_graph);
1249+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1236 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1250 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1237 1251 
1238 GraphId graph_id = 1001;1252 GraphId graph_id = 1001;
@@ -1418,6 +1432,7 @@ TEST_F(FftsPlusTest, FftsPlusTest_ffts_plus_auto_graph_with_mix_load_fail) {
1418 1432 
1419 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1433 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1420 ge_root_model->Initialize(root_graph);1434 ge_root_model->Initialize(root_graph);
1435+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1421 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1436 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1422 1437 
1423 GraphId graph_id = 1001;1438 GraphId graph_id = 1001;
@@ -1469,6 +1484,7 @@ TEST_F(FftsPlusTest, FftsPlusTest_ffts_plus_auto_graph_with_mix_load_success) {
1469 1484 
1470 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1485 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1471 ge_root_model->Initialize(root_graph);1486 ge_root_model->Initialize(root_graph);
1487+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1472 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1488 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1473 1489 
1474 GraphId graph_id = 1001;1490 GraphId graph_id = 1001;
@@ -1557,6 +1573,7 @@ TEST_F(FftsPlusTest, FftsPlusTest_ffts_plus_graph_mix_prof_Test) {
1557 1573 
1558 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1574 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1559 ge_root_model->Initialize(root_graph);1575 ge_root_model->Initialize(root_graph);
1576+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1560 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1577 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1561 1578 
1562 GraphId graph_id = 1001;1579 GraphId graph_id = 1001;
@@ -1625,6 +1642,7 @@ TEST_F(FftsPlusTest, ffts_plus_graph_load_with_level1update) {
1625 1642 
1626 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1643 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1627 ge_root_model->Initialize(root_graph);1644 ge_root_model->Initialize(root_graph);
1645+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1628 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);1646 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
1629 1647 
1630 GraphId graph_id = 1001;1648 GraphId graph_id = 1001;
@@ -41,6 +41,7 @@
41#include "framework/runtime/model_rt_var_manager.h"41#include "framework/runtime/model_rt_var_manager.h"
42#include "common/opskernel/ops_kernel_info_types.h"42#include "common/opskernel/ops_kernel_info_types.h"
43#include "graph_metadef/depends/checker/tensor_check_utils.h"43#include "graph_metadef/depends/checker/tensor_check_utils.h"
44+#include "graph/custom_op_factory.h"
44 45 
45using namespace std;46using namespace std;
46using namespace testing;47using namespace testing;
@@ -843,6 +844,7 @@ TEST_F(GeExecutorTest, dvpp_graph) {
843 844 
844 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();845 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
845 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);846 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
847+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
846 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);848 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
847 849 
848 GraphId graph_id = 1001;850 GraphId graph_id = 1001;
@@ -969,6 +971,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory) {
969 // Test LoadModelOnline: RunAsyncListener971 // Test LoadModelOnline: RunAsyncListener
970 const auto ge_root_model = MakeShared<GeRootModel>();972 const auto ge_root_model = MakeShared<GeRootModel>();
971 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);973 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
974+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
972 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());975 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
973 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);976 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
974 graph_node->SetGeRootModel(ge_root_model);;977 graph_node->SetGeRootModel(ge_root_model);;
@@ -1028,6 +1031,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory) {
1028 // Test LoadModelOnline: GraphModelListener1031 // Test LoadModelOnline: GraphModelListener
1029 const auto ge_root_model = MakeShared<GeRootModel>();1032 const auto ge_root_model = MakeShared<GeRootModel>();
1030 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1033 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1034+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1031 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1035 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1032 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1036 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1033 graph_node->SetGeRootModel(ge_root_model);;1037 graph_node->SetGeRootModel(ge_root_model);;
@@ -1070,6 +1074,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory) {
1070 // Test LoadModelOnline: RunGraphWithStream1074 // Test LoadModelOnline: RunGraphWithStream
1071 const auto ge_root_model = MakeShared<GeRootModel>();1075 const auto ge_root_model = MakeShared<GeRootModel>();
1072 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1076 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1077+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1073 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1078 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1074 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1079 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1075 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.1080 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.
@@ -1131,6 +1136,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory) {
1131 1136 
1132 const auto ge_root_model = MakeShared<GeRootModel>();1137 const auto ge_root_model = MakeShared<GeRootModel>();
1133 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1138 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1139+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1134 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1140 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1135 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1141 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1136 graph_node->SetGeRootModel(ge_root_model);;1142 graph_node->SetGeRootModel(ge_root_model);;
@@ -1233,6 +1239,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_recover_single_model) {
1233 // Test LoadModelOnline: RunGraphWithStream1239 // Test LoadModelOnline: RunGraphWithStream
1234 const auto ge_root_model = MakeShared<GeRootModel>();1240 const auto ge_root_model = MakeShared<GeRootModel>();
1235 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1241 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1242+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1236 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1243 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1237 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.1244 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.
1238 1245 
@@ -1314,6 +1321,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_lora_format_changed) {
1314 // Test LoadModelOnline: RunGraphWithStream1321 // Test LoadModelOnline: RunGraphWithStream
1315 const auto ge_root_model = MakeShared<GeRootModel>();1322 const auto ge_root_model = MakeShared<GeRootModel>();
1316 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1323 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1324+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1317 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1325 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1318 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1326 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1319 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.1327 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.
@@ -1360,6 +1368,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_lora_format_changed) {
1360 // Test LoadModelOnline: RunGraphWithStream1368 // Test LoadModelOnline: RunGraphWithStream
1361 const auto ge_root_model = MakeShared<GeRootModel>();1369 const auto ge_root_model = MakeShared<GeRootModel>();
1362 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1370 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1371+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1363 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1372 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1364 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1373 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1365 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.1374 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.
@@ -1415,6 +1424,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_invalid_input) {
1415 // Test LoadModelOnline: RunAsyncListener1424 // Test LoadModelOnline: RunAsyncListener
1416 const auto ge_root_model = MakeShared<GeRootModel>();1425 const auto ge_root_model = MakeShared<GeRootModel>();
1417 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1426 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1427+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1418 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1428 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1419 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1429 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1420 graph_node->SetGeRootModel(ge_root_model);;1430 graph_node->SetGeRootModel(ge_root_model);;
@@ -1529,6 +1539,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_dynamic_memory) {
1529 // Test LoadModelOnline: GraphModelListener1539 // Test LoadModelOnline: GraphModelListener
1530 const auto ge_root_model = MakeShared<GeRootModel>();1540 const auto ge_root_model = MakeShared<GeRootModel>();
1531 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1541 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1542+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1532 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1543 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1533 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1544 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1534 graph_node->SetGeRootModel(ge_root_model);;1545 graph_node->SetGeRootModel(ge_root_model);;
@@ -1555,6 +1566,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_dynamic_memory) {
1555 // Test LoadModelOnline: RunAsyncListener1566 // Test LoadModelOnline: RunAsyncListener
1556 const auto ge_root_model = MakeShared<GeRootModel>();1567 const auto ge_root_model = MakeShared<GeRootModel>();
1557 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1568 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1569+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1558 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());1570 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
1559 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1571 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1560 graph_node->SetGeRootModel(ge_root_model);;1572 graph_node->SetGeRootModel(ge_root_model);;
@@ -2218,6 +2230,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory_with_qos) {
2218 // Test LoadModelOnline: RunAsyncListener2230 // Test LoadModelOnline: RunAsyncListener
2219 const auto ge_root_model = MakeShared<GeRootModel>();2231 const auto ge_root_model = MakeShared<GeRootModel>();
2220 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);2232 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
2233+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2221 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());2234 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
2222 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2235 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2223 graph_node->SetGeRootModel(ge_root_model);;2236 graph_node->SetGeRootModel(ge_root_model);;
@@ -2274,6 +2287,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory_with_qos) {
2274 // Test LoadModelOnline: GraphModelListener2287 // Test LoadModelOnline: GraphModelListener
2275 const auto ge_root_model = MakeShared<GeRootModel>();2288 const auto ge_root_model = MakeShared<GeRootModel>();
2276 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);2289 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
2290+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2277 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());2291 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
2278 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2292 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2279 graph_node->SetGeRootModel(ge_root_model);;2293 graph_node->SetGeRootModel(ge_root_model);;
@@ -2328,6 +2342,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory_with_qos) {
2328 // Test LoadModelOnline: RunGraphWithStream2342 // Test LoadModelOnline: RunGraphWithStream
2329 const auto ge_root_model = MakeShared<GeRootModel>();2343 const auto ge_root_model = MakeShared<GeRootModel>();
2330 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);2344 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
2345+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2331 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());2346 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
2332 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2347 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2333 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.2348 ge_root_model->SetIsSpecificStream(true); // For not start DavinciModel thread.
@@ -2369,6 +2384,7 @@ TEST_F(GeExecutorTest, sample_davinci_model_static_memory_with_qos) {
2369 // Test LoadModelOnline: for SuperKernel2384 // Test LoadModelOnline: for SuperKernel
2370 const auto ge_root_model = MakeShared<GeRootModel>();2385 const auto ge_root_model = MakeShared<GeRootModel>();
2371 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);2386 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
2387+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
2372 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());2388 const auto graph_node = MakeShared<GraphNode>(graph->GetGraphID());
2373 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);2389 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
2374 graph_node->SetGeRootModel(ge_root_model);;2390 graph_node->SetGeRootModel(ge_root_model);;
@@ -17,6 +17,7 @@
17#include "ge/ut/ge/test_tools_task_info.h"17#include "ge/ut/ge/test_tools_task_info.h"
18#include "common/dump/dump_properties.h"18#include "common/dump/dump_properties.h"
19#include "common/dump/dump_manager.h"19#include "common/dump/dump_manager.h"
20+#include "graph/custom_op_factory.h"
20#include "graph_metadef/depends/checker/tensor_check_utils.h"21#include "graph_metadef/depends/checker/tensor_check_utils.h"
21#include "mmpa/mmpa_api.h"22#include "mmpa/mmpa_api.h"
22using namespace std;23using namespace std;
@@ -454,6 +455,7 @@ TEST_F(DynamicKnownTest, execute_known_from_dynamic) {
454 455 
455 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();456 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
456 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);457 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
458+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
457 BuildGraphModel2(dynamic, mem_offset, ge_root_model);459 BuildGraphModel2(dynamic, mem_offset, ge_root_model);
458 BuildGraphModel3(davinci, mem_offset, ge_root_model, then_branch, else_branch);460 BuildGraphModel3(davinci, mem_offset, ge_root_model, then_branch, else_branch);
459 BuildGraphModel4(collect, mem_offset, ge_root_model);461 BuildGraphModel4(collect, mem_offset, ge_root_model);
@@ -24,9 +24,11 @@
24 24 
25#include "common/model/ge_model.h"25#include "common/model/ge_model.h"
26#define private public26#define private public
27+#include "common/helper/custom_op_registry_builder.h"
27#include "common/helper/custom_op_so_loader.h"28#include "common/helper/custom_op_so_loader.h"
28#include "common/model/ge_root_model.h"29#include "common/model/ge_root_model.h"
29#undef private30#undef private
31+#include "depends/mmpa/src/mmpa_stub.h"
30#include "common/plugin/plugin_manager.h"32#include "common/plugin/plugin_manager.h"
31#include "framework/common/helper/model_helper.h"33#include "framework/common/helper/model_helper.h"
32#include "framework/common/helper/om_file_helper.h"34#include "framework/common/helper/om_file_helper.h"
@@ -34,6 +36,8 @@
34#include "graph/ge_local_context.h"36#include "graph/ge_local_context.h"
35#include "graph/custom_op.h"37#include "graph/custom_op.h"
36#include "graph/custom_op_factory.h"38#include "graph/custom_op_factory.h"
39+#include "graph/custom_op_pull_registry.h"
40+#include "graph/custom_op_registry.h"
37#include "mmpa/mmpa_api.h"41#include "mmpa/mmpa_api.h"
38 42 
39namespace ge {43namespace ge {
@@ -49,11 +53,28 @@ constexpr const char *kSaveEmptySubType = "StModelHelperSaveEmptySubPortableOp";
49constexpr const char *kSaveSuccessRootType = "StModelHelperSaveSuccessRootPortableOp";53constexpr const char *kSaveSuccessRootType = "StModelHelperSaveSuccessRootPortableOp";
50constexpr const char *kSaveSuccessSubType = "StModelHelperSaveSuccessSubPortableOp";54constexpr const char *kSaveSuccessSubType = "StModelHelperSaveSuccessSubPortableOp";
51constexpr const char *kLoadSuccessType = "StModelHelperLoadSuccessPortableOp";55constexpr const char *kLoadSuccessType = "StModelHelperLoadSuccessPortableOp";
56+constexpr const char *kLoadToRegistryType = "StModelHelperLoadToRegistryPortableOp";
57+constexpr const char *kPullRegistryType = "StModelHelperPullRegistryPortableOp";
58+constexpr const char *kCreatorRegisterType = "StModelHelperCreatorRegisterPortableOp";
59+constexpr const char *kBuilderPullOpA = "StModelHelperBuilderPullOpA";
60+constexpr const char *kBuilderPullOpB = "StModelHelperBuilderPullOpB";
61+constexpr const char *kSymbolAbiVersion = "GetRegisteredCustomOpCreatorAbiVersion";
62+constexpr const char *kSymbolCreatorNum = "GetRegisteredCustomOpCreatorNum";
63+constexpr const char *kSymbolCreators = "GetRegisteredCustomOpCreators";
52 64 
53const std::vector<uint8_t> kPortableKernelBin = {0x11U, 0x22U, 0x33U};65const std::vector<uint8_t> kPortableKernelBin = {0x11U, 0x22U, 0x33U};
54size_t g_deserialize_called_count = 0U;66size_t g_deserialize_called_count = 0U;
55size_t g_last_deserialize_bin_size = 0U;67size_t g_last_deserialize_bin_size = 0U;
56 68 
69+struct FakeSoCreatorsForSt {
70+ uint32_t abi_version = kCustomOpCreatorPullAbiVersion;
71+ int32_t get_creators_ret = 0;
72+ std::vector<CustomOpTypeToCreator> creators;
73+};
74+ 
75+FakeSoCreatorsForSt g_fake_so_a;
76+FakeSoCreatorsForSt g_fake_so_b;
77+ 
57class TestableModelHelper : public ModelHelper {78class TestableModelHelper : public ModelHelper {
58 public:79 public:
59 using ModelHelper::CollectUsedCustomOpTypes;80 using ModelHelper::CollectUsedCustomOpTypes;
@@ -143,6 +164,109 @@ class PortableOpForDeserializeRecord : public EagerExecuteOp, public PortableOp
143 }164 }
144};165};
145 166 
167+class BuilderPullOpA : public BaseCustomOp {};
168+class BuilderPullOpB : public BaseCustomOp {};
169+ 
170+class FakeSoHandleMmpaStubForSt : public MmpaStubApiGe {
171+ public:
172+ int32_t DlClose(void *handle) override {
173+ if ((handle == reinterpret_cast<void *>(0xA001U)) || (handle == reinterpret_cast<void *>(0xB001U))) {
174+ return 0;
175+ }
176+ return MmpaStubApiGe::DlClose(handle);
177+ }
178+};
179+ 
180+BaseCustomOp *CreateBuilderPullOpA() {
181+ return new BuilderPullOpA();
182+}
183+ 
184+BaseCustomOp *CreateBuilderPullOpB() {
185+ return new BuilderPullOpB();
186+}
187+ 
188+BaseCustomOp *CreatePullRegistryOp() {
189+ return new PortableOpForSerializeSuccess();
190+}
191+ 
192+uint32_t GetFakeAbiVersionA() {
193+ return g_fake_so_a.abi_version;
194+}
195+ 
196+uint32_t GetFakeAbiVersionB() {
197+ return g_fake_so_b.abi_version;
198+}
199+ 
200+size_t GetFakeCreatorNumA() {
201+ return g_fake_so_a.creators.size();
202+}
203+ 
204+size_t GetFakeCreatorNumB() {
205+ return g_fake_so_b.creators.size();
206+}
207+ 
208+int32_t CopyFakeCreatorsForSt(const FakeSoCreatorsForSt &fake_so, CustomOpTypeToCreator *creators,
209+ const size_t creator_num, const size_t creator_struct_size) {
210+ if (fake_so.get_creators_ret != 0) {
211+ return fake_so.get_creators_ret;
212+ }
213+ if ((creator_num < fake_so.creators.size()) || ((creator_num > 0U) && (creators == nullptr)) ||
214+ (creator_struct_size < sizeof(CustomOpTypeToCreator))) {
215+ return -1;
216+ }
217+ for (size_t i = 0U; i < fake_so.creators.size(); ++i) {
218+ auto *creator_addr = reinterpret_cast<uint8_t *>(creators) + (i * creator_struct_size);
219+ auto *creator = reinterpret_cast<CustomOpTypeToCreator *>(creator_addr);
220+ *creator = fake_so.creators[i];
221+ }
222+ return 0;
223+}
224+ 
225+int32_t GetFakeCreatorsA(CustomOpTypeToCreator *creators, size_t creator_num, size_t creator_struct_size) {
226+ return CopyFakeCreatorsForSt(g_fake_so_a, creators, creator_num, creator_struct_size);
227+}
228+ 
229+int32_t GetFakeCreatorsB(CustomOpTypeToCreator *creators, size_t creator_num, size_t creator_struct_size) {
230+ return CopyFakeCreatorsForSt(g_fake_so_b, creators, creator_num, creator_struct_size);
231+}
232+ 
233+void *ResolveFakeSymbolsForSt(void *handle, const char *symbol) {
234+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolAbiVersion) == 0)) {
235+ return reinterpret_cast<void *>(&GetFakeAbiVersionA);
236+ }
237+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolCreatorNum) == 0)) {
238+ return reinterpret_cast<void *>(&GetFakeCreatorNumA);
239+ }
240+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolCreators) == 0)) {
241+ return reinterpret_cast<void *>(&GetFakeCreatorsA);
242+ }
243+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolAbiVersion) == 0)) {
244+ return reinterpret_cast<void *>(&GetFakeAbiVersionB);
245+ }
246+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolCreatorNum) == 0)) {
247+ return reinterpret_cast<void *>(&GetFakeCreatorNumB);
248+ }
249+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolCreators) == 0)) {
250+ return reinterpret_cast<void *>(&GetFakeCreatorsB);
251+ }
252+ return nullptr;
253+}
254+ 
255+void *ResolveMissingCreatorNumForSt(void *handle, const char *symbol) {
256+ if (std::strcmp(symbol, kSymbolCreatorNum) == 0) {
257+ return nullptr;
258+ }
259+ return ResolveFakeSymbolsForSt(handle, symbol);
260+}
261+ 
262+CustomOpTypeToCreator MakeCreatorForSt(const char *op_type, const CustomOpCreateFunc creator) {
263+ return CustomOpTypeToCreator{sizeof(CustomOpTypeToCreator), op_type, creator};
264+}
265+ 
266+CustomOpSoHandlePtr MakeFakeSoHandleForSt(void *handle, const std::string &name) {
267+ return std::make_shared<CustomOpSoHandle>(name, handle, name, 0U, -1);
268+}
269+ 
146static void RegisterCustomOpCreatorForSt(const std::string &op_type, const BaseOpCreator &creator) {270static void RegisterCustomOpCreatorForSt(const std::string &op_type, const BaseOpCreator &creator) {
147 const auto ret = CustomOpFactory::RegisterCustomOpCreator(op_type.c_str(), creator);271 const auto ret = CustomOpFactory::RegisterCustomOpCreator(op_type.c_str(), creator);
148 EXPECT_TRUE((ret == GRAPH_SUCCESS) || (ret == GRAPH_FAILED));272 EXPECT_TRUE((ret == GRAPH_SUCCESS) || (ret == GRAPH_FAILED));
@@ -172,6 +296,7 @@ static GeRootModelPtr CreateRootModelForCustomOps(const std::string &root_op_typ
172 if (ge_root_model->Initialize(root_graph) != SUCCESS) {296 if (ge_root_model->Initialize(root_graph) != SUCCESS) {
173 return nullptr;297 return nullptr;
174 }298 }
299+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
175 300 
176 auto sub_graph = std::make_shared<ComputeGraph>("st_sub_graph_for_custom_kernels_helper");301 auto sub_graph = std::make_shared<ComputeGraph>("st_sub_graph_for_custom_kernels_helper");
177 if (!sub_op_type.empty()) {302 if (!sub_op_type.empty()) {
@@ -371,10 +496,128 @@ static void GetCurrentEnvWithFallbackForSt(std::string &current_env_os, std::str
371 496 
372class TestModelCustomOpsHelper : public testing::Test {497class TestModelCustomOpsHelper : public testing::Test {
373 protected:498 protected:
374- void SetUp() override {}499+ void SetUp() override {
375- void TearDown() override {}500+ g_fake_so_a = FakeSoCreatorsForSt{};
501+ g_fake_so_b = FakeSoCreatorsForSt{};
502+ MmpaStub::GetInstance().SetImpl(std::make_shared<FakeSoHandleMmpaStubForSt>());
503+ }
504+ 
505+ void TearDown() override {
506+ g_fake_so_a = FakeSoCreatorsForSt{};
507+ g_fake_so_b = FakeSoCreatorsForSt{};
508+ MmpaStub::GetInstance().Reset();
509+ }
510+ 
511+ void RunInvalidCreatorTests(const std::shared_ptr<CustomOpRegistry> &registry,
512+ const std::vector<CustomOpSoHandlePtr> &so_handles) {
513+ const std::vector<CustomOpTypeToCreator> invalid_creators = {
514+ MakeCreatorForSt(nullptr, CreateBuilderPullOpA),
515+ MakeCreatorForSt("", CreateBuilderPullOpA),
516+ MakeCreatorForSt(kBuilderPullOpA, nullptr),
517+ CustomOpTypeToCreator{sizeof(CustomOpTypeToCreator) - 1U, kBuilderPullOpA, CreateBuilderPullOpA}};
518+ for (const auto &invalid_creator : invalid_creators) {
519+ g_fake_so_a = FakeSoCreatorsForSt{};
520+ g_fake_so_a.creators = {invalid_creator};
521+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbolsForSt),
522+ SUCCESS);
523+ EXPECT_FALSE(registry->HasCreator(kBuilderPullOpA));
524+ }
525+ }
526+ 
527+ void RunDuplicateHandleTest(const std::shared_ptr<CustomOpRegistry> &registry) {
528+ g_fake_so_a = FakeSoCreatorsForSt{};
529+ g_fake_so_b = FakeSoCreatorsForSt{};
530+ g_fake_so_a.creators = {MakeCreatorForSt(kBuilderPullOpA, CreateBuilderPullOpA)};
531+ g_fake_so_b.creators = {MakeCreatorForSt(kBuilderPullOpA, CreateBuilderPullOpB)};
532+ std::vector<CustomOpSoHandlePtr> duplicate_handles = {
533+ MakeFakeSoHandleForSt(reinterpret_cast<void *>(0xA001U), "fake_a"),
534+ MakeFakeSoHandleForSt(reinterpret_cast<void *>(0xB001U), "fake_b")};
535+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(duplicate_handles, registry, ResolveFakeSymbolsForSt),
536+ SUCCESS);
537+ EXPECT_FALSE(registry->HasCreator(kBuilderPullOpA));
538+ }
376};539};
377 540 
541+TEST_F(TestModelCustomOpsHelper, pull_registry_c_abi_returns_registered_local_creators) {
542+ RegisterCustomOpLocalCreator(nullptr, CreatePullRegistryOp);
543+ RegisterCustomOpLocalCreator("", CreatePullRegistryOp);
544+ RegisterCustomOpLocalCreator(kPullRegistryType, nullptr);
545+ 
546+ const size_t creator_num_before = GetRegisteredCustomOpCreatorNum();
547+ RegisterCustomOpLocalCreator(kPullRegistryType, CreatePullRegistryOp);
548+ const size_t creator_num_after = GetRegisteredCustomOpCreatorNum();
549+ ASSERT_EQ(GetRegisteredCustomOpCreatorAbiVersion(), kCustomOpCreatorPullAbiVersion);
550+ ASSERT_EQ(creator_num_after, creator_num_before + 1U);
551+ EXPECT_NE(GetRegisteredCustomOpCreators(nullptr, creator_num_after, sizeof(CustomOpTypeToCreator)), 0);
552+ 
553+ std::vector<CustomOpTypeToCreator> creators(creator_num_after);
554+ EXPECT_NE(GetRegisteredCustomOpCreators(creators.data(), creator_num_after - 1U, sizeof(CustomOpTypeToCreator)), 0);
555+ EXPECT_NE(GetRegisteredCustomOpCreators(creators.data(), creator_num_after,
556+ sizeof(CustomOpTypeToCreator) - 1U), 0);
557+ ASSERT_EQ(GetRegisteredCustomOpCreators(creators.data(), creator_num_after, sizeof(CustomOpTypeToCreator)), 0);
558+ 
559+ const auto iter = std::find_if(creators.begin(), creators.end(), [](const CustomOpTypeToCreator &creator) {
560+ return (creator.op_type != nullptr) && (std::strcmp(creator.op_type, kPullRegistryType) == 0);
561+ });
562+ ASSERT_NE(iter, creators.end());
563+ EXPECT_EQ(iter->struct_size, sizeof(CustomOpTypeToCreator));
564+ EXPECT_EQ(iter->creator, CreatePullRegistryOp);
565+ std::unique_ptr<BaseCustomOp> op(iter->creator());
566+ EXPECT_NE(dynamic_cast<PortableOpForSerializeSuccess *>(op.get()), nullptr);
567+}
568+ 
569+TEST_F(TestModelCustomOpsHelper, custom_op_creator_register_registers_local_and_global_creator) {
570+ const size_t creator_num_before = GetRegisteredCustomOpCreatorNum();
571+ CustomOpCreatorRegister creator_register(AscendString(kCreatorRegisterType), CreatePullRegistryOp);
572+ (void)creator_register;
573+ EXPECT_EQ(GetRegisteredCustomOpCreatorNum(), creator_num_before + 1U);
574+ EXPECT_TRUE(CustomOpFactory::IsExistOp(kCreatorRegisterType));
575+ EXPECT_NE(dynamic_cast<PortableOpForSerializeSuccess *>(
576+ CustomOpFactory::CreateOrGetCustomOp(kCreatorRegisterType)), nullptr);
577+}
578+ 
579+TEST_F(TestModelCustomOpsHelper, custom_op_registry_builder_covers_pull_creator_success_and_failures) {
580+ auto registry = std::make_shared<CustomOpRegistry>();
581+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles({}, nullptr, ResolveFakeSymbolsForSt), SUCCESS);
582+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles({}, registry, nullptr), SUCCESS);
583+ EXPECT_EQ(CustomOpRegistryBuilder::AddCreatorsFromSoHandles({}, registry), SUCCESS);
584+ 
585+ std::vector<CustomOpSoHandlePtr> null_handles = {nullptr};
586+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(null_handles, registry, ResolveFakeSymbolsForSt),
587+ SUCCESS);
588+ 
589+ g_fake_so_a.creators = {MakeCreatorForSt(kBuilderPullOpA, CreateBuilderPullOpA)};
590+ std::vector<CustomOpSoHandlePtr> so_handles = {MakeFakeSoHandleForSt(reinterpret_cast<void *>(0xA001U), "fake_a")};
591+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveMissingCreatorNumForSt),
592+ SUCCESS);
593+ EXPECT_FALSE(registry->HasCreator(kBuilderPullOpA));
594+ 
595+ g_fake_so_a.abi_version = kCustomOpCreatorPullAbiVersion + 1U;
596+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbolsForSt),
597+ SUCCESS);
598+ EXPECT_FALSE(registry->HasCreator(kBuilderPullOpA));
599+ 
600+ g_fake_so_a = FakeSoCreatorsForSt{};
601+ g_fake_so_a.get_creators_ret = -1;
602+ g_fake_so_a.creators = {MakeCreatorForSt(kBuilderPullOpA, CreateBuilderPullOpA)};
603+ EXPECT_NE(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbolsForSt),
604+ SUCCESS);
605+ EXPECT_FALSE(registry->HasCreator(kBuilderPullOpA));
606+ 
607+ RunInvalidCreatorTests(registry, so_handles);
608+ RunDuplicateHandleTest(registry);
609+ 
610+ g_fake_so_a = FakeSoCreatorsForSt{};
611+ g_fake_so_a.creators = {MakeCreatorForSt(kBuilderPullOpA, CreateBuilderPullOpA),
612+ MakeCreatorForSt(kBuilderPullOpB, CreateBuilderPullOpB)};
613+ EXPECT_EQ(CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbolsForSt),
614+ SUCCESS);
615+ EXPECT_TRUE(registry->HasCreator(kBuilderPullOpA));
616+ EXPECT_TRUE(registry->HasCreator(kBuilderPullOpB));
617+ EXPECT_NE(dynamic_cast<BuilderPullOpA *>(registry->CreateOrGetCustomOp(kBuilderPullOpA)), nullptr);
618+ EXPECT_NE(dynamic_cast<BuilderPullOpB *>(registry->CreateOrGetCustomOp(kBuilderPullOpB)), nullptr);
619+}
620+ 
378TEST_F(TestModelCustomOpsHelper, collect_used_custom_op_types_collects_root_subgraph_and_skips_invalid_subgraphs) {621TEST_F(TestModelCustomOpsHelper, collect_used_custom_op_types_collects_root_subgraph_and_skips_invalid_subgraphs) {
379 RegisterCustomOpCreatorForSt(kCollectRootType, []() -> std::unique_ptr<BaseCustomOp> {622 RegisterCustomOpCreatorForSt(kCollectRootType, []() -> std::unique_ptr<BaseCustomOp> {
380 return std::make_unique<PortableOpForSerializeSuccess>();623 return std::make_unique<PortableOpForSerializeSuccess>();
@@ -410,7 +653,8 @@ TEST_F(TestModelCustomOpsHelper, serialize_custom_op_kernel_covers_all_target_br
410 653 
411 std::vector<uint8_t> empty_bin_merged_kernels = {0xD4U};654 std::vector<uint8_t> empty_bin_merged_kernels = {0xD4U};
412 PortableOpForSerializeEmpty portable_op_empty;655 PortableOpForSerializeEmpty portable_op_empty;
413- EXPECT_EQ(model_helper.SerializeCustomOpKernel(&portable_op_empty, kSerializeEmptyType, empty_bin_merged_kernels), SUCCESS);656+ EXPECT_NE(model_helper.SerializeCustomOpKernel(&portable_op_empty, kSerializeEmptyType, empty_bin_merged_kernels),
657+ SUCCESS);
414 EXPECT_EQ(empty_bin_merged_kernels, std::vector<uint8_t>({0xD4U}));658 EXPECT_EQ(empty_bin_merged_kernels, std::vector<uint8_t>({0xD4U}));
415 659 
416 std::vector<uint8_t> success_merged_kernels = {0xE5U};660 std::vector<uint8_t> success_merged_kernels = {0xE5U};
@@ -430,7 +674,7 @@ TEST_F(TestModelCustomOpsHelper, serialize_custom_op_kernel_covers_all_target_br
430 EXPECT_EQ(header.bin_len, kPortableKernelBin.size());674 EXPECT_EQ(header.bin_len, kPortableKernelBin.size());
431}675}
432 676 
433-TEST_F(TestModelCustomOpsHelper, save_custom_kernels_partition_skips_when_merged_kernels_empty_after_loop) {677+TEST_F(TestModelCustomOpsHelper, save_custom_kernels_partition_fails_when_serialized_kernel_bin_empty) {
434 RegisterCustomOpCreatorForSt(kSaveEmptyRootType, []() -> std::unique_ptr<BaseCustomOp> {678 RegisterCustomOpCreatorForSt(kSaveEmptyRootType, []() -> std::unique_ptr<BaseCustomOp> {
435 return std::make_unique<PortableOpForSerializeEmpty>();679 return std::make_unique<PortableOpForSerializeEmpty>();
436 });680 });
@@ -443,7 +687,7 @@ TEST_F(TestModelCustomOpsHelper, save_custom_kernels_partition_skips_when_merged
443 687 
444 auto om_file_save_helper = std::make_shared<OmFileSaveHelper>();688 auto om_file_save_helper = std::make_shared<OmFileSaveHelper>();
445 TestableModelHelper model_helper;689 TestableModelHelper model_helper;
446- EXPECT_EQ(model_helper.SaveCustomOpsPartition(om_file_save_helper, ge_root_model), SUCCESS);690+ EXPECT_NE(model_helper.SaveCustomOpsPartition(om_file_save_helper, ge_root_model), SUCCESS);
447}691}
448 692 
449TEST_F(TestModelCustomOpsHelper, save_custom_kernels_partition_success_with_non_empty_used_custom_op_types) {693TEST_F(TestModelCustomOpsHelper, save_custom_kernels_partition_success_with_non_empty_used_custom_op_types) {
@@ -467,10 +711,10 @@ TEST_F(TestModelCustomOpsHelper, load_custom_kernels_returns_success_when_partit
467 OmFileLoadHelper load_helper;711 OmFileLoadHelper load_helper;
468 load_helper.is_inited_ = true;712 load_helper.is_inited_ = true;
469 load_helper.model_contexts_.emplace_back(OmFileContext{});713 load_helper.model_contexts_.emplace_back(OmFileContext{});
470- EXPECT_EQ(model_helper.LoadCustomOps(load_helper), SUCCESS);714+ EXPECT_EQ(model_helper.LoadCustomOps(load_helper, nullptr), SUCCESS);
471}715}
472 716 
473-TEST_F(TestModelCustomOpsHelper, load_custom_kernels_loads_non_empty_partition_successfully) {717+TEST_F(TestModelCustomOpsHelper, load_custom_kernels_returns_failed_when_registry_is_null) {
474 RegisterCustomOpCreatorForSt(kLoadSuccessType, []() -> std::unique_ptr<BaseCustomOp> {718 RegisterCustomOpCreatorForSt(kLoadSuccessType, []() -> std::unique_ptr<BaseCustomOp> {
475 return std::make_unique<PortableOpForDeserializeRecord>();719 return std::make_unique<PortableOpForDeserializeRecord>();
476 });720 });
@@ -491,9 +735,28 @@ TEST_F(TestModelCustomOpsHelper, load_custom_kernels_loads_non_empty_partition_s
491 g_deserialize_called_count = 0U;735 g_deserialize_called_count = 0U;
492 g_last_deserialize_bin_size = 0U;736 g_last_deserialize_bin_size = 0U;
493 TestableModelHelper model_helper;737 TestableModelHelper model_helper;
494- EXPECT_EQ(model_helper.LoadCustomOps(load_helper), SUCCESS);738+ EXPECT_EQ(model_helper.LoadCustomOps(load_helper, nullptr), FAILED);
739+ EXPECT_EQ(g_deserialize_called_count, 0U);
740+ EXPECT_EQ(g_last_deserialize_bin_size, 0U);
741+}
742+ 
743+TEST_F(TestModelCustomOpsHelper, load_custom_ops_to_registry_uses_given_registry_only) {
744+ const std::vector<uint8_t> serialized_bin = {0x44U, 0x55U};
745+ const auto payload = BuildCustomKernelPartitionPayload(kLoadToRegistryType, serialized_bin);
746+ auto registry = std::make_shared<CustomOpRegistry>();
747+ ASSERT_EQ(registry->RegisterCreator(kLoadToRegistryType, []() -> std::unique_ptr<BaseCustomOp> {
748+ return std::make_unique<PortableOpForDeserializeRecord>();
749+ }), GRAPH_SUCCESS);
750+ ASSERT_FALSE(CustomOpFactory::IsExistOp(kLoadToRegistryType));
751+ 
752+ g_deserialize_called_count = 0U;
753+ g_last_deserialize_bin_size = 0U;
754+ EXPECT_EQ(LoadCustomOpsToRegistry(payload.data(), payload.size(), registry), SUCCESS);
755+ 
495 EXPECT_EQ(g_deserialize_called_count, 1U);756 EXPECT_EQ(g_deserialize_called_count, 1U);
496 EXPECT_EQ(g_last_deserialize_bin_size, serialized_bin.size());757 EXPECT_EQ(g_last_deserialize_bin_size, serialized_bin.size());
758+ EXPECT_NE(registry->FindCustomOp(kLoadToRegistryType), nullptr);
759+ EXPECT_FALSE(CustomOpFactory::IsExistOp(kLoadToRegistryType));
497}760}
498 761 
499TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_load_success_repeat_and_conflict_are_stable) {762TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_load_success_repeat_and_conflict_are_stable) {
@@ -506,10 +769,15 @@ TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_load_success_repeat_and_con
506 CustomOpSoLoader loader;769 CustomOpSoLoader loader;
507 const auto so_bin = BuildCustomOpSoBinForSt("libst_custom_loader_conflict.so", "st_vendor", so_data);770 const auto so_bin = BuildCustomOpSoBinForSt("libst_custom_loader_conflict.so", "st_vendor", so_data);
508 ASSERT_NE(so_bin, nullptr);771 ASSERT_NE(so_bin, nullptr);
509- ASSERT_EQ(loader.LoadCustomOpSoBins({so_bin}), SUCCESS);772+ std::vector<CustomOpSoHandlePtr> first_loaded_handles;
773+ ASSERT_EQ(loader.LoadCustomOpSoBins({so_bin}, first_loaded_handles), SUCCESS);
774+ ASSERT_EQ(first_loaded_handles.size(), 1U);
510 ASSERT_EQ(loader.loaded_states_.size(), 1U);775 ASSERT_EQ(loader.loaded_states_.size(), 1U);
511 776 
512- EXPECT_EQ(loader.LoadCustomOpSoBins({so_bin}), SUCCESS);777+ std::vector<CustomOpSoHandlePtr> second_loaded_handles;
778+ EXPECT_EQ(loader.LoadCustomOpSoBins({so_bin}, second_loaded_handles), SUCCESS);
779+ ASSERT_EQ(second_loaded_handles.size(), 1U);
780+ EXPECT_EQ(first_loaded_handles[0], second_loaded_handles[0]);
513 EXPECT_EQ(loader.loaded_states_.size(), 1U);781 EXPECT_EQ(loader.loaded_states_.size(), 1U);
514 782 
515 std::vector<char_t> modified_so_data = so_data;783 std::vector<char_t> modified_so_data = so_data;
@@ -517,7 +785,9 @@ TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_load_success_repeat_and_con
517 const auto modified_so_bin = BuildCustomOpSoBinForSt("libst_custom_loader_conflict.so", "st_vendor",785 const auto modified_so_bin = BuildCustomOpSoBinForSt("libst_custom_loader_conflict.so", "st_vendor",
518 modified_so_data);786 modified_so_data);
519 ASSERT_NE(modified_so_bin, nullptr);787 ASSERT_NE(modified_so_bin, nullptr);
520- EXPECT_NE(loader.LoadCustomOpSoBins({modified_so_bin}), SUCCESS);788+ std::vector<CustomOpSoHandlePtr> invalid_loaded_handles;
789+ EXPECT_NE(loader.LoadCustomOpSoBins({modified_so_bin}, invalid_loaded_handles), SUCCESS);
790+ EXPECT_TRUE(invalid_loaded_handles.empty());
521 EXPECT_EQ(loader.loaded_states_.size(), 1U);791 EXPECT_EQ(loader.loaded_states_.size(), 1U);
522 792 
523 loader.Cleanup();793 loader.Cleanup();
@@ -526,7 +796,9 @@ TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_load_success_repeat_and_con
526 796 
527TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_get_instance_and_empty_input_success) {797TEST_F(TestModelCustomOpsHelper, custom_op_so_loader_get_instance_and_empty_input_success) {
528 auto &loader = CustomOpSoLoader::GetInstance();798 auto &loader = CustomOpSoLoader::GetInstance();
529- EXPECT_EQ(loader.LoadCustomOpSoBins({}), SUCCESS);799+ std::vector<CustomOpSoHandlePtr> loaded_handles;
800+ EXPECT_EQ(loader.LoadCustomOpSoBins({}, loaded_handles), SUCCESS);
801+ EXPECT_TRUE(loaded_handles.empty());
530 loader.Cleanup();802 loader.Cleanup();
531}803}
532 804 
@@ -25,6 +25,7 @@
25#include "mmpa/mmpa_api.h"25#include "mmpa/mmpa_api.h"
26#include "securec.h"26#include "securec.h"
27#include "graph/operator_reg.h"27#include "graph/operator_reg.h"
28+#include "graph_metadef/graph/custom_op_factory.h"
28#include "graph/utils/op_desc_utils.h"29#include "graph/utils/op_desc_utils.h"
29#include "framework/common/ge_types.h"30#include "framework/common/ge_types.h"
30#include "stub/hostcpu_mmpa_stub.h"31#include "stub/hostcpu_mmpa_stub.h"
@@ -842,6 +843,7 @@ TEST_F(ModelHelperTest, SaveToOm_for_SplitAndUpgraded_Opp) {
842 ComputeGraphPtr root_graph = ge::MakeShared<ComputeGraph>("subgraph");843 ComputeGraphPtr root_graph = ge::MakeShared<ComputeGraph>("subgraph");
843 (void)AttrUtils::SetBool(root_graph, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, true);844 (void)AttrUtils::SetBool(root_graph, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, true);
844 ge_root_model->SetRootGraph(root_graph);845 ge_root_model->SetRootGraph(root_graph);
846+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
845 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);847 EXPECT_EQ(ge_root_model->CheckAndSetNeedSoInOM(), SUCCESS);
846 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x8000);848 EXPECT_EQ(ge_root_model->GetSoInOmFlag(), 0x8000);
847 849 
@@ -28,6 +28,7 @@
28#include "depends/runtime/src/runtime_stub.h"28#include "depends/runtime/src/runtime_stub.h"
29#include "ge_running_env/ge_running_env_faker.h"29#include "ge_running_env/ge_running_env_faker.h"
30#include "ge_running_env/fake_graph_optimizer.h"30#include "ge_running_env/fake_graph_optimizer.h"
31+#include "graph/custom_op_factory.h"
31#include "graph/utils/graph_utils_ex.h"32#include "graph/utils/graph_utils_ex.h"
32#include "graph/utils/op_desc_utils.h"33#include "graph/utils/op_desc_utils.h"
33#include "runtime/subscriber/global_dumper.h"34#include "runtime/subscriber/global_dumper.h"
@@ -480,6 +481,7 @@ Status OnlineInferDynamic(const ComputeGraphPtr &graph, const GeModelPtr &ge_mod
480 const DynamicAttribute &dynamic_callback, const bool sink_dynamic = false) {481 const DynamicAttribute &dynamic_callback, const bool sink_dynamic = false) {
481 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();482 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
482 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);483 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
484+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
483 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);485 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
484 486 
485 GraphId graph_id = 1001;487 GraphId graph_id = 1001;
@@ -1015,6 +1017,7 @@ TEST_F(OnlineInferTest, online_infer_dynamic_execute_invalide_input) {
1015 1017 
1016 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1018 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1017 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);1019 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
1020+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1018 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);1021 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
1019 1022 
1020 GraphId graph_id = 1001;1023 GraphId graph_id = 1001;
@@ -22,6 +22,7 @@
22#include "graph/op_desc.h"22#include "graph/op_desc.h"
23#include "ge/ut/ge/test_tools_task_info.h"23#include "ge/ut/ge/test_tools_task_info.h"
24#include "runtime/subscriber/global_profiler.h"24#include "runtime/subscriber/global_profiler.h"
25+#include "graph/custom_op_factory.h"
25 26 
26namespace ge {27namespace ge {
27class ProfilingStartNodeTest : public testing::Test {28class ProfilingStartNodeTest : public testing::Test {
@@ -176,6 +177,7 @@ TEST_F(ProfilingStartNodeTest, test_execute_graph_with_profiling_success) {
176 177 
177 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();178 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
178 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);179 EXPECT_EQ(ge_root_model->Initialize(graph), SUCCESS);
180+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
179 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);181 ge_root_model->SetSubgraphInstanceNameToModel(graph->GetName(), ge_model);
180 182 
181 GraphId graph_id = 1001;183 GraphId graph_id = 1001;
@@ -461,7 +461,9 @@ set(MULTI_PARTS_TEST_FILES
461 "common/platform_info_util_unittest.cc"461 "common/platform_info_util_unittest.cc"
462 "common/dnnengines_unittest.cc"462 "common/dnnengines_unittest.cc"
463 "common/engine_manage_unittest.cc"463 "common/engine_manage_unittest.cc"
464+ "common/helper/custom_op_registry_builder_unittest.cc"
464 "graph_ir/ge_custom_op_factory_unittest.cc"465 "graph_ir/ge_custom_op_factory_unittest.cc"
466+ "graph_ir/ge_custom_op_pull_registry_unittest.cc"
465 "graph_ir/ge_operator_factory_unittest.cc"467 "graph_ir/ge_operator_factory_unittest.cc"
466 "graph_ir/ge_ir_build_unittest.cc"468 "graph_ir/ge_ir_build_unittest.cc"
467 "graph/transop_util_unittest.cc"469 "graph/transop_util_unittest.cc"
@@ -669,6 +671,7 @@ target_link_libraries(ge_ut_common PRIVATE
669 671 
670target_link_libraries(ge_ut_common PUBLIC672target_link_libraries(ge_ut_common PUBLIC
671 ge_graph_dsl673 ge_graph_dsl
674+ custom_op_registry_static
672 ascendcl_stub)675 ascendcl_stub)
673 676 
674# ut binary677# ut binary
@@ -716,6 +719,7 @@ target_link_libraries(ut_libge_multiparts_utest
716 -Wl,-z,muldefs719 -Wl,-z,muldefs
717 symengine720 symengine
718 unified_dlog721 unified_dlog
722+ custom_op_registry_static
719 graph723 graph
720 graph_base724 graph_base
721 ge_executor_shared725 ge_executor_shared
@@ -19,6 +19,7 @@
19 19 
20#include "macro_utils/dt_public_scope.h"20#include "macro_utils/dt_public_scope.h"
21#include "common/model/ge_root_model.h"21#include "common/model/ge_root_model.h"
22+#include "graph/custom_op_factory.h"
22#include "ge_graph_dsl/graph_dsl.h"23#include "ge_graph_dsl/graph_dsl.h"
23#include "macro_utils/dt_public_unscope.h"24#include "macro_utils/dt_public_unscope.h"
24#include "common/op_tiling/op_tiling_rt2.h"25#include "common/op_tiling/op_tiling_rt2.h"
@@ -79,6 +80,7 @@ TEST_F(UtestGeRootModel, CheckSoInDynamicSuccsess) {
79 auto root_graph = std::make_shared<ComputeGraph>("root-graph");80 auto root_graph = std::make_shared<ComputeGraph>("root-graph");
80 auto root_model = std::make_shared<GeRootModel>();81 auto root_model = std::make_shared<GeRootModel>();
81 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);82 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);
83+ root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
82 84 
83 AttrUtils::SetBool(root_graph, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, true);85 AttrUtils::SetBool(root_graph, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, true);
84 86 
@@ -90,6 +92,7 @@ TEST_F(UtestGeRootModel, CheckSoInStaticSuccsess) {
90 auto root_graph = std::make_shared<ComputeGraph>("root-graph");92 auto root_graph = std::make_shared<ComputeGraph>("root-graph");
91 auto root_model = std::make_shared<GeRootModel>();93 auto root_model = std::make_shared<GeRootModel>();
92 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);94 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);
95+ root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
93 96 
94 OpDescPtr dy_op = std::make_shared<OpDesc>("padv4", "PadV4");97 OpDescPtr dy_op = std::make_shared<OpDesc>("padv4", "PadV4");
95 vector<int64_t> dims = {1, 2, 3, 4};98 vector<int64_t> dims = {1, 2, 3, 4};
@@ -123,6 +126,7 @@ TEST_F(UtestGeRootModel, CheckSoInSuccsessRetFalse) {
123 auto root_graph = std::make_shared<ComputeGraph>("root-graph");126 auto root_graph = std::make_shared<ComputeGraph>("root-graph");
124 auto root_model = std::make_shared<GeRootModel>();127 auto root_model = std::make_shared<GeRootModel>();
125 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);128 EXPECT_EQ(root_model->Initialize(root_graph), SUCCESS);
129+ root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
126 130 
127 OpDescPtr dy_op = std::make_shared<OpDesc>("padv4", "PadV4");131 OpDescPtr dy_op = std::make_shared<OpDesc>("padv4", "PadV4");
128 vector<int64_t> dims = {1, 2, 3, 4};132 vector<int64_t> dims = {1, 2, 3, 4};
@@ -0,0 +1,275 @@
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 <gtest/gtest.h>
12+ 
13+#include <algorithm>
14+#include <cstring>
15+#include <memory>
16+#include <string>
17+#include <vector>
18+ 
19+#include "common/helper/custom_op_so_loader.h"
20+#include "graph/custom_op_registry.h"
21+#define private public
22+#include "common/helper/custom_op_registry_builder.h"
23+#undef private
24+#include "depends/mmpa/src/mmpa_stub.h"
25+#include "framework/common/helper/model_helper.h"
26+#include "framework/common/framework_types_internal.h"
27+#include "graph/custom_op_factory.h"
28+#include "graph/custom_op_pull_registry.h"
29+#include "securec.h"
30+ 
31+namespace ge {
32+namespace {
33+constexpr const char *kSymbolAbiVersion = "GetRegisteredCustomOpCreatorAbiVersion";
34+constexpr const char *kSymbolCreatorNum = "GetRegisteredCustomOpCreatorNum";
35+constexpr const char *kSymbolCreators = "GetRegisteredCustomOpCreators";
36+constexpr const char *kBuilderOpA = "Task4BuilderOpA";
37+constexpr const char *kBuilderOpB = "Task4BuilderOpB";
38+constexpr const char *kPartitionOnlyOp = "Task4PartitionOnlyOp";
39+ 
40+struct FakeSoCreators {
41+ uint32_t abi_version = kCustomOpCreatorPullAbiVersion;
42+ std::vector<CustomOpTypeToCreator> creators;
43+};
44+ 
45+FakeSoCreators g_fake_so_a;
46+FakeSoCreators g_fake_so_b;
47+ 
48+class FakeSoHandleMmpaStub : public MmpaStubApiGe {
49+ public:
50+ int32_t DlClose(void *handle) override {
51+ if ((handle == reinterpret_cast<void *>(0xA001U)) || (handle == reinterpret_cast<void *>(0xB001U))) {
52+ return 0;
53+ }
54+ return MmpaStubApiGe::DlClose(handle);
55+ }
56+};
57+ 
58+class BuilderTestOpA : public BaseCustomOp {};
59+class BuilderTestOpB : public BaseCustomOp {};
60+ 
61+class BuilderPortableOp : public PortableOp {
62+ public:
63+ graphStatus Serialize(std::vector<uint8_t> &buffer) override {
64+ buffer.clear();
65+ return GRAPH_SUCCESS;
66+ }
67+ 
68+ graphStatus Deserialize(const std::vector<uint8_t> &buffer) override {
69+ deserialized_buffer = buffer;
70+ return GRAPH_SUCCESS;
71+ }
72+ 
73+ std::vector<uint8_t> deserialized_buffer;
74+};
75+ 
76+BaseCustomOp *CreateBuilderOpA() {
77+ return new BuilderTestOpA();
78+}
79+ 
80+BaseCustomOp *CreateBuilderOpB() {
81+ return new BuilderTestOpB();
82+}
83+ 
84+BaseCustomOp *CreateBuilderPortableOp() {
85+ return new BuilderPortableOp();
86+}
87+ 
88+uint32_t GetFakeAbiVersionA() {
89+ return g_fake_so_a.abi_version;
90+}
91+ 
92+uint32_t GetFakeAbiVersionB() {
93+ return g_fake_so_b.abi_version;
94+}
95+ 
96+size_t GetFakeCreatorNumA() {
97+ return g_fake_so_a.creators.size();
98+}
99+ 
100+size_t GetFakeCreatorNumB() {
101+ return g_fake_so_b.creators.size();
102+}
103+ 
104+int32_t CopyFakeCreators(const FakeSoCreators &fake_so, CustomOpTypeToCreator *creators,
105+ const size_t creator_num, const size_t creator_struct_size) {
106+ if ((creator_num < fake_so.creators.size()) || ((creator_num > 0U) && (creators == nullptr)) ||
107+ (creator_struct_size < sizeof(CustomOpTypeToCreator))) {
108+ return -1;
109+ }
110+ for (size_t i = 0U; i < fake_so.creators.size(); ++i) {
111+ auto *creator_addr = reinterpret_cast<uint8_t *>(creators) + (i * creator_struct_size);
112+ (void)memcpy_s(creator_addr, creator_struct_size, &fake_so.creators[i], sizeof(CustomOpTypeToCreator));
113+ }
114+ return 0;
115+}
116+ 
117+int32_t GetFakeCreatorsA(CustomOpTypeToCreator *creators, size_t creator_num, size_t creator_struct_size) {
118+ return CopyFakeCreators(g_fake_so_a, creators, creator_num, creator_struct_size);
119+}
120+ 
121+int32_t GetFakeCreatorsB(CustomOpTypeToCreator *creators, size_t creator_num, size_t creator_struct_size) {
122+ return CopyFakeCreators(g_fake_so_b, creators, creator_num, creator_struct_size);
123+}
124+ 
125+void *ResolveFakeSymbols(void *handle, const char *symbol) {
126+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolAbiVersion) == 0)) {
127+ return reinterpret_cast<void *>(&GetFakeAbiVersionA);
128+ }
129+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolCreatorNum) == 0)) {
130+ return reinterpret_cast<void *>(&GetFakeCreatorNumA);
131+ }
132+ if ((handle == reinterpret_cast<void *>(0xA001U)) && (std::strcmp(symbol, kSymbolCreators) == 0)) {
133+ return reinterpret_cast<void *>(&GetFakeCreatorsA);
134+ }
135+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolAbiVersion) == 0)) {
136+ return reinterpret_cast<void *>(&GetFakeAbiVersionB);
137+ }
138+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolCreatorNum) == 0)) {
139+ return reinterpret_cast<void *>(&GetFakeCreatorNumB);
140+ }
141+ if ((handle == reinterpret_cast<void *>(0xB001U)) && (std::strcmp(symbol, kSymbolCreators) == 0)) {
142+ return reinterpret_cast<void *>(&GetFakeCreatorsB);
143+ }
144+ return nullptr;
145+}
146+ 
147+void *ResolveMissingCreatorNum(void *handle, const char *symbol) {
148+ if (std::strcmp(symbol, kSymbolCreatorNum) == 0) {
149+ return nullptr;
150+ }
151+ return ResolveFakeSymbols(handle, symbol);
152+}
153+ 
154+CustomOpSoHandlePtr MakeFakeSoHandle(void *handle, const std::string &name) {
155+ return std::make_shared<CustomOpSoHandle>(name, handle, name, 0U, -1);
156+}
157+ 
158+CustomOpTypeToCreator MakeCreator(const char *op_type, const CustomOpCreateFunc creator) {
159+ return CustomOpTypeToCreator{sizeof(CustomOpTypeToCreator), op_type, creator};
160+}
161+ 
162+std::vector<uint8_t> BuildCustomOpPartition(const std::string &name, const std::vector<uint8_t> &bin) {
163+ CustomKernelItemHeader header{kCustomKernelItemMagic, static_cast<uint32_t>(name.size()),
164+ static_cast<uint32_t>(bin.size())};
165+ std::vector<uint8_t> payload(sizeof(header) + name.size() + bin.size(), 0U);
166+ (void)memcpy_s(payload.data(), payload.size(), &header, sizeof(header));
167+ (void)memcpy_s(payload.data() + sizeof(header), payload.size() - sizeof(header), name.data(), name.size());
168+ if (!bin.empty()) {
169+ (void)memcpy_s(payload.data() + sizeof(header) + name.size(),
170+ payload.size() - sizeof(header) - name.size(), bin.data(), bin.size());
171+ }
172+ return payload;
173+}
174+} // namespace
175+ 
176+class UtestCustomOpRegistryBuilder : public testing::Test {
177+ protected:
178+ void SetUp() override {
179+ g_fake_so_a = FakeSoCreators{};
180+ g_fake_so_b = FakeSoCreators{};
181+ MmpaStub::GetInstance().SetImpl(std::make_shared<FakeSoHandleMmpaStub>());
182+ }
183+ 
184+ void TearDown() override {
185+ g_fake_so_a = FakeSoCreators{};
186+ g_fake_so_b = FakeSoCreators{};
187+ MmpaStub::GetInstance().Reset();
188+ }
189+};
190+ 
191+TEST_F(UtestCustomOpRegistryBuilder, add_creators_from_so_handles_registers_valid_pull_creators) {
192+ g_fake_so_a.creators = {MakeCreator(kBuilderOpA, CreateBuilderOpA), MakeCreator(kBuilderOpB, CreateBuilderOpB)};
193+ auto registry = std::make_shared<CustomOpRegistry>();
194+ std::vector<CustomOpSoHandlePtr> so_handles = {MakeFakeSoHandle(reinterpret_cast<void *>(0xA001U), "fake_a")};
195+ 
196+ EXPECT_EQ(SUCCESS, CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbols));
197+ 
198+ EXPECT_TRUE(registry->HasCreator(kBuilderOpA));
199+ EXPECT_TRUE(registry->HasCreator(kBuilderOpB));
200+ EXPECT_NE(nullptr, dynamic_cast<BuilderTestOpA *>(registry->CreateOrGetCustomOp(kBuilderOpA)));
201+ EXPECT_NE(nullptr, dynamic_cast<BuilderTestOpB *>(registry->CreateOrGetCustomOp(kBuilderOpB)));
202+ registry.reset();
203+ so_handles.clear();
204+}
205+ 
206+TEST_F(UtestCustomOpRegistryBuilder, add_creators_from_so_handles_fails_when_required_symbol_missing) {
207+ g_fake_so_a.creators = {MakeCreator(kBuilderOpA, CreateBuilderOpA)};
208+ auto registry = std::make_shared<CustomOpRegistry>();
209+ std::vector<CustomOpSoHandlePtr> so_handles = {MakeFakeSoHandle(reinterpret_cast<void *>(0xA001U), "fake_a")};
210+ 
211+ EXPECT_NE(SUCCESS, CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveMissingCreatorNum));
212+ EXPECT_FALSE(registry->HasCreator(kBuilderOpA));
213+ so_handles.clear();
214+}
215+ 
216+TEST_F(UtestCustomOpRegistryBuilder, add_creators_from_so_handles_fails_on_abi_version_mismatch) {
217+ g_fake_so_a.abi_version = kCustomOpCreatorPullAbiVersion + 1U;
218+ g_fake_so_a.creators = {MakeCreator(kBuilderOpA, CreateBuilderOpA)};
219+ auto registry = std::make_shared<CustomOpRegistry>();
220+ std::vector<CustomOpSoHandlePtr> so_handles = {MakeFakeSoHandle(reinterpret_cast<void *>(0xA001U), "fake_a")};
221+ 
222+ EXPECT_NE(SUCCESS, CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbols));
223+ EXPECT_FALSE(registry->HasCreator(kBuilderOpA));
224+ so_handles.clear();
225+}
226+ 
227+TEST_F(UtestCustomOpRegistryBuilder, add_creators_from_so_handles_fails_on_invalid_creator_entry) {
228+ auto registry = std::make_shared<CustomOpRegistry>();
229+ const std::vector<CustomOpTypeToCreator> invalid_creators = {
230+ MakeCreator(nullptr, CreateBuilderOpA),
231+ MakeCreator("", CreateBuilderOpA),
232+ MakeCreator(kBuilderOpA, nullptr),
233+ CustomOpTypeToCreator{sizeof(CustomOpTypeToCreator) - 1U, kBuilderOpA, CreateBuilderOpA}};
234+ 
235+ for (const auto &invalid_creator : invalid_creators) {
236+ g_fake_so_a.creators = {invalid_creator};
237+ std::vector<CustomOpSoHandlePtr> so_handles = {MakeFakeSoHandle(reinterpret_cast<void *>(0xA001U), "fake_a")};
238+ EXPECT_NE(SUCCESS, CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbols));
239+ EXPECT_FALSE(registry->HasCreator(kBuilderOpA));
240+ so_handles.clear();
241+ }
242+}
243+ 
244+TEST_F(UtestCustomOpRegistryBuilder, add_creators_from_so_handles_fails_on_duplicate_op_type_across_so_handles) {
245+ g_fake_so_a.creators = {MakeCreator(kBuilderOpA, CreateBuilderOpA)};
246+ g_fake_so_b.creators = {MakeCreator(kBuilderOpA, CreateBuilderOpB)};
247+ auto registry = std::make_shared<CustomOpRegistry>();
248+ std::vector<CustomOpSoHandlePtr> so_handles = {
249+ MakeFakeSoHandle(reinterpret_cast<void *>(0xA001U), "fake_a"),
250+ MakeFakeSoHandle(reinterpret_cast<void *>(0xB001U), "fake_b")};
251+ 
252+ EXPECT_NE(SUCCESS, CustomOpRegistryBuilder::AddCreatorsFromSoHandles(so_handles, registry, ResolveFakeSymbols));
253+ EXPECT_FALSE(registry->HasCreator(kBuilderOpA));
254+ so_handles.clear();
255+}
256+ 
257+TEST_F(UtestCustomOpRegistryBuilder, load_custom_ops_to_registry_uses_given_registry_without_global_pollution) {
258+ const std::vector<uint8_t> serialized_bin = {0x21U, 0x22U, 0x23U};
259+ auto registry = std::make_shared<CustomOpRegistry>();
260+ ASSERT_EQ(GRAPH_SUCCESS,
261+ registry->RegisterCreator(
262+ kPartitionOnlyOp, []() -> std::unique_ptr<BaseCustomOp> {
263+ return std::unique_ptr<BaseCustomOp>(CreateBuilderPortableOp());
264+ }));
265+ ASSERT_FALSE(CustomOpFactory::IsExistOp(kPartitionOnlyOp));
266+ 
267+ const auto payload = BuildCustomOpPartition(kPartitionOnlyOp, serialized_bin);
268+ EXPECT_EQ(SUCCESS, LoadCustomOpsToRegistry(payload.data(), payload.size(), registry));
269+ 
270+ const auto *op = dynamic_cast<BuilderPortableOp *>(registry->FindCustomOp(kPartitionOnlyOp));
271+ ASSERT_NE(nullptr, op);
272+ EXPECT_EQ(serialized_bin, op->deserialized_buffer);
273+ EXPECT_FALSE(CustomOpFactory::IsExistOp(kPartitionOnlyOp));
274+}
275+} // namespace ge
@@ -30,6 +30,7 @@
30#include "hcom/hcom_topo_info.h"30#include "hcom/hcom_topo_info.h"
31#include "executor/ge_executor.h"31#include "executor/ge_executor.h"
32#include "graph_metadef/common/ge_common/util.h"32#include "graph_metadef/common/ge_common/util.h"
33+#include "graph/custom_op_factory.h"
33 34 
34using namespace std;35using namespace std;
35 36 
@@ -144,6 +145,7 @@ TEST_F(UtestModelExecutorTest, test_load_graph_sync) {
144 auto compute_graph = MakeShared<ComputeGraph>("test_graph");145 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
145 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();146 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
146 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);147 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
148+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
147 149 
148 GeModelPtr ge_model = MakeShared<GeModel>();150 GeModelPtr ge_model = MakeShared<GeModel>();
149 ge_model->SetGraph(compute_graph);151 ge_model->SetGraph(compute_graph);
@@ -175,6 +177,7 @@ TEST_F(UtestModelExecutorTest, test_load_graph_async) {
175 auto compute_graph = MakeShared<ComputeGraph>("test_graph");177 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
176 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();178 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
177 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);179 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
180+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
178 GeModelPtr ge_model = MakeShared<GeModel>();181 GeModelPtr ge_model = MakeShared<GeModel>();
179 ge_model->SetGraph(compute_graph);182 ge_model->SetGraph(compute_graph);
180 183 
@@ -205,6 +208,7 @@ TEST_F(UtestModelExecutorTest, test_recover_graph) {
205 auto compute_graph = MakeShared<ComputeGraph>("test_graph");208 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
206 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();209 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
207 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);210 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
211+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
208 212 
209 GeModelPtr ge_model = MakeShared<GeModel>();213 GeModelPtr ge_model = MakeShared<GeModel>();
210 ge_model->SetGraph(compute_graph);214 ge_model->SetGraph(compute_graph);
@@ -269,6 +273,7 @@ TEST_F(UtestModelExecutorTest, test_check_and_release_stream_success) {
269 auto compute_graph = MakeShared<ComputeGraph>(graph_name);273 auto compute_graph = MakeShared<ComputeGraph>(graph_name);
270 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();274 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
271 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);275 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
276+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
272 277 
273 GeModelPtr ge_model = MakeShared<GeModel>();278 GeModelPtr ge_model = MakeShared<GeModel>();
274 ge_model->SetGraph(compute_graph);279 ge_model->SetGraph(compute_graph);
@@ -327,6 +332,7 @@ TEST_F(UtestModelExecutorTest, test_check_and_release_stream_failed) {
327 auto compute_graph = MakeShared<ComputeGraph>(graph_name);332 auto compute_graph = MakeShared<ComputeGraph>(graph_name);
328 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();333 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
329 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);334 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
335+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
330 GeModelPtr ge_model = MakeShared<GeModel>();336 GeModelPtr ge_model = MakeShared<GeModel>();
331 ge_model->SetGraph(compute_graph);337 ge_model->SetGraph(compute_graph);
332 ge_root_model->SetSubgraphInstanceNameToModel(compute_graph->GetName(), ge_model);338 ge_root_model->SetSubgraphInstanceNameToModel(compute_graph->GetName(), ge_model);
@@ -383,6 +389,7 @@ TEST_F(UtestModelExecutorTest, test_check_and_release_event_success) {
383 auto compute_graph = MakeShared<ComputeGraph>(graph_name);389 auto compute_graph = MakeShared<ComputeGraph>(graph_name);
384 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();390 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
385 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);391 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
392+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
386 393 
387 GeModelPtr ge_model = MakeShared<GeModel>();394 GeModelPtr ge_model = MakeShared<GeModel>();
388 ge_model->SetGraph(compute_graph);395 ge_model->SetGraph(compute_graph);
@@ -460,6 +467,7 @@ TEST_F(UtestModelExecutorTest, test_check_and_release_event_failed) {
460 auto compute_graph = MakeShared<ComputeGraph>(graph_name);467 auto compute_graph = MakeShared<ComputeGraph>(graph_name);
461 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();468 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
462 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);469 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
470+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
463 471 
464 GeModelPtr ge_model = MakeShared<GeModel>();472 GeModelPtr ge_model = MakeShared<GeModel>();
465 ge_model->SetGraph(compute_graph);473 ge_model->SetGraph(compute_graph);
@@ -894,6 +902,7 @@ TEST_F(UtestModelExecutorTest, test_run_thread) {
894 auto compute_graph = MakeShared<ComputeGraph>("test_graph");902 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
895 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();903 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
896 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);904 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
905+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
897 906 
898 GeModelPtr ge_model = MakeShared<GeModel>();907 GeModelPtr ge_model = MakeShared<GeModel>();
899 ge_model->SetGraph(compute_graph);908 ge_model->SetGraph(compute_graph);
@@ -942,6 +951,7 @@ TEST_F(UtestModelExecutorTest, test_run_thread_2) {
942 auto compute_graph = MakeShared<ComputeGraph>("test_graph");951 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
943 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();952 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
944 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);953 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
954+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
945 955 
946 GeModelPtr ge_model = MakeShared<GeModel>();956 GeModelPtr ge_model = MakeShared<GeModel>();
947 ge_model->SetGraph(compute_graph);957 ge_model->SetGraph(compute_graph);
@@ -1182,6 +1192,7 @@ static void test_run_graph(ModelExecutor &model_executor) {
1182 auto compute_graph = MakeShared<ComputeGraph>("test_graph");1192 auto compute_graph = MakeShared<ComputeGraph>("test_graph");
1183 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();1193 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
1184 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);1194 EXPECT_EQ(ge_root_model->Initialize(compute_graph), SUCCESS);
1195+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
1185 GeModelPtr ge_model = MakeShared<GeModel>();1196 GeModelPtr ge_model = MakeShared<GeModel>();
1186 ge_model->SetGraph(compute_graph);1197 ge_model->SetGraph(compute_graph);
1187 shared_ptr<domi::ModelTaskDef> model_task_def = std::make_shared<domi::ModelTaskDef>();1198 shared_ptr<domi::ModelTaskDef> model_task_def = std::make_shared<domi::ModelTaskDef>();
@@ -23,6 +23,7 @@
23#include "depends/ascendcl/src/ascendcl_stub.h"23#include "depends/ascendcl/src/ascendcl_stub.h"
24#include "graph/custom_op.h"24#include "graph/custom_op.h"
25#include "graph/custom_op_factory.h"25#include "graph/custom_op_factory.h"
26+#include "graph/custom_op_registry.h"
26#include "exe_graph/runtime/kernel_args.h"27#include "exe_graph/runtime/kernel_args.h"
27#include "framework/runtime/args_handler.h"28#include "framework/runtime/args_handler.h"
28 29 
@@ -422,6 +423,10 @@ std::string GenerateUniqueOpType() {
422}423}
423 424 
424void SetUpMinimalDavinciModel(DavinciModel &model, const OpDescPtr &op_desc) {425void SetUpMinimalDavinciModel(DavinciModel &model, const OpDescPtr &op_desc) {
426+ if (model.GetCustomOpRegistry() == nullptr) {
427+ model.SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
428+ }
429+ 
425 // Set input shape {2, 3} so input tensor has verifiable origin shape430 // Set input shape {2, 3} so input tensor has verifiable origin shape
426 auto in_desc = op_desc->MutableInputDesc(0);431 auto in_desc = op_desc->MutableInputDesc(0);
427 if (in_desc != nullptr) {432 if (in_desc != nullptr) {
@@ -497,6 +502,29 @@ class TestNonEagerCustomOp : public BaseCustomOp {};
497 502 
498} // namespace503} // namespace
499 504 
505+TEST_F(UtestCustomTaskInfo, ParseTaskRunParam_UsesModelCustomOpRegistry) {
506+ const std::string op_type = GenerateUniqueOpType();
507+ auto registry = std::make_shared<CustomOpRegistry>();
508+ ASSERT_NE(registry, nullptr);
509+ ASSERT_EQ(registry->RegisterCreator(op_type.c_str(), []() -> std::unique_ptr<BaseCustomOp> {
510+ return std::make_unique<TestArgsUpdaterCustomOp>();
511+ }), GRAPH_SUCCESS);
512+ 
513+ DavinciModel model(0, nullptr);
514+ model.SetCustomOpRegistry(registry);
515+ const auto op_desc = CreateOpDesc(op_type, op_type, 1, 1);
516+ SetUpMinimalDavinciModel(model, op_desc);
517+ 
518+ domi::TaskDef task_def;
519+ task_def.set_type(static_cast<uint32_t>(ModelTaskType::MODEL_TASK_CUSTOM_KERNEL));
520+ task_def.mutable_kernel()->mutable_context()->set_op_index(op_desc->GetId());
521+ 
522+ CustomTaskInfo task_info;
523+ TaskRunParam task_run_param;
524+ EXPECT_EQ(task_info.ParseTaskRunParam(task_def, &model, task_run_param), SUCCESS);
525+ EXPECT_TRUE(task_info.NeedReserveArgsTable());
526+}
527+ 
500class UtestCustomTaskInfoE2E : public testing::Test {528class UtestCustomTaskInfoE2E : public testing::Test {
501 protected:529 protected:
502 void SetUp() {530 void SetUp() {
@@ -161,6 +161,18 @@ void TestNnExecute() {
161 dlog_setlevel(GE_MODULE_NAME, DLOG_ERROR, 0);161 dlog_setlevel(GE_MODULE_NAME, DLOG_ERROR, 0);
162}162}
163 163 
164+TEST(DavinciModelCustomOpRegistry, SetAndGetCustomOpRegistry) {
165+ DavinciModel model(0, nullptr);
166+ auto registry = MakeShared<CustomOpRegistry>();
167+ ASSERT_NE(registry, nullptr);
168+ 
169+ model.SetCustomOpRegistry(registry);
170+ EXPECT_EQ(model.GetCustomOpRegistry(), registry);
171+ 
172+ model.SetCustomOpRegistryRaw(registry.get());
173+ EXPECT_EQ(model.GetCustomOpRegistry().get(), registry.get());
174+}
175+ 
164void TestNnExecuteWithGertTensor() {176void TestNnExecuteWithGertTensor() {
165 DavinciModel model(0, nullptr);177 DavinciModel model(0, nullptr);
166 ComputeGraphPtr graph = MakeShared<ComputeGraph>("default");178 ComputeGraphPtr graph = MakeShared<ComputeGraph>("default");
@@ -11556,4 +11568,4 @@ TEST_F(UtestDavinciModel, UpdateStaticModelArgsByFm_ExecutesWhenHasQueueAttrs) {
11556 EXPECT_EQ(model.UpdateStaticModelArgsByFm(), SUCCESS);11568 EXPECT_EQ(model.UpdateStaticModelArgsByFm(), SUCCESS);
11557}11569}
11558 11570 
11559-} // namespace ge11571+} // namespace ge
@@ -33,6 +33,7 @@
33#include "graph/utils/op_desc_utils.h"33#include "graph/utils/op_desc_utils.h"
34#include "engine/aicore/fe_rt2_common.h"34#include "engine/aicore/fe_rt2_common.h"
35#include "graph/args_format_desc.h"35#include "graph/args_format_desc.h"
36+#include "graph/custom_op_factory.h"
36 37 
37#include "base/registry/op_impl_space_registry_v2.h"38#include "base/registry/op_impl_space_registry_v2.h"
38#include "common/opskernel/ops_kernel_info_types.h"39#include "common/opskernel/ops_kernel_info_types.h"
@@ -3490,6 +3491,7 @@ TEST_F(UtestFftsPlusTaskInfo, success_ffts_plus_profiling) {
3490 3491 
3491 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();3492 GeRootModelPtr ge_root_model = MakeShared<GeRootModel>();
3492 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);3493 EXPECT_EQ(ge_root_model->Initialize(root_graph), SUCCESS);
3494+ ge_root_model->SetCustomOpRegistry(CustomOpFactory::GetGlobalRegistryPtr());
3493 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);3495 ge_root_model->SetSubgraphInstanceNameToModel(root_graph->GetName(), ge_model);
3494 3496 
3495 GraphId graph_id = 1001;3497 GraphId graph_id = 1001;