ONNX Imagescaler op (#1262)
authorTomasz Dołbniak <tomasz.dolbniak@intel.com>
Thu, 9 Jul 2020 10:19:40 +0000 (12:19 +0200)
committerGitHub <noreply@github.com>
Thu, 9 Jul 2020 10:19:40 +0000 (12:19 +0200)
* ONNX ImageScaler op

* UT for ImageScaler op

ngraph/src/ngraph/frontend/onnx_import/CMakeLists.txt
ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.cpp [new file with mode: 0644]
ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.hpp [new file with mode: 0644]
ngraph/src/ngraph/frontend/onnx_import/ops_bridge.cpp
ngraph/test/models/onnx/image_scaler.prototxt [new file with mode: 0644]
ngraph/test/onnx/onnx_import.in.cpp

index 82b6a18..36371e5 100644 (file)
@@ -121,6 +121,7 @@ add_library(onnx_importer SHARED
         op/hardmax.cpp
         op/hardmax.hpp
         op/identity.hpp
+        op/image_scaler.cpp
         op/instance_norm.cpp
         op/instance_norm.hpp
         op/leaky_relu.cpp
diff --git a/ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.cpp b/ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.cpp
new file mode 100644 (file)
index 0000000..8043000
--- /dev/null
@@ -0,0 +1,63 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include "image_scaler.hpp"
+#include "default_opset.hpp"
+
+namespace ngraph
+{
+    namespace onnx_import
+    {
+        namespace op
+        {
+            namespace set_1
+            {
+                NodeVector image_scaler(const Node& node)
+                {
+                    const auto inputs = node.get_ng_inputs();
+                    NGRAPH_CHECK(
+                        inputs.size() == 1, "ImageScaler 1 input tensor. Got: ", inputs.size());
+
+                    const auto data = inputs[0];
+                    const auto& data_shape = data->get_output_partial_shape(0);
+                    NGRAPH_CHECK(data_shape.rank().same_scheme({4}),
+                                 "ImageScaler expects a 4D tensor with NCHW format. Got: ",
+                                 data_shape);
+
+                    const auto scale = node.get_attribute_value<float>("scale", 1.0);
+                    const auto bias = node.get_attribute_value<std::vector<float>>("bias");
+
+                    NGRAPH_CHECK(data_shape[1].same_scheme(bias.size()),
+                                 "Number of bias attribute elements: ",
+                                 bias.size(),
+                                 " does not match the channel dimension: ",
+                                 data_shape[1].get_length());
+
+                    const auto scale_const =
+                        default_opset::Constant::create(element::f32, Shape{}, {scale});
+
+                    const auto bias_const =
+                        default_opset::Constant::create(element::f32, {1, bias.size(), 1, 1}, bias);
+
+                    const auto scaler = std::make_shared<default_opset::Add>(
+                        std::make_shared<default_opset::Multiply>(data, scale_const), bias_const);
+
+                    return {scaler};
+                }
+            }
+        }
+    }
+}
diff --git a/ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.hpp b/ngraph/src/ngraph/frontend/onnx_import/op/image_scaler.hpp
new file mode 100644 (file)
index 0000000..7f5a088
--- /dev/null
@@ -0,0 +1,34 @@
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include "core/node.hpp"
+#include "ngraph/node.hpp"
+
+namespace ngraph
+{
+    namespace onnx_import
+    {
+        namespace op
+        {
+            namespace set_1
+            {
+                NodeVector image_scaler(const Node& node);
+            }
+        }
+    }
+}
index 1fee117..79ccb60 100644 (file)
@@ -70,6 +70,7 @@
 #include "op/hard_sigmoid.hpp"
 #include "op/hardmax.hpp"
 #include "op/identity.hpp"
+#include "op/image_scaler.hpp"
 #include "op/instance_norm.hpp"
 #include "op/leaky_relu.hpp"
 #include "op/less.hpp"
@@ -303,6 +304,7 @@ namespace ngraph
             REGISTER_OPERATOR("Hardmax", 1, hardmax);
             REGISTER_OPERATOR("HardSigmoid", 1, hard_sigmoid);
             REGISTER_OPERATOR("Identity", 1, identity);
+            REGISTER_OPERATOR("ImageScaler", 1, image_scaler);
             REGISTER_OPERATOR("InstanceNormalization", 1, instance_norm);
             REGISTER_OPERATOR("LeakyRelu", 1, leaky_relu);
             REGISTER_OPERATOR("Less", 1, less);
diff --git a/ngraph/test/models/onnx/image_scaler.prototxt b/ngraph/test/models/onnx/image_scaler.prototxt
new file mode 100644 (file)
index 0000000..bc45e8a
--- /dev/null
@@ -0,0 +1,69 @@
+ir_version: 3
+producer_name: "nGraph ONNX Importer"
+graph {
+  node {
+    input: "data"
+    output: "out"
+    name: "image_scaler"
+    op_type: "ImageScaler"
+    attribute {
+        name: "scale"
+        f: 2
+        type: FLOAT
+    }
+    attribute {
+        name: "bias"
+        floats: 10
+        floats: 1
+        type: FLOATS
+    }
+  }
+  name: "test_graph"
+  input {
+    name: "data"
+    type {
+      tensor_type {
+        elem_type: 1
+        shape {
+          dim {
+            dim_value: 1
+          }
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 2
+          }
+        }
+      }
+    }
+  }
+  output {
+    name: "out"
+    type {
+      tensor_type {
+        elem_type: 1
+        shape {
+          dim {
+            dim_value: 1
+          }
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 2
+          }
+          dim {
+            dim_value: 2
+          }
+        }
+      }
+    }
+  }
+}
+opset_import {
+  version: 7
+}
index fa818b1..9be2ed9 100644 (file)
@@ -2280,3 +2280,15 @@ NGRAPH_TEST(${BACKEND_NAME}, onnx_upsample9_scales_const_linear_infer)
         {1.0, 1.5, 2.0, 2.0, 2.0, 2.5, 3.0, 3.0, 3.0, 3.5, 4.0, 4.0, 3.0, 3.5, 4.0, 4.0});
     test_case.run();
 }
+
+NGRAPH_TEST(${BACKEND_NAME}, onnx_image_scaler)
+{
+    const auto function = onnx_import::import_onnx_model(
+        file_util::path_join(SERIALIZED_ZOO, "onnx/image_scaler.prototxt"));
+
+    auto test_case = test::TestCase<TestEngine>(function);
+    test_case.add_input<float>({1.0, 2.0, 3.0, 4.0, 10.0, 20.0, 30.0, 40.0});
+    test_case.add_expected_output<float>(Shape{1, 2, 2, 2},
+                                         {12.0, 14.0, 16.0, 18.0, 21.0, 41.0, 61.0, 81.0});
+    test_case.run();
+}