Browse Source

add OptimizeAfterStage1

tags/v1.3.0
wangzhengjun 3 years ago
parent
commit
7089d82c33
5 changed files with 288 additions and 4 deletions
  1. +3
    -2
      ge/graph/manager/graph_manager.cc
  2. +42
    -2
      ge/graph/optimize/graph_optimize.cc
  3. +3
    -0
      ge/graph/optimize/graph_optimize.h
  4. +1
    -0
      tests/ut/ge/CMakeLists.txt
  5. +239
    -0
      tests/ut/ge/graph/optimize/graph_optimize_unittest.cc

+ 3
- 2
ge/graph/manager/graph_manager.cc View File

@@ -886,6 +886,7 @@ Status GraphManager::PreRunOptimizeOriginalGraph(const GraphNodePtr &graph_node,
GM_RUN_AND_DUMP_PERF("OptimizeSwitchOp", stages.preparer.SwitchOpOptimize, compute_graph); GM_RUN_AND_DUMP_PERF("OptimizeSwitchOp", stages.preparer.SwitchOpOptimize, compute_graph);
} }
GM_RUN_AND_DUMP_PERF("Optimize1", OptimizeStage1, compute_graph); GM_RUN_AND_DUMP_PERF("Optimize1", OptimizeStage1, compute_graph);
GM_RUN_AND_DUMP_PERF("OptimizeAfterStage1", stages.optimizer.OptimizeAfterStage1, compute_graph);
GM_RUN_AND_DUMP_PERF("InferShape2", compute_graph->InferShapeInNeed); GM_RUN_AND_DUMP_PERF("InferShape2", compute_graph->InferShapeInNeed);


PassManager graph_pass; PassManager graph_pass;
@@ -3118,7 +3119,7 @@ void GraphManager::PreRunThread(GraphManager *graph_manager) {
GraphNodePtr graph_node = nullptr; GraphNodePtr graph_node = nullptr;
Status ret = graph_manager->GetGraphNode(args.graph_id, graph_node); Status ret = graph_manager->GetGraphNode(args.graph_id, graph_node);
if (ret != SUCCESS) { if (ret != SUCCESS) {
ReturnError(graph_manager, args.callback, GE_GRAPH_ALREADY_RUNNING,
ReturnError(graph_manager, args.callback, GE_GRAPH_GRAPH_NODE_NULL,
"[RunGraph] graph not exist, graph_id=" + std::to_string(args.graph_id)); "[RunGraph] graph not exist, graph_id=" + std::to_string(args.graph_id));
return; return;
} }
@@ -3143,7 +3144,7 @@ void GraphManager::PreRunThread(GraphManager *graph_manager) {
graph_node->Lock(); graph_node->Lock();


if (graph_node->GetRunFlag()) { if (graph_node->GetRunFlag()) {
ReturnError(graph_manager, args.callback, GE_GRAPH_GRAPH_NODE_NULL,
ReturnError(graph_manager, args.callback, GE_GRAPH_ALREADY_RUNNING,
"[RunGraph] graph already running, graph id=" + std::to_string(args.graph_id)); "[RunGraph] graph already running, graph id=" + std::to_string(args.graph_id));
graph_node->Unlock(); graph_node->Unlock();
return; return;


+ 42
- 2
ge/graph/optimize/graph_optimize.cc View File

@@ -155,7 +155,7 @@ Status GraphOptimize::OptimizeOriginalGraph(ComputeGraphPtr &compute_graph) {
} }


auto graph_optimizer = instance_ptr->OpsKernelManagerObj().GetAllGraphOptimizerObjsByPriority(); auto graph_optimizer = instance_ptr->OpsKernelManagerObj().GetAllGraphOptimizerObjsByPriority();
GELOGI("optimize by opskernel in original graph optimize phase. num of graph_optimizer is %lu.",
GELOGI("optimize by opskernel in original graph optimize phase. num of graph_optimizer is %zu.",
graph_optimizer.size()); graph_optimizer.size());
string exclude_core_Type = (core_type_ == kVectorCore) ? kAicoreEngine : kVectorEngine; string exclude_core_Type = (core_type_ == kVectorCore) ? kAicoreEngine : kVectorEngine;
GELOGD("[OptimizeOriginalGraph]: engine type will exclude: %s", exclude_core_Type.c_str()); GELOGD("[OptimizeOriginalGraph]: engine type will exclude: %s", exclude_core_Type.c_str());
@@ -194,7 +194,7 @@ Status GraphOptimize::OptimizeOriginalGraphJudgeInsert(ComputeGraphPtr &compute_
} }


auto graph_optimizer = instance_ptr->OpsKernelManagerObj().GetAllGraphOptimizerObjsByPriority(); auto graph_optimizer = instance_ptr->OpsKernelManagerObj().GetAllGraphOptimizerObjsByPriority();
GELOGI("optimize by opskernel in original graph optimize phase. num of graph_optimizer is %lu.",
GELOGI("optimize by opskernel in judging insert phase. num of graph_optimizer is %zu.",
graph_optimizer.size()); graph_optimizer.size());
string exclude_core_Type = (core_type_ == kVectorCore) ? kAicoreEngine : kVectorEngine; string exclude_core_Type = (core_type_ == kVectorCore) ? kAicoreEngine : kVectorEngine;
if (graph_optimizer.size() != 0) { if (graph_optimizer.size() != 0) {
@@ -294,6 +294,46 @@ Status GraphOptimize::OptimizeGraphBeforeBuildForRts(ComputeGraphPtr &compute_gr
return ret; return ret;
} }


Status GraphOptimize::OptimizeAfterStage1(ComputeGraphPtr &compute_graph) {
GE_CHECK_NOTNULL(compute_graph);
GELOGD("OptimizeAfterStage1 in");
if (GetContext().GetHostExecFlag()) {
// graph exec on host, no need OptimizeAfterStage1
return SUCCESS;
}

Status ret = SUCCESS;
std::shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
if (instance_ptr == nullptr || !instance_ptr->InitFlag()) {
REPORT_INNER_ERROR("E19999", "Gelib not init before, check invalid");
GELOGE(GE_CLI_GE_NOT_INITIALIZED, "OptimizeAfterStage1 failed.");
return GE_CLI_GE_NOT_INITIALIZED;
}

auto graph_optimizer = instance_ptr->OpsKernelManagerObj().GetAllGraphOptimizerObjsByPriority();
GELOGI("Optimize by ops kernel in after stage1 phase, num of graph_optimizer is %zu.", graph_optimizer.size());
string exclude_core_type = (core_type_ == kVectorCore) ? kAicoreEngine : kVectorEngine;
if (graph_optimizer.size() != 0) {
for (auto iter = graph_optimizer.begin(); iter != graph_optimizer.end(); ++iter) {
if (iter->first == exclude_core_type) {
GELOGI("[OptimizeAfterStage1]: engine type will exclude:%s.", exclude_core_type.c_str());
continue;
}
#ifndef ONLY_COMPILE_OPEN_SRC
GELOGI("Begin to optimize graph after stage1 by engine %s.", iter->first.c_str());
ret = (iter->second)->OptimizeAfterStage1(*compute_graph);
#endif
if (ret != SUCCESS) {
REPORT_INNER_ERROR("E19999", "Call OptimizeAfterStage1 failed, ret:%d, engine_name:%s, "
"graph_name:%s.", ret, iter->first.c_str(), compute_graph->GetName().c_str());
GELOGE(ret, "[OptimizeAfterStage1]: graph optimize failed, ret:%d.", ret);
return ret;
}
}
}
return ret;
}

Status GraphOptimize::SetOptions(const ge::GraphManagerOptions &options) { Status GraphOptimize::SetOptions(const ge::GraphManagerOptions &options) {
if (options.framework_type >= static_cast<int32_t>(domi::FrameworkType::FRAMEWORK_RESERVED)) { if (options.framework_type >= static_cast<int32_t>(domi::FrameworkType::FRAMEWORK_RESERVED)) {
REPORT_INNER_ERROR("E19999", "Param framework_type:%d in option check invalid", REPORT_INNER_ERROR("E19999", "Param framework_type:%d in option check invalid",


+ 3
- 0
ge/graph/optimize/graph_optimize.h View File

@@ -58,6 +58,9 @@ class GraphOptimize {
// for rts optimize before build to add attr and insert memcpy op // for rts optimize before build to add attr and insert memcpy op
Status OptimizeGraphBeforeBuildForRts(ComputeGraphPtr &compute_graph); Status OptimizeGraphBeforeBuildForRts(ComputeGraphPtr &compute_graph);


// optimize whole graph, using after stage1
Status OptimizeAfterStage1(ComputeGraphPtr &graph);

// set options // set options
Status SetOptions(const GraphManagerOptions &options); Status SetOptions(const GraphManagerOptions &options);




+ 1
- 0
tests/ut/ge/CMakeLists.txt View File

@@ -803,6 +803,7 @@ set(MULTI_PARTS_TEST_FILES
"graph/partition/dynamic_shape_partition_unittest.cc" "graph/partition/dynamic_shape_partition_unittest.cc"
"graph/manager/graph_manager_unittest.cc" "graph/manager/graph_manager_unittest.cc"
"graph/optimize/mem_rw_conflict_optimize_unittest.cc" "graph/optimize/mem_rw_conflict_optimize_unittest.cc"
"graph/optimize/graph_optimize_unittest.cc"
"session/omg_omg_unittest.cc" "session/omg_omg_unittest.cc"
"session/ge_api_unittest.cc" "session/ge_api_unittest.cc"
"session/inner_session_unittest.cc" "session/inner_session_unittest.cc"


+ 239
- 0
tests/ut/ge/graph/optimize/graph_optimize_unittest.cc View File

@@ -0,0 +1,239 @@
/**
* Copyright 2021 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 <memory>
#include <iostream>
#define protected public
#define private public
#include "graph/optimize/graph_optimize.h"
#include "init/gelib.h"
#include "ge/ge_api.h"
#undef private
#undef protected

using namespace std;
using namespace testing;
using namespace ge;

namespace {
const char *const kVectorCore = "VectorCore";
const char *const kAicoreEngine = "AIcoreEngine";
string CreateEngineConfigJson() {
GELOGI("Begin to create engine config json file.");
string base_path = PluginManager::GetPath();
GELOGI("Base path is %s.", base_path.c_str());
string dir_path = base_path.substr(0, base_path.rfind('/') + 1) + "plugin/nnengine/ge_config";
string cmd = "mkdir -p " + dir_path;
system(cmd.c_str());
string file_path = dir_path + "/engine_conf.json";
GELOGI("Begin to write into the config file: %s.", file_path.c_str());
ofstream ofs(file_path, ios::out);
EXPECT_EQ(!ofs, false);
ofs << "{\n"
" \"schedule_units\" : [ {\n"
" \"id\" : \"TS_1\",\n"
" \"name\" : \"1980_hwts\",\n"
" \"ex_attrs\" : \"\",\n"
" \"cal_engines\" : [\n"
" {\"id\" : \"DNN_VM_GE_LOCAL\", \"name\" : \"GE_LOCAL\", \"independent\" : false, \"attch\" : true, \"skip_assign_stream\" : true },\n"
" {\"id\" : \"AIcoreEngine\", \"name\" : \"AICORE\", \"independent\" : false, \"attch\" : false, \"skip_assign_stream\" : false}\n"
" ]\n"
" } ]\n"
"}";
ofs.close();
GELOGI("Json config file %s has been written.", file_path.c_str());
return file_path;
}

void DeleteFile(const string &file_name) {
auto ret = remove(file_name.c_str());
if (ret == 0) {
GELOGI("Delete file successfully, file:%s.", file_name.c_str());
}
}
}
class UtestGraphOptimizeTest : public testing::Test {
protected:
void SetUp() {
config_file_ = CreateEngineConfigJson();
}

void TearDown() {
DeleteFile(config_file_);
}

private:
string config_file_;
};

class TestGraphOptimizerSuccess : public GraphOptimizer {
public:
~TestGraphOptimizerSuccess() override { Finalize(); }
Status Initialize(const map<string, string> &options) override { return SUCCESS; }
Status Finalize() override { return SUCCESS; }
Status OptimizeGraphPrepare(ComputeGraph& graph) override { return SUCCESS; }
Status OptimizeGraphBeforeBuild(ComputeGraph& graph) override { return SUCCESS; }
Status OptimizeOriginalGraph(ComputeGraph &graph) override { return SUCCESS; }
Status OptimizeOriginalGraphJudgeInsert(ComputeGraph &graph) override { return SUCCESS; }
Status OptimizeFusedGraph(ComputeGraph &graph) override { return SUCCESS; }
Status OptimizeWholeGraph(ComputeGraph &graph) override { return SUCCESS; }
Status GetAttributes(GraphOptimizerAttribute &attrs) const override {
attrs.engineName = "AIcoreEngine";
attrs.scope = OPTIMIZER_SCOPE::ENGINE;
return SUCCESS;
}
Status OptimizeStreamGraph(ComputeGraph &graph, const RunContext &context) override { return SUCCESS; }
Status OptimizeFusedGraphAfterGraphSlice(ComputeGraph &graph) override { return SUCCESS; }
Status OptimizeAfterStage1(ComputeGraph &graph) override { return SUCCESS; }
};

class TestGraphOptimizerFail : public GraphOptimizer {
public:
~TestGraphOptimizerFail() override { Finalize(); }
Status Initialize(const map<string, string> &options) override { return SUCCESS; }
Status Finalize() override { return SUCCESS; }
Status OptimizeGraphPrepare(ComputeGraph& graph) override { return FAILED; }
Status OptimizeGraphBeforeBuild(ComputeGraph& graph) override { return FAILED; }
Status OptimizeOriginalGraph(ComputeGraph &graph) override { return FAILED; }
Status OptimizeOriginalGraphJudgeInsert(ComputeGraph &graph) override { return FAILED; }
Status OptimizeFusedGraph(ComputeGraph &graph) override { return FAILED; }
Status OptimizeWholeGraph(ComputeGraph &graph) override { return FAILED; }
Status GetAttributes(GraphOptimizerAttribute &attrs) const override {
attrs.engineName = "AIcoreEngine";
attrs.scope = OPTIMIZER_SCOPE::ENGINE;
return SUCCESS;
}
Status OptimizeStreamGraph(ComputeGraph &graph, const RunContext &context) override { return FAILED; }
Status OptimizeFusedGraphAfterGraphSlice(ComputeGraph &graph) override { return FAILED; }
Status OptimizeAfterStage1(ComputeGraph &graph) override { return FAILED; }
};

TEST_F(UtestGraphOptimizeTest, test_OptimizeAfterStage1_succ) {
map<string, string> options;
Status ret = ge::GELib::Initialize(options);
EXPECT_EQ(ret, SUCCESS);

shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
EXPECT_NE(instance_ptr, nullptr);
GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerSuccess>();
instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));

ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
GraphOptimize base_optimize;
ret = base_optimize.OptimizeAfterStage1(compute_graph);
EXPECT_EQ(ret, SUCCESS);

base_optimize.core_type_ = kVectorCore;
ret = base_optimize.OptimizeAfterStage1(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = instance_ptr->Finalize();
EXPECT_EQ(ret, SUCCESS);
}

TEST_F(UtestGraphOptimizeTest, test_OptimizeAfterStage1_fail) {
ComputeGraphPtr compute_graph = nullptr;
GraphOptimize base_optimize;

// 1. Input graph is nullptr.
Status ret = base_optimize.OptimizeAfterStage1(compute_graph);
EXPECT_EQ(ret, PARAM_INVALID);

// 2. GELib is not initialized.
compute_graph = MakeShared<ComputeGraph>("test_graph");
ret = base_optimize.OptimizeAfterStage1(compute_graph);
EXPECT_EQ(ret, GE_CLI_GE_NOT_INITIALIZED);

// 3. The optimizer registered with the engine returned a failure.
map<string, string> options;
ret = ge::GELib::Initialize(options);
EXPECT_EQ(ret, SUCCESS);

shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
EXPECT_NE(instance_ptr, nullptr);
GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerFail>();
instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));
ret = base_optimize.OptimizeAfterStage1(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = instance_ptr->Finalize();
EXPECT_EQ(ret, SUCCESS);
}

TEST_F(UtestGraphOptimizeTest, test_optimizers_succ) {
map<string, string> options;
Status ret = ge::GELib::Initialize(options);
EXPECT_EQ(ret, SUCCESS);

shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
EXPECT_NE(instance_ptr, nullptr);
GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerSuccess>();
instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));

ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
GraphOptimize base_optimize;

ret = base_optimize.OptimizeOriginalGraph(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = base_optimize.OptimizeOriginalGraphJudgeInsert(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = base_optimize.OptimizeOriginalGraphForQuantize(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = base_optimize.OptimizeGraphBeforeBuildForRts(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = base_optimize.OptimizeWholeGraph(compute_graph);
EXPECT_EQ(ret, SUCCESS);

ret = instance_ptr->Finalize();
EXPECT_EQ(ret, SUCCESS);
}

TEST_F(UtestGraphOptimizeTest, test_optimizers_fail) {
map<string, string> options;
Status ret = ge::GELib::Initialize(options);
EXPECT_EQ(ret, SUCCESS);

shared_ptr<GELib> instance_ptr = ge::GELib::GetInstance();
EXPECT_NE(instance_ptr, nullptr);
GraphOptimizerPtr graph_opt = MakeShared<TestGraphOptimizerFail>();
instance_ptr->opsManager_.graph_optimizers_by_priority_.push_back(make_pair("AIcoreEngine", graph_opt));

ComputeGraphPtr compute_graph = MakeShared<ComputeGraph>("test_graph");
GraphOptimize base_optimize;

ret = base_optimize.OptimizeOriginalGraph(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = base_optimize.OptimizeOriginalGraphJudgeInsert(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = base_optimize.OptimizeOriginalGraphForQuantize(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = base_optimize.OptimizeGraphBeforeBuildForRts(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = base_optimize.OptimizeWholeGraph(compute_graph);
EXPECT_EQ(ret, FAILED);

ret = instance_ptr->Finalize();
EXPECT_EQ(ret, SUCCESS);
}

Loading…
Cancel
Save