Fix unit tests failures in build with contrib ops disabled (#18659)

Fix unit tests failures in build with contrib ops disabled.
- QDQTransformerTests.QDQPropagation_GH11605_Opset12_19
- TransposeOptimizerTests.QnnTransposeNonConstBroadcastInput
This commit is contained in:
Edward Chen 2023-12-01 09:41:25 -08:00 committed by GitHub
parent fcea2cb7f1
commit b22f49ff35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 49 deletions

View file

@ -3356,16 +3356,27 @@ TEST(QDQTransformerTests, QDQPropagation_GH11605_Opset12_19) {
// Original: DQ -> Tr -> SoftM -> Tr
// QDQ Prop inserts a Q/DQ pair to create a QDQ node group for the Transpose: DQ -> Tr -> Q -> DQ -> SoftM -> Tr
// Transpose opt phase 1 moves the Tr down until it blocks on the SoftMax: DQ -> Q -> DQ -> Tr -> SoftM -> Tr
// Transpose opt phase 2 repairs the QDQ node units: DQ -> Q -> DQ -> Tr -> Q -> DQ -> SoftM -> TR
// Transpose opt phase 2 repairs the QDQ node units: DQ -> Q -> DQ -> Tr -> Q -> DQ -> SoftM -> Tr
// and removes the unnecessary DQ/Q pair at the start: DQ -> Tr -> Q -> DQ -> SoftM -> Tr
// The L2 CPU EP QDQ handling converts the DQ -> Tr -> Q to a Transpose with 8-bit data.
// The L2 CPU EP QDQ handling converts the DQ -> Tr -> Q to a Transpose with 8-bit data: Tr -> DQ -> SoftM -> Tr
// Note: This L2 CPU EP QDQ handling is currently only enabled when contrib ops are enabled.
auto check_graph = [&](InferenceSessionWrapper& session) {
const QDQOpKeys qdq_keys = GetQDQOpKeys(use_contrib_qdq);
#if !defined(DISABLE_CONTRIB_OPS)
std::vector<std::string> expected_op_types_in_order{
"Transpose",
qdq_keys.dequantize_linear,
"Softmax",
"Transpose"};
#else
std::vector<std::string> expected_op_types_in_order{
qdq_keys.dequantize_linear,
"Transpose",
qdq_keys.quantize_linear,
qdq_keys.dequantize_linear,
"Softmax",
"Transpose"};
#endif
const auto& graph = session.GetGraph();
GraphViewer graph_viewer(graph);

View file

@ -4393,7 +4393,7 @@ TEST(TransposeOptimizerTests, RegressionTest_GitHubIssue12151) {
testing::ContainerEq(fetches[0].Get<Tensor>().DataAsSpan<float>()));
}
// These tests uses internal testing EP with static kernels which requires a full build,
// These tests use the internal testing EP with static kernels which requires a full build and contrib ops,
// and the NHWC Conv which requires contrib ops
#if !defined(ORT_MINIMAL_BUILD) && !defined(DISABLE_CONTRIB_OPS)
@ -4529,6 +4529,52 @@ TEST(TransposeOptimizerTests, QnnResizeOpset11) {
GraphViewer viewer(graph);
EXPECT_EQ(graph.GetNode(viewer.GetNodesInTopologicalOrder().back())->OpType(), "Transpose");
}
// model where layout transform results in transposing a non-const input that is broadcast.
// this inserts Unsqueeze -> Transpose between the input and the node.
// test that QDQ node units are created for Unsqueeze and Transpose by inserting Q->DQ pairs after them
TEST(TransposeOptimizerTests, QnnTransposeNonConstBroadcastInput) {
Status status;
auto model_uri = ORT_TSTR("testdata/layout_transform_nonconst_broadcast_input.onnx");
SessionOptions so;
// ASSERT_STATUS_OK(so.config_options.AddConfigEntry(kDebugLayoutTransformation, "1"));
using InternalTestingEP = onnxruntime::internal_testing_ep::InternalTestingExecutionProvider;
// set the test EP to support all ops in the model so that the layout transform applies to all nodes
const std::unordered_set<std::string> empty_set;
auto internal_testing_ep = std::make_unique<InternalTestingEP>(empty_set, empty_set, DataLayout::NHWC);
internal_testing_ep->EnableStaticKernels().TakeAllNodes();
InferenceSessionWrapper session{so, GetEnvironment()};
ASSERT_STATUS_OK(session.RegisterExecutionProvider(std::move(internal_testing_ep)));
ASSERT_STATUS_OK(session.Load(model_uri));
ASSERT_STATUS_OK(session.Initialize());
const auto& graph = session.GetGraph();
std::map<std::string, int> op_to_count = CountOpsInGraph(graph);
ASSERT_EQ(op_to_count["Transpose"], 3) << "Should have Transpose on 2 inputs and one on output.";
// all nodes should be assigned to the internal testing EP, which also means they should be in NHWC layout
std::string expected_ep(onnxruntime::utils::kInternalTestingExecutionProvider);
for (const auto& node : graph.Nodes()) {
EXPECT_EQ(node.GetExecutionProviderType(), expected_ep) << node.OpType() << " node named '" << node.Name()
<< "' was not assigned to the internal testing EP.";
// all nodes should be in QDQ node units except the Cast on an input which was not in a QDQ unit
if (node.OpType() != "QuantizeLinear" && node.OpType() != "DequantizeLinear" && node.OpType() != "Cast") {
for (auto cur_input = node.InputNodesBegin(), end = node.InputNodesEnd(); cur_input != end; ++cur_input) {
EXPECT_EQ(cur_input->OpType(), "DequantizeLinear");
}
for (auto cur_output = node.OutputNodesBegin(), end = node.OutputNodesEnd(); cur_output != end; ++cur_output) {
EXPECT_EQ(cur_output->OpType(), "QuantizeLinear");
}
}
}
}
#endif // !defined(ORT_MINIMAL_BUILD) && !defined(DISABLE_CONTRIB_OPS)
static void CheckSharedInitializerHandling(bool broadcast) {
@ -4706,51 +4752,5 @@ TEST(TransposeOptimizerTests, SharedInitializerHandlingBroadcast2) {
ASSERT_THAT(fetches_orig[0].Get<Tensor>().DataAsSpan<float>(),
testing::ContainerEq(fetches[0].Get<Tensor>().DataAsSpan<float>()));
}
// model where layout transform results in transposing a non-const input that is broadcast.
// this inserts Unsqueeze -> Transpose between the input and the node.
// test that QDQ node units are created for Unsqueeze and Transpose by inserting Q->DQ pairs after them
TEST(TransposeOptimizerTests, QnnTransposeNonConstBroadcastInput) {
Status status;
auto model_uri = ORT_TSTR("testdata/layout_transform_nonconst_broadcast_input.onnx");
SessionOptions so;
// ASSERT_STATUS_OK(so.config_options.AddConfigEntry(kDebugLayoutTransformation, "1"));
using InternalTestingEP = onnxruntime::internal_testing_ep::InternalTestingExecutionProvider;
// set the test EP to support all ops in the model so that the layout transform applies to all nodes
const std::unordered_set<std::string> empty_set;
auto internal_testing_ep = std::make_unique<InternalTestingEP>(empty_set, empty_set, DataLayout::NHWC);
internal_testing_ep->EnableStaticKernels().TakeAllNodes();
InferenceSessionWrapper session{so, GetEnvironment()};
ASSERT_STATUS_OK(session.RegisterExecutionProvider(std::move(internal_testing_ep)));
ASSERT_STATUS_OK(session.Load(model_uri));
ASSERT_STATUS_OK(session.Initialize());
const auto& graph = session.GetGraph();
std::map<std::string, int> op_to_count = CountOpsInGraph(graph);
ASSERT_EQ(op_to_count["Transpose"], 3) << "Should have Transpose on 2 inputs and one on output.";
// all nodes should be assigned to the internal testing EP, which also means they should be in NHWC layout
std::string expected_ep(onnxruntime::utils::kInternalTestingExecutionProvider);
for (const auto& node : graph.Nodes()) {
EXPECT_EQ(node.GetExecutionProviderType(), expected_ep) << node.OpType() << " node named '" << node.Name()
<< "' was not assigned to the internal testing EP.";
// all nodes should be in QDQ node units except the Cast on an input which was not in a QDQ unit
if (node.OpType() != "QuantizeLinear" && node.OpType() != "DequantizeLinear" && node.OpType() != "Cast") {
for (auto cur_input = node.InputNodesBegin(), end = node.InputNodesEnd(); cur_input != end; ++cur_input) {
EXPECT_EQ(cur_input->OpType(), "DequantizeLinear");
}
for (auto cur_output = node.OutputNodesBegin(), end = node.OutputNodesEnd(); cur_output != end; ++cur_output) {
EXPECT_EQ(cur_output->OpType(), "QuantizeLinear");
}
}
}
}
} // namespace test
} // namespace onnxruntime