You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dynamic_shape_partition.h 8.5 kB

4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_
  17. #define GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_
  18. #include <string>
  19. #include <unordered_map>
  20. #include <unordered_set>
  21. #include <vector>
  22. #include "common/ge_inner_error_codes.h"
  23. #include "graph/compute_graph.h"
  24. namespace ge {
  25. class DynamicShapePartitioner {
  26. public:
  27. // An cluster means set of nodes that can be merged in same partition,
  28. // Corresponding relationship between cluster type and node:
  29. // DATA:DATA, UNKNOWN_SHAPE:unknowshape, KNOWN_SHAPE:knowshape, NETOUTPUT:NETOUTPUT.
  30. class Cluster : public std::enable_shared_from_this<Cluster> {
  31. public:
  32. enum Type { DATA, INPUT_NODE, NETOUTPUT, STAGE, KNOWN_SHAPE, UNKNOWN_SHAPE };
  33. Cluster(size_t rank, Type type, NodePtr node, DynamicShapePartitioner *partitioner)
  34. : id_(rank), min_(rank), max_(rank), type_(type), partitioner_(partitioner) {
  35. nodes_.push_back(node);
  36. }
  37. ~Cluster() = default;
  38. std::string DebugString() const;
  39. // Basic bean functions
  40. size_t Id() const;
  41. void UpdateRank(size_t rank);
  42. bool IsData() const;
  43. bool IsKnownShape() const;
  44. bool IsUnknownShape() const;
  45. bool IsIndependent() const;
  46. bool IsNetOutput() const;
  47. std::vector<std::shared_ptr<Cluster>> Inputs() const;
  48. std::vector<std::shared_ptr<Cluster>> Outputs() const;
  49. bool IsInputNode() const;
  50. std::vector<NodePtr> Nodes() const;
  51. bool IsRefVariable() const;
  52. // Cluster modify functions
  53. void AddInput(std::shared_ptr<Cluster> in);
  54. void RemoveInput(std::shared_ptr<Cluster> in);
  55. void AddOutput(std::shared_ptr<Cluster> out);
  56. void RemoveOutput(std::shared_ptr<Cluster> out);
  57. // Merge other cluster to this cluster, Whether it leads to a ring or not
  58. // Merge src to dst means:
  59. // All links to src will break and link to dst instead
  60. // All nodes of src will change its owner to dst
  61. // Update max and min rank of dst
  62. void Merge(std::shared_ptr<Cluster> other);
  63. // Try merge other cluster to this cluster, ONLY if will not leads to a ring
  64. bool TryMerge(std::shared_ptr<Cluster> other);
  65. // Merge all clusters on path(s) from other to this
  66. std::vector<std::shared_ptr<Cluster>> MergeAllPathFrom(std::shared_ptr<Cluster> other);
  67. // Convert cluster to functioned call functions
  68. void AddFrameInput(InDataAnchorPtr anchor);
  69. void AddFrameOutput(OutDataAnchorPtr anchor);
  70. InDataAnchorPtr GetFrameInDataAnchor(InDataAnchorPtr anchor);
  71. OutDataAnchorPtr GetFrameOutDataAnchor(OutDataAnchorPtr anchor);
  72. InControlAnchorPtr GetFrameInControlAnchor();
  73. OutControlAnchorPtr GetFrameOutControlAnchor();
  74. Status BuildFrame();
  75. Status BuildPartitionFrame();
  76. Status CombinePartitionFrame();
  77. Status BuildPartitionSubgraph();
  78. // Clear resource and break circular dependency
  79. void Clear();
  80. bool IsAdjoinNodes(const std::shared_ptr<Cluster> &other) const {
  81. const auto &out_clusters = other->out_clusters_;
  82. return std::find(out_clusters.begin(), out_clusters.end(), shared_from_this()) != out_clusters.end();
  83. }
  84. private:
  85. static thread_local size_t unique_id_;
  86. size_t id_;
  87. // Each Cluster records the maximum and minimum topological order of its node
  88. size_t min_; // maximum topological order
  89. size_t max_; // minimum topological order
  90. Type type_;
  91. std::vector<std::shared_ptr<Cluster>> in_clusters_;
  92. std::vector<std::shared_ptr<Cluster>> out_clusters_;
  93. std::vector<NodePtr> nodes_;
  94. // Fileds for build partitoned call and subgraph
  95. DynamicShapePartitioner *partitioner_; // Not owned, the partitioner this cluster belongs to
  96. std::unordered_map<InDataAnchorPtr, size_t> inputs_index_;
  97. std::unordered_map<OutDataAnchorPtr, size_t> outputs_index_;
  98. std::vector<InDataAnchorPtr> inputs_;
  99. std::vector<OutDataAnchorPtr> outputs_;
  100. std::unordered_set<std::shared_ptr<Cluster>> control_inputs_;
  101. std::unordered_set<OutControlAnchorPtr> control_outputs_;
  102. NodePtr partition_node_; // corresponding partitioned call node
  103. ComputeGraphPtr subgraph_; // corresponding subgraph
  104. };
  105. explicit DynamicShapePartitioner(ge::ComputeGraphPtr graph) : root_graph_(graph) {}
  106. ~DynamicShapePartitioner() = default;
  107. Status Partition();
  108. using OrderedFilter = std::function<bool(const std::shared_ptr<Cluster> &cluster)>;
  109. private:
  110. Status PartitionImpl();
  111. // Collect nodes that satisfy the unknowshape rules:
  112. // 1) The Tensor shape of any input or output is unknow shape(dim_size = -1) or unknow rank(dim_size=-2)
  113. // 2) Subgraphs of the node has an operator that satisfies rule 1)
  114. Status MarkUnknownShapeNodes();
  115. // For each node a Cluster structure, and connected according to the connection relationship of the nodes
  116. // An cluster means set of nodes that can be merged in same partition,
  117. // Corresponding relationship between cluster type and node:
  118. // DATA:DATA, UNKNOWN_SHAPE:unknowshape, KNOWN_SHAPE:knowshape, NETOUTPUT:NETOUTPUT
  119. Status InitClusters();
  120. // Merge clusters according to the following rules:
  121. // 1) Iterate through the UNKNOWN_SHAPE clusters, if the input is UNKNOWN_SHAPE,
  122. // merge all the clusters in the path(s) between the two clusters
  123. // 2) Iterate through the KNOWN_SHAPE clusters, if the input is KNOWN_SHAPE, and
  124. // and there's only one path between the two clusters , merge the two clusters
  125. // 3) Iterate through the INPUT_DATA clusters, merge all INPUT_DATA
  126. Status MergeClusters();
  127. // Merge clusters step0
  128. void MergeClustersControlFlow();
  129. // Merge clusters step1
  130. void MergeClustersUnknownShape();
  131. // Merge clusters step2
  132. void MergeClustersKnownShape();
  133. // Merge clusters step3
  134. void MergeClustersInputData();
  135. // Topological sort clusters after merge unknown shape clusters.
  136. Status TopologicalSortClusters(const OrderedFilter &ordered_filter);
  137. // Deduplicate merged clusters
  138. void PruneUniqueClusters();
  139. // Establish the input-output anchors for each partition of the cluster and record links to other clusters
  140. Status BuildPartitionFrame();
  141. // Establish connection between corresponding partitioned of clusters
  142. Status CombinePartitionFrame();
  143. // Convert the nodes in cluster into a complete ComputeGraph
  144. Status BuildPartitionSubgraph();
  145. // Clear resource and break circular dependency
  146. void ClearResource();
  147. // Debug functions
  148. void DumpGraph(const std::string &suffix);
  149. std::string DebugString() const;
  150. bool JudgeUnknowShapeWithAttr(const OpDescPtr &opdesc);
  151. // Util functions
  152. Status CollectSpreadUnknownShapeNodes(NodePtr node);
  153. Status IsUnknownShapeGraph(ge::ComputeGraphPtr graph, bool &is_unknow);
  154. Status IsUnknownShapeNode(ge::NodePtr node, bool &is_unknow);
  155. Status CtrlEdgeTransfer();
  156. ge::ComputeGraphPtr root_graph_; // The original graph to partition
  157. std::unordered_map<NodePtr, std::shared_ptr<Cluster>> node_2_cluster_; // Record nodes and the cluster it belongs to
  158. // V1 control flow cluster, need merge to one Graph.
  159. std::map<int64_t, std::vector<std::shared_ptr<Cluster>>> control_clusters_;
  160. // topological sorted clusters, this field will change with the splitting.
  161. // When partitioning UNKNOWN_SHAPE cluster, it is a collection of all topological sorted UNKNOWN_SHAPE clusters
  162. // When partitioning KNOWN_SHAPE cluster, it is a collection of all topological sorted KNOWN_SHAPE clusters
  163. std::vector<std::shared_ptr<Cluster>> ordered_cluster_;
  164. // Unique clusters left after merged clusters
  165. std::unordered_set<std::shared_ptr<Cluster>> unique_clusters_;
  166. // Unique clusters left after merged clusters sorted by rank
  167. std::vector<std::shared_ptr<Cluster>> sorted_unique_clusters_;
  168. // Nodes of root_graph_ that satisfy the unknowshape rules
  169. std::unordered_set<NodePtr> unknown_shape_nodes_;
  170. };
  171. } // namespace ge
  172. #endif // GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示