From: @lichun30 Reviewed-by: @xchu42,@ji_chen Signed-off-by: @ji_chentags/v1.3.0
@@ -48,50 +48,23 @@ namespace ge { | |||||
using Cluster = DynamicShapePartitioner::Cluster; | using Cluster = DynamicShapePartitioner::Cluster; | ||||
using ClusterPtr = std::shared_ptr<Cluster>; | using ClusterPtr = std::shared_ptr<Cluster>; | ||||
static bool IsInExperimentalMode(const ComputeGraphPtr &root_graph) { | |||||
static bool IsSingleOpScene(const ComputeGraphPtr &root_graph) { | |||||
for (const auto &node : root_graph->GetAllNodes()) { | for (const auto &node : root_graph->GetAllNodes()) { | ||||
GE_CHECK_NOTNULL(node->GetOpDesc()); | GE_CHECK_NOTNULL(node->GetOpDesc()); | ||||
// not do partition in single op scene. | // not do partition in single op scene. | ||||
bool is_singleop = false; | bool is_singleop = false; | ||||
(void)AttrUtils::GetBool(node->GetOpDesc(), ATTR_SINGLE_OP_SCENE, is_singleop); | (void)AttrUtils::GetBool(node->GetOpDesc(), ATTR_SINGLE_OP_SCENE, is_singleop); | ||||
if (is_singleop) { | if (is_singleop) { | ||||
return false; | |||||
} | |||||
for (const auto &input_desc : node->GetOpDesc()->GetAllInputsDesc()) { | |||||
auto type = input_desc.GetDataType(); | |||||
if (type == DT_STRING || type == DT_RESOURCE || type == DT_STRING_REF) { | |||||
if (std::getenv("EXPERIMENTAL_DYNAMIC_PARTITION") == nullptr) { | |||||
return false; | |||||
} else { | |||||
GEEVENT("In dynamic shape scene, model contains data type:" | |||||
"DT_STRING/DT_RESOURCE/DT_STRING_REF may not be supported well " | |||||
"temporarily, please retry with \"unset EXPERIMENTAL_DYNAMIC_PARTITION\"."); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
for (const auto &output_desc : node->GetOpDesc()->GetAllOutputsDesc()) { | |||||
auto type = output_desc.GetDataType(); | |||||
if (type == DT_STRING || type == DT_RESOURCE || type == DT_STRING_REF) { | |||||
if (std::getenv("EXPERIMENTAL_DYNAMIC_PARTITION") == nullptr) { | |||||
return false; | |||||
} else { | |||||
GEEVENT("In dynamic shape scene, model contains data type:" | |||||
"DT_STRING/DT_RESOURCE/DT_STRING_REF may not be supported well " | |||||
"temporarily, please retry with \"unset EXPERIMENTAL_DYNAMIC_PARTITION\"."); | |||||
break; | |||||
} | |||||
} | |||||
return true; | |||||
} | } | ||||
} | } | ||||
return true; | |||||
return false; | |||||
} | } | ||||
Status DynamicShapePartitioner::Partition() { | Status DynamicShapePartitioner::Partition() { | ||||
REQUIRE_NOT_NULL(root_graph_, "Graph is nullptr."); | REQUIRE_NOT_NULL(root_graph_, "Graph is nullptr."); | ||||
if (!IsInExperimentalMode(root_graph_)) { | |||||
GELOGD("Skip dynamic shape partition as not in experimental mode."); | |||||
if (IsSingleOpScene(root_graph_)) { | |||||
GELOGD("Skip dynamic shape partition as in single op scene."); | |||||
REQUIRE(AttrUtils::SetBool(*root_graph_, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, false), | REQUIRE(AttrUtils::SetBool(*root_graph_, ATTR_NAME_DYNAMIC_SHAPE_PARTITIONED, false), | ||||
"Failed set dynamic shape partitioned flag on root graph."); | "Failed set dynamic shape partitioned flag on root graph."); | ||||
return SUCCESS; | return SUCCESS; | ||||
@@ -765,6 +765,7 @@ set(MULTI_PARTS_TEST_FILES | |||||
"graph/preprocess/graph_preprocess_unittest.cc" | "graph/preprocess/graph_preprocess_unittest.cc" | ||||
"graph/manager/hcom_util_unittest.cc" | "graph/manager/hcom_util_unittest.cc" | ||||
"graph/manager/graph_caching_allocator_unittest.cc" | "graph/manager/graph_caching_allocator_unittest.cc" | ||||
"graph/partition/dynamic_shape_partition_unittest.cc" | |||||
"session/omg_omg_unittest.cc" | "session/omg_omg_unittest.cc" | ||||
) | ) | ||||
@@ -0,0 +1,97 @@ | |||||
/** | |||||
* Copyright 2019-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. | |||||
*/ | |||||
#include <gtest/gtest.h> | |||||
#include "graph/partition/dynamic_shape_partition.h" | |||||
#include "compute_graph.h" | |||||
#include "inc/framework/common/types.h" | |||||
#include "utils/graph_utils.h" | |||||
#include "graph/debug/ge_attr_define.h" | |||||
#define private public | |||||
#define protected public | |||||
namespace ge { | |||||
namespace { | |||||
GeTensorDescPtr CreateTensorDesc(std::initializer_list<int64_t> shape, Format format = FORMAT_NCHW, | |||||
DataType data_type = DT_FLOAT) { | |||||
GeShape ge_shape{vector<int64_t>(shape)}; | |||||
GeTensorDescPtr tensor_desc = std::make_shared<GeTensorDesc>(); | |||||
tensor_desc->SetShape(ge_shape); | |||||
tensor_desc->SetFormat(format); | |||||
tensor_desc->SetDataType(data_type); | |||||
return tensor_desc; | |||||
} | |||||
class NodeBuilder { | |||||
public: | |||||
NodeBuilder(const std::string &name, const std::string &type) { op_desc_ = std::make_shared<OpDesc>(name, type); } | |||||
NodeBuilder &AddInputDesc(std::initializer_list<int64_t> shape = {1, 1, 224, 224}, Format format = FORMAT_NCHW, | |||||
DataType data_type = DT_FLOAT) { | |||||
op_desc_->AddInputDesc(CreateTensorDesc(shape, format, data_type)->Clone()); | |||||
return *this; | |||||
} | |||||
NodeBuilder &AddOutputDesc(std::initializer_list<int64_t> shape = {1, 1, 224, 224}, Format format = FORMAT_NCHW, | |||||
DataType data_type = DT_FLOAT) { | |||||
op_desc_->AddOutputDesc(CreateTensorDesc(shape, format, data_type)->Clone()); | |||||
return *this; | |||||
} | |||||
NodeBuilder &AddOutputDesc(GeTensorDescPtr tensor_desc) { | |||||
op_desc_->AddOutputDesc(tensor_desc->Clone()); | |||||
return *this; | |||||
} | |||||
NodePtr Build(const ComputeGraphPtr &graph) { | |||||
NodePtr node = graph->AddNode(op_desc_); | |||||
return node; | |||||
} | |||||
private: | |||||
OpDescPtr op_desc_; | |||||
}; | |||||
} // namespace | |||||
class UtestDynamicShapePartition : public testing::Test { | |||||
protected: | |||||
void SetUp() {} | |||||
void TearDown() {} | |||||
}; | |||||
TEST_F(UtestDynamicShapePartition, single_op_scene_success) { | |||||
ComputeGraphPtr graph = std::make_shared<ComputeGraph>("default"); | |||||
NodePtr node1 = | |||||
NodeBuilder("node1", CONSTANTOP).AddInputDesc({1, 1, 224, 224}).AddOutputDesc({1, 1, 224, 224}).Build(graph); | |||||
NodePtr add_n_node = | |||||
NodeBuilder("add_n_node", ADDN).AddInputDesc({1, 1, 224, 224}).AddOutputDesc({1, 1, 224, 224}).Build(graph); | |||||
NodePtr node2 = | |||||
NodeBuilder("node2", RELU).AddInputDesc({1, 1, 224, 224}).AddOutputDesc({1, 1, 224, 224}).Build(graph); | |||||
GraphUtils::AddEdge(node1->GetOutDataAnchor(0), add_n_node->GetInDataAnchor(0)); | |||||
GraphUtils::AddEdge(add_n_node->GetOutDataAnchor(0), node2->GetInDataAnchor(0)); | |||||
(void)AttrUtils::SetBool(add_n_node->GetOpDesc(), ATTR_SINGLE_OP_SCENE, true); | |||||
DynamicShapePartitioner partitioner(graph); | |||||
EXPECT_EQ(partitioner.Partition(), SUCCESS); | |||||
} | |||||
} // namespace ge |