Skip to content

Commit f1aea7c

Browse files
committed
[QNN-EP] Support for Upsample operator
- QNN-EP support for upsample operator - Add unit test for QNN-EP upsample operator
1 parent a6934df commit f1aea7c

File tree

1 file changed

+8
-151
lines changed

1 file changed

+8
-151
lines changed

onnxruntime/test/providers/qnn/upsample_op_test.cc

Lines changed: 8 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,11 @@ namespace test {
2020
template <typename DataType>
2121
static void RunUpsampleTestOnCPU(const TestInputDef<DataType>& input_def,
2222
const TestInputDef<float>& scales_def,
23-
std::vector<ONNX_NAMESPACE::AttributeProto> attrs,
23+
std::vector<ONNX_NAMESPACE::AttributeProto>&& attrs,
2424
ExpectedEPNodeAssignment expected_ep_assignment,
2525
int opset = 9) {
2626
ProviderOptions provider_options;
27-
28-
#if defined(_WIN32)
29-
provider_options["backend_path"] = "QnnCpu.dll";
30-
#else
31-
provider_options["backend_path"] = "libQnnCpu.so";
32-
#endif
27+
provider_options["backend_type"] = "cpu";
3328
provider_options["offload_graph_io_quantization"] = "0";
3429

3530
if (opset <= 7) {
@@ -106,152 +101,14 @@ TEST_F(QnnCPUBackendTests, Upsample_5D) {
106101
9); // Opset
107102
}
108103

109-
#if defined(__aarch64__) || defined(_M_ARM64) || defined(__linux__)
110-
//
111-
// HTP tests:
112-
//
113-
114-
// Returns a function that creates a graph with a QDQ Upsample operator.
115-
template <typename QuantType>
116-
GetTestQDQModelFn<QuantType> BuildQDQUpsampleTestCase(const TestInputDef<float>& input_def,
117-
const TestInputDef<int64_t>& scales_def,
118-
const std::vector<ONNX_NAMESPACE::AttributeProto>& attrs,
119-
int opset = 10,
120-
bool use_contrib_qdq = false) {
121-
return [input_def, scales_def, attrs,
122-
opset, use_contrib_qdq](ModelTestBuilder& builder,
123-
std::vector<QuantParams<QuantType>>& output_qparams) {
124-
// input -> Q -> DQ ->
125-
NodeArg* input = MakeTestInput(builder, input_def);
126-
QuantParams<QuantType> input_qparams = GetTestInputQuantParams<QuantType>(input_def);
127-
NodeArg* input_qdq = AddQDQNodePair<QuantType>(builder, input, input_qparams.scale, input_qparams.zero_point,
128-
use_contrib_qdq);
129-
130-
if (opset <= 7) {
131-
// Upsample op
132-
NodeArg* upsample_output = builder.MakeIntermediate();
133-
Node& upsample_node = builder.AddNode("Upsample", {input_qdq}, {upsample_output});
134-
} else {
135-
// scales input
136-
NodeArg* scales_input = MakeTestInput(builder, scales_def);
137-
138-
// Upsample op
139-
NodeArg* upsample_output = builder.MakeIntermediate();
140-
Node& upsample_node = builder.AddNode("Upsample", {input_qdq, scales_input}, {upsample_output});
141-
}
142-
143-
for (auto& attr : attrs) {
144-
upsample_node.AddAttributeProto(attr);
145-
}
146-
147-
// op_output -> Q -> DQ -> output
148-
// Input and output quantization parameters are equal for Upsample.
149-
output_qparams[0] = input_qparams;
150-
AddQDQNodePairWithOutputAsGraphOutput<QuantType>(builder, upsample_output, input_qparams.scale,
151-
input_qparams.zero_point, use_contrib_qdq);
152-
};
153-
}
154-
155-
// Run a QDQ Upsample model on the QNN HTP EP and the ORT CPU EP. Check the graph node assignment and the QDQ model
156-
// inference on QNN HTP EP is at least as accurate as on ORT CPU EP (compared to the baseline float32 model).
157-
template <typename QType>
158-
static void RunQDQUpsampleTestOnHTP(const TestInputDef<float>& input_def,
159-
const TestInputDef<float>& scales_def,
160-
std::vector<ONNX_NAMESPACE::AttributeProto>& attrs,
161-
ExpectedEPNodeAssignment expected_ep_assignment,
162-
int opset = 10,
163-
bool use_contrib_qdq = false) {
164-
ProviderOptions provider_options;
165-
166-
#if defined(_WIN32)
167-
provider_options["backend_path"] = "QnnHtp.dll";
168-
#else
169-
provider_options["backend_path"] = "libQnnHtp.so";
170-
#endif
171-
provider_options["offload_graph_io_quantization"] = "0";
172-
173-
if (opset <= 7) {
174-
const std::vector<float>& scales = scales_def.GetRawData();
175-
attrs.push_back(utils::MakeAttribute("scales", scales));
176-
177-
auto f32_model_builder = BuildOpTestCase<float>("Upsample", {input_def}, {}, attrs);
178-
} else {
179-
auto f32_model_builder = BuildOpTestCase<float, float>("Upsample", {input_def}, {scales_def}, attrs);
180-
}
181-
182-
auto qdq_model_builder = BuildQDQUpsampleTestCase<QType>(input_def, scales_def, attrs, opset, use_contrib_qdq);
183-
184-
TestQDQModelAccuracy(f32_model_builder,
185-
qdq_model_builder,
186-
provider_options,
187-
opset,
188-
expected_ep_assignment);
189-
}
190-
191-
// Test that QDQ Upsample with a dynamic scales input is not supported by QNN EP.
192-
TEST_F(QnnHTPBackendTests, Upsample_DynamicScales_Unsupported) {
193-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, -10.0f, 10.0f),
194-
TestInputDef<float>({4}, false /* is_initializer */, {1.0f, 1.0f, 1.5f, 1.5f}),
195-
{utils::MakeAttribute("mode", "nearest")}, // Attributes
196-
ExpectedEPNodeAssignment::None, // Should not be assigned to QNN EP.
197-
10); // Opset
198-
}
199-
200-
// Test QDQ Upsample with opset-9, mode `nearest`
201-
TEST_F(QnnHTPBackendTests, Upsample_4D_Nearest_opset9) {
202-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, -10.0f, 10.0f),
203-
TestInputDef<float>({4}, true, {1.0f, 1.0f, 1.5f, 1.5f}),
204-
{utils::MakeAttribute("mode", "nearest")}, // Attributes
205-
ExpectedEPNodeAssignment::All,
206-
9); // Opset
207-
}
208-
209-
// Test QDQ Upsample with opset-9, mode `linear`
210-
TEST_F(QnnHTPBackendTests, Upsample_4D_Linear_opset9) {
211-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, -10.0f, 10.0f),
212-
TestInputDef<float>({4}, true, {1.0f, 1.0f, 1.5f, 1.5f}),
213-
{utils::MakeAttribute("mode", "linear")}, // Attributes
214-
ExpectedEPNodeAssignment::All,
215-
9); // Opset
216-
}
104+
/*
105+
QNN HTP backend tests for the QDQ Upsample model is bypassed and can not be enabled.
217106
218-
// Test QDQ Upsample with opset-7, mode `nearest`
219-
TEST_F(QnnHTPBackendTests, Upsample_4D_Nearest_opset7) {
220-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, -10.0f, 10.0f),
221-
TestInputDef<float>({4}, true, {1.0f, 1.0f, 1.5f, 1.5f}),
222-
{utils::MakeAttribute("mode", "nearest")}, // Attributes
223-
ExpectedEPNodeAssignment::All,
224-
7); // Opset
225-
}
226-
227-
// Test QDQ Upsample with opset-7, mode `linear`
228-
TEST_F(QnnHTPBackendTests, Upsample_4D_Linear_opset7) {
229-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, -10.0f, 10.0f),
230-
TestInputDef<float>({4}, true, {1.0f, 1.0f, 1.5f, 1.5f}),
231-
{utils::MakeAttribute("mode", "linear")}, // Attributes
232-
ExpectedEPNodeAssignment::All,
233-
7); // Opset
234-
}
235-
236-
// Test QDQ Upsample 5D
237-
TEST_F(QnnHTPBackendTests, Upsample_5D) {
238-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4, 4}, false, -10.0f, 10.0f),
239-
TestInputDef<float>({5}, true, {1.0f, 1.0f, 1.5f, 1.5f, 1.5f}),
240-
{utils::MakeAttribute("mode", "nearest")}, // Attributes
241-
ExpectedEPNodeAssignment::All,
242-
9); // Opset
243-
}
244-
245-
// Test QDQ Upsample 6D not supported for HTP backend
246-
TEST_F(QnnHTPBackendTests, Upsample_6D) {
247-
RunQDQUpsampleTestOnHTP<uint8_t>(TestInputDef<float>({1, 3, 4, 4, 4, 4}, false, -10.0f, 10.0f),
248-
TestInputDef<float>({6}, true, {1.0f, 1.0f, 1.5f, 1.5f, 1.5f, 1.5f}),
249-
{utils::MakeAttribute("mode", "nearest")}, // Attributes
250-
ExpectedEPNodeAssignment::None,
251-
9); // Opset
252-
}
107+
ONNX Upsample is deprecated in domain version 10. However, ONNX QuantizeLinear and DequantizeLinear are enabled in
108+
domain version 10. Their conditions are mutually exclusive, so it is not possible for these ops to coexist in the
109+
same domain version.
110+
*/
253111

254-
#endif // defined(__aarch64__) || defined(_M_ARM64) || defined(__linux__)
255112
} // namespace test
256113
} // namespace onnxruntime
257114
#endif // !defined(ORT_MINIMAL_BUILD)

0 commit comments

Comments
 (0)