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

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