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.0 kB

4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. bool IsControlFlow() const;
  48. std::vector<std::shared_ptr<Cluster>> Inputs() const;
  49. std::vector<std::shared_ptr<Cluster>> Outputs() const;
  50. bool IsInputNode() const;
  51. std::vector<NodePtr> Nodes() const;
  52. bool IsRefVariable() const;
  53. // Cluster modify functions
  54. void AddInput(std::shared_ptr<Cluster> in);
  55. void RemoveInput(std::shared_ptr<Cluster> in);
  56. void AddOutput(std::shared_ptr<Cluster> out);
  57. void RemoveOutput(std::shared_ptr<Cluster> out);
  58. // Merge other cluster to this cluster, Whether it leads to a ring or not
  59. // Merge src to dst means:
  60. // All links to src will break and link to dst instead
  61. // All nodes of src will change its owner to dst
  62. // Update max and min rank of dst
  63. void Merge(std::shared_ptr<Cluster> other);
  64. // Try merge other cluster to this cluster, ONLY if will not leads to a ring
  65. bool TryMerge(std::shared_ptr<Cluster> other);
  66. // Merge all clusters on path(s) from other to this
  67. std::vector<std::shared_ptr<Cluster>> MergeAllPathFrom(std::shared_ptr<Cluster> other);
  68. // Convert cluster to functioned call functions
  69. void AddFrameInput(InDataAnchorPtr anchor);
  70. void AddFrameOutput(OutDataAnchorPtr anchor);
  71. InDataAnchorPtr GetFrameInDataAnchor(InDataAnchorPtr anchor);
  72. OutDataAnchorPtr GetFrameOutDataAnchor(OutDataAnchorPtr anchor);
  73. InControlAnchorPtr GetFrameInControlAnchor();
  74. OutControlAnchorPtr GetFrameOutControlAnchor();
  75. Status BuildFrame();
  76. Status BuildPartitionFrame();
  77. Status CombinePartitionFrame();
  78. Status BuildPartitionSubgraph();
  79. // Clear resource and break circular dependency
  80. void Clear();
  81. private:
  82. static thread_local size_t unique_id_;
  83. size_t id_;
  84. // Each Cluster records the maximum and minimum topological order of its node
  85. size_t min_; // maximum topological order
  86. size_t max_; // minimum topological order
  87. Type type_;
  88. std::vector<std::shared_ptr<Cluster>> in_clusters_;
  89. std::vector<std::shared_ptr<Cluster>> out_clusters_;
  90. std::vector<NodePtr> nodes_;
  91. // Fileds for build partitoned call and subgraph
  92. DynamicShapePartitioner *partitioner_; // Not owned, the partitioner this cluster belongs to
  93. std::unordered_map<InDataAnchorPtr, size_t> inputs_index_;
  94. std::unordered_map<OutDataAnchorPtr, size_t> outputs_index_;
  95. std::vector<InDataAnchorPtr> inputs_;
  96. std::vector<OutDataAnchorPtr> outputs_;
  97. std::unordered_set<std::shared_ptr<Cluster>> control_inputs_;
  98. std::unordered_set<OutControlAnchorPtr> control_outputs_;
  99. NodePtr partition_node_; // corresponding partitioned call node
  100. ComputeGraphPtr subgraph_; // corresponding subgraph
  101. };
  102. explicit DynamicShapePartitioner(ge::ComputeGraphPtr graph) : root_graph_(graph) {}
  103. ~DynamicShapePartitioner() = default;
  104. Status Partition();
  105. private:
  106. Status PartitionImpl();
  107. // Collect nodes that satisfy the unknowshape rules:
  108. // 1) The Tensor shape of any input or output is unknow shape(dim_size = -1) or unknow rank(dim_size=-2)
  109. // 2) Subgraphs of the node has an operator that satisfies rule 1)
  110. Status MarkUnknownShapeNodes();
  111. // For each node a Cluster structure, and connected according to the connection relationship of the nodes
  112. // An cluster means set of nodes that can be merged in same partition,
  113. // Corresponding relationship between cluster type and node:
  114. // DATA:DATA, UNKNOWN_SHAPE:unknowshape, KNOWN_SHAPE:knowshape, NETOUTPUT:NETOUTPUT
  115. Status InitClusters();
  116. // Merge clusters according to the following rules:
  117. // 1) Iterate through the UNKNOWN_SHAPE clusters, if the input is UNKNOWN_SHAPE,
  118. // merge all the clusters in the path(s) between the two clusters
  119. // 2) Iterate through the KNOWN_SHAPE clusters, if the input is KNOWN_SHAPE, and
  120. // and there's only one path between the two clusters , merge the two clusters
  121. // 3) Iterate through the INPUT_DATA clusters, merge all INPUT_DATA
  122. Status MergeClusters();
  123. // Merge clusters step1
  124. void MergeClustersUnknownShape();
  125. // Merge clusters step2
  126. void MergeClustersKnownShape();
  127. // Merge clusters step3
  128. void MergeClustersInputData();
  129. // Topological sort clusters after merge unknow shape clusters.
  130. Status TopologicalSortClusters();
  131. // Deduplicate merged clusters
  132. void PruneUniqueClusters();
  133. // Establish the input-output anchors for each partition of the cluster and record links to other clusters
  134. Status BuildPartitionFrame();
  135. // Establish connection between corresponding partitioned of clusters
  136. Status CombinePartitionFrame();
  137. // Convert the nodes in cluster into a complete ComputeGraoh
  138. Status BuildPartitionSubgraph();
  139. // Clear resource and break circular dependency
  140. void ClearResource();
  141. // Debug functions
  142. void DumpGraph(const std::string &suffix);
  143. std::string DebugString() const;
  144. bool JudgeUnknowShapeWithAttr(const OpDescPtr &opdesc);
  145. // Util functions
  146. Status CollectSpreadUnknownShapeNodes(NodePtr node);
  147. Status IsUnknownShapeGraph(ge::ComputeGraphPtr graph, bool &is_unknow);
  148. Status IsUnknownShapeNode(ge::NodePtr node, bool &is_unknow);
  149. Status CtrlEdgeTransfer();
  150. ge::ComputeGraphPtr root_graph_; // The original graph to partition
  151. std::unordered_map<NodePtr, std::shared_ptr<Cluster>> node_2_cluster_; // Record nodes and the cluster it belongs to
  152. // topological sorted clusters, this field will change with the splitting.
  153. // When partitioning UNKNOWN_SHAPE cluster, it is a collection of all topological sorted UNKNOWN_SHAPE clusters
  154. // When partitioning KNOWN_SHAPE cluster, it is a collection of all topological sorted KNOWN_SHAPE clusters
  155. std::vector<std::shared_ptr<Cluster>> ordered_cluster_;
  156. // Unique clusters left after merged clusters
  157. std::unordered_set<std::shared_ptr<Cluster>> unique_clusters_;
  158. // Unique clusters left after merged clusters sorted by rank
  159. std::vector<std::shared_ptr<Cluster>> sorted_unique_clusters_;
  160. // Nodes of root_graph_ that satisfy the unknowshape rules
  161. std::unordered_set<NodePtr> unknown_shape_nodes_;
  162. };
  163. } // namespace ge
  164. #endif // GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_

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