diff --git a/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/converter/pad.cc b/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/converter/pad.cc index 194b9693115..d7f635c06e3 100644 --- a/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/converter/pad.cc +++ b/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/converter/pad.cc @@ -16,7 +16,7 @@ #include "driver/huawei_ascend_npu/converter/converter.h" #include "utility/debug.h" #include "utility/logging.h" - +#include "utility/modeling.h" namespace nnadapter { namespace huawei_ascend_npu { @@ -40,6 +40,46 @@ int ConvertPad(Converter* converter, hal::Operation* operation) { if (!input_operator) { input_operator = converter->ConvertOperand(input_operand); } + if ((mode == NNADAPTER_PAD_MODE_REFLECT || mode == NNADAPTER_PAD_MODE_EDGE) && + input_operand->type.dimensions.count == 5 && + IsConstantOperand(pads_operand) && + !IsOperandWithDynamicShape(input_operand)) { + uint32_t pads_size = + pads_operand->length / static_cast(sizeof(int32_t)); + auto pads_buffer = reinterpret_cast(pads_operand->buffer); + if (pads_size == 10 && pads_buffer[6] == 0 && pads_buffer[7] == 0 && + pads_buffer[8] == 0 && pads_buffer[9] == 0) { + // Reshape to 4-dimensions + std::vector shape_data(input_operand->type.dimensions.data, + input_operand->type.dimensions.data + 3); + shape_data.push_back(input_operand->type.dimensions.data[3] * + input_operand->type.dimensions.data[4]); + auto shape_operator = converter->AddInt32ConstantOperator(shape_data); + auto reshape_op = converter->AddOperator(output_operand); + SET_INPUT(reshape_op, x, input_operator); + SET_INPUT(reshape_op, shape, shape_operator); + auto reshape_output_operator = MAP_OUTPUT(reshape_op, y, output_operand); + // Use NCHW data format + std::vector pad_data(pads_buffer, pads_buffer + 8); + auto pads_operator = converter->AddInt32ConstantOperator(pad_data); + auto pad_op = converter->AddOperator(output_operand); + pad_op->set_attr_mode(pad_mode); + SET_INPUT(pad_op, x, reshape_output_operator); + SET_INPUT(pad_op, paddings, pads_operator); + auto pad2d_output_operator = MAP_OUTPUT(pad_op, y, output_operand); + // Reshape to 5-dimensions + auto shape_operator2 = converter->AddInt32ConstantOperator( + std::vector(output_operand->type.dimensions.data, + output_operand->type.dimensions.data + + output_operand->type.dimensions.count)); + auto reshape_op2 = + converter->AddOperator(output_operand); + SET_INPUT(reshape_op2, x, pad2d_output_operator); + SET_INPUT(reshape_op2, shape, shape_operator2); + MAP_OUTPUT(reshape_op2, y, output_operand); + return NNADAPTER_NO_ERROR; + } + } auto pads_operator = converter->GetMappedOperator(pads_operand); if (!pads_operator) { pads_operator = converter->ConvertOperand(pads_operand); diff --git a/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/utility.cc b/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/utility.cc index 21d83d8b6d8..88c6f48ba2b 100644 --- a/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/utility.cc +++ b/lite/backends/nnadapter/nnadapter/driver/huawei_ascend_npu/utility.cc @@ -221,6 +221,9 @@ bool BuildOMModelToBuffer( options.insert(std::make_pair(ge::ir_option::LOG_LEVEL, "error")); options.insert(std::make_pair(ge::ir_option::OP_DEBUG_LEVEL, "0")); ATC_CALL(aclgrphBuildModel(ir_graph, options, om_buffer)); + ATC_CALL(aclgrphSaveModel( + "ir_graph_model", + om_buffer)); // For debug: save ascend offline model to local. // Copy from om model buffer model_buffer->resize(om_buffer.length); memcpy(reinterpret_cast(model_buffer->data()), diff --git a/lite/core/optimizer/mir/fusion/unsqueeze2_pad3d_squeeze2_fuse.cc b/lite/core/optimizer/mir/fusion/unsqueeze2_pad3d_squeeze2_fuse.cc index 027eb5e5cc2..6e72a4ec058 100644 --- a/lite/core/optimizer/mir/fusion/unsqueeze2_pad3d_squeeze2_fuse.cc +++ b/lite/core/optimizer/mir/fusion/unsqueeze2_pad3d_squeeze2_fuse.cc @@ -17,6 +17,7 @@ // #include "lite/core/optimizer/mir/fusion/unsqueeze2_pad3d_squeeze2_fuse.h" + #include #include @@ -26,6 +27,12 @@ namespace mir { namespace fusion { void Unsqueeze2Pad3dSqueeze2Fuser::BuildPattern() { + auto paddings_teller = [](const Node* node) -> bool { + auto op_desc = *const_cast(node)->stmt()->op_info(); + auto paddings = op_desc.GetAttr>("paddings"); + return paddings.size() == 6 && paddings[4] == 0 && paddings[5] == 0; + }; + // create input nodes. auto* unsqu_input = VarNode("unsqu_input") ->assert_is_op_input(unsqueeze2_type_, "X") @@ -35,8 +42,10 @@ void Unsqueeze2Pad3dSqueeze2Fuser::BuildPattern() { auto* unsque = OpNode("unsqueeze2", unsqueeze2_type_) ->assert_is_op(unsqueeze2_type_) ->AsIntermediate(); - auto* p3d = - OpNode("pad3d", pad3d_type_)->assert_is_op(pad3d_type_)->AsIntermediate(); + auto* p3d = OpNode("pad3d", pad3d_type_) + ->assert_is_op(pad3d_type_) + ->assert_node_satisfied(paddings_teller) + ->AsIntermediate(); auto* sque = OpNode("squeeze2", squeeze2_type_) ->assert_is_op(squeeze2_type_) ->AsIntermediate(); diff --git a/lite/kernels/nnadapter/converter/interpolate.cc b/lite/kernels/nnadapter/converter/interpolate.cc index 368b67e93a7..b686e95c8d5 100644 --- a/lite/kernels/nnadapter/converter/interpolate.cc +++ b/lite/kernels/nnadapter/converter/interpolate.cc @@ -133,8 +133,7 @@ int ConvertInterpolate(Converter* converter, OpInfo* op, Scope* scope) { int align_mode = op->HasAttr("align_mode") ? op->GetAttr("align_mode") : 1; if (align_mode == 0 && align_corners) { - auto align_corners_operand = converter->AddConstantOperand(false); - input_operands[3] = align_corners_operand; + align_mode = 1; } auto align_mode_operand = converter->AddConstantOperand(align_mode); input_operands.push_back(align_mode_operand); diff --git a/lite/tests/kernels/pad2d_compute_test.cc b/lite/tests/kernels/pad2d_compute_test.cc index 9bfec13842b..da0eaf31771 100644 --- a/lite/tests/kernels/pad2d_compute_test.cc +++ b/lite/tests/kernels/pad2d_compute_test.cc @@ -200,7 +200,7 @@ TEST(Pad2d, precision) { #if defined(NNADAPTER_WITH_HUAWEI_ASCEND_NPU) // Ascend does not support the following scenarios. if (std::abs(pad_value - 1) < 1e-6 || - (pad_top == 0 && pad_bottom == 1 && pad_left == 0 && + ((pad_top == 1 || pad_bottom == 1) && pad_left == 0 && pad_right == 0)) continue; #endif