Check output edges in QDQ (#9600)

This commit is contained in:
Yi-Hong Lyu 2021-10-31 23:41:51 -07:00 committed by GitHub
parent ccf1b8ad00
commit d203cdf132
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 1 deletions

View file

@ -33,7 +33,7 @@ bool BaseSelector::CheckQDQNodes(const Graph& graph, const Node& node,
return num_dq_inputs == gsl::narrow_cast<int>(dq_nodes.size()) &&
num_outputs == gsl::narrow_cast<int>(q_nodes.size()) &&
!graph.NodeProducesGraphOutput(node);
optimizer_utils::CheckOutputEdges(graph, node, q_nodes.size());
}
bool BaseSelector::Select(Graph& graph, const Node& node, std::unique_ptr<NodesToOptimize>& selection) const {

View file

@ -684,6 +684,97 @@ TEST(QDQTransformerTests, Resize) {
test_case({2, 13, 12, 37}, {4});
}
TEST(QDQTransformerTests, Resize_No_Fusion) {
auto test_case = [&](const std::vector<int64_t>& input_shape,
const std::vector<int64_t>& sizes_shape,
const std::vector<int64_t>& concat_input2_shape,
const int64_t axis) {
auto build_test_case = [&](ModelTestBuilder& builder) {
auto* input_arg = builder.MakeInput<uint8_t>(input_shape,
std::numeric_limits<uint8_t>::min(),
std::numeric_limits<uint8_t>::max());
auto* roi = builder.MakeInitializer<float>({0}, {});
auto* scales = builder.MakeInitializer<float>({0}, {});
auto* sizes = builder.MakeInitializer<int64_t>(sizes_shape, {1, 8, 128, 128});
auto* output_arg = builder.MakeOutput();
// add DQ
auto* dq_output = builder.MakeIntermediate();
builder.AddDequantizeLinearNode<uint8_t>(input_arg, .003f, 1, dq_output);
// add Resize
auto* resize_output = builder.MakeIntermediate();
builder.AddNode("Resize", {dq_output, roi, scales, sizes}, {resize_output});
// add Concat
std::vector<NodeArg*> concat_input_args;
concat_input_args.push_back(resize_output);
concat_input_args.push_back(builder.MakeInput<float>(concat_input2_shape,
std::numeric_limits<float>::min(),
std::numeric_limits<float>::max()));
auto* concat_output = builder.MakeIntermediate();
Node& concat_node = builder.AddNode("Concat", concat_input_args, {concat_output});
concat_node.AddAttribute("axis", axis);
// add Q
builder.AddQuantizeLinearNode<uint8_t>(resize_output, .003f, 1, output_arg);
};
auto check_qdq_graph = [&](InferenceSessionWrapper& session) {
auto op_to_count = CountOpsInGraph(session.GetGraph());
EXPECT_EQ(op_to_count["Resize"], 1);
EXPECT_EQ(op_to_count["Concat"], 1);
EXPECT_EQ(op_to_count["QuantizeLinear"], 1);
EXPECT_EQ(op_to_count["DequantizeLinear"], 1);
};
TransformerTester(build_test_case, check_qdq_graph,
TransformerLevel::Level1,
TransformerLevel::Level2);
};
test_case({1, 8, 64, 64}, {4}, {1, 4, 128, 128}, 1);
}
TEST(QDQTransformerTests, ResizeReshape) {
auto test_case = [&](const std::vector<int64_t>& input_shape,
const std::vector<int64_t>& sizes_shape) {
auto build_test_case = [&](ModelTestBuilder& builder) {
auto* input_arg = builder.MakeInput<float>(input_shape,
std::numeric_limits<float>::min(),
std::numeric_limits<float>::max());
auto* roi = builder.MakeInitializer<float>({0}, {});
auto* scales = builder.MakeInitializer<float>({0}, {});
auto* sizes = builder.MakeInitializer<int64_t>(sizes_shape, {1, 2, 52, 82});
auto* output_arg = builder.MakeOutput();
// add QDQ + Resize
auto* qdq_input = AddQDQNodePair<uint8_t>(builder, input_arg, .003f, 1);
auto* resize_output = builder.MakeIntermediate();
builder.AddNode("Resize", {qdq_input, roi, scales, sizes}, {resize_output});
// add QDQ + Reshape
auto* qdq_resize_output = AddQDQNodePair<uint8_t>(builder, resize_output, .003f, 1);
auto* reshape_shape = builder.Make1DInitializer<int64_t>({1, 2, 52, 82});
builder.AddNode("Reshape", {qdq_resize_output, reshape_shape}, {output_arg});
};
auto check_qdq_graph = [&](InferenceSessionWrapper& session) {
auto op_to_count = CountOpsInGraph(session.GetGraph());
EXPECT_EQ(op_to_count["Resize"], 1);
EXPECT_EQ(op_to_count["Reshape"], 1);
EXPECT_EQ(op_to_count["QuantizeLinear"], 1);
EXPECT_EQ(op_to_count["DequantizeLinear"], 1);
};
TransformerTester(build_test_case, check_qdq_graph,
TransformerLevel::Level1,
TransformerLevel::Level2);
};
test_case({1, 2, 26, 42}, {4});
}
TEST(QDQTransformerTests, QLinearMatMul) {
auto test_case = [&](const std::vector<int64_t>& input1_shape, const std::vector<int64_t>& input2_shape) {
auto build_test_case = [&](ModelTestBuilder& builder) {