Skip to content

Commit

Permalink
[NNAdapter] Optimize NNAdapter's dynamic shape derivation for slice, …
Browse files Browse the repository at this point in the history
…stride_slice and elementwise_ops (#10076)
  • Loading branch information
shentanyue authored Mar 13, 2023
1 parent 3de3ce1 commit eb5d792
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 75 deletions.
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

0 comments on commit eb5d792

Please sign in to comment.