已合并
【fix】: 修复重复声明output/dim_a && 修复Reduce多同输入节点断图逻辑问题 && 断图后group按照依赖关系重新排序 #1736
【fix】: 修复重复声明output/dim_a && 修复Reduce多同输入节点断图逻辑问题 && 断图后group按照依赖关系重新排序 #1736
已合并
WangYanMale创建于 22 天前
6 个文件变更+111-27
@@ -503,7 +503,7 @@ void Loop::Destruct() {
503 }503 }
504}504}
505 505 
506-void Loop::CollectTensorCrossLoop(std::map<ascir::AxisId, std::vector<ApiCall *>> &api_calls) {506+void Loop::CollectTensorCrossLoop(std::map<ascir::AxisId, std::map<Loop *, std::vector<ApiCall *>>> &api_calls) {
507 if (this->bodys.size() <= 1) {507 if (this->bodys.size() <= 1) {
508 return;508 return;
509 }509 }
@@ -517,7 +517,7 @@ void Loop::CollectTensorCrossLoop(std::map<ascir::AxisId, std::vector<ApiCall *>
517 ascir::AxisId target_axis;517 ascir::AxisId target_axis;
518 bool flag = inner_body.call->IsReadOutersideWrite(target_axis);518 bool flag = inner_body.call->IsReadOutersideWrite(target_axis);
519 if (flag) {519 if (flag) {
520- api_calls[target_axis].emplace_back(inner_body.call);520+ api_calls[target_axis][body.loop].emplace_back(inner_body.call);
521 }521 }
522 }522 }
523 }523 }
@@ -585,11 +585,11 @@ static std::string GetCacheGuardCondition(const ApiCall &call, bool is_enable_ca
585Status Loop::GenerateBody(const Tiler &tiler, const TPipe &tpipe, std::vector<ascir::AxisId> &current_axis,585Status Loop::GenerateBody(const Tiler &tiler, const TPipe &tpipe, std::vector<ascir::AxisId> &current_axis,
586 std::stringstream &ss) {586 std::stringstream &ss) {
587 bool need_collect = this->bodys.size() > 1;587 bool need_collect = this->bodys.size() > 1;
588- std::map<ascir::AxisId, std::vector<ApiCall *>> api_calls_cross_loop;588+ std::map<ascir::AxisId, std::map<Loop *, std::vector<ApiCall *>>> api_calls_cross_loop;
589 if (need_collect) {589 if (need_collect) {
590 CollectTensorCrossLoop(api_calls_cross_loop);590 CollectTensorCrossLoop(api_calls_cross_loop);
591 }591 }
592- auto target_calls = api_calls_cross_loop[this->axis_id];592+ auto &cross_loop_map = api_calls_cross_loop[this->axis_id];
593 593 
594 for (const auto &body : this->bodys) {594 for (const auto &body : this->bodys) {
595 if ((body.type == LoopType::CALL) && (body.call->api_call_context.scene == ApiScene::kCVFuseUBLoad ||595 if ((body.type == LoopType::CALL) && (body.call->api_call_context.scene == ApiScene::kCVFuseUBLoad ||
@@ -597,14 +597,19 @@ Status Loop::GenerateBody(const Tiler &tiler, const TPipe &tpipe, std::vector<as
597 continue;597 continue;
598 }598 }
599 if (body.type == LoopType::LOOP) {599 if (body.type == LoopType::LOOP) {
600- for (auto call : target_calls) {600+ auto it = cross_loop_map.find(body.loop);
601- GE_CHK_STATUS_RET(call->AllocOutputs(tpipe, ss), "Codegen alloc outputs failed");601+ if (it != cross_loop_map.end()) {
602- used_calls.insert(call);602+ for (auto call : it->second) {
603+ GE_CHK_STATUS_RET(call->AllocOutputs(tpipe, ss), "Codegen alloc outputs failed");
604+ used_calls.insert(call);
605+ }
603 }606 }
604 body.loop->compute_stage = this->compute_stage;607 body.loop->compute_stage = this->compute_stage;
605 GE_CHK_STATUS_RET(body.loop->GenerateLoop(tiler, tpipe, current_axis, ss), "Generate loop for body failed");608 GE_CHK_STATUS_RET(body.loop->GenerateLoop(tiler, tpipe, current_axis, ss), "Generate loop for body failed");
606- for (auto call : target_calls) {609+ if (it != cross_loop_map.end()) {
607- GE_CHK_BOOL_RET_STATUS(call->SyncOutputs(tpipe, ss), af::FAILED, "Func SyncOutputs return false");610+ for (auto call : it->second) {
611+ GE_CHK_BOOL_RET_STATUS(call->SyncOutputs(tpipe, ss), af::FAILED, "Func SyncOutputs return false");
612+ }
608 }613 }
609 used_calls.clear();614 used_calls.clear();
610 } else {615 } else {
@@ -761,7 +766,7 @@ Status Loop::GenerateLoop(const Tiler &tiler, const TPipe &tpipe, std::vector<as
761 ss << "uint32_t " << reduce_dim_a << ";" << std::endl;766 ss << "uint32_t " << reduce_dim_a << ";" << std::endl;
762 }767 }
763 if (axis.type != Axis::Type::kAxisTypeBlockInner && this->is_graph_has_reduce_node) {768 if (axis.type != Axis::Type::kAxisTypeBlockInner && this->is_graph_has_reduce_node) {
764- ss << "bool control_dis_enable_cache_a = true;" << std::endl;769+ ss << "control_dis_enable_cache_a = true;" << std::endl;
765 ss << "if ( " << axis.loop_size.Str() << " == 1) {" << std::endl;770 ss << "if ( " << axis.loop_size.Str() << " == 1) {" << std::endl;
766 ss << "control_dis_enable_cache_a = false;" << std::endl;771 ss << "control_dis_enable_cache_a = false;" << std::endl;
767 ss << "}" << std::endl;772 ss << "}" << std::endl;
@@ -950,6 +955,9 @@ Status Loop::Generate(const Tiler &tiler, const TPipe &tpipe, std::string &resul
950 std::vector<ascir::AxisId> current_axis;955 std::vector<ascir::AxisId> current_axis;
951 this->compute_stage = stage;956 this->compute_stage = stage;
952 stringstream ss;957 stringstream ss;
958+ if (this->is_graph_has_reduce_node) {
959+ ss << "bool control_dis_enable_cache_a = true;" << std::endl;
960+ }
953 GE_CHK_STATUS_RET(this->GenerateLoop(tiler, tpipe, current_axis, ss), "Generate loop failed");961 GE_CHK_STATUS_RET(this->GenerateLoop(tiler, tpipe, current_axis, ss), "Generate loop failed");
954 result = ss.str();962 result = ss.str();
955 return af::SUCCESS;963 return af::SUCCESS;
@@ -177,7 +177,7 @@ struct Loop {
177 ComputeStage stage = ComputeStage::kDefault);177 ComputeStage stage = ComputeStage::kDefault);
178 const Tensor *GetReduceOutputTensor(const TPipe &tpipe) const;178 const Tensor *GetReduceOutputTensor(const TPipe &tpipe) const;
179 const Tensor *GetReduceInputTensor(const TPipe &tpipe) const;179 const Tensor *GetReduceInputTensor(const TPipe &tpipe) const;
180- void CollectTensorCrossLoop(std::map<ascir::AxisId, std::vector<ApiCall *>> &api_calls);180+ void CollectTensorCrossLoop(std::map<ascir::AxisId, std::map<Loop *, std::vector<ApiCall *>>> &api_calls);
181 Status ActualSizeDefine(const Tiler &tiler, const TPipe &tpipe, std::string dtype_name, std::string &result);181 Status ActualSizeDefine(const Tiler &tiler, const TPipe &tpipe, std::string dtype_name, std::string &result);
182 182 
183 private:183 private:
@@ -255,7 +255,7 @@ Status ReducePartitionCaseGenerator::GeneratorRCoreTask(ascir::HintGraph &optimi
255 std::map<size_t, std::vector<size_t>> map;255 std::map<size_t, std::vector<size_t>> map;
256 size_t phase_2_graph_size = 0;256 size_t phase_2_graph_size = 0;
257 for (size_t i = 0; i < task.grouped_graphs.size(); i++) {257 for (size_t i = 0; i < task.grouped_graphs.size(); i++) {
258- GE_ASSERT_TRUE(IsGroupGraphLegal(task.grouped_graphs[i]));258+ GE_ASSERT_TRUE(IsOnlyHasOneOrLessReduce(task.grouped_graphs[i]));
259 if (!HasReduce(task.grouped_graphs[i])) {259 if (!HasReduce(task.grouped_graphs[i])) {
260 ::ascir::ImplGraph graph((task.grouped_graphs[i].GetName() + "_r_multicore").c_str());260 ::ascir::ImplGraph graph((task.grouped_graphs[i].GetName() + "_r_multicore").c_str());
261 graph.CopyFrom(task.grouped_graphs[i]);261 graph.CopyFrom(task.grouped_graphs[i]);
@@ -304,10 +304,8 @@ Status ReducePartitionCaseGenerator::GeneratorTask(ascir::HintGraph &optimize_gr
304 const bool force_all_load = ShouldForceAllLoad(optimize_graph);304 const bool force_all_load = ShouldForceAllLoad(optimize_graph);
305 GELOGI("Graph %s force AllLoad = %d, begin to generate reduce tasks.", optimize_graph.GetName().c_str(),305 GELOGI("Graph %s force AllLoad = %d, begin to generate reduce tasks.", optimize_graph.GetName().c_str(),
306 static_cast<int32_t>(force_all_load));306 static_cast<int32_t>(force_all_load));
307- if (!force_all_load || options.graph_type != GraphType::kFusedAscBackend) {307+ GE_CHK_STATUS_RET(GeneratorGeneralTask(optimize_graph, tasks));
308- GE_CHK_STATUS_RET(GeneratorGeneralTask(optimize_graph, tasks));308+ GELOGI("After GeneralTask, graph %s has %zu task(s).", optimize_graph.GetName().c_str(), tasks.size());
309- GELOGI("After GeneralTask, graph %s has %zu task(s).", optimize_graph.GetName().c_str(), tasks.size());
310- }
311 if (!force_all_load) {309 if (!force_all_load) {
312 GE_CHK_STATUS_RET(GeneratorRCoreTask(optimize_graph, tasks));310 GE_CHK_STATUS_RET(GeneratorRCoreTask(optimize_graph, tasks));
313 GELOGI("After RCoreTask, graph %s has %zu task(s).", optimize_graph.GetName().c_str(), tasks.size());311 GELOGI("After RCoreTask, graph %s has %zu task(s).", optimize_graph.GetName().c_str(), tasks.size());
@@ -324,7 +322,7 @@ Status ReducePartitionCaseGenerator::Generate([[maybe_unused]] ascir::HintGraph
324}322}
325 323 
326bool ReducePartitionCaseGenerator::ShouldForceAllLoad(ascir::HintGraph &graph) {324bool ReducePartitionCaseGenerator::ShouldForceAllLoad(ascir::HintGraph &graph) {
327- if (!IsGroupGraphLegal(graph)) {325+ if (!IsOnlyHasOneOrLessReduce(graph)) {
328 return true;326 return true;
329 }327 }
330 328 
@@ -400,7 +398,7 @@ Status ReducePartitionCaseGenerator::GenerateAllLoadCase(ascir::HintGraph &graph
400}398}
401 399 
402Status ReducePartitionCaseGenerator::ReducePartitionMultipleCitations(ascir::ImplGraph &impl_graph) {400Status ReducePartitionCaseGenerator::ReducePartitionMultipleCitations(ascir::ImplGraph &impl_graph) {
403- if (IsGroupGraphLegal(impl_graph)) {401+ if (IsOnlyHasOneOrLessReduce(impl_graph)) {
404 return ge::GRAPH_SUCCESS;402 return ge::GRAPH_SUCCESS;
405 }403 }
406 std::vector<af::AscNodePtr> multi_output_nodes;404 std::vector<af::AscNodePtr> multi_output_nodes;
@@ -510,20 +508,25 @@ Status ReducePartitionCaseGenerator::PartitionLoadNode(af::AscNodePtr &src_load_
510 auto load_node = impl_graph.AddNode(load);508 auto load_node = impl_graph.AddNode(load);
511 DoCopyAscNodeTensorAttr(load_input_asc_node, new_load_input_node);509 DoCopyAscNodeTensorAttr(load_input_asc_node, new_load_input_node);
512 DoCopyAscNodeTensorAttr(src_load_node, load_node);510 DoCopyAscNodeTensorAttr(src_load_node, load_node);
511+ // dst_node 的多个输入可能来自同一个 src_load_node(如 Mul 的两个输入都是同一个 Load),
512+ // 需要遍历所有 peer 边逐一断开并替换,不能找到第一条就 return。
513+ // new_load_input -> load_node 的边只需建一次,后续匹配的 peer 边共用这条链路。
514+ bool found = false;
513 for (const auto &out_anchor : src_load_node->GetAllOutDataAnchors()) {515 for (const auto &out_anchor : src_load_node->GetAllOutDataAnchors()) {
514 GE_CHECK_NOTNULL(out_anchor, "Out data anchor is null, node:%s.", src_load_node->GetNamePtr());516 GE_CHECK_NOTNULL(out_anchor, "Out data anchor is null, node:%s.", src_load_node->GetNamePtr());
515 for (const auto &peer_in_anchor : out_anchor->GetPeerInDataAnchors()) {517 for (const auto &peer_in_anchor : out_anchor->GetPeerInDataAnchors()) {
516 GE_CHECK_NOTNULL(peer_in_anchor);518 GE_CHECK_NOTNULL(peer_in_anchor);
517 GE_CHECK_NOTNULL(peer_in_anchor->GetOwnerNodeBarePtr(), "Peer in node:%s is null", src_load_node->GetNamePtr());519 GE_CHECK_NOTNULL(peer_in_anchor->GetOwnerNodeBarePtr(), "Peer in node:%s is null", src_load_node->GetNamePtr());
518 if (peer_in_anchor->GetOwnerNodeBarePtr() == dst_node.get()) {520 if (peer_in_anchor->GetOwnerNodeBarePtr() == dst_node.get()) {
519- // remove load->dst521+ if (!found) {
522+ found = true;
523+ GE_CHK_STATUS_RET(
524+ af::GraphUtils::AddEdge(new_load_input_node->GetOutAnchor(0UL), load_node->GetInAnchor(0UL)));
525+ }
520 GE_CHK_STATUS_RET(af::GraphUtils::RemoveEdge(src_load_node->GetOutAnchor(out_anchor->GetIdx()),526 GE_CHK_STATUS_RET(af::GraphUtils::RemoveEdge(src_load_node->GetOutAnchor(out_anchor->GetIdx()),
521 dst_node->GetInAnchor(peer_in_anchor->GetIdx())));527 dst_node->GetInAnchor(peer_in_anchor->GetIdx())));
522- // add new_load_input->new_load->dst
523- GE_CHK_STATUS_RET(af::GraphUtils::AddEdge(new_load_input_node->GetOutAnchor(0UL), load_node->GetInAnchor(0UL)));
524 GE_CHK_STATUS_RET(528 GE_CHK_STATUS_RET(
525 af::GraphUtils::AddEdge(load_node->GetOutAnchor(0UL), dst_node->GetInAnchor(peer_in_anchor->GetIdx())));529 af::GraphUtils::AddEdge(load_node->GetOutAnchor(0UL), dst_node->GetInAnchor(peer_in_anchor->GetIdx())));
526- return ge::GRAPH_SUCCESS;
527 }530 }
528 }531 }
529 }532 }
@@ -541,19 +544,17 @@ Status ReducePartitionCaseGenerator::PartitionScalarNode(af::AscNodePtr &src_nod
541 scalar_node = impl_graph.AddNode(scalar);544 scalar_node = impl_graph.AddNode(scalar);
542 }545 }
543 DoCopyAscNodeTensorAttr(src_node, scalar_node);546 DoCopyAscNodeTensorAttr(src_node, scalar_node);
547+ // dst_node 的多个输入可能来自同一个 src_node,需要遍历所有 peer 边逐一断开并替换,不能找到第一条就 return。
544 for (const auto &out_anchor : src_node->GetAllOutDataAnchors()) {548 for (const auto &out_anchor : src_node->GetAllOutDataAnchors()) {
545 GE_CHECK_NOTNULL(out_anchor, "Out data anchor is null, node:%s.", src_node->GetNamePtr());549 GE_CHECK_NOTNULL(out_anchor, "Out data anchor is null, node:%s.", src_node->GetNamePtr());
546 for (const auto &peer_in_anchor : out_anchor->GetPeerInDataAnchors()) {550 for (const auto &peer_in_anchor : out_anchor->GetPeerInDataAnchors()) {
547 GE_CHECK_NOTNULL(peer_in_anchor);551 GE_CHECK_NOTNULL(peer_in_anchor);
548 GE_CHECK_NOTNULL(peer_in_anchor->GetOwnerNodeBarePtr(), "Peer in node:%s is null", src_node->GetNamePtr());552 GE_CHECK_NOTNULL(peer_in_anchor->GetOwnerNodeBarePtr(), "Peer in node:%s is null", src_node->GetNamePtr());
549 if (peer_in_anchor->GetOwnerNodeBarePtr() == dst_node.get()) {553 if (peer_in_anchor->GetOwnerNodeBarePtr() == dst_node.get()) {
550- // remove src->dst
551 GE_CHK_STATUS_RET(af::GraphUtils::RemoveEdge(src_node->GetOutAnchor(out_anchor->GetIdx()),554 GE_CHK_STATUS_RET(af::GraphUtils::RemoveEdge(src_node->GetOutAnchor(out_anchor->GetIdx()),
552 dst_node->GetInAnchor(peer_in_anchor->GetIdx())));555 dst_node->GetInAnchor(peer_in_anchor->GetIdx())));
553- // add new_scalar->dst
554 GE_CHK_STATUS_RET(556 GE_CHK_STATUS_RET(
555 af::GraphUtils::AddEdge(scalar_node->GetOutAnchor(0UL), dst_node->GetInAnchor(peer_in_anchor->GetIdx())));557 af::GraphUtils::AddEdge(scalar_node->GetOutAnchor(0UL), dst_node->GetInAnchor(peer_in_anchor->GetIdx())));
556- return ge::GRAPH_SUCCESS;
557 }558 }
558 }559 }
559 }560 }
@@ -760,7 +761,7 @@ bool ReducePartitionCaseGenerator::CanFullLoadReduceFuse(const ascir::ImplGraph
760 return true;761 return true;
761}762}
762 763 
763-bool ReducePartitionCaseGenerator::IsGroupGraphLegal(const ascir::ImplGraph &impl_graph) {764+bool ReducePartitionCaseGenerator::IsOnlyHasOneOrLessReduce(const ascir::ImplGraph &impl_graph) {
764 int reduce_count = 0;765 int reduce_count = 0;
765 for (const auto &node : impl_graph.GetAllNodes()) {766 for (const auto &node : impl_graph.GetAllNodes()) {
766 if (ScheduleUtils::IsReduce(node)) {767 if (ScheduleUtils::IsReduce(node)) {
@@ -52,7 +52,7 @@ class ReducePartitionCaseGenerator : public FusionCaseGenerator {
52 static Status PartitionScalarNode(af::AscNodePtr &src_node, af::AscNodePtr &dst_node, ascir::ImplGraph &impl_graph);52 static Status PartitionScalarNode(af::AscNodePtr &src_node, af::AscNodePtr &dst_node, ascir::ImplGraph &impl_graph);
53 static bool HasReduce(const ascir::ImplGraph &impl_graph);53 static bool HasReduce(const ascir::ImplGraph &impl_graph);
54 static bool HasArgMaxReduce(const ScheduleTask &task);54 static bool HasArgMaxReduce(const ScheduleTask &task);
55- static bool IsGroupGraphLegal(const ascir::ImplGraph &impl_graph);55+ static bool IsOnlyHasOneOrLessReduce(const ascir::ImplGraph &impl_graph);
56 static bool CanFullLoadReduceFuse(const ascir::ImplGraph &impl_graph);56 static bool CanFullLoadReduceFuse(const ascir::ImplGraph &impl_graph);
57 Status ReducePartitionMultipleCitations(ascir::ImplGraph &impl_graph);57 Status ReducePartitionMultipleCitations(ascir::ImplGraph &impl_graph);
58 bool FindOutputReduce(const af::AscNodePtr &node, af::AscNodePtr &reduce_node);58 bool FindOutputReduce(const af::AscNodePtr &node, af::AscNodePtr &reduce_node);
@@ -97,6 +97,7 @@ Status ScheduleGroupGraphPartitioner::PartitionByConnectivity(const ::ascir::Imp
97 for (auto &sub_optimize_graph : sub_optimize_graphs) {97 for (auto &sub_optimize_graph : sub_optimize_graphs) {
98 GE_CHK_STATUS_RET(ScheduleUtils::RemoveUnusedAxes(sub_optimize_graph), "Failed to remove unused axes");98 GE_CHK_STATUS_RET(ScheduleUtils::RemoveUnusedAxes(sub_optimize_graph), "Failed to remove unused axes");
99 }99 }
100+ GE_CHK_STATUS_RET(SortSubGraphsByDependency(sub_optimize_graphs), "Failed to sort subgraphs by dependency");
100 }101 }
101 if (visited.size() != num_nodes) {102 if (visited.size() != num_nodes) {
102 for (const auto &node : optimize_graph.GetAllNodes()) {103 for (const auto &node : optimize_graph.GetAllNodes()) {
@@ -179,6 +180,78 @@ bool ScheduleGroupGraphPartitioner::CompareByNodeId(const AscNodePtr &lhs, const
179 return lhs->GetOpDesc()->GetId() < rhs->GetOpDesc()->GetId();180 return lhs->GetOpDesc()->GetId() < rhs->GetOpDesc()->GetId();
180}181}
181 182 
183+bool ScheduleGroupGraphPartitioner::HasDataDependency(const ::ascir::ImplGraph &producer,
184+ const ::ascir::ImplGraph &consumer) {
185+ std::set<std::string> producer_output_names;
186+ for (const auto &node : producer.GetAllNodes()) {
187+ if (node->GetOutDataNodes().empty()) {
188+ producer_output_names.insert(node->GetName());
189+ }
190+ }
191+ if (producer_output_names.empty()) {
192+ return false;
193+ }
194+ for (const auto &node : consumer.GetAllNodes()) {
195+ for (const auto &in_node : node->GetInDataNodes()) {
196+ if (producer_output_names.find(in_node->GetName()) != producer_output_names.end()) {
197+ return true;
198+ }
199+ }
200+ }
201+ return false;
202+}
203+ 
204+Status ScheduleGroupGraphPartitioner::SortSubGraphsByDependency(std::vector<::ascir::ImplGraph> &sub_optimize_graphs) {
205+ const size_t n = sub_optimize_graphs.size();
206+ if (n <= 1U) {
207+ return af::SUCCESS;
208+ }
209+ std::vector<std::vector<bool>> dep_matrix(n, std::vector<bool>(n, false));
210+ std::vector<size_t> in_degree(n, 0U);
211+ for (size_t i = 0U; i < n; ++i) {
212+ for (size_t j = 0U; j < n; ++j) {
213+ if (i != j) {
214+ dep_matrix[i][j] = HasDataDependency(sub_optimize_graphs[i], sub_optimize_graphs[j]);
215+ if (dep_matrix[i][j]) {
216+ ++in_degree[j];
217+ }
218+ }
219+ }
220+ }
221+ std::vector<size_t> sorted;
222+ sorted.reserve(n);
223+ std::queue<size_t> zero_in_degree_queue;
224+ for (size_t i = 0U; i < n; ++i) {
225+ if (in_degree[i] == 0U) {
226+ zero_in_degree_queue.push(i);
227+ }
228+ }
229+ while (!zero_in_degree_queue.empty()) {
230+ size_t idx = zero_in_degree_queue.front();
231+ zero_in_degree_queue.pop();
232+ sorted.emplace_back(idx);
233+ for (size_t j = 0U; j < n; ++j) {
234+ if (dep_matrix[idx][j]) {
235+ --in_degree[j];
236+ if (in_degree[j] == 0U) {
237+ zero_in_degree_queue.push(j);
238+ }
239+ }
240+ }
241+ }
242+ if (sorted.size() != n) {
243+ GELOGE(af::FAILED, "Cycle detected in subgraph dependency, sorted[%zu] != total[%zu]", sorted.size(), n);
244+ return af::FAILED;
245+ }
246+ std::vector<::ascir::ImplGraph> reordered;
247+ reordered.reserve(n);
248+ for (const auto idx : sorted) {
249+ reordered.emplace_back(std::move(sub_optimize_graphs[idx]));
250+ }
251+ sub_optimize_graphs = std::move(reordered);
252+ return af::SUCCESS;
253+}
254+ 
182Status ScheduleGroupGraphPartitioner::RecordAxisSizes(const std::vector<af::Expression> &repeats,255Status ScheduleGroupGraphPartitioner::RecordAxisSizes(const std::vector<af::Expression> &repeats,
183 const std::vector<int64_t> &axis_ids,256 const std::vector<int64_t> &axis_ids,
184 std::map<af::AxisId, af::Expression> &axis_id_to_size) {257 std::map<af::AxisId, af::Expression> &axis_id_to_size) {
@@ -46,6 +46,8 @@ class ScheduleGroupGraphPartitioner {
46 static bool CompareByNodeId(const af::AscNodePtr &lhs, const af::AscNodePtr &rhs);46 static bool CompareByNodeId(const af::AscNodePtr &lhs, const af::AscNodePtr &rhs);
47 static Status RecordAxisSizes(const std::vector<af::Expression> &repeats, const std::vector<int64_t> &axis_ids,47 static Status RecordAxisSizes(const std::vector<af::Expression> &repeats, const std::vector<int64_t> &axis_ids,
48 std::map<af::AxisId, af::Expression> &axis_id_to_size);48 std::map<af::AxisId, af::Expression> &axis_id_to_size);
49+ static Status SortSubGraphsByDependency(std::vector<::ascir::ImplGraph> &sub_optimize_graphs);
50+ static bool HasDataDependency(const ::ascir::ImplGraph &producer, const ::ascir::ImplGraph &consumer);
49};51};
50} // namespace optimize52} // namespace optimize
51 53