[QNN EP] Fix pool and conv op tests (#15504)

### Description
- Fixes QNN unit tests for pool and conv ops.
- Temporarily disables QNN Resize tests until we fix type/shape
inferencing for NHWC Resize.

### Motivation and Context
The Linux QNN CI Pipeline has not run unit tests for a week (see
https://github.com/microsoft/onnxruntime/pull/15497). Some tests broke
in the meantime.

Fixed
[AB#14625](https://aiinfra.visualstudio.com/6a833879-cd9b-44a4-a9de-adc2d818f13c/_workitems/edit/14625)

---------

Co-authored-by: Changming Sun <chasun@microsoft.com>
This commit is contained in:
Adrian Lizarraga 2023-04-14 13:18:38 -07:00 committed by GitHub
parent fbe88fccbd
commit 5ebe700a9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 19 deletions

View file

@ -59,16 +59,27 @@ Status ConvOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
const NodeUnit& node_unit,
const logging::Logger& logger,
bool is_quantized_model) const {
ORT_UNUSED_PARAMETER(qnn_model_wrapper);
ORT_UNUSED_PARAMETER(node_unit);
ORT_UNUSED_PARAMETER(logger);
ORT_UNUSED_PARAMETER(is_quantized_model);
auto input_0 = node_unit.Inputs()[0];
if (node_unit.Domain() == kMSInternalNHWCDomain) { // Use QNN validation API if layout is NHWC.
return AddToModelBuilder(qnn_model_wrapper, node_unit, logger, is_quantized_model, true);
}
const auto& input_0 = node_unit.Inputs()[0];
std::vector<uint32_t> input_shape;
ORT_RETURN_IF_NOT(qnn_model_wrapper.GetOnnxShape(input_0.node_arg, input_shape), "Cannot get shape");
if (input_shape.size() != 4) {
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "QNN Conv only support 2D!");
}
ONNX_NAMESPACE::DataType input_data_type = input_0.node_arg.Type();
ORT_RETURN_IF(!is_quantized_model && input_data_type != ONNX_NAMESPACE::Utils::DataTypeUtils::ToType("float"),
"QNN EP: Data type ", input_data_type->c_str(),
" is not supported for Conv operator in CPU backend.");
NodeAttrHelper node_helper(node_unit);
auto auto_pad = node_helper.Get("auto_pad", std::string("NOTSET"));
ORT_RETURN_IF(auto_pad != "NOTSET" && auto_pad != "SAME_LOWER" && auto_pad != "SAME_UPPER",
"QNN Conv operators do not support 'auto_pad' value: ", auto_pad.c_str());
return Status::OK();
}
@ -286,6 +297,9 @@ Status ConvOpBuilder::ProcessAttributesAndOutputs(QnnModelWrapper& qnn_model_wra
std::vector<int32_t> pad_values = {0, 0, 0, 0};
auto auto_pad = node_helper.Get("auto_pad", std::string("NOTSET"));
ORT_RETURN_IF(auto_pad != "NOTSET" && auto_pad != "SAME_LOWER" && auto_pad != "SAME_UPPER",
"QNN Conv operators do not support 'auto_pad' value: ", auto_pad.c_str());
if (auto_pad.compare("NOTSET") != 0) {
auto input_0 = node_unit.Inputs()[0];
auto input_1 = node_unit.Inputs()[1];

View file

@ -49,9 +49,10 @@ Status PoolOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
const NodeUnit& node_unit,
const logging::Logger& logger,
bool is_quantized_model) const {
ORT_UNUSED_PARAMETER(qnn_model_wrapper);
ORT_UNUSED_PARAMETER(node_unit);
ORT_UNUSED_PARAMETER(logger);
if (node_unit.Domain() == kMSInternalNHWCDomain) { // Use QNN validation API if layout is NHWC.
return AddToModelBuilder(qnn_model_wrapper, node_unit, logger, is_quantized_model, true);
}
const auto& inputs = node_unit.Inputs();
ONNX_NAMESPACE::DataType input_data_type = inputs[0].node_arg.Type();
if (!is_quantized_model && input_data_type != ONNX_NAMESPACE::Utils::DataTypeUtils::ToType("float")) {
@ -73,6 +74,13 @@ Status PoolOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
if (node_unit.Outputs().size() > 1) {
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "QNN only support 1 output!");
}
if (node_unit.OpType() == "MaxPool" || node_unit.OpType() == "AveragePool") {
auto auto_pad = node_helper.Get("auto_pad", std::string("NOTSET"));
ORT_RETURN_IF(auto_pad != "NOTSET" && auto_pad != "SAME_LOWER" && auto_pad != "SAME_UPPER",
"QNN Pool operators do not support 'auto_pad' value: ", auto_pad.c_str());
}
return Status::OK();
}
@ -98,6 +106,9 @@ Status PoolOpBuilder::SetCommonPoolParams(const NodeAttrHelper& node_helper,
std::vector<int32_t> pads = {0, 0, 0, 0};
auto auto_pad = node_helper.Get("auto_pad", std::string("NOTSET"));
ORT_RETURN_IF(auto_pad != "NOTSET" && auto_pad != "SAME_LOWER" && auto_pad != "SAME_UPPER",
"QNN Pool operators do not support 'auto_pad' value: ", auto_pad.c_str());
if (auto_pad.compare("NOTSET") != 0) {
auto dilation_values = node_helper.Get("dilations", std::vector<int32_t>{1, 1});

View file

@ -915,13 +915,7 @@ TEST(PoolTest, AveragePool_DefaultStrides) {
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider});
}
#ifdef USE_QNN
// TODO: Unskip when fixed AB#14594
// Error message: ComposeGraph Failed to compose Qnn graph.
TEST(PoolTest, DISABLED_AveragePool_10_ceil1_2d) {
#else
TEST(PoolTest, AveragePool_10_ceil1_2d) {
#endif
// TODO: Unskip when fixed #41968513
if (DefaultDmlExecutionProvider().get() != nullptr) {
GTEST_SKIP() << "Skipping because of the following error: MLOperatorAuthorImpl.cpp(2100): The parameter is incorrect.";

View file

@ -179,12 +179,24 @@ TEST(QnnCPUBackendTests, DISABLED_TestResizeDownsampleNearestAlignCorners_rpf) {
// Cpu tests that use the "linear" mode.
//
TEST(QnnCPUBackendTests, TestResize2xLinearHalfPixel) {
// TODO: Enable once we fix type/shape inferece for NHWC Resize.
// See: https://github.com/microsoft/onnxruntime/pull/15477
//
// Error: [W:onnxruntime:QnnEP.TestQDQModel, graph.cc:108 MergeShapeInfo]
// Error merging shape info for output. 'node' source:{1,4,2,4} target:{1,4,4,2}.
// Falling back to lenient merge.
TEST(QnnCPUBackendTests, DISABLED_TestResize2xLinearHalfPixel) {
RunCPUResizeOpTest({1, 2, 2, 2}, {1, 2, 4, 4}, "linear", "half_pixel", "",
ExpectedEPNodeAssignment::All, "TestResize2xLinearHalfPixel");
}
TEST(QnnCPUBackendTests, TestResize2xLinearAlignCorners) {
// TODO: Enable once we fix type/shape inferece for NHWC Resize.
// See: https://github.com/microsoft/onnxruntime/pull/15477
//
// Error: [W:onnxruntime:QnnEP.TestQDQModel, graph.cc:108 MergeShapeInfo]
// Error merging shape info for output. 'node' source:{1,4,2,4} target:{1,4,4,2}.
// Falling back to lenient merge.
TEST(QnnCPUBackendTests, DISABLED_TestResize2xLinearAlignCorners) {
RunCPUResizeOpTest({1, 2, 2, 2}, {1, 2, 4, 4}, "linear", "align_corners", "",
ExpectedEPNodeAssignment::All, "TestResize2xLinearAlignCorners");
}
@ -193,13 +205,26 @@ TEST(QnnCPUBackendTests, TestResize2xLinearAlignCorners) {
//
// HTP tests:
//
TEST_F(QnnHTPBackendTests, TestQDQU8Resize2xLinearPytorchHalfPixel) {
// TODO: Enable once we fix type/shape inferece for NHWC Resize.
// See: https://github.com/microsoft/onnxruntime/pull/15477
//
// Error: [W:onnxruntime:QnnEP.TestQDQModel, graph.cc:108 MergeShapeInfo]
// Error merging shape info for output. 'node_token_5' source:{1,8,3,8} target:{1,8,8,3}.
// Falling back to lenient merge.
TEST_F(QnnHTPBackendTests, DISABLED_TestQDQU8Resize2xLinearPytorchHalfPixel) {
RunQDQResizeOpTest<uint8_t>({1, 3, 4, 4}, {1, 3, 8, 8}, "linear", "pytorch_half_pixel", "",
ExpectedEPNodeAssignment::All, 0.0031f,
"TestQDQU8Resize2xLinearPytorchHalfPixel");
}
TEST_F(QnnHTPBackendTests, TestQDQU8Resize2xNearestHalfPixelRoundPreferFloor) {
// TODO: Enable once we fix type/shape inferece for NHWC Resize.
// See: https://github.com/microsoft/onnxruntime/pull/15477
//
// Error: [W:onnxruntime:QnnEP.TestQDQModel, graph.cc:108 MergeShapeInfo]
// Error merging shape info for output. 'node_token_5' source:{1,8,3,8} target:{1,8,8,3}.
// Falling back to lenient merge.
TEST_F(QnnHTPBackendTests, DISABLED_TestQDQU8Resize2xNearestHalfPixelRoundPreferFloor) {
RunQDQResizeOpTest<uint8_t>({1, 3, 4, 4}, {1, 3, 8, 8}, "nearest", "half_pixel", "round_prefer_floor",
ExpectedEPNodeAssignment::All, 1e-5f,
"TestQDQU8Resize2xNearestHalfPixelRoundPreferFloor");
@ -210,4 +235,4 @@ TEST_F(QnnHTPBackendTests, TestQDQU8Resize2xNearestHalfPixelRoundPreferFloor) {
} // namespace test
} // namespace onnxruntime
#endif // !defined(ORT_MINIMAL_BUILD)
#endif // !defined(ORT_MINIMAL_BUILD)