You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
7.8 KiB
172 lines
7.8 KiB
/**
|
|
* Copyright 2020 Huawei Technologies Co., Ltd
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_
|
|
#define GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_
|
|
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
#include "common/ge_inner_error_codes.h"
|
|
#include "graph/compute_graph.h"
|
|
|
|
namespace ge {
|
|
class DynamicShapePartitioner {
|
|
public:
|
|
// An cluster means set of nodes that can be merged in same partition,
|
|
// Corresponding relationship between cluster type and node:
|
|
// DATA:DATA, UNKNOWN_SHAPE:unknowshape, KNOWN_SHAPE:knowshape, NETOUTPUT:NETOUTPUT.
|
|
class Cluster : public std::enable_shared_from_this<Cluster> {
|
|
public:
|
|
enum Type { DATA, INPUT_NODE, NETOUTPUT, STAGE, KNOWN_SHAPE, UNKNOWN_SHAPE };
|
|
Cluster(size_t rank, Type type, NodePtr node, DynamicShapePartitioner *partitioner)
|
|
: id_(rank), min_(rank), max_(rank), type_(type), partitioner_(partitioner) {
|
|
nodes_.push_back(node);
|
|
}
|
|
~Cluster() = default;
|
|
std::string DebugString() const;
|
|
// Basic bean functions
|
|
size_t Id() const;
|
|
void UpdateRank(size_t rank);
|
|
bool IsData() const;
|
|
bool IsKnownShape() const;
|
|
bool IsUnknownShape() const;
|
|
bool IsIndependent() const;
|
|
bool IsNetOutput() const;
|
|
std::vector<std::shared_ptr<Cluster>> Inputs() const;
|
|
std::vector<std::shared_ptr<Cluster>> Outputs() const;
|
|
bool IsInputNode() const;
|
|
std::vector<NodePtr> Nodes() const;
|
|
bool IsRefVariable() const;
|
|
// Cluster modify functions
|
|
void AddInput(std::shared_ptr<Cluster> in);
|
|
void RemoveInput(std::shared_ptr<Cluster> in);
|
|
void AddOutput(std::shared_ptr<Cluster> out);
|
|
void RemoveOutput(std::shared_ptr<Cluster> out);
|
|
// Merge other cluster to this cluster, Whether it leads to a ring or not
|
|
// Merge src to dst means:
|
|
// All links to src will break and link to dst instead
|
|
// All nodes of src will change its owner to dst
|
|
// Update max and min rank of dst
|
|
void Merge(std::shared_ptr<Cluster> other);
|
|
// Try merge other cluster to this cluster, ONLY if will not leads to a ring
|
|
bool TryMerge(std::shared_ptr<Cluster> other);
|
|
// Merge all clusters on path(s) from other to this
|
|
std::vector<std::shared_ptr<Cluster>> MergeAllPathFrom(std::shared_ptr<Cluster> other);
|
|
// Convert cluster to functioned call functions
|
|
void AddFrameInput(InDataAnchorPtr anchor);
|
|
void AddFrameOutput(OutDataAnchorPtr anchor);
|
|
InDataAnchorPtr GetFrameInDataAnchor(InDataAnchorPtr anchor);
|
|
OutDataAnchorPtr GetFrameOutDataAnchor(OutDataAnchorPtr anchor);
|
|
InControlAnchorPtr GetFrameInControlAnchor();
|
|
OutControlAnchorPtr GetFrameOutControlAnchor();
|
|
Status BuildFrame();
|
|
Status BuildPartitionFrame();
|
|
Status CombinePartitionFrame();
|
|
Status BuildPartitionSubgraph();
|
|
// Clear resource and break circular dependency
|
|
void Clear();
|
|
|
|
private:
|
|
static thread_local size_t unique_id_;
|
|
size_t id_;
|
|
// Each Cluster records the maximum and minimum topological order of its node
|
|
size_t min_; // maximum topological order
|
|
size_t max_; // minimum topological order
|
|
Type type_;
|
|
std::vector<std::shared_ptr<Cluster>> in_clusters_;
|
|
std::vector<std::shared_ptr<Cluster>> out_clusters_;
|
|
std::vector<NodePtr> nodes_;
|
|
// Fileds for build partitoned call and subgraph
|
|
DynamicShapePartitioner *partitioner_; // Not owned, the partitioner this cluster belongs to
|
|
std::unordered_map<InDataAnchorPtr, size_t> inputs_index_;
|
|
std::unordered_map<OutDataAnchorPtr, size_t> outputs_index_;
|
|
std::vector<InDataAnchorPtr> inputs_;
|
|
std::vector<OutDataAnchorPtr> outputs_;
|
|
std::unordered_set<std::shared_ptr<Cluster>> control_inputs_;
|
|
std::unordered_set<OutControlAnchorPtr> control_outputs_;
|
|
NodePtr partition_node_; // corresponding partitioned call node
|
|
ComputeGraphPtr subgraph_; // corresponding subgraph
|
|
};
|
|
explicit DynamicShapePartitioner(ge::ComputeGraphPtr graph) : root_graph_(graph) {}
|
|
~DynamicShapePartitioner() = default;
|
|
|
|
Status Partition();
|
|
|
|
private:
|
|
Status PartitionImpl();
|
|
// Collect nodes that satisfy the unknowshape rules:
|
|
// 1) The Tensor shape of any input or output is unknow shape(dim_size = -1) or unknow rank(dim_size=-2)
|
|
// 2) Subgraphs of the node has an operator that satisfies rule 1)
|
|
Status MarkUnknownShapeNodes();
|
|
// For each node a Cluster structure, and connected according to the connection relationship of the nodes
|
|
// An cluster means set of nodes that can be merged in same partition,
|
|
// Corresponding relationship between cluster type and node:
|
|
// DATA:DATA, UNKNOWN_SHAPE:unknowshape, KNOWN_SHAPE:knowshape, NETOUTPUT:NETOUTPUT
|
|
Status InitClusters();
|
|
// Merge clusters according to the following rules:
|
|
// 1) Iterate through the UNKNOWN_SHAPE clusters, if the input is UNKNOWN_SHAPE,
|
|
// merge all the clusters in the path(s) between the two clusters
|
|
// 2) Iterate through the KNOWN_SHAPE clusters, if the input is KNOWN_SHAPE, and
|
|
// and there's only one path between the two clusters , merge the two clusters
|
|
// 3) Iterate through the INPUT_DATA clusters, merge all INPUT_DATA
|
|
Status MergeClusters();
|
|
// Merge clusters step1
|
|
void MergeClustersUnknownShape();
|
|
// Merge clusters step2
|
|
void MergeClustersKnownShape();
|
|
// Merge clusters step3
|
|
void MergeClustersInputData();
|
|
// Topological sort clusters after merge unknow shape clusters.
|
|
Status TopologicalSortClusters();
|
|
// Deduplicate merged clusters
|
|
void PruneUniqueClusters();
|
|
// Establish the input-output anchors for each partition of the cluster and record links to other clusters
|
|
Status BuildPartitionFrame();
|
|
// Establish connection between corresponding partitioned of clusters
|
|
Status CombinePartitionFrame();
|
|
// Convert the nodes in cluster into a complete ComputeGraoh
|
|
Status BuildPartitionSubgraph();
|
|
// Clear resource and break circular dependency
|
|
void ClearResource();
|
|
// Debug functions
|
|
void DumpGraph(const std::string &suffix);
|
|
std::string DebugString() const;
|
|
bool JudgeUnknowShapeWithAttr(const OpDescPtr &opdesc);
|
|
// Util functions
|
|
Status CollectSpreadUnknownShapeNodes(NodePtr node);
|
|
Status IsUnknownShapeGraph(ge::ComputeGraphPtr graph, bool &is_unknow);
|
|
Status IsUnknownShapeNode(ge::NodePtr node, bool &is_unknow);
|
|
bool IsUnknownShapeTensor(const ge::GeTensorDesc &tensor);
|
|
Status CtrlEdgeTransfer();
|
|
ge::ComputeGraphPtr root_graph_; // The original graph to partition
|
|
std::unordered_map<NodePtr, std::shared_ptr<Cluster>> node_2_cluster_; // Record nodes and the cluster it belongs to
|
|
// topological sorted clusters, this field will change with the splitting.
|
|
// When partitioning UNKNOWN_SHAPE cluster, it is a collection of all topological sorted UNKNOWN_SHAPE clusters
|
|
// When partitioning KNOWN_SHAPE cluster, it is a collection of all topological sorted KNOWN_SHAPE clusters
|
|
std::vector<std::shared_ptr<Cluster>> ordered_cluster_;
|
|
// Unique clusters left after merged clusters
|
|
std::unordered_set<std::shared_ptr<Cluster>> unique_clusters_;
|
|
// Unique clusters left after merged clusters sorted by rank
|
|
std::vector<std::shared_ptr<Cluster>> sorted_unique_clusters_;
|
|
// Nodes of root_graph_ that satisfy the unknowshape rules
|
|
std::unordered_set<NodePtr> unknown_shape_nodes_;
|
|
};
|
|
} // namespace ge
|
|
|
|
#endif // GE_GRAPH_PARTITION_DYNAMIC_SHAPE_PARTITION_H_
|