forked from huawei/mindspore2022
!27792 add add,concat and activation fusion
Merge pull request !27792 from wangyanling/concatactivation
This commit is contained in:
commit
375ee5691f
|
|
@ -113,15 +113,7 @@ if(MSLITE_ENABLE_CONVERTER)
|
|||
${TEST_DIR}/st/graph_test.cc
|
||||
${TEST_DIR}/st/sub_graph_test.cc
|
||||
${TEST_DIR}/ut/src/dynamic_library_loader_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/fusion_inout_test/fusion_inout_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/fusion_inout_test/conv_fusion_inout_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/fusion_inout_test/conv_act_fusion_inout_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/fusion_inout_test/conv_bias_fusion_inout_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/conv_biasadd_fusion_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/conv_bn_fusion_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/conv_scale_fusion_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/conv_activation_fusion_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/constant_folding_fusion_test.cc
|
||||
${TEST_DIR}/ut/tools/optimizer/fusion/*.cc
|
||||
)
|
||||
list(APPEND TEST_UT_SRC ${TEST_CONVERTER_UT_SRC})
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ echo 'run common ut tests'
|
|||
## ./lite-test --gtest_filter="TestTfliteParser*"
|
||||
./lite-test --gtest_filter="ConvActFusionInoutTest*"
|
||||
./lite-test --gtest_filter="ConvBiasFusionInoutTest*"
|
||||
|
||||
./lite-test --gtest_filter="ConcatActFusionInoutTest*"
|
||||
# test cases of framework
|
||||
|
||||
# test cases of FP32 OP
|
||||
|
|
|
|||
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* Copyright 2020-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 <memory>
|
||||
#include "schema/inner/model_generated.h"
|
||||
#include "include/model.h"
|
||||
#include "common/common_test.h"
|
||||
#include "include/lite_session.h"
|
||||
#include "include/context.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "tools/converter/anf_transform.h"
|
||||
#include "tools/anf_exporter/anf_exporter.h"
|
||||
#include "tools/optimizer/common/gllo_utils.h"
|
||||
#include "test/common/import_from_meta_graphT.h"
|
||||
|
||||
namespace mindspore {
|
||||
constexpr size_t kAddInputTensorWSize = 128;
|
||||
constexpr size_t kConcatInputTensorWDims = 256;
|
||||
constexpr size_t kGraphNodeSize = 3;
|
||||
class AddConcatActivationFusionTest : public mindspore::CommonTest {
|
||||
public:
|
||||
AddConcatActivationFusionTest() = default;
|
||||
};
|
||||
using MetaGraphTptr = std::shared_ptr<schema::MetaGraphT>;
|
||||
using CNodeTptr = std::unique_ptr<schema::CNodeT>;
|
||||
|
||||
namespace {
|
||||
CNodeTptr BuildAdd(const string &name, std::vector<uint32_t> input_index, std::vector<uint32_t> output_index) {
|
||||
auto add_node = std::make_unique<schema::CNodeT>();
|
||||
add_node->inputIndex = input_index;
|
||||
add_node->outputIndex = output_index;
|
||||
add_node->primitive = std::make_unique<schema::PrimitiveT>();
|
||||
add_node->primitive->value.type = schema::PrimitiveType_AddFusion;
|
||||
auto prim1 = new schema::AddFusionT;
|
||||
prim1->activation_type = mindspore::schema::ActivationType_NO_ACTIVATION;
|
||||
add_node->primitive->value.value = prim1;
|
||||
add_node->name = name;
|
||||
return add_node;
|
||||
}
|
||||
|
||||
CNodeTptr BuildConcat() {
|
||||
auto concat_node = std::make_unique<schema::CNodeT>();
|
||||
concat_node->inputIndex = {opt::kInputIndexTwo, opt::kInputIndexFive};
|
||||
concat_node->outputIndex = {opt::kInputIndexSix};
|
||||
concat_node->primitive = std::make_unique<schema::PrimitiveT>();
|
||||
concat_node->primitive->value.type = schema::PrimitiveType_Concat;
|
||||
auto prim1 = new schema::ConcatT;
|
||||
prim1->axis = 1;
|
||||
concat_node->primitive->value.value = prim1;
|
||||
concat_node->name = "Concat";
|
||||
return concat_node;
|
||||
}
|
||||
|
||||
void BuildTensorT(const std::unique_ptr<schema::TensorT> &input, std::vector<int32_t> shape) {
|
||||
input->nodeType = lite::NodeType_Parameter;
|
||||
input->format = schema::Format_NHWC;
|
||||
input->dataType = TypeId::kNumberTypeFloat32;
|
||||
input->dims = shape;
|
||||
return;
|
||||
}
|
||||
|
||||
MetaGraphTptr BuildGraph(schema::ActivationType activation_type) {
|
||||
auto meta_graph = std::make_shared<schema::MetaGraphT>();
|
||||
meta_graph->name = "graph";
|
||||
|
||||
// add node1
|
||||
std::vector<uint32_t> input_index{0, 1};
|
||||
std::vector<uint32_t> output_index{opt::kInputIndexTwo};
|
||||
auto add_node1 = BuildAdd("add_node1", input_index, output_index);
|
||||
meta_graph->nodes.emplace_back(std::move(add_node1));
|
||||
|
||||
// add node2
|
||||
input_index = std::vector<uint32_t>({opt::kInputIndexThree, opt::kInputIndexFour});
|
||||
output_index = std::vector<uint32_t>({opt::kInputIndexFive});
|
||||
auto add_node2 = BuildAdd("add_node2", input_index, output_index);
|
||||
meta_graph->nodes.emplace_back(std::move(add_node2));
|
||||
|
||||
// concat node
|
||||
auto caoncat_node = BuildConcat();
|
||||
meta_graph->nodes.emplace_back(std::move(caoncat_node));
|
||||
|
||||
// relu node
|
||||
auto next_node = std::make_unique<schema::CNodeT>();
|
||||
next_node->inputIndex = {opt::kInputIndexSix};
|
||||
next_node->outputIndex = {opt::kInputIndexSeven};
|
||||
next_node->primitive = std::make_unique<schema::PrimitiveT>();
|
||||
next_node->primitive->value.type = schema::PrimitiveType_Activation;
|
||||
auto prim4 = new schema::ActivationT;
|
||||
prim4->activation_type = activation_type;
|
||||
next_node->primitive->value.value = prim4;
|
||||
next_node->name = "activation";
|
||||
meta_graph->nodes.emplace_back(std::move(next_node));
|
||||
|
||||
meta_graph->inputIndex = {0, 1, opt::kInputIndexThree, opt::kInputIndexFour};
|
||||
meta_graph->outputIndex = {opt::kInputIndexSeven};
|
||||
|
||||
// input 0: data
|
||||
auto input0 = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(input0, {1, kAddInputTensorWSize});
|
||||
input0->offset = -1;
|
||||
meta_graph->allTensors.emplace_back(std::move(input0));
|
||||
|
||||
// input 1: data
|
||||
auto input2 = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(input2, {1, kAddInputTensorWSize});
|
||||
input2->offset = -1;
|
||||
meta_graph->allTensors.emplace_back(std::move(input2));
|
||||
|
||||
// output 1: data
|
||||
auto add_node1_out = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(add_node1_out, {1, kAddInputTensorWSize});
|
||||
meta_graph->allTensors.emplace_back(std::move(add_node1_out));
|
||||
|
||||
// input 2: data
|
||||
auto add_node2_input1 = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(add_node2_input1, {1, kAddInputTensorWSize});
|
||||
add_node2_input1->offset = -1;
|
||||
meta_graph->allTensors.emplace_back(std::move(add_node2_input1));
|
||||
|
||||
// input 3: data
|
||||
auto add_node2_input2 = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(add_node2_input2, {1, kAddInputTensorWSize});
|
||||
add_node2_input2->offset = -1;
|
||||
meta_graph->allTensors.emplace_back(std::move(add_node2_input2));
|
||||
|
||||
// output 2: data
|
||||
auto add_node2_out = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(add_node2_out, {1, kAddInputTensorWSize});
|
||||
meta_graph->allTensors.emplace_back(std::move(add_node2_out));
|
||||
|
||||
// concat output
|
||||
auto concat_output = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(concat_output, {1, kConcatInputTensorWDims});
|
||||
meta_graph->allTensors.emplace_back(std::move(concat_output));
|
||||
|
||||
// final output
|
||||
auto output = std::make_unique<schema::TensorT>();
|
||||
BuildTensorT(output, {1, kConcatInputTensorWDims});
|
||||
meta_graph->allTensors.emplace_back(std::move(output));
|
||||
return meta_graph;
|
||||
}
|
||||
} // namespace
|
||||
TEST_F(AddConcatActivationFusionTest, TestAddConcatReluNode) {
|
||||
auto meta_graph = BuildGraph(schema::ActivationType_RELU6);
|
||||
auto func_graph = lite::AnfImporterFromMetaGraphT::Fb2Anf(meta_graph.get());
|
||||
auto anf_transform = new lite::AnfTransform();
|
||||
auto new_graph = anf_transform->Transform(func_graph);
|
||||
ASSERT_NE(nullptr, new_graph);
|
||||
auto new_meta_graph = lite::Export(new_graph);
|
||||
ASSERT_EQ(new_meta_graph->nodes.size(), kGraphNodeSize);
|
||||
for (auto &cnode : new_meta_graph->nodes) {
|
||||
if (cnode->primitive->value.type == schema::PrimitiveType_AddFusion) {
|
||||
ASSERT_EQ(cnode->primitive->value.AsAddFusion()->activation_type, schema::ActivationType_RELU6);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace mindspore
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* 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 <string>
|
||||
#include <memory>
|
||||
#include "test/ut/tools/optimizer/fusion/fusion_inout_test/fusion_inout_test.h"
|
||||
#include "ir/anf.h"
|
||||
#include "backend/optimizer/common/pass.h"
|
||||
#include "backend/optimizer/common/optimizer.h"
|
||||
#include "backend/optimizer/common/pass_manager.h"
|
||||
#include "tools/optimizer/fusion/add_concat_activation_fusion.h"
|
||||
#include "backend/kernel_compiler/cpu/nnacl/op_base.h"
|
||||
#include "ops/fusion/activation.h"
|
||||
#include "ops/concat.h"
|
||||
#include "ops/fusion/add_fusion.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace {
|
||||
constexpr size_t kAddInputTensorWSize = 128;
|
||||
}
|
||||
class ConcatActFusionInoutTest : public FusionInoutTest {
|
||||
public:
|
||||
ConcatActFusionInoutTest() = default;
|
||||
|
||||
protected:
|
||||
void InitPass() override { this->pass_ = std::make_shared<opt::AddConcatActivationFusion>(); }
|
||||
|
||||
void InitGraph() override {
|
||||
this->graph_ = std::make_shared<FuncGraph>();
|
||||
MS_CHECK_TRUE_MSG(graph_ != nullptr, , "Create FuncGraph failed");
|
||||
auto left_add_node = AddAdd(graph_, "left_add_node");
|
||||
if (left_add_node == nullptr) {
|
||||
this->graph_ = nullptr;
|
||||
return;
|
||||
}
|
||||
auto right_add_node = AddAdd(graph_, "right_add_node");
|
||||
if (right_add_node == nullptr) {
|
||||
this->graph_ = nullptr;
|
||||
return;
|
||||
}
|
||||
auto concat_node = AddConcat(graph_, left_add_node, right_add_node, "concat");
|
||||
if (concat_node == nullptr) {
|
||||
this->graph_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
auto act = AddAct(graph_, concat_node, "concat_act");
|
||||
if (act == nullptr) {
|
||||
this->graph_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
auto ret = AddReturn(graph_, {act});
|
||||
if (ret == nullptr) {
|
||||
this->graph_ = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
CNodePtr AddAdd(const FuncGraphPtr &graph, const std::string &name) {
|
||||
AnfNodePtr input1 =
|
||||
AddParameter(graph_, 0, {add_left_h_, add_left_w_}, kNumberTypeFloat32, "graph_" + name + "_input1");
|
||||
AnfNodePtr input2 =
|
||||
AddParameter(graph_, 0, {add_left_h_, add_left_w_}, kNumberTypeFloat32, "graph_" + name + "_input2");
|
||||
auto prim = std::make_unique<ops::AddFusion>();
|
||||
MS_CHECK_TRUE_MSG(prim != nullptr, nullptr, "create AddFusion primitivec failed");
|
||||
prim->Init(ActivationType::NO_ACTIVATION);
|
||||
auto add_primitive = NewValueNode(std::shared_ptr<ops::PrimitiveC>(prim.release()));
|
||||
MS_CHECK_TRUE_RET(add_primitive != nullptr, nullptr);
|
||||
auto add_fusion = graph->NewCNode({add_primitive, input1, input2});
|
||||
MS_CHECK_TRUE_MSG(add_fusion != nullptr, nullptr, "create AddFusion failed");
|
||||
add_fusion->set_fullname_with_scope(name);
|
||||
return add_fusion;
|
||||
}
|
||||
|
||||
CNodePtr AddConcat(const FuncGraphPtr &graph, const AnfNodePtr &input1, const AnfNodePtr &input2,
|
||||
const std::string &name) {
|
||||
auto concat_primitive = std::make_unique<ops::Concat>();
|
||||
MS_CHECK_TRUE_MSG(concat_primitive != nullptr, nullptr, "create concat primitivec failed");
|
||||
concat_primitive->Init();
|
||||
concat_primitive->set_axis(1);
|
||||
auto concat_primc = NewValueNode(std::shared_ptr<ops::PrimitiveC>(concat_primitive.release()));
|
||||
MS_CHECK_TRUE_RET(concat_primc != nullptr, nullptr);
|
||||
auto concat = graph->NewCNode({concat_primc, input1, input2});
|
||||
MS_CHECK_TRUE_MSG(concat != nullptr, nullptr, "create Concat failed");
|
||||
concat->set_fullname_with_scope(name);
|
||||
return concat;
|
||||
}
|
||||
|
||||
CNodePtr AddAct(const FuncGraphPtr &graph, const AnfNodePtr &input, const std::string &name) {
|
||||
auto prim = std::make_unique<ops::Activation>();
|
||||
MS_CHECK_TRUE_MSG(prim != nullptr, nullptr, "create Act primitivec failed");
|
||||
prim->Init();
|
||||
prim->set_activation_type(ActivationType::RELU6);
|
||||
auto act_primitive = NewValueNode(std::shared_ptr<ops::PrimitiveC>(prim.release()));
|
||||
MS_CHECK_TRUE_RET(act_primitive != nullptr, nullptr);
|
||||
auto act = graph->NewCNode({act_primitive, input});
|
||||
MS_CHECK_TRUE_MSG(act != nullptr, nullptr, "create Act failed");
|
||||
act->set_fullname_with_scope(name);
|
||||
return act;
|
||||
}
|
||||
|
||||
private:
|
||||
int add_left_h_ = 1;
|
||||
int add_left_w_ = kAddInputTensorWSize;
|
||||
};
|
||||
|
||||
TEST_F(ConcatActFusionInoutTest, test) { ASSERT_EQ(DoTest(), true); }
|
||||
} // namespace mindspore
|
||||
|
|
@ -67,8 +67,11 @@ ParameterPtr FusionInoutTest::AddParameter(const FuncGraphPtr &graph, size_t dat
|
|||
}
|
||||
}
|
||||
auto tensor_info = lite::CreateTensorInfo(data, data_size, shape, data_type);
|
||||
free(data);
|
||||
data = nullptr;
|
||||
if (data != nullptr) {
|
||||
free(data);
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
if (tensor_info == nullptr) {
|
||||
MS_LOG(ERROR) << "CreateTensorInfo failed";
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "tools/optimizer/fusion/scale_activation_fusion.h"
|
||||
#include "tools/optimizer/fusion/scale_scale_fusion.h"
|
||||
#include "tools/optimizer/fusion/fullconnected_fusion.h"
|
||||
#include "tools/optimizer/fusion/add_concat_activation_fusion.h"
|
||||
#include "tools/optimizer/graph/add_tensor_array.h"
|
||||
#include "tools/optimizer/graph/redundant_op_remove_pass.h"
|
||||
#include "tools/optimizer/graph/clip_convert_activation_pass.h"
|
||||
|
|
@ -178,6 +179,7 @@ int AnfTransform::RunFusionPass(const FuncGraphPtr &old_graph, const converter::
|
|||
|
||||
// The training model only does the fusion of the inference part
|
||||
// remove quantdtype when awaretraining
|
||||
fusion_pm->AddPass(std::make_shared<opt::AddConcatActivationFusion>());
|
||||
fusion_pm->AddPass(std::make_shared<opt::SqueezeFusion>());
|
||||
fusion_pm->AddPass(std::make_shared<opt::TransposeFusion>());
|
||||
fusion_pm->AddPass(std::make_shared<opt::ReshapeReshapeFusion>());
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ inline constexpr int kInputIndexTwo = 2;
|
|||
inline constexpr int kInputIndexThree = 3;
|
||||
inline constexpr int kInputIndexFour = 4;
|
||||
inline constexpr int kInputIndexFive = 5;
|
||||
inline constexpr int kInputIndexSix = 6;
|
||||
inline constexpr int kInputIndexSeven = 7;
|
||||
inline constexpr size_t kInputSizeTwo = 2;
|
||||
inline constexpr size_t kInputSizeThree = 3;
|
||||
inline constexpr size_t kInputSizeFour = 4;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* 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 "tools/optimizer/fusion/add_concat_activation_fusion.h"
|
||||
#include <memory>
|
||||
#include "ops/concat.h"
|
||||
#include "ops/fusion/activation.h"
|
||||
#include "ops/fusion/add_fusion.h"
|
||||
#include "tools/optimizer/common/gllo_utils.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
namespace mindspore::opt {
|
||||
const BaseRef AddConcatActivationFusion::DefinePattern() const {
|
||||
auto is_act = std::make_shared<CondVar>(IsSpecifiedNode<&prim::kPrimActivation>);
|
||||
MS_CHECK_TRUE_RET(is_act != nullptr, {});
|
||||
auto is_concat = std::make_shared<CondVar>(IsSpecifiedNode<&prim::kPrimConcat>);
|
||||
MS_CHECK_TRUE_RET(is_concat != nullptr, {});
|
||||
auto is_seq_var = std::make_shared<SeqVar>();
|
||||
MS_CHECK_TRUE_RET(is_seq_var != nullptr, {});
|
||||
VectorRef pattern_ref = VectorRef({is_act, is_concat, is_seq_var});
|
||||
return pattern_ref;
|
||||
}
|
||||
|
||||
const AnfNodePtr AddConcatActivationFusion::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node,
|
||||
const EquivPtr &) const {
|
||||
if (func_graph == nullptr || node == nullptr) {
|
||||
lite::ReturnCode::GetSingleReturnCode()->UpdateReturnCode(lite::RET_NULL_PTR);
|
||||
return nullptr;
|
||||
}
|
||||
if (!CheckPrimitiveType(node, prim::kPrimActivation)) {
|
||||
MS_LOG(INFO) << "node is not activation node";
|
||||
return nullptr;
|
||||
}
|
||||
auto act_cnode = node->cast<CNodePtr>();
|
||||
MS_CHECK_TRUE_RET(act_cnode != nullptr, nullptr);
|
||||
auto concat_node = act_cnode->input(1);
|
||||
auto concat_cnode = concat_node->cast<CNodePtr>();
|
||||
MS_CHECK_TRUE_RET(concat_node != nullptr, nullptr);
|
||||
if (concat_cnode->size() != kInputIndexThree || !utils::isa<CNode>(concat_cnode->input(kInputIndexTwo))) {
|
||||
MS_LOG(INFO) << "concat node must link two add node in front";
|
||||
return nullptr;
|
||||
}
|
||||
auto right_add_node = concat_cnode->input(1);
|
||||
MS_CHECK_TRUE_RET(right_add_node != nullptr, nullptr);
|
||||
if (!CheckPrimitiveType(right_add_node, prim::kPrimAddFusion)) {
|
||||
MS_LOG(INFO) << "right node is not add node";
|
||||
return nullptr;
|
||||
}
|
||||
auto right_add_cnode = right_add_node->cast<CNodePtr>();
|
||||
auto right_add_prim = GetValueNode<std::shared_ptr<ops::AddFusion>>(right_add_cnode->input(0));
|
||||
MS_CHECK_TRUE_RET(right_add_prim != nullptr, nullptr);
|
||||
if (right_add_prim->GetAttr(ops::kActivationType) == nullptr) {
|
||||
right_add_prim->AddAttr(ops::kActivationType, MakeValue<int64_t>(ActivationType::NO_ACTIVATION));
|
||||
}
|
||||
if (right_add_prim->get_activation_type() != ActivationType::NO_ACTIVATION) {
|
||||
MS_LOG(INFO) << "right add node has activation";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto left_add_node = concat_cnode->input(kInputIndexTwo);
|
||||
MS_CHECK_TRUE_RET(left_add_node != nullptr, nullptr);
|
||||
if (!CheckPrimitiveType(left_add_node, prim::kPrimAddFusion)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto left_add_cnode = left_add_node->cast<CNodePtr>();
|
||||
auto left_add_prim = GetValueNode<std::shared_ptr<ops::AddFusion>>(left_add_cnode->input(0));
|
||||
MS_CHECK_TRUE_RET(left_add_prim != nullptr, nullptr);
|
||||
if (left_add_prim->GetAttr(ops::kActivationType) == nullptr) {
|
||||
left_add_prim->AddAttr(ops::kActivationType, MakeValue<int64_t>(ActivationType::NO_ACTIVATION));
|
||||
}
|
||||
if (left_add_prim->get_activation_type() != ActivationType::NO_ACTIVATION) {
|
||||
MS_LOG(INFO) << "left add node has activation";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto act_prim = GetValueNode<std::shared_ptr<ops::Activation>>(act_cnode->input(0));
|
||||
MS_CHECK_TRUE_RET(act_prim != nullptr, nullptr);
|
||||
if (act_prim->GetAttr(ops::kActivationType) != nullptr) {
|
||||
right_add_prim->set_activation_type(act_prim->get_activation_type());
|
||||
left_add_prim->set_activation_type(act_prim->get_activation_type());
|
||||
}
|
||||
|
||||
// delete activation node
|
||||
auto manager = func_graph->manager();
|
||||
MS_CHECK_TRUE_RET(manager != nullptr, nullptr);
|
||||
(void)manager->Replace(act_cnode, act_cnode->input(1));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace mindspore::opt
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_TOOLS_OPTIMIZER_FUSION_ADD_CONCAT_ACTIVATION_FUSION_H_
|
||||
#define MINDSPORE_LITE_TOOLS_OPTIMIZER_FUSION_ADD_CONCAT_ACTIVATION_FUSION_H_
|
||||
|
||||
#include <string>
|
||||
#include "backend/optimizer/common/optimizer.h"
|
||||
|
||||
namespace mindspore::opt {
|
||||
class AddConcatActivationFusion : public PatternProcessPass {
|
||||
public:
|
||||
explicit AddConcatActivationFusion(bool multigraph = true, const std::string &name = "AddConcatActivationFusion")
|
||||
: PatternProcessPass(name, multigraph) {}
|
||||
~AddConcatActivationFusion() override = default;
|
||||
|
||||
private:
|
||||
const BaseRef DefinePattern() const override;
|
||||
const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override;
|
||||
};
|
||||
} // namespace mindspore::opt
|
||||
#endif // MINDSPORE_LITE_TOOLS_OPTIMIZER_FUSION_ADD_CONCAT_ACTIVATION_FUSION_H_
|
||||
Loading…
Reference in New Issue