Skip to content

Commit d9f3598

Browse files
authored
[QNN-EP] Fix QNN-EP resize constraints (#26040)
### Description Fix the constraints of Resize operator in QNN-EP.
1 parent bac0bff commit d9f3598

File tree

2 files changed

+36
-32
lines changed

2 files changed

+36
-32
lines changed

onnxruntime/core/providers/qnn/builder/opbuilder/resize_op_builder.cc

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -173,33 +173,37 @@ Status ResizeOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
173173
"QNN EP: Resize does not support nearest_mode ", nearest_mode.c_str());
174174

175175
if (is_npu_backend) {
176-
// QNN only supports the following nearest_mode values on HTP:
177-
// - QNN 2.19: "round_prefer_floor" via QNN's Resize operator
178-
// - QNN 2.20 (API version 2.14): "round_prefer_ceil" via QNN's Resize operator
179-
// - "floor" via QNN's ResizeNearestNeighbor operator
180-
#if QNN_API_VERSION_MAJOR >= 2 && QNN_API_VERSION_MINOR >= 14
181-
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_ceil" || nearest_mode == "floor",
182-
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
183-
#else
184-
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_floor" || nearest_mode == "floor",
185-
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
186-
#endif
187-
188-
// Use ResizeNearestNeighbor for rank-4 inputs.
176+
// For better performance with HTP backend, use QNN's ResizeNearestNeighbor for rank-4 input.
189177
const bool use_resize_nn_op = input_rank == 4;
190178

191-
// If HTP uses ResizeNearestNeighbor ("floor"), then the "pytorch_half_pixel" coordinate_transformation_mode
192-
// is not supported.
193-
ORT_RETURN_IF(!use_resize_nn_op && nearest_mode == "floor" && transformation_mode == "pytorch_half_pixel",
194-
"QNN EP: Resize on the NPU does not support the combination of nearest_mode == 'floor' ",
195-
" and coordinate_transformation_mode == 'pytorch_half_pixel'.");
196-
179+
if (!use_resize_nn_op) {
180+
// QNN only supports the following nearest_mode values on HTP:
181+
// - QNN 2.19: "round_prefer_floor" via QNN's Resize operator
182+
// - QNN 2.20 (API version 2.14): "round_prefer_ceil" via QNN's Resize operator
197183
#if QNN_API_VERSION_MAJOR >= 2 && QNN_API_VERSION_MINOR >= 14
198-
// QNN's Resize only supports "round_prefer_ceil" if transformation_mode is "align_corners".
199-
ORT_RETURN_IF(!use_resize_nn_op && transformation_mode != "align_corners",
200-
"QNN EP: Resize on the NPU only supports 'round_prefer_ceil' if "
201-
"transformation mode is 'align_corners'");
184+
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_ceil" || nearest_mode == "floor",
185+
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
186+
187+
// QNN HTP Resize only supports "round_prefer_ceil" if transformation_mode is "align_corners".
188+
ORT_RETURN_IF(nearest_mode == "round_prefer_ceil" && transformation_mode != "align_corners",
189+
"QNN EP: Resize on the NPU only supports 'round_prefer_ceil' if "
190+
"transformation mode is 'align_corners'");
191+
#else
192+
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_floor" || nearest_mode == "floor",
193+
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
202194
#endif
195+
// If HTP uses Resize ("floor"), then the transformation_mode "pytorch_half_pixel" is not supported.
196+
ORT_RETURN_IF(nearest_mode == "floor" && transformation_mode == "pytorch_half_pixel",
197+
"QNN EP: Resize on the NPU does not support the combination of nearest_mode == 'floor' ",
198+
" and transformation_mode == 'pytorch_half_pixel'.");
199+
} else {
200+
// If HTP uses ResizeNearestNeighbor "ceil" or "round_prefer_floor", then the
201+
// transformation_mode "asymmetric" is not supported.
202+
// This is verified in unit test but not be documented in QNN SDK.
203+
ORT_RETURN_IF((nearest_mode == "ceil" || nearest_mode == "round_prefer_floor") && transformation_mode == "asymmetric",
204+
"QNN EP: ResizeNearestNeighbor on the NPU does not support the combination of ",
205+
"nearest_mode == 'ceil' or 'round_prefer_floor' and transformation_mode == 'asymmetric'.");
206+
}
203207
}
204208
}
205209

onnxruntime/test/providers/qnn/resize_test.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,17 +374,16 @@ TEST_F(QnnHTPBackendTests, ResizeU8_2xLinearAsymmetric) {
374374
}
375375

376376
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "half_pixel", nearest_mode: "round_prefer_floor"
377-
// Maps to QNN's Resize operator.
378-
// UPDATE: "round_prefer_floor" no longer supported in QNN SDK 2.21 (supported in QNN SDK 2.19)
379-
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferFloor_Unsupported) {
377+
// Maps to QNN's ResizeNearestNeighbor operator.
378+
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferFloor) {
380379
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
381380
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, input_data),
382381
{1, 3, 8, 8}, "nearest", "half_pixel", "round_prefer_floor",
383-
ExpectedEPNodeAssignment::None); // No longer supported as of QNN SDK 2.21
382+
ExpectedEPNodeAssignment::All);
384383
}
385384

386385
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "half_pixel", nearest_mode: "round_prefer_Ceil"
387-
// Maps to QNN's ResizeNearesetNeighbor operator.
386+
// Maps to QNN's ResizeNearestNeighbor operator.
388387
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferCeil) {
389388
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
390389
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, input_data),
@@ -393,7 +392,7 @@ TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferCeil) {
393392
}
394393

395394
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "align_corners", nearest_mode: "round_prefer_ceil"
396-
// Maps to QNN's Resize operator.
395+
// Maps to QNN's ResizeNearestNeighbor operator.
397396
// UPDATE: "round_prefer_ceil" is supported as of QNN SDK 2.21 if using "align_corners". (Unsupported in QNN SDK 2.19).
398397
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAlignCornersRoundPreferCeil) {
399398
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
@@ -402,8 +401,9 @@ TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAlignCornersRoundPreferCeil) {
402401
ExpectedEPNodeAssignment::All);
403402
}
404403

405-
// Test that the nearest_mode "ceil" is not supported on the HTP backend.
406-
TEST_F(QnnHTPBackendTests, ResizeU8_NearestModeCeil_Unsupported) {
404+
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "asymmetric", nearest_mode: "ceil"
405+
// Maps to QNN's ResizeNearestNeighbor operator.
406+
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAsymmetricCeil_Unsupported) {
407407
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
408408
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, input_data),
409409
{1, 3, 8, 8}, "nearest", "asymmetric", "ceil",
@@ -420,7 +420,7 @@ TEST_F(QnnHTPBackendTests, ResizeU8_3xNearestAsymmetricFloor) {
420420
}
421421

422422
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "asymmetric", nearest_mode: "round_prefer_floor"
423-
// Maps to QNN's Resize operator.
423+
// Maps to QNN's ResizeNearestNeighbor operator.
424424
// UPDATE: "round_prefer_floor" no longer supported in QNN SDK 2.21 (supported in QNN SDK 2.19)
425425
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAsymmetricRoundPreferFloor_Unsupported) {
426426
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 8);

0 commit comments

Comments
 (0)