Accept empty initializers from ONNX models (#1776)
authorTomasz Dołbniak <tomasz.dolbniak@intel.com>
Fri, 21 Aug 2020 12:15:27 +0000 (14:15 +0200)
committerGitHub <noreply@github.com>
Fri, 21 Aug 2020 12:15:27 +0000 (15:15 +0300)
* Accept empty initializers from ONNX models

* Create dummy constants instead of null nodes

* Code formatting

* Test the empty initializers handling in onnx importer

ngraph/frontend/onnx_import/src/core/graph.cpp
ngraph/test/models/onnx/empty_initializers_handling.prototxt [new file with mode: 0644]
ngraph/test/onnx/onnx_import.in.cpp
ngraph/test/runtime/interpreter/unit_test.manifest

index 79343984ed03204d495f25cf39f77987f6115dd7..6ae9a52a271c73192e6e45c9af8ddc38154d35ed 100644 (file)
@@ -87,10 +87,22 @@ namespace ngraph
                 if (initializer_tensor.has_name())
                 {
                     Tensor tensor = Tensor{initializer_tensor};
-                    initializers.emplace(initializer_tensor.name(), tensor);
-
+                    std::shared_ptr<default_opset::Constant> ng_constant;
                     // For each initializer create a Constant node and store it in cache
-                    auto ng_constant = tensor.get_ng_constant();
+                    try
+                    {
+                        ng_constant = tensor.get_ng_constant();
+                    }
+                    catch (const ngraph::ngraph_error& exc)
+                    {
+                        NGRAPH_WARN << "Could not create an nGraph Constant for initializer '"
+                                    << initializer_tensor.name() << "'. Detailed error:\n"
+                                    << exc.what();
+                        ng_constant =
+                            default_opset::Constant::create(tensor.get_ng_type(), Shape{}, {0});
+                    }
+
+                    initializers.emplace(initializer_tensor.name(), tensor);
                     add_provenance_tag_to_initializer(tensor, ng_constant);
                     m_cache->emplace_node(initializer_tensor.name(), std::move(ng_constant));
                 }
diff --git a/ngraph/test/models/onnx/empty_initializers_handling.prototxt b/ngraph/test/models/onnx/empty_initializers_handling.prototxt
new file mode 100644 (file)
index 0000000..a91df89
--- /dev/null
@@ -0,0 +1,130 @@
+ir_version: 7
+producer_name: "onnx-importer-test"
+graph {
+  initializer {
+    dims: 0
+    data_type: 1
+    name: "scales"
+    raw_data: ""
+  }
+  node {
+    output: "sizes"
+    op_type: "Constant"
+    attribute {
+      name: "value"
+      t {
+        dims: 4
+        data_type: 7
+        int64_data: 2
+        int64_data: 1
+        int64_data: 4
+        int64_data: 8
+        name: "const_tensor"
+      }
+      type: TENSOR
+    }
+  }
+  node {
+    output: "roi"
+    op_type: "Constant"
+    attribute {
+      name: "value"
+      t {
+        dims: 8
+        data_type: 1
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        float_data: 1.0
+        name: "const_tensor"
+      }
+      type: TENSOR
+    }
+  }
+  node {
+    input: "X"
+    input: "roi"
+    input: "scales"
+    input: "sizes"
+    output: "Y"
+    op_type: "Resize"
+    attribute {
+      name: "coordinate_transformation_mode"
+      s: "asymmetric"
+      type: STRING
+    }
+    attribute {
+      name: "cubic_coeff_a"
+      f: -0.75
+      type: FLOAT
+    }
+    attribute {
+      name: "exclude_outside"
+      i: 0
+      type: INT
+    }
+    attribute {
+      name: "extrapolation_value"
+      f: 0
+      type: FLOAT
+    }
+    attribute {
+      name: "mode"
+      s: "linear"
+      type: STRING
+    }
+  }
+  name: "test-model"
+  input {
+    name: "X"
+    type {
+      tensor_type {
+        elem_type: 1
+        shape {
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 1
+          }
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 2
+          }
+        }
+      }
+    }
+  }
+  output {
+    name: "Y"
+    type {
+      tensor_type {
+        elem_type: 1
+        shape {
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 1
+          }
+          dim {
+            dim_value: 4
+          }
+          dim {
+            dim_value: 8
+          }
+        }
+      }
+    }
+  }
+}
+opset_import {
+  domain: ""
+  version: 11
+}
index 6d77219988cb2ef4a6e360a1f751e4c64c1e6264..522c19d90f4ee04f36eb426557c981031248100f 100644 (file)
@@ -2424,3 +2424,26 @@ NGRAPH_TEST(${BACKEND_NAME}, onnx_image_scaler)
                                          {12.0, 14.0, 16.0, 18.0, 21.0, 41.0, 61.0, 81.0});
     test_case.run();
 }
+
+NGRAPH_TEST(${BACKEND_NAME}, onnx_empty_initializers_handling)
+{
+    // int this test the "scales" input of the Resize operator is set to an empty initializer
+    // this input should be ignored since the "sizes" optional input is provided
+    // and the inference should use the data from the latter
+    const auto function = onnx_import::import_onnx_model(
+        file_util::path_join(SERIALIZED_ZOO, "onnx/empty_initializers_handling.prototxt"));
+
+    const Shape expected_output_shape{2, 1, 4, 8};
+    auto test_case = test::TestCase<TestEngine>(function);
+    std::vector<float> input_data{2.0f, 4.0f, 1.0f, 3.0f, 7.0f, 8.0f, 9.0f, 6.0f};
+    test_case.add_input<float>(input_data);
+    test_case.add_expected_output<float>(
+        expected_output_shape,
+        {2.0f, 2.5f, 3.0f,  3.5f, 4.0f,  4.0f,  4.0f, 4.0f,  1.5f, 2.0f,  2.5f,  3.0f, 3.5f,
+         3.5f, 3.5f, 3.5f,  1.0f, 1.5f,  2.0f,  2.5f, 3.0f,  3.0f, 3.0f,  3.0f,  1.0f, 1.5f,
+         2.0f, 2.5f, 3.0f,  3.0f, 3.0f,  3.0f,  7.0f, 7.25f, 7.5f, 7.75f, 8.0f,  8.0f, 8.0f,
+         8.0f, 8.0f, 7.75f, 7.5f, 7.25f, 7.0f,  7.0f, 7.0f,  7.0f, 9.0f,  8.25f, 7.5f, 6.75f,
+         6.0f, 6.0f, 6.0f,  6.0f, 9.0f,  8.25f, 7.5f, 6.75f, 6.0f, 6.0f,  6.0f,  6.0f});
+
+    test_case.run();
+}
index e60ac6d84c78bbb5b22b999c2dd2efbb1eda0a89..d95f5f64aac46e191957985997b994f51861f6b0 100644 (file)
@@ -27,6 +27,7 @@ INTERPRETER.onnx_resize11_sizes_nearest_asymmetric_floor
 INTERPRETER.onnx_resize11_sizes_linear
 INTERPRETER.onnx_resize11_scales_nearest_asymmetric_floor_dynamic_sizes
 INTERPRETER.interpolate_down_scales_const_linear
+INTERPRETER.onnx_empty_initializers_handling
 
 # ONNX Loop
 onnx_controlflow_loop_2d_add_execution