已合并
ge support fx converter. #78
ge support fx converter. #78
已合并
gaoyong10创建于 19 天前
18 个文件变更+1192-405
@@ -299,6 +299,7 @@ Status SerializeModelMeta(const gert::Om2ModelData &model_data, const std::share
299 (void)model_meta_info.Set("dynamic_type", model_data.model_meta.dynamic_type);299 (void)model_meta_info.Set("dynamic_type", model_data.model_meta.dynamic_type);
300 (void)model_meta_info.Set("work_size", model_data.model_meta.work_size);300 (void)model_meta_info.Set("work_size", model_data.model_meta.work_size);
301 (void)model_meta_info.Set("zero_copy_size", model_data.model_meta.zero_copy_size);301 (void)model_meta_info.Set("zero_copy_size", model_data.model_meta.zero_copy_size);
302+ (void)model_meta_info.Set("reusable_notify_num", model_data.model_meta.reusable_notify_num);
302 (void)model_meta_info.Set("name", model_data.model_meta.model_name);303 (void)model_meta_info.Set("name", model_data.model_meta.model_name);
303 (void)model_meta_info.Set("root_graph_name", model_data.model_meta.root_graph_name);304 (void)model_meta_info.Set("root_graph_name", model_data.model_meta.root_graph_name);
304 305 
@@ -9,6 +9,8 @@
9 */9 */
10 10 
11#include <algorithm>11#include <algorithm>
12+#include <cstdlib>
13+#include <fstream>
12 14 
13#include "common/ge_common/string_util.h"15#include "common/ge_common/string_util.h"
14#include "framework/common/helper/om2_package_helper.h"16#include "framework/common/helper/om2_package_helper.h"
@@ -49,6 +51,22 @@ constexpr size_t kAippDimShapeIdx = 5U;
49constexpr int32_t kAippDecimalRadix = 10;51constexpr int32_t kAippDecimalRadix = 10;
50constexpr char_t const *kLegacySoSuffix = "_legacy.so";52constexpr char_t const *kLegacySoSuffix = "_legacy.so";
51 53 
54+void DumpDynamicCodegenArtifacts(const Om2CodegenArtifacts &artifacts) {
55+ const char *const dump_dir = std::getenv("OM2_DYNAMIC_DEBUG_DUMP_SOURCE_DIR");
56+ if ((dump_dir == nullptr) || (*dump_dir == '\0')) {
57+ return;
58+ }
59+ for (const auto &artifact : artifacts) {
60+ std::ofstream output(std::string(dump_dir) + "/" + artifact.file_name,
61+ std::ios::out | std::ios::binary | std::ios::trunc);
62+ if (!output.is_open()) {
63+ GELOGW("[OM2] Failed to dump dynamic codegen artifact %s", artifact.file_name.c_str());
64+ continue;
65+ }
66+ (void)output.write(artifact.data.data(), static_cast<std::streamsize>(artifact.data.size()));
67+ }
68+}
69+ 
52bool IsLegacySoName(const std::string &name) {70bool IsLegacySoName(const std::string &name) {
53 constexpr size_t suffix_size = sizeof("_legacy.so") - 1U;71 constexpr size_t suffix_size = sizeof("_legacy.so") - 1U;
54 return name.size() >= suffix_size && name.compare(name.size() - suffix_size, suffix_size, kLegacySoSuffix) == 0;72 return name.size() >= suffix_size && name.compare(name.size() - suffix_size, suffix_size, kLegacySoSuffix) == 0;
@@ -1065,11 +1083,16 @@ Status Om2PackageHelper::BuildKernelBinaries(const GeRootModelPtr &ge_root_model
1065Status Om2PackageHelper::BuildSoBinaries(const std::vector<OpSoBinPtr> &so_bins,1083Status Om2PackageHelper::BuildSoBinaries(const std::vector<OpSoBinPtr> &so_bins,
1066 std::vector<gert::Om2SoBinary> &so_binaries) {1084 std::vector<gert::Om2SoBinary> &so_binaries) {
1067 std::map<std::string, std::vector<uint8_t>> binaries_by_name;1085 std::map<std::string, std::vector<uint8_t>> binaries_by_name;
1086+ GELOGI("[OM2][SO_TRACE] count=%zu data=%p", so_bins.size(), so_bins.data());
1087+ size_t so_index = 0U;
1068 for (const auto &so_bin : so_bins) {1088 for (const auto &so_bin : so_bins) {
1089+ GELOGI("[OM2][SO_TRACE] index=%zu object=%p use_count=%ld", so_index, so_bin.get(), so_bin.use_count());
1069 GE_ASSERT_NOTNULL(so_bin, "[OM2] OpSoBin is nullptr");1090 GE_ASSERT_NOTNULL(so_bin, "[OM2] OpSoBin is nullptr");
1070 GE_ASSERT_TRUE(!so_bin->GetSoName().empty(), "[OM2] SO name is empty");1091 GE_ASSERT_TRUE(!so_bin->GetSoName().empty(), "[OM2] SO name is empty");
1071 const auto *const data = so_bin->GetBinData();1092 const auto *const data = so_bin->GetBinData();
1072 const size_t data_size = so_bin->GetBinDataSize();1093 const size_t data_size = so_bin->GetBinDataSize();
1094+ GELOGI("[OM2][SO_TRACE] index=%zu name=%s type=%u ptr=%p size=%zu", so_index,
1095+ so_bin->GetSoName().c_str(), static_cast<unsigned>(so_bin->GetSoBinType()), data, data_size);
1073 GE_ASSERT_TRUE((data != nullptr) && (data_size > 0U), "[OM2] SO binary is empty: %s",1096 GE_ASSERT_TRUE((data != nullptr) && (data_size > 0U), "[OM2] SO binary is empty: %s",
1074 so_bin->GetSoName().c_str());1097 so_bin->GetSoName().c_str());
1075 std::vector<uint8_t> binary(data, data + data_size);1098 std::vector<uint8_t> binary(data, data + data_size);
@@ -1080,6 +1103,7 @@ Status Om2PackageHelper::BuildSoBinaries(const std::vector<OpSoBinPtr> &so_bins,
1080 GE_ASSERT_TRUE(iter->second == binary, "[OM2] SO binary has conflicting content: %s",1103 GE_ASSERT_TRUE(iter->second == binary, "[OM2] SO binary has conflicting content: %s",
1081 so_bin->GetSoName().c_str());1104 so_bin->GetSoName().c_str());
1082 }1105 }
1106+ ++so_index;
1083 }1107 }
1084 1108 
1085 so_binaries.clear();1109 so_binaries.clear();
@@ -1235,6 +1259,10 @@ Status Om2PackageHelper::BuildModelMeta(const GeModelPtr &ge_model, gert::Om2Mod
1235 int64_t zero_copy_size = 0;1259 int64_t zero_copy_size = 0;
1236 (void)AttrUtils::GetInt(ge_model, ATTR_MODEL_ZERO_COPY_MEMORY_SIZE, zero_copy_size);1260 (void)AttrUtils::GetInt(ge_model, ATTR_MODEL_ZERO_COPY_MEMORY_SIZE, zero_copy_size);
1237 model_meta.zero_copy_size = zero_copy_size;1261 model_meta.zero_copy_size = zero_copy_size;
1262+ int64_t reusable_notify_num = 0;
1263+ (void)AttrUtils::GetInt(ge_model, ATTR_MODEL_NOTIFY_NUM, reusable_notify_num);
1264+ GE_ASSERT_TRUE(reusable_notify_num >= 0, "[OM2] Invalid reusable notify count: %ld", reusable_notify_num);
1265+ model_meta.reusable_notify_num = static_cast<size_t>(reusable_notify_num);
1238 model_meta.dynamic_batch_info = extra_info.dynamic_batch_info;1266 model_meta.dynamic_batch_info = extra_info.dynamic_batch_info;
1239 model_meta.dynamic_type = extra_info.dynamic_type;1267 model_meta.dynamic_type = extra_info.dynamic_type;
1240 model_meta.dynamic_output_shape = extra_info.dynamic_output_shape;1268 model_meta.dynamic_output_shape = extra_info.dynamic_output_shape;
@@ -1359,6 +1387,7 @@ Status Om2PackageHelper::BuildDynamicOm2ModelData(const GeRootModelPtr &ge_root_
1359 1387 
1360 const std::string model_name = root_model_iter->second->GetName();1388 const std::string model_name = root_model_iter->second->GetName();
1361 model_data.program_body.source_artifacts = result.program_body_artifacts;1389 model_data.program_body.source_artifacts = result.program_body_artifacts;
1390+ DumpDynamicCodegenArtifacts(model_data.program_body.source_artifacts);
1362 GE_ASSERT_SUCCESS(Om2Utils::CompileGeneratedCppToSo(model_data.program_body.source_artifacts,1391 GE_ASSERT_SUCCESS(Om2Utils::CompileGeneratedCppToSo(model_data.program_body.source_artifacts,
1363 model_name, model_data.program_body.so_artifact, false));1392 model_name, model_data.program_body.so_artifact, false));
1364 model_data.program_body.so_artifact.file_name = "lib" + model_name + "_program_body.so";1393 model_data.program_body.so_artifact.file_name = "lib" + model_name + "_program_body.so";
@@ -10,6 +10,8 @@
10 10 
11#include "chain_normalizer.h"11#include "chain_normalizer.h"
12 12 
13+#include <algorithm>
14+ 
13#include "common/checker.h"15#include "common/checker.h"
14#include "core/builder/equivalent_data_edges.h"16#include "core/builder/equivalent_data_edges.h"
15#include "core/builder/node_types.h"17#include "core/builder/node_types.h"
@@ -142,24 +144,23 @@ ge::graphStatus ChainNormalizer::Normalize(ge::ExecuteGraph &execute_graph, std:
142 GE_ASSERT_GRAPH_SUCCESS(AllocateChainIndices(execute_graph, chains));144 GE_ASSERT_GRAPH_SUCCESS(AllocateChainIndices(execute_graph, chains));
143 GE_ASSERT_GRAPH_SUCCESS(RecordChainSources(execute_graph.GetAllNodes(), chains));145 GE_ASSERT_GRAPH_SUCCESS(RecordChainSources(execute_graph.GetAllNodes(), chains));
144 for (const auto *const node : execute_graph.GetAllNodes()) {146 for (const auto *const node : execute_graph.GetAllNodes()) {
145- if (!IsConstType(node->GetTypePtr())) {147+ if ((node == nullptr) || !IsConstType(node->GetTypePtr())) {
146 continue;148 continue;
147 }149 }
148- std::vector<uint32_t> output_chain_indices;150+ for (size_t i = 0U; i < node->GetDataOutNum(); ++i) {
149- GE_ASSERT_GRAPH_SUCCESS(GetOutputChainIndices(*node, output_chain_indices));151+ uint32_t chain_index = 0U;
150- if (output_chain_indices.size() != 1U) {152+ GE_ASSERT_GRAPH_SUCCESS(GetChainIndex(*node, static_cast<uint32_t>(i), EndpointDirection::kOutput,
151- continue;153+ chain_index));
154+ const auto iter = const_producers_.find(chain_index);
155+ GE_ASSERT_TRUE(iter == const_producers_.cend() || iter->second == node,
156+ "OM2 chain %u has multiple Const producers", chain_index);
157+ const_producers_[chain_index] = node;
152 }158 }
153- const auto chain_index = output_chain_indices[0U];
154- const auto iter = const_producers_.find(chain_index);
155- GE_ASSERT_TRUE((iter == const_producers_.cend()) || (iter->second == node),
156- "OM2 chain %u has multiple Const producers", chain_index);
157- const_producers_[chain_index] = node;
158 }159 }
159 return ge::GRAPH_SUCCESS;160 return ge::GRAPH_SUCCESS;
160}161}
161 162 
162-const ge::FastNode *ChainNormalizer::GetConstProducer(const uint32_t chain_index) const {163+const ge::FastNode *ChainNormalizer::FindConstProducer(const uint32_t chain_index) const {
163 const auto iter = const_producers_.find(chain_index);164 const auto iter = const_producers_.find(chain_index);
164 return iter == const_producers_.cend() ? nullptr : iter->second;165 return iter == const_producers_.cend() ? nullptr : iter->second;
165}166}
@@ -205,6 +206,13 @@ ge::graphStatus ChainNormalizer::AllocateGraphChains(const std::vector<ge::FastN
205 206 
206ge::graphStatus ChainNormalizer::RecordChainSources(const std::vector<ge::FastNode *> &nodes,207ge::graphStatus ChainNormalizer::RecordChainSources(const std::vector<ge::FastNode *> &nodes,
207 std::vector<ChainInfo> &chains) const {208 std::vector<ChainInfo> &chains) const {
209+ // Legacy GE graphs use OutputData itself as the model-output marker. FXRT
210+ // graphs add an explicit Output/NetOutput node and use OutputData as tensor
211+ // shells. Select the convention per graph to preserve both routes.
212+ const bool has_explicit_model_output = std::any_of(
213+ nodes.cbegin(), nodes.cend(), [](const ge::FastNode *node) {
214+ return (node != nullptr) && (IsOutputType(node->GetTypePtr()) || IsTypeNetOutput(node->GetTypePtr()));
215+ });
208 for (const auto *const node : nodes) {216 for (const auto *const node : nodes) {
209 GE_ASSERT_NOTNULL(node);217 GE_ASSERT_NOTNULL(node);
210 const auto *const op_desc = node->GetOpDescBarePtr();218 const auto *const op_desc = node->GetOpDescBarePtr();
@@ -232,16 +240,30 @@ ge::graphStatus ChainNormalizer::RecordChainSources(const std::vector<ge::FastNo
232 binding_phase = GetConstDataBindingPhase(source_index);240 binding_phase = GetConstDataBindingPhase(source_index);
233 binding_kind = GetConstDataBindingKind(source_index);241 binding_kind = GetConstDataBindingKind(source_index);
234 } else if (IsTypeOutputData(node->GetTypePtr())) {242 } else if (IsTypeOutputData(node->GetTypePtr())) {
235- source_kind = ChainSourceKind::kModelOutput;243+ // OutputData is also used as a shell for intermediate tensors by FXRT.
244+ // The model-output ownership and port index are recorded from NetOutput
245+ // below, so every OutputData output starts as an ordinary kernel output.
246+ source_kind = has_explicit_model_output ? ChainSourceKind::kKernelOutput : ChainSourceKind::kModelOutput;
247+ } else if (IsOutputType(node->GetTypePtr()) || IsTypeNetOutput(node->GetTypePtr())) {
248+ // A NetOutput input position is the authoritative model-output port.
249+ // Do not infer it from OutputData's local output index: intermediate
250+ // OutputData shells commonly have one output and would all become index 0.
251+ for (size_t i = 0U; i < node->GetDataInNum(); ++i) {
252+ uint32_t chain_index = 0U;
253+ GE_ASSERT_GRAPH_SUCCESS(
254+ GetChainIndex(*node, static_cast<uint32_t>(i), EndpointDirection::kInput, chain_index));
255+ GE_ASSERT_GRAPH_SUCCESS(UpdateChainSource(chains[chain_index], ChainSourceKind::kModelOutput,
256+ static_cast<int64_t>(i), ChainBindingPhase::kRun,
257+ ChainBindingKind::kNone));
258+ }
259+ continue;
236 }260 }
237 for (size_t i = 0U; i < node->GetDataOutNum(); ++i) {261 for (size_t i = 0U; i < node->GetDataOutNum(); ++i) {
238 uint32_t chain_index = 0U;262 uint32_t chain_index = 0U;
239 GE_ASSERT_GRAPH_SUCCESS(GetChainIndex(*node, static_cast<uint32_t>(i), EndpointDirection::kOutput,263 GE_ASSERT_GRAPH_SUCCESS(GetChainIndex(*node, static_cast<uint32_t>(i), EndpointDirection::kOutput,
240 chain_index));264 chain_index));
241 auto &chain = chains[chain_index];265 auto &chain = chains[chain_index];
242- const auto output_source_index = IsTypeOutputData(node->GetTypePtr()) ? static_cast<int64_t>(i) : source_index;266+ GE_ASSERT_GRAPH_SUCCESS(UpdateChainSource(chain, source_kind, source_index, binding_phase, binding_kind));
243- GE_ASSERT_GRAPH_SUCCESS(
244- UpdateChainSource(chain, source_kind, output_source_index, binding_phase, binding_kind));
245 }267 }
246 }268 }
247 return ge::GRAPH_SUCCESS;269 return ge::GRAPH_SUCCESS;
@@ -25,7 +25,10 @@ class ChainNormalizer {
25 ge::graphStatus Normalize(ge::ExecuteGraph &execute_graph, std::vector<ChainInfo> &chains);25 ge::graphStatus Normalize(ge::ExecuteGraph &execute_graph, std::vector<ChainInfo> &chains);
26 ge::graphStatus GetInputChainIndices(const ge::FastNode &node, std::vector<uint32_t> &indices) const;26 ge::graphStatus GetInputChainIndices(const ge::FastNode &node, std::vector<uint32_t> &indices) const;
27 ge::graphStatus GetOutputChainIndices(const ge::FastNode &node, std::vector<uint32_t> &indices) const;27 ge::graphStatus GetOutputChainIndices(const ge::FastNode &node, std::vector<uint32_t> &indices) const;
28- const ge::FastNode *GetConstProducer(uint32_t chain_index) const;28+ // CEM may replace a Const edge with an InnerData edge when a lifecycle constant is
29+ // exported from Init into Main. Preserve the original Const producer so collectors
30+ // can materialize the process-local value without depending on graph plumbing.
31+ const ge::FastNode *FindConstProducer(uint32_t chain_index) const;
29 32 
30 private:33 private:
31 enum class EndpointDirection : uint64_t { kInput = 0U, kOutput = 1U };34 enum class EndpointDirection : uint64_t { kInput = 0U, kOutput = 1U };
Mbase/common/om2/dynamic_codegen/info_collect/const_value_collector.cc+320-81文件内容审核中,请稍后刷新重试
@@ -197,39 +197,21 @@ struct ExecutionPlanCollector::CanonicalIfAnalysis {
197};197};
198 198 
199ge::graphStatus ExecutionPlanCollector::Collect(ge::ExecuteGraph &execute_graph,199ge::graphStatus ExecutionPlanCollector::Collect(ge::ExecuteGraph &execute_graph,
200- const ChainNormalizer &chain_normalizer,200+ const ChainNormalizer &chain_normalizer,
201- const ProgramPlanType plan_type, ProgramBlock &program_block) const {201+ const ProgramPlanType plan_type, ProgramBlock &program_block) const {
202 program_block = {};202 program_block = {};
203 program_block.plan_type = plan_type;203 program_block.plan_type = plan_type;
204 program_block.root_region_index = 0U;204 program_block.root_region_index = 0U;
205 program_block.regions.push_back({0U, execute_graph.GetName(), {}});205 program_block.regions.push_back({0U, execute_graph.GetName(), {}});
206- ge::graphStatus ret = ge::GRAPH_SUCCESS;
207 switch (plan_type) {206 switch (plan_type) {
208 case ProgramPlanType::kSequential:207 case ProgramPlanType::kSequential:
209- ret = CollectSequential(execute_graph, chain_normalizer, program_block);208+ return CollectSequential(execute_graph, chain_normalizer, program_block);
210- break;
211 case ProgramPlanType::kStructuredTopological:209 case ProgramPlanType::kStructuredTopological:
212 case ProgramPlanType::kStructuredTopologicalPriority:210 case ProgramPlanType::kStructuredTopologicalPriority:
213- ret = CollectRegion(execute_graph, chain_normalizer, 0U, program_block);211+ return CollectRegion(execute_graph, chain_normalizer, 0U, program_block);
214- break;
215- default:
216- GELOGE(ge::GRAPH_FAILED, "Unknown OM2 plan type for graph %s", execute_graph.GetName().c_str());
217- return ge::GRAPH_FAILED;
218 }212 }
219- if (ret != ge::GRAPH_SUCCESS) {213+ GELOGE(ge::GRAPH_FAILED, "Unknown OM2 plan type for graph %s", execute_graph.GetName().c_str());
220- return ret;214+ return ge::GRAPH_FAILED;
221- }
222- std::map<std::string, size_t> kernel_counts;
223- for (const auto &kernel : program_block.kernels) {
224- ++kernel_counts[kernel.kernel_type];
225- }
226- GELOGI("OM2 kernel collection finished: graph=%s, total=%zu", execute_graph.GetName().c_str(),
227- program_block.kernels.size());
228- for (const auto &kernel_count : kernel_counts) {
229- GELOGI("OM2 kernel collection summary: graph=%s, type=%s, count=%zu", execute_graph.GetName().c_str(),
230- kernel_count.first.c_str(), kernel_count.second);
231- }
232- return ge::GRAPH_SUCCESS;
233}215}
234 216 
235ge::graphStatus ExecutionPlanCollector::CollectSequential(ge::ExecuteGraph &execute_graph,217ge::graphStatus ExecutionPlanCollector::CollectSequential(ge::ExecuteGraph &execute_graph,
@@ -275,47 +257,29 @@ ge::graphStatus ExecutionPlanCollector::CollectKernel(const ge::FastNode &node,
275 chain.Set(nullptr, nullptr);257 chain.Set(nullptr, nullptr);
276 }258 }
277 });259 });
278- const auto get_const_producer = [&node, &chain_normalizer,260+ const auto materialize_input = [&node, &input_chains, &chain_normalizer, &input_chain_indices](
279- &input_chain_indices](const uint32_t input_index) -> const ge::FastNode * {261+ const uint32_t input_index) -> ge::graphStatus {
262+ GE_ASSERT_TRUE(input_index < node.GetDataInNum());
280 const ge::FastEdge *producer_edge = nullptr;263 const ge::FastEdge *producer_edge = nullptr;
281 for (const auto *const edge : node.GetAllInDataEdgesRef()) {264 for (const auto *const edge : node.GetAllInDataEdgesRef()) {
282 if ((edge != nullptr) && (edge->dst_input == static_cast<int32_t>(input_index))) {265 if ((edge != nullptr) && (edge->dst_input == static_cast<int32_t>(input_index))) {
283- if (producer_edge != nullptr) {266+ GE_ASSERT_TRUE(producer_edge == nullptr, "OM2 kernel %s input %u has multiple producers",
284- GELOGE(ge::GRAPH_PARAM_INVALID, "OM2 kernel %s input %u has multiple producers", node.GetNamePtr(),267+ node.GetNamePtr(), input_index);
285- input_index);
286- return nullptr;
287- }
288 producer_edge = edge;268 producer_edge = edge;
289 }269 }
290 }270 }
291- if (producer_edge == nullptr) {271+ GE_ASSERT_NOTNULL(producer_edge, "OM2 kernel %s input %u has no producer", node.GetNamePtr(), input_index);
292- GELOGE(ge::GRAPH_PARAM_INVALID, "OM2 kernel %s input %u has no producer", node.GetNamePtr(), input_index);272+ const ge::FastNode *producer = producer_edge->src;
293- return nullptr;273+ int32_t producer_output = producer_edge->src_output;
274+ if (!IsConstType(producer->GetTypePtr())) {
275+ producer = chain_normalizer.FindConstProducer(input_chain_indices[input_index]);
276+ producer_output = 0;
294 }277 }
295- const auto *const direct_producer = producer_edge->src;278+ GE_ASSERT_NOTNULL(producer, "OM2 kernel %s input %u has no Const producer", node.GetNamePtr(), input_index);
296- if (IsConstType(direct_producer->GetTypePtr())) {279+ GE_ASSERT_TRUE(IsConstType(producer->GetTypePtr()),
297- return direct_producer;280+ "OM2 kernel %s input %u must be driven by Const", node.GetNamePtr(), input_index);
298- }281+ GE_ASSERT_TRUE((producer_output == 0) && (producer->GetDataOutNum() == 1U),
299- const auto *const const_producer = chain_normalizer.GetConstProducer(input_chain_indices[input_index]);282+ "OM2 Const producer %s has invalid output index %d", producer->GetNamePtr(), producer_output);
300- if (const_producer != nullptr) {
301- GELOGI("OM2 kernel %s input %u resolves Const producer %s through producer=%s type=%s", node.GetNamePtr(),
302- input_index, const_producer->GetNamePtr(), direct_producer->GetNamePtr(), direct_producer->GetTypePtr());
303- return const_producer;
304- }
305- GELOGE(ge::GRAPH_PARAM_INVALID,
306- "OM2 kernel %s input %u must be driven by Const, producer=%s type=%s", node.GetNamePtr(), input_index,
307- direct_producer->GetNamePtr(), direct_producer->GetTypePtr());
308- return nullptr;
309- };
310- const auto materialize_input = [&node, &input_chains, &get_const_producer](const uint32_t input_index)
311- -> ge::graphStatus {
312- GE_ASSERT_TRUE(input_index < node.GetDataInNum());
313- const auto *const producer = get_const_producer(input_index);
314- GE_ASSERT_NOTNULL(producer);
315- const auto *const producer_edge = node.GetInDataEdgeByIndex(static_cast<int32_t>(input_index));
316- GE_ASSERT_NOTNULL(producer_edge);
317- GE_ASSERT_TRUE((producer_edge->src_output == 0) && (producer->GetDataOutNum() == 1U),
318- "OM2 Const producer %s has invalid output index %d", producer->GetNamePtr(), producer_edge->src_output);
319 return MaterializeConstOutput(*producer, input_chains[input_index]);283 return MaterializeConstOutput(*producer, input_chains[input_index]);
320 };284 };
321 const auto ordinary_restore_input_indices = builder->GetRestoreConstInputIndices();285 const auto ordinary_restore_input_indices = builder->GetRestoreConstInputIndices();
@@ -378,9 +342,9 @@ ge::graphStatus ExecutionPlanCollector::CollectKernel(const ge::FastNode &node,
378 }342 }
379 }343 }
380 GE_ASSERT_NOTNULL(producer_edge);344 GE_ASSERT_NOTNULL(producer_edge);
381- const auto *const const_producer = get_const_producer(resolved_index);345+ const auto *const const_producer = chain_normalizer.FindConstProducer(input_chain_indices[resolved_index]);
382- GE_ASSERT_NOTNULL(const_producer);346+ descriptor.producer_name = const_producer == nullptr ? producer_edge->src->GetNamePtr()
383- descriptor.producer_name = const_producer->GetNamePtr();347+ : const_producer->GetNamePtr();
384 GE_ASSERT_TRUE(!descriptor.initializer.empty(), "OM2 kernel %s custom const input %u has no initializer",348 GE_ASSERT_TRUE(!descriptor.initializer.empty(), "OM2 kernel %s custom const input %u has no initializer",
385 node.GetNamePtr(), resolved_index);349 node.GetNamePtr(), resolved_index);
386 GE_ASSERT_TRUE(!descriptor.payload.empty(), "OM2 kernel %s custom const input %u has no payload",350 GE_ASSERT_TRUE(!descriptor.payload.empty(), "OM2 kernel %s custom const input %u has no payload",
@@ -407,8 +371,6 @@ ge::graphStatus ExecutionPlanCollector::CollectKernel(const ge::FastNode &node,
407 }371 }
408 kernel_index = static_cast<uint32_t>(program_block.kernels.size());372 kernel_index = static_cast<uint32_t>(program_block.kernels.size());
409 program_block.kernels.emplace_back(std::move(kernel_info));373 program_block.kernels.emplace_back(std::move(kernel_info));
410- GELOGI("OM2 collected kernel[%u]: name=%s, type=%s, total=%zu", kernel_index, node.GetNamePtr(),
411- node.GetTypePtr(), program_block.kernels.size());
412 return ge::GRAPH_SUCCESS;374 return ge::GRAPH_SUCCESS;
413}375}
414 376 
@@ -25,6 +25,10 @@ class BuildTensorKernelCodeBuilder : public KernelCodeBuilder {
25 {"tensor_attr", Om2ValueType::kGertBuildTensorAttrPtr}}, info));25 {"tensor_attr", Om2ValueType::kGertBuildTensorAttrPtr}}, info));
26 return SetOutputPortNames(context, {"tensor"}, info);26 return SetOutputPortNames(context, {"tensor"}, info);
27 }27 }
28+ 
29+ std::vector<uint32_t> GetRestoreConstInputIndices() const override {
30+ return {2U};
31+ }
28};32};
29REGISTER_KERNEL_CODE_BUILDER("BuildTensor", BuildTensorKernelCodeBuilder);33REGISTER_KERNEL_CODE_BUILDER("BuildTensor", BuildTensorKernelCodeBuilder);
30 34 
@@ -48,10 +48,10 @@ bool IsSupportedBinding(const ChainBindingKind binding_kind) {
48 case ChainBindingKind::kSpaceRegistry:48 case ChainBindingKind::kSpaceRegistry:
49 case ChainBindingKind::kBinary:49 case ChainBindingKind::kBinary:
50 case ChainBindingKind::kOuterWeightMem:50 case ChainBindingKind::kOuterWeightMem:
51+ case ChainBindingKind::kNotifies:
51 return true;52 return true;
52 case ChainBindingKind::kNone:53 case ChainBindingKind::kNone:
53 case ChainBindingKind::kRuntimeEvents:54 case ChainBindingKind::kRuntimeEvents:
54- case ChainBindingKind::kNotifies:
55 case ChainBindingKind::kRtSession:55 case ChainBindingKind::kRtSession:
56 return false;56 return false;
57 }57 }
Mbase/common/om2/dynamic_codegen/lowering/om2_model.h+3-0文件内容审核中,请稍后刷新重试
@@ -19,13 +19,10 @@
19 19 
20namespace gert {20namespace gert {
21namespace om2 {21namespace om2 {
22-Om2ModelPtr Om2Generator::Lower(const ge::GeRootModelPtr &root_model) const {22+namespace {
23- return Om2CompileLowering().Lower(root_model);23+Om2GenerationResult GenerateFromModel(const Om2ModelPtr &model, const std::string &model_name) {
24-}24+ if (model == nullptr || model->GetExecuteGraph() == nullptr) {
25- 25+ GELOGE(ge::GRAPH_PARAM_INVALID, "Failed to generate OM2 from an empty model");
26-Om2GenerationResult Om2Generator::Generate(const ge::GeRootModelPtr &root_model) const {
27- auto model = Lower(root_model);
28- if (model == nullptr) {
29 return {};26 return {};
30 }27 }
31 ProgramInfo program_info;28 ProgramInfo program_info;
@@ -34,13 +31,7 @@ Om2GenerationResult Om2Generator::Generate(const ge::GeRootModelPtr &root_model)
34 }31 }
35 ProgramBodyCodegenResult program_body_result;32 ProgramBodyCodegenResult program_body_result;
36 ProgramBodyCodegenOption program_body_option;33 ProgramBodyCodegenOption program_body_option;
37- program_body_option.model_name = root_model->GetModelName();34+ program_body_option.model_name = model_name.empty() ? "om2_dynamic" : model_name;
38- if (program_body_option.model_name.empty() && (root_model->GetRootGraph() != nullptr)) {
39- program_body_option.model_name = root_model->GetRootGraph()->GetName();
40- }
41- if (program_body_option.model_name.empty()) {
42- program_body_option.model_name = "om2_dynamic";
43- }
44 program_body_option.interface_file_name = program_body_option.model_name + "_interface.h";35 program_body_option.interface_file_name = program_body_option.model_name + "_interface.h";
45 program_body_option.source_file_name = program_body_option.model_name + "_program_body.cpp";36 program_body_option.source_file_name = program_body_option.model_name + "_program_body.cpp";
46 program_body_option.makefile_file_name = "Makefile";37 program_body_option.makefile_file_name = "Makefile";
@@ -51,5 +42,31 @@ Om2GenerationResult Om2Generator::Generate(const ge::GeRootModelPtr &root_model)
51 ge::DumpGraph(model->GetExecuteGraph().get(), "ExecuteGraphAfterProgramInfoCollect");42 ge::DumpGraph(model->GetExecuteGraph().get(), "ExecuteGraphAfterProgramInfoCollect");
52 return {std::move(program_body_result.artifacts)};43 return {std::move(program_body_result.artifacts)};
53}44}
45+} // namespace
46+ 
47+Om2ModelPtr Om2Generator::Lower(const ge::GeRootModelPtr &root_model) const {
48+ return Om2CompileLowering().Lower(root_model);
49+}
50+ 
51+Om2GenerationResult Om2Generator::Generate(const ge::GeRootModelPtr &root_model) const {
52+ auto model = Lower(root_model);
53+ std::string model_name;
54+ if (root_model != nullptr) {
55+ model_name = root_model->GetModelName();
56+ if (model_name.empty() && (root_model->GetRootGraph() != nullptr)) {
57+ model_name = root_model->GetRootGraph()->GetName();
58+ }
59+ }
60+ return GenerateFromModel(model, model_name);
61+}
62+ 
63+Om2GenerationResult Om2Generator::GenerateFromExecuteGraph(const ge::ExecuteGraphPtr &execute_graph,
64+ const std::string &model_name) const {
65+ if (execute_graph == nullptr) {
66+ GELOGE(ge::GRAPH_PARAM_INVALID, "Failed to generate OM2 from a null ExecuteGraph");
67+ return {};
68+ }
69+ return GenerateFromModel(std::make_shared<Om2Model>(execute_graph), model_name);
70+}
54} // namespace om271} // namespace om2
55} // namespace gert72} // namespace gert
@@ -14,6 +14,7 @@
14#include "common/model/ge_root_model.h"14#include "common/model/ge_root_model.h"
15#include "common/om2/codegen/om2_codegen_types.h"15#include "common/om2/codegen/om2_codegen_types.h"
16#include "common/om2/dynamic_codegen/lowering/om2_compile_lowering.h"16#include "common/om2/dynamic_codegen/lowering/om2_compile_lowering.h"
17+#include "graph/fast_graph/execute_graph.h"
17 18 
18namespace gert {19namespace gert {
19namespace om2 {20namespace om2 {
@@ -25,6 +26,8 @@ class Om2Generator {
25 public:26 public:
26 Om2ModelPtr Lower(const ge::GeRootModelPtr &root_model) const;27 Om2ModelPtr Lower(const ge::GeRootModelPtr &root_model) const;
27 Om2GenerationResult Generate(const ge::GeRootModelPtr &root_model) const;28 Om2GenerationResult Generate(const ge::GeRootModelPtr &root_model) const;
29+ Om2GenerationResult GenerateFromExecuteGraph(const ge::ExecuteGraphPtr &execute_graph,
30+ const std::string &model_name) const;
28};31};
29} // namespace om232} // namespace om2
30} // namespace gert33} // namespace gert
Mbase/common/om2/dynamic_codegen/program_body_codegen.cc+543-193文件内容审核中,请稍后刷新重试
@@ -58,6 +58,7 @@ struct Om2ModelMeta {
58 std::string root_graph_name;58 std::string root_graph_name;
59 size_t work_size = 0U;59 size_t work_size = 0U;
60 int64_t zero_copy_size = 0;60 int64_t zero_copy_size = 0;
61+ size_t reusable_notify_num = 0U;
61 std::vector<ge::Om2TensorDesc> input_desc;62 std::vector<ge::Om2TensorDesc> input_desc;
62 std::vector<ge::Om2TensorDesc> output_desc;63 std::vector<ge::Om2TensorDesc> output_desc;
63 std::vector<ge::Om2TensorDesc> input_desc_v2;64 std::vector<ge::Om2TensorDesc> input_desc_v2;
@@ -40,6 +40,7 @@ enum class AttrDataType {
40 BOOL,40 BOOL,
41 STRING,41 STRING,
42 INT32,42 INT32,
43+ INT64,
43 UINT32,44 UINT32,
44 FLOAT32,45 FLOAT32,
45 FLOAT16,46 FLOAT16,
@@ -58,6 +59,7 @@ static const std::map<std::string, AttrDataType> kAttrDataTypeMap{{"bool", AttrD
58 {"string", AttrDataType::STRING},59 {"string", AttrDataType::STRING},
59 {"int", AttrDataType::INT32},60 {"int", AttrDataType::INT32},
60 {"int32", AttrDataType::INT32},61 {"int32", AttrDataType::INT32},
62+ {"int64", AttrDataType::INT64},
61 {"uint", AttrDataType::UINT32},63 {"uint", AttrDataType::UINT32},
62 {"uint32", AttrDataType::UINT32},64 {"uint32", AttrDataType::UINT32},
63 {"float", AttrDataType::FLOAT32},65 {"float", AttrDataType::FLOAT32},
@@ -77,7 +79,7 @@ static const std::vector<AttrDataType> kValidSrcDTypeList{AttrDataType::BOOL,
77 AttrDataType::LIST_INT32, AttrDataType::LIST_FLOAT32};79 AttrDataType::LIST_INT32, AttrDataType::LIST_FLOAT32};
78 80 
79static const std::vector<AttrDataType> kValidDstDTypeList{81static const std::vector<AttrDataType> kValidDstDTypeList{
80- AttrDataType::UINT32, AttrDataType::INT32, AttrDataType::FLOAT32,82+ AttrDataType::UINT32, AttrDataType::INT32, AttrDataType::INT64, AttrDataType::FLOAT32,
81 AttrDataType::FLOAT16, AttrDataType::BFLOAT16, AttrDataType::LIST_INT32,83 AttrDataType::FLOAT16, AttrDataType::BFLOAT16, AttrDataType::LIST_INT32,
82 AttrDataType::LIST_UINT32, AttrDataType::LIST_FLOAT16, AttrDataType::LIST_FLOAT32};84 AttrDataType::LIST_UINT32, AttrDataType::LIST_FLOAT16, AttrDataType::LIST_FLOAT32};
83 85 
@@ -266,6 +268,24 @@ class AttrDataManager {
266 return attr_data_ptr;268 return attr_data_ptr;
267 }269 }
268 270 
271+ AttrDataPtr GetFloatAttrValueAndToInt64(const ge::Operator &op, const char *attr_name) const {
272+ float attr_value = 0.0F;
273+ if (op.GetAttr(attr_name, attr_value) != ge::GRAPH_SUCCESS) {
274+ GELOGW("Failed to retrieve attribute [%s] from op.", attr_name);
275+ return nullptr;
276+ }
277+ 
278+ // Dynamic TBE metadata uses int64 as the transport type for scalar attrs
279+ // on int64 kernels. The attr itself remains a schema-level float; the
280+ // tiling ABI consumes the numeric converted value.
281+ std::vector<int64_t> attr_vec;
282+ attr_vec.push_back(static_cast<int64_t>(attr_value));
283+ 
284+ AttrDataPtr attr_data_ptr = nullptr;
285+ OP_TILING_MAKE_SHARED(attr_data_ptr = std::make_shared<AttrDataImpl<int64_t>>(attr_vec), return nullptr);
286+ return attr_data_ptr;
287+ }
288+ 
269 AttrDataPtr GetListFloatAttrValueAndToListFp16(const ge::Operator &op, const char *attr_name) const {289 AttrDataPtr GetListFloatAttrValueAndToListFp16(const ge::Operator &op, const char *attr_name) const {
270 std::vector<float> attr_value;290 std::vector<float> attr_value;
271 if (op.GetAttr(attr_name, attr_value) != ge::GRAPH_SUCCESS) {291 if (op.GetAttr(attr_name, attr_value) != ge::GRAPH_SUCCESS) {
@@ -328,6 +348,7 @@ const std::map<uint32_t, GetOpAttrValueFunc> AttrDataManager::attr_func_ = {
328 {GenerateAttrFuncKey(AttrDataType::LIST_FLOAT32, AttrDataType::LIST_FLOAT16),348 {GenerateAttrFuncKey(AttrDataType::LIST_FLOAT32, AttrDataType::LIST_FLOAT16),
329 &AttrDataManager::GetListFloatAttrValueAndToListFp16},349 &AttrDataManager::GetListFloatAttrValueAndToListFp16},
330 {GenerateAttrFuncKey(AttrDataType::FLOAT32, AttrDataType::INT32), &AttrDataManager::GetFloatAttrValueAndToInt},350 {GenerateAttrFuncKey(AttrDataType::FLOAT32, AttrDataType::INT32), &AttrDataManager::GetFloatAttrValueAndToInt},
351+ {GenerateAttrFuncKey(AttrDataType::FLOAT32, AttrDataType::INT64), &AttrDataManager::GetFloatAttrValueAndToInt64},
331 {GenerateAttrFuncKey(AttrDataType::LIST_FLOAT32, AttrDataType::LIST_INT32),352 {GenerateAttrFuncKey(AttrDataType::LIST_FLOAT32, AttrDataType::LIST_INT32),
332 &AttrDataManager::GetListFloatAttrValueAndToListInt}};353 &AttrDataManager::GetListFloatAttrValueAndToListInt}};
333 354 
@@ -89,7 +89,8 @@ typedef enum {
89 OM2_RUN_ATTR_INPUTS = 1,89 OM2_RUN_ATTR_INPUTS = 1,
90 OM2_RUN_ATTR_INPUT_COUNT = 2,90 OM2_RUN_ATTR_INPUT_COUNT = 2,
91 OM2_RUN_ATTR_OUTPUTS = 3,91 OM2_RUN_ATTR_OUTPUTS = 3,
92- OM2_RUN_ATTR_OUTPUT_COUNT = 492+ OM2_RUN_ATTR_OUTPUT_COUNT = 4,
93+ OM2_RUN_ATTR_NOTIFIES = 5
93} Om2ProgramBodyRunAttrId;94} Om2ProgramBodyRunAttrId;
94 95 
95typedef union {96typedef union {
@@ -98,6 +99,7 @@ typedef union {
98 size_t input_count;99 size_t input_count;
99 void *const *outputs;100 void *const *outputs;
100 size_t output_count;101 size_t output_count;
102+ void *notifies;
101 uint64_t reserved;103 uint64_t reserved;
102} Om2ProgramBodyRunAttrValue;104} Om2ProgramBodyRunAttrValue;
103 105 
Mruntime/om2/om2_model_executor.cc+159-34文件内容审核中,请稍后刷新重试
@@ -125,4 +125,8 @@ target_link_libraries(gert PRIVATE
125target_compile_options(gert PRIVATE ${AIR_COMMON_COMPILE_OPTION}125target_compile_options(gert PRIVATE ${AIR_COMMON_COMPILE_OPTION}
126 $<$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>:-fblocks>126 $<$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>:-fblocks>
127 -fno-strict-aliasing127 -fno-strict-aliasing
128+ # FXRT's converter reuses the GE runtime-v2 pass objects through its
129+ # offline optimizer. Export their ABI symbols from the shared
130+ # runtime so the converter can resolve them after installation.
131+ -fvisibility=default
128 )132 )
@@ -11,6 +11,7 @@
11#ifndef AIR_CXX_RUNTIME_V2_KERNEL_TILING_H_11#ifndef AIR_CXX_RUNTIME_V2_KERNEL_TILING_H_
12#define AIR_CXX_RUNTIME_V2_KERNEL_TILING_H_12#define AIR_CXX_RUNTIME_V2_KERNEL_TILING_H_
13#include "graph/error_codes.h"13#include "graph/error_codes.h"
14+#include "common/ge_visibility.h"
14#include "common/math/ge_math_util.h"15#include "common/math/ge_math_util.h"
15#include "exe_graph/runtime/tiling_context.h"16#include "exe_graph/runtime/tiling_context.h"
16#include "exe_graph/runtime/continuous_vector.h"17#include "exe_graph/runtime/continuous_vector.h"
@@ -29,7 +30,7 @@ ge::graphStatus Tiling(KernelContext *context);
29ge::graphStatus FallibleTiling(KernelContext *context);30ge::graphStatus FallibleTiling(KernelContext *context);
30ge::graphStatus TilingAppendWorkspace(KernelContext *context);31ge::graphStatus TilingAppendWorkspace(KernelContext *context);
31ge::graphStatus TilingAppendMemCheck(KernelContext *context);32ge::graphStatus TilingAppendMemCheck(KernelContext *context);
32-ge::graphStatus FillTilingInfo(const KernelContext *context, ExceptionDumpInfoWrapper &wrapper);33+VISIBILITY_EXPORT ge::graphStatus FillTilingInfo(const KernelContext *context, ExceptionDumpInfoWrapper &wrapper);
33std::vector<std::string> PrintTilingData(const KernelContext *context);34std::vector<std::string> PrintTilingData(const KernelContext *context);
34ge::graphStatus RefreshOutputAddr(KernelContext *context, RtKernelLaunchArgsEx *launch_arg);35ge::graphStatus RefreshOutputAddr(KernelContext *context, RtKernelLaunchArgsEx *launch_arg);
35ge::graphStatus AlignWorkspaceSizes(KernelContext *context);36ge::graphStatus AlignWorkspaceSizes(KernelContext *context);