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] Optimize NNAdapter's dynamic shape derivation for slice, stride_slice and elementwise_ops #10076

Merged
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 @@ -15,6 +15,7 @@
#pragma once

#include <vector>
#include "utility/modeling.h"

namespace nnadapter {
namespace operation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

#pragma once

#include <vector>

#include "utility/modeling.h"

namespace nnadapter {
namespace operation {

Expand All @@ -37,30 +41,39 @@ namespace operation {
} \
/* Starts */ \
auto starts_operand = input_operands[2]; \
auto starts_count = \
starts_operand->length / static_cast<uint32_t>(sizeof(int32_t)); \
NNADAPTER_CHECK_EQ(starts_count, axes_count); \
auto starts = reinterpret_cast<int32_t*>(starts_operand->buffer); \
for (uint32_t i = 0; i < starts_count; i++) { \
NNADAPTER_VLOG(5) << "starts[" << i << "] = " << starts[i]; \
int32_t* starts = nullptr; \
if (IsConstantOperand(starts_operand)) { \
auto starts_count = starts_operand->length / sizeof(int32_t); \
starts = reinterpret_cast<int32_t*>(starts_operand->buffer); \
for (size_t i = 0; i < starts_count; i++) { \
NNADAPTER_VLOG(5) << "starts[" << i << "]: " << starts[i]; \
} \
} else { \
NNADAPTER_VLOG(5) << "starts: " << OperandToString(starts_operand); \
} \
/* Ends */ \
auto ends_operand = input_operands[3]; \
auto ends_count = \
ends_operand->length / static_cast<uint32_t>(sizeof(int32_t)); \
NNADAPTER_CHECK_EQ(ends_count, axes_count); \
auto ends = reinterpret_cast<int32_t*>(ends_operand->buffer); \
for (uint32_t i = 0; i < ends_count; i++) { \
NNADAPTER_VLOG(5) << "ends[" << i << "] = " << ends[i]; \
int32_t* ends = nullptr; \
if (IsConstantOperand(ends_operand)) { \
auto ends_count = ends_operand->length / sizeof(int32_t); \
ends = reinterpret_cast<int32_t*>(ends_operand->buffer); \
for (size_t i = 0; i < ends_count; i++) { \
NNADAPTER_VLOG(5) << "ends[" << i << "]: " << ends[i]; \
} \
} else { \
NNADAPTER_VLOG(5) << "ends: " << OperandToString(ends_operand); \
} \
/* Steps */ \
auto steps_operand = input_operands[4]; \
auto steps_count = \
steps_operand->length / static_cast<uint32_t>(sizeof(int32_t)); \
NNADAPTER_CHECK_EQ(steps_count, axes_count); \
auto steps = reinterpret_cast<int32_t*>(steps_operand->buffer); \
for (uint32_t i = 0; i < steps_count; i++) { \
NNADAPTER_VLOG(5) << "steps[" << i << "] = " << steps[i]; \
int32_t* steps = nullptr; \
if (IsConstantOperand(steps_operand)) { \
auto steps_count = steps_operand->length / sizeof(int32_t); \
steps = reinterpret_cast<int32_t*>(steps_operand->buffer); \
for (size_t i = 0; i < steps_count; i++) { \
NNADAPTER_VLOG(5) << "steps[" << i << "]: " << steps[i]; \
} \
} else { \
NNADAPTER_VLOG(5) << "steps: " << OperandToString(steps_operand); \
} \
/* Output */ \
auto output_operand = output_operands[0]; \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include "utility/modeling.h"

namespace nnadapter {
namespace operation {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ int ConvertPool2D(Converter* converter, core::Operation* operation) {
pool2d_op->set_attr_pads(ge::Operator::OpListInt(
{pad_height_top, pad_height_bottom, pad_width_left, pad_width_right}));
pool2d_op->set_attr_global_pooling(global_pooling);
#if NNADAPTER_HUAWEI_ASCEND_NPU_CANN_VERSION_LESS_THAN(6, 0, 0)
if (IsDynamicShapeOperandType(input_operand->type)) {
pool2d_op->set_attr_global_pooling(false);
}
#endif
pool2d_op->set_attr_ceil_mode(ceil_mode);
if (flag) {
pool2d_op->set_attr_exclusive(0);
Expand Down Expand Up @@ -90,9 +92,11 @@ int ConvertPool2D(Converter* converter, core::Operation* operation) {
pad_width_right}));
}
pool2d_op->set_attr_global_pooling(global_pooling);
#if NNADAPTER_HUAWEI_ASCEND_NPU_CANN_VERSION_LESS_THAN(6, 0, 0)
if (IsDynamicShapeOperandType(input_operand->type)) {
pool2d_op->set_attr_global_pooling(false);
}
#endif
#else
auto pool2d_op = converter->AddOperator<ge::op::Pooling>(output_operand);
pool2d_op->set_attr_mode(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,24 @@ int ConvertSlice(Converter* converter, core::Operation* operation) {
if (!input_tensor) {
input_tensor = converter->ConvertOperand(input_operand);
}
auto start_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(starts, starts + starts_count));
auto end_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(ends, ends + ends_count));
auto strides_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(steps, steps + steps_count));
std::shared_ptr<Tensor> start_idx_tensor;
std::shared_ptr<Tensor> end_idx_tensor;
std::shared_ptr<Tensor> strides_idx_tensor;
if (IsConstantOperand(starts_operand)) {
auto starts_count = starts_operand->length / sizeof(int32_t);
start_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(starts, starts + starts_count));
}
if (IsConstantOperand(ends_operand)) {
auto ends_count = ends_operand->length / sizeof(int32_t);
end_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(ends, ends + ends_count));
}
if (IsConstantOperand(steps_operand)) {
auto steps_count = steps_operand->length / sizeof(int32_t);
strides_idx_tensor = converter->AddConstantTensor(
std::vector<int32_t>(steps, steps + steps_count));
}

// The following process is:
// Given:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ NNADAPTER_EXPORT void CalcEltwiseBinaryOperationsOutputSize(
output_dimensions_data[i] = input1_data;
} else if (input1_data == 1) {
output_dimensions_data[i] = input0_data;
} else if (input0_data == NNADAPTER_UNKNOWN ||
input1_data == NNADAPTER_UNKNOWN) {
output_dimensions_data[i] = NNADAPTER_UNKNOWN;
} else {
NNADAPTER_LOG(ERROR) << "Cannot broadcast input0: " << input0_data
<< ", input1: " << input1_data;
Expand Down
22 changes: 20 additions & 2 deletions lite/backends/nnadapter/nnadapter/src/operation/slice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ NNADAPTER_EXPORT int PrepareSlice(core::Operation* operation) {

// Infer the shape and type of output operands
CopyOperandTypeExceptQuantParams(&output_operand->type, input_operand->type);

if (IsTemporaryShapeOperand(starts_operand) ||
IsTemporaryShapeOperand(ends_operand) ||
IsTemporaryShapeOperand(steps_operand)) {
output_operand->type.lifetime = NNADAPTER_TEMPORARY_SHAPE;
for (uint32_t i = 0; i < axes_count; i++) {
output_operand->type.dimensions.data[axes[i]] = NNADAPTER_UNKNOWN;
output_operand->type.dimensions.dynamic_data[i][axes[i]] =
NNADAPTER_UNKNOWN;
}
NNADAPTER_VLOG(5) << "output: " << OperandToString(output_operand);
return NNADAPTER_NO_ERROR;
}

if (IsTemporaryVariableOperand(starts_operand) ||
IsTemporaryVariableOperand(ends_operand) ||
IsTemporaryVariableOperand(steps_operand)) {
NNADAPTER_LOG(FATAL) << "Start or end or step is not supported as variable";
}

auto infer_output_shape = [&](int32_t* output_dimensions) {
for (size_t i = 0; i < axes_count; ++i) {
int dim = output_dimensions[axes[i]];
Expand All @@ -103,12 +123,10 @@ NNADAPTER_EXPORT int PrepareSlice(core::Operation* operation) {
}
}
};

infer_output_shape(output_operand->type.dimensions.data);
for (uint32_t i = 0; i < input_operand->type.dimensions.dynamic_count; i++) {
infer_output_shape(output_operand->type.dimensions.dynamic_data[i]);
}

if (IsTemporaryShapeOperand(input_operand)) {
output_operand->type.lifetime = NNADAPTER_TEMPORARY_SHAPE;
auto& temporary_shape = *(GetTemporaryShape(input_operand));
Expand Down
48 changes: 28 additions & 20 deletions lite/kernels/nnadapter/converter/slice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,21 @@ int ConvertSlice(Converter* converter, OpInfo* op, Scope* scope) {
starts_operand = converter->AddInputOperand(scope, name);
} else if (HasInput(op, scope, "StartsTensorList")) {
auto names = op->Input("StartsTensorList");
std::vector<NNAdapterOperand*> concat_input_operands;
for (auto name : names) {
auto sub_start_operand = converter->AddInputOperand(scope, name);
concat_input_operands.push_back(sub_start_operand);
if (names.size() == 1) {
starts_operand = converter->AddInputOperand(scope, names[0]);
} else {
std::vector<NNAdapterOperand*> concat_input_operands;
for (auto name : names) {
auto sub_start_operand = converter->AddInputOperand(scope, name);
concat_input_operands.push_back(sub_start_operand);
}
NNAdapterOperand* concat_axis_operand =
converter->AddConstantOperand<int>(0);
concat_input_operands.push_back(concat_axis_operand);
starts_operand = converter->AddOutputOperand();
converter->AddOperation(
NNADAPTER_CONCAT, concat_input_operands, {starts_operand});
}
NNAdapterOperand* concat_axis_operand =
converter->AddConstantOperand<int>(0);
concat_input_operands.push_back(concat_axis_operand);
starts_operand = converter->AddOutputOperand();
converter->AddOperation(
NNADAPTER_CONCAT, concat_input_operands, {starts_operand});
} else {
CHECK(op->HasAttr("starts")) << "One of 'StartsTensor', "
"'StartsTensorList', 'starts'(attr) must "
Expand All @@ -67,17 +71,21 @@ int ConvertSlice(Converter* converter, OpInfo* op, Scope* scope) {
ends_operand = converter->AddInputOperand(scope, name);
} else if (HasInput(op, scope, "EndsTensorList")) {
auto names = op->Input("EndsTensorList");
std::vector<NNAdapterOperand*> concat_input_operands;
for (auto name : names) {
auto sub_end_operand = converter->AddInputOperand(scope, name);
concat_input_operands.push_back(sub_end_operand);
if (names.size() == 1) {
ends_operand = converter->AddInputOperand(scope, names[0]);
} else {
std::vector<NNAdapterOperand*> concat_input_operands;
for (auto name : names) {
auto sub_end_operand = converter->AddInputOperand(scope, name);
concat_input_operands.push_back(sub_end_operand);
}
NNAdapterOperand* concat_axis_operand =
converter->AddConstantOperand<int>(0);
concat_input_operands.push_back(concat_axis_operand);
ends_operand = converter->AddOutputOperand();
converter->AddOperation(
NNADAPTER_CONCAT, concat_input_operands, {ends_operand});
}
NNAdapterOperand* concat_axis_operand =
converter->AddConstantOperand<int>(0);
concat_input_operands.push_back(concat_axis_operand);
ends_operand = converter->AddOutputOperand();
converter->AddOperation(
NNADAPTER_CONCAT, concat_input_operands, {ends_operand});
} else {
CHECK(op->HasAttr("ends"))
<< "One of 'EndsTensor', 'EndsTensorList', 'ends'(attr) must be exist.";
Expand Down
Loading