From 90e2a4b936d0ab79806d5e1ecb87cc45b11537df Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Thu, 20 Jan 2022 07:46:35 +1000 Subject: [PATCH] Fix GH Issue 10305 by adding implicit inputs to consumer nodes map. (#10319) --- onnxruntime/core/graph/graph.cc | 19 +- .../optimizer/transpose_optimizer_test.cc | 364 +++++++++--------- .../test/testdata/ort_github_issue_10305.onnx | Bin 0 -> 729 bytes .../test/testdata/ort_github_issue_10305.py | 58 +++ 4 files changed, 258 insertions(+), 183 deletions(-) create mode 100644 onnxruntime/test/testdata/ort_github_issue_10305.onnx create mode 100644 onnxruntime/test/testdata/ort_github_issue_10305.py diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 54dfca8217..2c19452a88 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -1066,7 +1066,7 @@ void Node::ForEachDef(std::function loaded from model file, construct // a object and Resolve() it. -//Status Graph::LoadGraph(const GraphProto& graph_proto, +// Status Graph::LoadGraph(const GraphProto& graph_proto, // const std::unordered_map& domain_to_version, // Version ir_version, // std::unique_ptr& new_graph) { @@ -1607,16 +1607,19 @@ Status Graph::BuildConnections(std::unordered_set& outer_scope_node // now build connections within this Graph instance node_arg_to_producer_node_.clear(); node_arg_to_consumer_nodes_.clear(); + for (auto& node : Nodes()) { // Need mutable input defs to be able to set any outer scope NodeArg implicit inputs auto& input_args = node.MutableInputDefs(); auto& output_args = node.MutableOutputDefs(); - if (!output_args.empty()) { - for (const auto* output_arg : output_args) { - if (output_arg->Exists()) { - node_arg_to_producer_node_.insert({output_arg->Name(), node.Index()}); - } + for (const auto* implicit_input : node.ImplicitInputDefs()) { + node_arg_to_consumer_nodes_[implicit_input->Name()].insert(node.Index()); + } + + for (const auto* output_arg : output_args) { + if (output_arg->Exists()) { + node_arg_to_producer_node_.insert({output_arg->Name(), node.Index()}); } } @@ -2650,7 +2653,7 @@ void Graph::InitFunctionBodyForNode(Node& node) { << node.Name() << "' optype " << node.OpType() #ifndef ORT_NO_EXCEPTIONS << ". Error message " << e.what() -#endif //ORT_NO_EXCEPTIONS +#endif // ORT_NO_EXCEPTIONS << ". Execution will fail if ORT does not have a specialized kernel for this op"; // Return without using this function op's expansion. No need to fail just yet. // If ORT has a specialized kernel for this op then execution will proceed @@ -3476,7 +3479,7 @@ void Graph::CleanUnusedInitializersAndNodeArgs(const std::unordered_set used_args; used_args.reserve(node_args_.size()); - //Node Args we want to preserved even not being used + // Node Args we want to preserved even not being used std::unordered_set node_args_to_preserve; if (initializer_names_to_preserve) { node_args_to_preserve.reserve(initializer_names_to_preserve->size()); diff --git a/onnxruntime/test/optimizer/transpose_optimizer_test.cc b/onnxruntime/test/optimizer/transpose_optimizer_test.cc index a76843413e..855baaf575 100644 --- a/onnxruntime/test/optimizer/transpose_optimizer_test.cc +++ b/onnxruntime/test/optimizer/transpose_optimizer_test.cc @@ -294,209 +294,209 @@ TEST(TransposeOptimizerTests, TestPadNonconst) { // Todo: renable tests on resize transformer after adding NHWC support in upsample op on cpu // https://github.com/microsoft/onnxruntime/issues/9857 -//TEST(TransposeOptimizerTests, TestResize) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* const_1 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); +// TEST(TransposeOptimizerTests, TestResize) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* const_1 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// builder.AddNode("Resize", {transpose_1_out_0, const_1}, {resize_1_out_0}); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// builder.AddNode("Resize", {transpose_1_out_0, const_1}, {resize_1_out_0}); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 10); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 10); +// } // -//TEST(TransposeOptimizerTests, TestResizeOpset11) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* const_1 = builder.MakeInitializer({8}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}); -// auto* const_2 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); +// TEST(TransposeOptimizerTests, TestResizeOpset11) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* const_1 = builder.MakeInitializer({8}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}); +// auto* const_2 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// builder.AddNode("Resize", {transpose_1_out_0, const_1, const_2}, {resize_1_out_0}); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// builder.AddNode("Resize", {transpose_1_out_0, const_1, const_2}, {resize_1_out_0}); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 11); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 11); +// } // -//TEST(TransposeOptimizerTests, TestResizeOpset15) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* const_1 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); -// auto empty_arg = NodeArg("", nullptr); +// TEST(TransposeOptimizerTests, TestResizeOpset15) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* const_1 = builder.MakeInitializer({4}, {0.3f, 2.5f, 1.0f, 0.7f}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); +// auto empty_arg = NodeArg("", nullptr); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// builder.AddNode("Resize", {transpose_1_out_0, &empty_arg, const_1}, {resize_1_out_0}); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// builder.AddNode("Resize", {transpose_1_out_0, &empty_arg, const_1}, {resize_1_out_0}); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 15); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 15); +// } // -//TEST(TransposeOptimizerTests, TestResizeSizeRoi) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* const_1 = builder.MakeInitializer({8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); -// auto* const_2 = builder.MakeInitializer({4}, {10, 9, 8, 7}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); -// auto empty_arg = NodeArg("", nullptr); +// TEST(TransposeOptimizerTests, TestResizeSizeRoi) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* const_1 = builder.MakeInitializer({8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); +// auto* const_2 = builder.MakeInitializer({4}, {10, 9, 8, 7}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); +// auto empty_arg = NodeArg("", nullptr); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, const_1, &empty_arg, const_2}, {resize_1_out_0}); -// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, const_1, &empty_arg, const_2}, {resize_1_out_0}); +// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 15); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 15); +// } // -//TEST(TransposeOptimizerTests, TestResizeRoiScalesZeroRank0) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input = builder.MakeInput({1, 512, 512, 3}, -// std::numeric_limits::min(), -// std::numeric_limits::max()); -// auto* resize_in_roi = builder.MakeInitializer({0}, {}); -// auto* resize_in_scales = builder.MakeInitializer({0}, {}); -// auto* resize_in_sizes = builder.MakeInitializer({4}, {1, 256, 32, 32}); +// TEST(TransposeOptimizerTests, TestResizeRoiScalesZeroRank0) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input = builder.MakeInput({1, 512, 512, 3}, +// std::numeric_limits::min(), +// std::numeric_limits::max()); +// auto* resize_in_roi = builder.MakeInitializer({0}, {}); +// auto* resize_in_scales = builder.MakeInitializer({0}, {}); +// auto* resize_in_sizes = builder.MakeInitializer({4}, {1, 256, 32, 32}); // -// auto* transpose1_out_transposed = builder.MakeIntermediate(); -// auto* resize_out_Y = builder.MakeIntermediate(); -// auto* output = builder.MakeOutput(); +// auto* transpose1_out_transposed = builder.MakeIntermediate(); +// auto* resize_out_Y = builder.MakeIntermediate(); +// auto* output = builder.MakeOutput(); // -// auto& transpose_1 = builder.AddNode("Transpose", {input}, {transpose1_out_transposed}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// builder.AddNode("Resize", -// {transpose1_out_transposed, resize_in_roi, resize_in_scales, resize_in_sizes}, -// {resize_out_Y}); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_out_Y}, {output}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input}, {transpose1_out_transposed}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// builder.AddNode("Resize", +// {transpose1_out_transposed, resize_in_roi, resize_in_scales, resize_in_sizes}, +// {resize_out_Y}); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_out_Y}, {output}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1); +// } // -//TEST(TransposeOptimizerTests, TestResizeNonconst) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* input1_arg = MakeInput(builder, {{8}}, {8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); -// auto* input2_arg = MakeInput(builder, {{4}}, {4}, {0.3f, 2.5f, 1.0f, 0.7f}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); +// TEST(TransposeOptimizerTests, TestResizeNonconst) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* input1_arg = MakeInput(builder, {{8}}, {8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); +// auto* input2_arg = MakeInput(builder, {{4}}, {4}, {0.3f, 2.5f, 1.0f, 0.7f}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, input1_arg, input2_arg}, {resize_1_out_0}); -// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, input1_arg, input2_arg}, {resize_1_out_0}); +// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 11); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 11); +// } // -//TEST(TransposeOptimizerTests, TestResizeNonconstOpset13) { -// auto build_test_case_1 = [&](ModelTestBuilder& builder) { -// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); -// auto* input1_arg = MakeInput(builder, {{8}}, {8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); -// auto* input2_arg = MakeInput(builder, {{4}}, {4}, {0.3f, 2.5f, 1.0f, 0.7f}); -// auto* transpose_1_out_0 = builder.MakeIntermediate(); -// auto* resize_1_out_0 = builder.MakeIntermediate(); -// auto* transpose_2_out_0 = builder.MakeOutput(); +// TEST(TransposeOptimizerTests, TestResizeNonconstOpset13) { +// auto build_test_case_1 = [&](ModelTestBuilder& builder) { +// auto* input0_arg = MakeInput(builder, {{4, -1, 2, -1}}, {4, 6, 2, 10}, 0.0, 1.0); +// auto* input1_arg = MakeInput(builder, {{8}}, {8}, {0.1f, 0.2f, 0.3f, 0.4f, 0.9f, 0.8f, 0.7f, 0.6f}); +// auto* input2_arg = MakeInput(builder, {{4}}, {4}, {0.3f, 2.5f, 1.0f, 0.7f}); +// auto* transpose_1_out_0 = builder.MakeIntermediate(); +// auto* resize_1_out_0 = builder.MakeIntermediate(); +// auto* transpose_2_out_0 = builder.MakeOutput(); // -// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); -// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); -// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, input1_arg, input2_arg}, {resize_1_out_0}); -// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); -// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); -// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); -// }; +// auto& transpose_1 = builder.AddNode("Transpose", {input0_arg}, {transpose_1_out_0}); +// transpose_1.AddAttribute("perm", std::vector{0, 3, 1, 2}); +// auto& resize_1 = builder.AddNode("Resize", {transpose_1_out_0, input1_arg, input2_arg}, {resize_1_out_0}); +// resize_1.AddAttribute("coordinate_transformation_mode", "tf_crop_and_resize"); +// auto& transpose_2 = builder.AddNode("Transpose", {resize_1_out_0}, {transpose_2_out_0}); +// transpose_2.AddAttribute("perm", std::vector{0, 2, 3, 1}); +// }; // -// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { -// int transpose_cost = EstimateTransposeCost(session.GetGraph()); -// EXPECT_EQ(transpose_cost, 0); -// }; +// auto check_optimized_graph_1 = [&](InferenceSessionWrapper& session) { +// int transpose_cost = EstimateTransposeCost(session.GetGraph()); +// EXPECT_EQ(transpose_cost, 0); +// }; // -// TransformerTester(build_test_case_1, -// check_optimized_graph_1, -// TransformerLevel::Default, -// TransformerLevel::Level1, -// /*opset_version*/ 13); -//} +// TransformerTester(build_test_case_1, +// check_optimized_graph_1, +// TransformerLevel::Default, +// TransformerLevel::Level1, +// /*opset_version*/ 13); +// } TEST(TransposeOptimizerTests, TestAdd) { auto build_test_case_1 = [&](ModelTestBuilder& builder) { @@ -3869,5 +3869,19 @@ TEST(TransposeOptimizerTests, RegressionTest_GitHubIssue9671) { ASSERT_STATUS_OK(session_object.Initialize()); // optimizers run during initialization } +// regression test for a model where the transpose optimizations incorrectly removed a node providing an implicit +// input to a subgraph. fixed by updating Graph::BuildConnections to add implicit inputs to node_arg_to_consumer_nodes_ +// see https://github.com/microsoft/onnxruntime/issues/10305 for more details. +TEST(TransposeOptimizerTests, RegressionTest_GitHubIssue10305) { + Status status; + auto model_uri = ORT_TSTR("testdata/ort_github_issue_10305.onnx"); + + SessionOptions so; + so.session_logid = "TransposeOptimizerTests.RegressionTest_GitHubIssue10305"; + InferenceSession session_object{so, GetEnvironment()}; + ASSERT_STATUS_OK(session_object.Load(model_uri)); + ASSERT_STATUS_OK(session_object.Initialize()); // optimizers run during initialization +} + } // namespace test } // namespace onnxruntime diff --git a/onnxruntime/test/testdata/ort_github_issue_10305.onnx b/onnxruntime/test/testdata/ort_github_issue_10305.onnx new file mode 100644 index 0000000000000000000000000000000000000000..f4b0d1f839d47f48574c386699935435bdefec6e GIT binary patch literal 729 zcma))!A^rf5Qbd}0%J>?J=lcCm=I5#pcf+tQ#tFYp15qFY$~x`5Ei38O<%{GkKzM( za4AKRw222`hxzB*e|A>WyblGgK}}dza?imhJP%osr3LjI6Mh26((jvuJp?(U`Fe(C zM>A=IRJek687Ku0a}GVqVmvH(p2RdJ#VT1;%;W9Cv6OlB1E$bb?8>o{R)$Qicq%D< zqmHG{>lM69V64LzBFGt8q$T5UT9nZ;53>jINNGlvX~LEyVbB*=I3>?vE}|Ogn#ygO zX09byANvb|9HsH=^b^75-#!K_As{tDR2!{Ocr)djICia`cw@ankqQ$`V32T{hdfCc zVdWYFXqt*;kTeur95T99={uD`w6+pER|r%mqkkcUs^b=87zsvS*pQlMgA@#RVZzAv z=xjqnBh^Dkemy|DU&qL=CTWkGsB`xAxk%_XLjHjv1ZTh3YmbY->`bZM?HKB7fDI6C Ru+~_QCUwHy*OxDihToTmzS{r* literal 0 HcmV?d00001 diff --git a/onnxruntime/test/testdata/ort_github_issue_10305.py b/onnxruntime/test/testdata/ort_github_issue_10305.py new file mode 100644 index 0000000000..e8d4829448 --- /dev/null +++ b/onnxruntime/test/testdata/ort_github_issue_10305.py @@ -0,0 +1,58 @@ +import onnx +from onnx import helper +from onnx import TensorProto + +# Loop is so the Tranpose output is used in a subgraph +loop_body = helper.make_graph( + [ + helper.make_node("Add", ["transpose:0", "loop_state_in"], ["loop_state_out"], "Add1"), + ], + "Loop_body", + [ + helper.make_tensor_value_info('iteration_num', TensorProto.INT64, [1]), + helper.make_tensor_value_info('subgraph_keep_going_in', TensorProto.BOOL, [1]), + helper.make_tensor_value_info('loop_state_in', TensorProto.FLOAT, [1]) + ], + [ + helper.make_tensor_value_info('subgraph_keep_going_in', TensorProto.BOOL, [1]), + helper.make_tensor_value_info('loop_state_out', TensorProto.FLOAT, [2, 2, 2]), + ], + [ + ] +) + +# Create the main graph +graph_proto = helper.make_graph( + [ + # add a Transpose that can be moved past the Slice + helper.make_node('Transpose', inputs=['input:0'], outputs=['transpose:0'], name='transpose0', perm=[1, 0, 2]), + helper.make_node('Slice', + inputs=['transpose:0', 'start', 'end'], + outputs=['strided_slice:0'], name='slice0'), + helper.make_node('Squeeze', + inputs=['strided_slice:0', 'start'], + outputs=['out:0'], + name='squeeze0'), + helper.make_node("Loop", ["max_trip_count", "subgraph_keep_going_in", "state_var_in"], ["out:1"], "Loop1", + body=loop_body) + ], + "Main_graph", + [ + helper.make_tensor_value_info('input:0', TensorProto.FLOAT, [2, 2, 2]), + helper.make_tensor_value_info('state_var_in', TensorProto.FLOAT, [1]), + ], + [ + helper.make_tensor_value_info('out:0', TensorProto.FLOAT, [2, 2]), + helper.make_tensor_value_info('out:1', TensorProto.FLOAT, [2, 2, 2]), + ], + [ + helper.make_tensor('start', TensorProto.INT64, [1], [0]), + helper.make_tensor('end', TensorProto.INT64, [1], [1]), + helper.make_tensor('max_trip_count', TensorProto.INT64, [1], [1]), + helper.make_tensor('subgraph_keep_going_in', TensorProto.BOOL, [1], [1]), + ] +) + +model = helper.make_model(graph_proto) +onnx.checker.check_model(model, True) +onnx.save(model, 'ort_github_issue_10305.onnx') \ No newline at end of file