Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NNAdapter][Ascend] Support transformer model #8594

Merged
merged 5 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ namespace huawei_ascend_npu {

int ConvertRange(Converter* converter, core::Operation* operation) {
RANGE_OPERATION_EXTRACT_INPUTS_OUTPUTS
NNADAPTER_CHECK(IsOperationWithAllInputConstantOperands(operation))
<< "Range input operands only support constant!";

// Convert to GE operators
auto start_operator = converter->GetMappedOperator(start_operand);
Expand Down
2 changes: 2 additions & 0 deletions lite/backends/nnadapter/nnadapter/src/operation/cast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "operation/cast.h"
#include "core/types.h"
#include "utility/debug.h"
#include "utility/hints.h"
#include "utility/logging.h"
#include "utility/modeling.h"
#include "utility/utility.h"
Expand All @@ -28,6 +29,7 @@ int PrepareCast(core::Operation* operation) {
// Infer the shape and type of output operands
CopyOperandTypeExceptQuantParams(&output_operand->type, input_operand->type);
output_operand->type.precision = dtype;
SetTemporaryShape(output_operand, input_operand->type.dimensions);
NNADAPTER_VLOG(5) << "output: " << OperandToString(output_operand);
return NNADAPTER_NO_ERROR;
}
Expand Down
38 changes: 28 additions & 10 deletions lite/backends/nnadapter/nnadapter/src/operation/range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,28 @@
#include "operation/range.h"
#include "core/types.h"
#include "utility/debug.h"
#include "utility/hints.h"
#include "utility/logging.h"
#include "utility/modeling.h"
#include "utility/utility.h"

namespace nnadapter {
namespace operation {

void GetRangeOperandValue(core::Operand* operand, int64_t* data) { // NOLINT
if (IsConstantOperand(operand)) {
*data = reinterpret_cast<int64_t*>(operand->buffer)[0];
} else if (IsTemporaryShapeOperand(operand)) {
auto& temporary_shape = *(GetTemporaryShape(operand));
NNADAPTER_CHECK_EQ(temporary_shape.count, 1);
*data = temporary_shape.data[0];
} else {
NNADAPTER_LOG(FATAL) << "Unsupported operand precision"
<< OperandPrecisionCodeToString(
operand->type.precision);
}
}

int PrepareRange(core::Operation* operation) {
RANGE_OPERATION_EXTRACT_INPUTS_OUTPUTS

Expand All @@ -31,19 +46,22 @@ int PrepareRange(core::Operation* operation) {
NNADAPTER_CHECK_EQ(limit_operand->type.dimensions.count, 1);
NNADAPTER_CHECK_EQ(delta_operand->type.dimensions.count, 1);

if (IsConstantOperand(start_operand) && IsConstantOperand(limit_operand) &&
IsConstantOperand(delta_operand)) {
auto start_data = reinterpret_cast<float*>(start_operand->buffer)[0];
auto limit_data = reinterpret_cast<float*>(limit_operand->buffer)[0];
auto delta_data = reinterpret_cast<float*>(delta_operand->buffer)[0];
int64_t start_data, limit_data, delta_data;
start_data = limit_data = delta_data = -1;
GetRangeOperandValue(start_operand, &start_data);
GetRangeOperandValue(limit_operand, &limit_data);
GetRangeOperandValue(delta_operand, &delta_data);

output_type.dimensions.count = 1;
output_type.precision = start_operand->type.precision;
output_type.lifetime = NNADAPTER_TEMPORARY_VARIABLE;
if (start_data == NNADAPTER_UNKNOWN || limit_data == NNADAPTER_UNKNOWN ||
delta_data == NNADAPTER_UNKNOWN) {
output_type.dimensions.data[0] = NNADAPTER_UNKNOWN;
} else {
output_type.dimensions.data[0] =
GetSpanCount(start_data, limit_data, delta_data);
} else {
output_type.dimensions.data[0] = NNADAPTER_UNKNOWN;
}
output_type.precision = start_operand->type.precision;
output_type.lifetime = NNADAPTER_TEMPORARY_VARIABLE;
output_type.dimensions.count = 1;

NNADAPTER_VLOG(5) << "output: " << OperandToString(output_operand);
return NNADAPTER_NO_ERROR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -36,6 +37,20 @@ void AssignValueCalcOfflinePass::RemoveAssignValuePattern(
const std::unique_ptr<SSAGraph>& graph) {
for (auto& node : graph->StmtTopologicalOrder()) {
if (node->AsStmt().op_type() != "assign_value") continue;
auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(
graph.get(), out_link->arg()->name, {"assign_value"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "The output var of op is not supported with multiple producers";
continue;
}

std::set<const Node*> nodes2rm_;
auto& assign_value_instruct = node->AsStmt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -45,7 +46,20 @@ void FillConstantCalcOfflinePass::RemoveFillConstantPattern(
const std::unique_ptr<SSAGraph>& graph) {
for (auto& node : graph->StmtTopologicalOrder()) {
if (node->AsStmt().op_type() != "fill_constant") continue;

auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(
graph.get(), out_link->arg()->name, {"fill_constant"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "Unsupported for op output var containing multiple producers";
continue;
}
std::set<const Node*> nodes2rm_;
auto& fill_constant_instruct = node->AsStmt();
auto* scope = fill_constant_instruct.op()->scope();
Expand Down
14 changes: 14 additions & 0 deletions lite/core/optimizer/mir/elimination/range_calc_offline_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -43,6 +44,19 @@ void RangeCalcOfflinePass::RemoveRangePattern(
const std::unique_ptr<SSAGraph>& graph) {
for (auto& node : graph->StmtTopologicalOrder()) {
if (node->AsStmt().op_type() != "range") continue;
auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(graph.get(), out_link->arg()->name, {"range"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "Unsupported for op output var containing multiple producers";
continue;
}

std::set<const Node*> nodes2rm_;
auto& range_instruct = node->AsStmt();
Expand Down
14 changes: 14 additions & 0 deletions lite/core/optimizer/mir/elimination/scale_calc_offline_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -36,6 +37,19 @@ void ScaleCalcOfflinePass::RemoveScalePattern(
const std::unique_ptr<SSAGraph>& graph) {
for (auto& node : graph->StmtTopologicalOrder()) {
if (node->AsStmt().op_type() != "scale") continue;
auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(graph.get(), out_link->arg()->name, {"scale"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "Unsupported for op output var containing multiple producers";
continue;
}

std::set<const Node*> nodes2rm_;
auto& scale_instruct = node->AsStmt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -41,6 +42,21 @@ void SSDBoxesCalcOfflinePass::RemovePriorboxPattern(
if (node->AsStmt().op_type() != "prior_box" &&
node->AsStmt().op_type() != "density_prior_box")
continue;
auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(graph.get(),
out_link->arg()->name,
{"prior_box", "density_prior_box"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "Unsupported for op output var containing multiple producers";
continue;
}

std::set<const Node*> nodes2rm_;
auto& priorbox_instruct = node->AsStmt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lite/core/optimizer/mir/pass.h"
#include "lite/core/optimizer/mir/pass_registry.h"
#include "lite/core/optimizer/mir/pattern_matcher.h"
#include "lite/core/optimizer/mir/ssa_graph_utils.h"
#include "lite/model_parser/cpp_desc.h"

namespace paddle {
Expand All @@ -38,6 +39,21 @@ void UnsqueezeCalcOfflinePass::RemoveUnsqueezePattern(
if (node->AsStmt().op_type() != "unsqueeze" &&
node->AsStmt().op_type() != "unsqueeze2")
continue;
auto outlinks = node->outlinks;
bool has_extra_producers = false;
for (auto& out_link : outlinks) {
if (HasExtraProducers(graph.get(),
out_link->arg()->name,
{"unsqueeze", "unsqueeze2"})) {
has_extra_producers = true;
break;
}
}
if (has_extra_producers) {
LOG(WARNING)
<< "Unsupported for op output var containing multiple producers";
continue;
}

std::set<const Node*> nodes2rm_;
auto& unsqueeze_instruct = node->AsStmt();
Expand Down
45 changes: 45 additions & 0 deletions lite/core/optimizer/mir/ssa_graph_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "lite/core/optimizer/mir/ssa_graph_utils.h"

namespace paddle {
namespace lite {
namespace mir {

bool HasExtraProducers(mir::SSAGraph *graph,
const std::string &var_name,
const std::set<std::string> &exclude_op_list,
const std::set<std::string> &candidate_op) {
for (auto &op_node : graph->StmtTopologicalOrder()) {
if (!op_node->IsStmt()) continue;
auto op_info = op_node->AsStmt().op_info();
auto op_type = op_info->Type();
if (exclude_op_list.count(op_type)) continue;
if (candidate_op.empty() || candidate_op.count(op_type)) {
for (auto &var_node : op_node->outlinks) {
if (var_name == var_node->AsArg().name ||
var_node->AsArg().name.find(std::string(var_name + "__Mangled_")) !=
std::string::npos) {
return true;
}
}
}
}
return false;
}

} // namespace mir
} // namespace lite
} // namespace paddle
34 changes: 34 additions & 0 deletions lite/core/optimizer/mir/ssa_graph_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
//
// 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.

#pragma once

#include <memory>
#include <set>
#include <string>
#include "lite/core/optimizer/mir/ssa_graph.h"

namespace paddle {
namespace lite {
namespace mir {

bool HasExtraProducers(mir::SSAGraph *graph,
const std::string &var_name,
const std::set<std::string> &exclude_op_list,
const std::set<std::string> &candidate_op = {
"while", "conditional_block", "increment"});

} // namespace mir
} // namespace lite
} // namespace paddle
3 changes: 2 additions & 1 deletion lite/core/optimizer/optimizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ void Optimizer::ApplyPasses(
<< " because the target or kernel does not match.";
} else {
// Check the pass whether it is supported for processing subblocks
if (kSubblockUnsupportedPasses.count(pass->name())) {
if (kSubblockUnsupportedPasses.count(pass->name()) ||
kSubblockSkippedPasses.count(pass->name())) {
pass->Apply((*graphes)[kRootBlockIdx]);
} else {
for (auto& graph : *graphes) {
Expand Down
9 changes: 9 additions & 0 deletions lite/core/optimizer/optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ namespace lite {
const std::set<std::string> kSubblockUnsupportedPasses(
{"memory_optimize_pass", "xpu_memory_optimize_pass"});

const std::set<std::string> kSubblockSkippedPasses(
{"fill_constant_calc_offline_pass",
"scale_calc_offline_pass",
"unsqueeze_calc_offline_pass",
"range_calc_offline_pass",
"assign_value_calc_offline_pass",
"ssd_boxes_calc_offline_pass",
"p_norm_fill_constant_max_div_fuse_pass"});

/*
* lite::Optimizer optimize a program. It utilize the mir passes to analysis the
* program and export an optimized program.
Expand Down
4 changes: 2 additions & 2 deletions lite/operators/elementwise_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ bool ElementwiseOp::AttachImpl(const cpp::OpDesc& opdesc, lite::Scope* scope) {
auto Y_name = opdesc.Input("Y").front();
auto Out_name = opdesc.Output("Out").front();

param_.X = GetVar<lite::Tensor>(scope, X_name);
param_.Y = GetVar<lite::Tensor>(scope, Y_name);
param_.X = GetMutableVar<lite::Tensor>(scope, X_name);
param_.Y = GetMutableVar<lite::Tensor>(scope, Y_name);
param_.Out = GetMutableVar<lite::Tensor>(scope, Out_name);
param_.axis = opdesc.GetAttr<int>("axis");
if (opdesc.HasAttr("fuse_scale")) {
Expand Down
5 changes: 5 additions & 0 deletions lite/operators/fill_zeros_like_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ namespace paddle {
namespace lite {
namespace operators {

bool FillZerosLikeOp::CheckShape() const {
CHECK(param_.Out);
return true;
}

bool FillZerosLikeOp::InferShapeImpl() const {
param_.Out->Resize(param_.X->dims());
param_.Out->set_lod(param_.X->lod());
Expand Down
Loading