From b8f5b8ce3dbc3509e85e843079bda67d6ba68b0d Mon Sep 17 00:00:00 2001 From: iliya mironov Date: Thu, 15 Oct 2020 07:41:46 +0300 Subject: [PATCH] Add hsigmoid op to ngraph (#2647) --- ngraph/core/include/ngraph/op/hsigmoid.hpp | 53 +++++++++++++ ngraph/core/include/ngraph/ops.hpp | 1 + .../core/include/ngraph/opsets/opset5_tbl.hpp | 3 +- .../ngraph/runtime/reference/hsigmoid.hpp | 38 +++++++++ ngraph/core/src/op/hsigmoid.cpp | 79 +++++++++++++++++++ ngraph/test/CMakeLists.txt | 1 + ngraph/test/op_eval/hsigmoid.cpp | 48 +++++++++++ 7 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 ngraph/core/include/ngraph/op/hsigmoid.hpp create mode 100644 ngraph/core/reference/include/ngraph/runtime/reference/hsigmoid.hpp create mode 100644 ngraph/core/src/op/hsigmoid.cpp create mode 100644 ngraph/test/op_eval/hsigmoid.cpp diff --git a/ngraph/core/include/ngraph/op/hsigmoid.hpp b/ngraph/core/include/ngraph/op/hsigmoid.hpp new file mode 100644 index 00000000000000..d8963f9148f32f --- /dev/null +++ b/ngraph/core/include/ngraph/op/hsigmoid.hpp @@ -0,0 +1,53 @@ +//***************************************************************************** +// 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 "ngraph/node.hpp" +#include "ngraph/op/op.hpp" +#include "ngraph/op/util/unary_elementwise_arithmetic.hpp" + +namespace ngraph +{ + namespace op + { + namespace v5 + { + /// \brief A HSigmoid Activation Function + /// f(x) = min(max(x + 3, 0), 6) / 6 or + /// f(x) = min(ReLU(x + 3), 6) / 6 + /// + class NGRAPH_API HSigmoid : public ngraph::op::util::UnaryElementwiseArithmetic + { + public: + NGRAPH_RTTI_DECLARATION; + HSigmoid() = default; + + /// \brief Constructs a HSigmoid (hard version of Swish) operation. + /// + /// \param data Input tensor + HSigmoid(const Output& arg); + + bool visit_attributes(AttributeVisitor& visitor) override; + + virtual std::shared_ptr + clone_with_new_inputs(const OutputVector& new_args) const override; + bool evaluate(const HostTensorVector& outputs, + const HostTensorVector& inputs) const override; + }; + } + } +} diff --git a/ngraph/core/include/ngraph/ops.hpp b/ngraph/core/include/ngraph/ops.hpp index a2116197f9f778..c2293b54b3bc54 100644 --- a/ngraph/core/include/ngraph/ops.hpp +++ b/ngraph/core/include/ngraph/ops.hpp @@ -76,6 +76,7 @@ #include "ngraph/op/gru_cell.hpp" #include "ngraph/op/gru_sequence.hpp" #include "ngraph/op/hard_sigmoid.hpp" +#include "ngraph/op/hsigmoid.hpp" #include "ngraph/op/hswish.hpp" #include "ngraph/op/interpolate.hpp" #include "ngraph/op/less.hpp" diff --git a/ngraph/core/include/ngraph/opsets/opset5_tbl.hpp b/ngraph/core/include/ngraph/opsets/opset5_tbl.hpp index bddd7c84fadecd..c665d94d0e2e21 100644 --- a/ngraph/core/include/ngraph/opsets/opset5_tbl.hpp +++ b/ngraph/core/include/ngraph/opsets/opset5_tbl.hpp @@ -164,9 +164,10 @@ NGRAPH_OP(Swish, ngraph::op::v4) // New operations added in opset5 NGRAPH_OP(GatherND, ngraph::op::v5) +NGRAPH_OP(GRUSequence, ngraph::op::v5) +NGRAPH_OP(HSigmoid, ngraph::op::v5) NGRAPH_OP(LogSoftmax, ngraph::op::v5) NGRAPH_OP(LSTMSequence, ngraph::op::v5) NGRAPH_OP(NonMaxSuppression, ngraph::op::v5) -NGRAPH_OP(GRUSequence, ngraph::op::v5) NGRAPH_OP(RNNSequence, ngraph::op::v5) NGRAPH_OP(Round, ngraph::op::v5) diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/hsigmoid.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/hsigmoid.hpp new file mode 100644 index 00000000000000..861e152543a3b1 --- /dev/null +++ b/ngraph/core/reference/include/ngraph/runtime/reference/hsigmoid.hpp @@ -0,0 +1,38 @@ +//***************************************************************************** +// 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 +#include + +namespace ngraph +{ + namespace runtime + { + namespace reference + { + template + void hsigmoid(const T* arg, T* out, size_t count) + { + for (size_t i = 0; i < count; i++) + { + out[i] = std::min(std::max(arg[i] + 3.0f, 0.0f), 6.0f) / 6.0f; + } + } + } + } +} diff --git a/ngraph/core/src/op/hsigmoid.cpp b/ngraph/core/src/op/hsigmoid.cpp new file mode 100644 index 00000000000000..0854fe35fcb566 --- /dev/null +++ b/ngraph/core/src/op/hsigmoid.cpp @@ -0,0 +1,79 @@ +//***************************************************************************** +// 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 "ngraph/op/hsigmoid.hpp" +#include "ngraph/attribute_visitor.hpp" +#include "ngraph/op/constant.hpp" + +#include "ngraph/runtime/host_tensor.hpp" +#include "ngraph/runtime/reference/hsigmoid.hpp" + +using namespace std; +using namespace ngraph; + +NGRAPH_RTTI_DEFINITION(op::v5::HSigmoid, "HSigmoid", 5); + +op::v5::HSigmoid::HSigmoid(const Output& arg) + : UnaryElementwiseArithmetic(arg) +{ + constructor_validate_and_infer_types(); +} + +bool op::v5::HSigmoid::visit_attributes(AttributeVisitor& visitor) +{ + return true; +} + +shared_ptr op::v5::HSigmoid::clone_with_new_inputs(const OutputVector& new_args) const +{ + return make_shared(new_args.at(0)); +} + +namespace +{ + template + inline bool evaluate(const HostTensorPtr& arg, const HostTensorPtr& out, const size_t count) + { + using T = typename element_type_traits::value_type; + + runtime::reference::hsigmoid(arg->get_data_ptr(), out->get_data_ptr(), count); + return true; + } + + bool evaluate_hsigmoid(const HostTensorPtr& arg, const HostTensorPtr& out, const size_t count) + { + bool rc = true; + out->set_unary(arg); + + switch (arg->get_element_type()) + { + TYPE_CASE(bf16)(arg, out, count); + break; + TYPE_CASE(f16)(arg, out, count); + break; + TYPE_CASE(f32)(arg, out, count); + break; + default: rc = false; break; + } + return rc; + } +} + +bool op::v5::HSigmoid::evaluate(const HostTensorVector& outputs, + const HostTensorVector& inputs) const +{ + return evaluate_hsigmoid(inputs[0], outputs[0], shape_size(get_output_shape(0))); +} diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 996f1cafec5b9e..8969eb90cba6fb 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC node_input_output.cpp op.cpp op_eval/floor_mod.cpp + op_eval/hsigmoid.cpp op_eval/hswish.cpp op_eval/interpolate.cpp op_eval/matmul.cpp diff --git a/ngraph/test/op_eval/hsigmoid.cpp b/ngraph/test/op_eval/hsigmoid.cpp new file mode 100644 index 00000000000000..58e67e8baa35f8 --- /dev/null +++ b/ngraph/test/op_eval/hsigmoid.cpp @@ -0,0 +1,48 @@ +//***************************************************************************** +// 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 +#include + +#include "gtest/gtest.h" + +#include "ngraph/op/hsigmoid.hpp" +#include "ngraph/runtime/host_tensor.hpp" +#include "ngraph/validation_util.hpp" +#include "runtime/backend.hpp" +#include "util/test_tools.hpp" + +using namespace std; +using namespace ngraph; + +TEST(op_eval, hsigmoid) +{ + auto p = make_shared(element::f32, Shape{3}); + auto swish = make_shared(p); + auto fun = make_shared(OutputVector{swish}, ParameterVector{p}); + + std::vector inputs{-0.5f, 0.0f, 0.5f}; + std::vector expected_result{0.416667f, 0.5f, 0.583333f}; + + auto result = make_shared(); + ASSERT_TRUE( + fun->evaluate({result}, {make_host_tensor(Shape{3}, inputs)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{3}); + auto result_data = read_vector(result); + for (auto i = 0; i < inputs.size(); i++) + EXPECT_NEAR(result_data[i], expected_result[i], 0.000001); +}