diff --git a/onnx/checker.cc b/onnx/checker.cc index 39b38df01ed..a397ea60c4a 100644 --- a/onnx/checker.cc +++ b/onnx/checker.cc @@ -709,6 +709,12 @@ void check_graph(const GraphProto& graph, const CheckerContext& ctx, const Lexic lex_ctx.add(output); } } + for (const auto& value_info : graph.output()) { + if (!lex_ctx.this_graph_has(value_info.name())) { + fail_check("Graph output '", value_info.name(), "' is not an output of any node in graph."); + } + } + print_warning_if_has_experimental(used_experimental_ops); } diff --git a/onnx/test/checker_test.py b/onnx/test/checker_test.py index e920ceb111c..379edf2aca9 100644 --- a/onnx/test/checker_test.py +++ b/onnx/test/checker_test.py @@ -797,7 +797,7 @@ def test_loop_with_different_initializer_input_below_ir4(self) -> None: ], outputs=[ helper.make_tensor_value_info( - "cond___while_Identity_graph_outputs_Identity__3_0", + "cond___while_Less__13_0", TensorProto.BOOL, shape=[], ), @@ -825,7 +825,7 @@ def test_loop_with_different_initializer_input_below_ir4(self) -> None: outputs=["cond___while_Less__13_0"], name="cond___while_Less__13", domain="", - to=TensorProto.FLOAT, + to=TensorProto.BOOL, ), ], ), @@ -1076,6 +1076,39 @@ def test_check_model_supports_unicode_path(self): onnx.save(model, unicode_model_path) checker.check_model(unicode_model_path, full_check=True) + def test_graph_output_is_defined(self): + model = onnx.parser.parse_model( + """ + + agraph (float[N] x) => (float[N] y, float[N] z) + { + y = Add(x, x) + } + # Error: z is not defined + """ + ) + self.assertRaises(checker.ValidationError, checker.check_model, model) + + def test_graph_output_is_defined_within_sub_graph(self): + model = onnx.parser.parse_model( + """ + + agraph (float[N] x, bool cond) => (float[N] y) + { + sum = Add (x, x) + prod = Mul (x, x) + y = If (cond) < + then_branch = then_graph () => (sum) {}, + else_branch = else_graph () => (prod) {} + > + } + # Error: sum/prod are accessible inside if-then-else branches, but cannot + # be used as outputs of the then/else branch implicitly. + # An explicit "Identity(sum)" must be used to return sum as output. + """ + ) + self.assertRaises(checker.ValidationError, checker.check_model, model) + if __name__ == "__main__": unittest.main() diff --git a/onnx/test/compose_test.py b/onnx/test/compose_test.py index 9c18cb9f56b..9e1afac2dfc 100644 --- a/onnx/test/compose_test.py +++ b/onnx/test/compose_test.py @@ -87,7 +87,7 @@ def _make_sparse_tensor(name: str) -> SparseTensorProto: { C0 = Add(B01, B11) C1 = Sub(B11, B21) - M1 = Mul(C0, C1) + D0 = Mul(C0, C1) } """