Skip to content

Commit

Permalink
Revise erf OP (openvinotoolkit#6477)
Browse files Browse the repository at this point in the history
* Revise Erf OP sepc

Signed-off-by: Luwei Zhou <[email protected]>

* Revise the NGraph Erf OP implment to switch to RTTI.

Signed-off-by: Luwei Zhou <[email protected]>

* Remove the duplicated Erf in the activation type vector.

Signed-off-by: Luwei Zhou <[email protected]>

* Add NGraph visitor API test case.

Signed-off-by: Luwei Zhou <[email protected]>

* Enalbe the Erf visitor API CmakeLists.txt.

Signed-off-by: Luwei Zhou <[email protected]>

* Revise the Erf OP backend test

Signed-off-by: Luwei Zhou <[email protected]>

* Migrate to use the template test.

* Add erf type_prop test.

* Update the license

* Unary Visitor test template fix

-Migrate OP Tanh to use RTTI;
-Remove the using namespace in the header file
-Migrate the Swish and Tanh visitor test to use template code


Signed-off-by: Luwei Zhou <[email protected]>

* Revert "Unary Visitor test template fix"

This reverts commit b686c93.

* Update the doc format.

* Update the document format and description.

Signed-off-by: Luwei Zhou <[email protected]>

* Add Erf OP into the layer test summary list

* Migrate the Erf backend test into template_plugin infrastructure

* Update the Erf supported input type.

* Remove the boolean type support in erf reference implement.

validate_and_infer_elementwise_arithmetic() will fail with boolean type.

* Update the erf test  with all supported types.

* Update with separate namespace of CommonReferenceTest
  • Loading branch information
luweizhou2016 authored and akuporos committed Sep 29, 2021
1 parent a5a0f30 commit f874e3f
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 70 deletions.
18 changes: 8 additions & 10 deletions docs/ops/arithmetic/Erf_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,32 @@

**Category**: Arithmetic unary operation

**Short description**: *Erf* calculates the Gauss error function element-wise with given tensor.
**Short description**: *Erf* performs element-wise Gauss error function (erf) on a given input tensor.

**Detailed Description**

For each element from the input tensor calculates corresponding element in the output tensor with the following formula:
*Erf* performs element-wise erf operation on a given input tensor, based on the following mathematical formula:

\f[
erf(x) = \pi^{-1} \int_{-x}^{x} e^{-t^2} dt
\f]

**Attributes**:

No attributes available.
**Attributes**: *Erf* operation has no attributes.

**Inputs**

* **1**: A tensor of type *T*. **Required.**
* **1**: A tensor of type *T* and arbitrary shape. **Required.**

**Outputs**

* **1**: The result of element-wise operation. A tensor of type *T*.
* **1**: The result of element-wise *Erf* function applied to the input tensor. A tensor of type *T* and the same shape as the input tensor.

**Types**

* *T*: any supported floating-point type.
* *T*: any supported numeric type.

**Examples**

*Example 1*
**Example**

```xml
<layer ... type="Erf">
Expand Down
94 changes: 94 additions & 0 deletions docs/template_plugin/tests/functional/op_reference/erf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include <gtest/gtest.h>

#include <ie_core.hpp>
#include <ie_ngraph_utils.hpp>
#include <limits>
#include <ngraph/ngraph.hpp>
#include <shared_test_classes/base/layer_test_utils.hpp>
#include <tuple>

#include "base_reference_test.hpp"

using namespace reference_tests;
using namespace ngraph;
using namespace InferenceEngine;

struct ErfParams {
template <class IT>
ErfParams(const ngraph::PartialShape& shape, const ngraph::element::Type& iType, const std::vector<IT>& iValues)
: pshape(shape), inType(iType), outType(iType), inputData(CreateBlob(iType, iValues)) {
std::vector<IT> oValues;
std::vector<double> output;
for (auto element : iValues)
output.push_back(static_cast<double>(element));

std::transform(output.begin(), output.end(), output.begin(), [](double input) -> double {
return std::erf(input);
});

if (std::is_integral<IT>()) {
std::transform(output.begin(), output.end(), output.begin(), [](double input) -> double {
return std::round(input);
});
}

for (auto element : output)
oValues.push_back(static_cast<IT>(element));
refData = CreateBlob(outType, oValues);
}
ngraph::PartialShape pshape;
ngraph::element::Type inType;
ngraph::element::Type outType;
InferenceEngine::Blob::Ptr inputData;
InferenceEngine::Blob::Ptr refData;
};

class ReferenceErfLayerTest : public testing::TestWithParam<ErfParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.pshape, params.inType, params.outType);
inputData = {params.inputData};
refOutData = {params.refData};
}
static std::string getTestCaseName(const testing::TestParamInfo<ErfParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "shape=" << param.pshape << "_";
result << "iType=" << param.inType << "_";
result << "oType=" << param.outType;
return result.str();
}

private:
static std::shared_ptr<Function> CreateFunction(const PartialShape& input_shape, const element::Type& input_type,
const element::Type& expected_output_type) {
const auto in = std::make_shared<op::Parameter>(input_type, input_shape);
const auto erf = std::make_shared<op::Erf>(in);
return std::make_shared<Function>(NodeVector {erf}, ParameterVector {in});
}
};

TEST_P(ReferenceErfLayerTest, CompareWithRefs) {
Exec();
}

INSTANTIATE_TEST_SUITE_P(
smoke_Erf_With_Hardcoded_Refs, ReferenceErfLayerTest,
::testing::Values(ErfParams(ngraph::PartialShape {2, 5}, ngraph::element::f32,
std::vector<float> {-INFINITY, -4.0f, -3.0f, -2.0f, -1.0f, 0.0f, 1.0f, 2.0f, 3.0f, INFINITY}),
ErfParams(ngraph::PartialShape {2, 5}, ngraph::element::f16,
std::vector<float16> {-INFINITY, -4.0f, -3.0f, -2.0f, -1.0f, 0.0f, 1.0f, 2.0f, 3.0f, INFINITY}),
ErfParams(ngraph::PartialShape {2, 3}, ngraph::element::i32,
std::vector<int32_t> {std::numeric_limits<int32_t>::min(), -2, -1, 1, 2, std::numeric_limits<int32_t>::max()}),
ErfParams(ngraph::PartialShape {2, 3}, ngraph::element::u32,
std::vector<uint32_t> {std::numeric_limits<uint32_t>::min(), 0, 1, 2, 3, std::numeric_limits<uint32_t>::max()}),
ErfParams(ngraph::PartialShape {2, 3}, ngraph::element::i64,
std::vector<int64_t> {std::numeric_limits<int64_t>::min(), -2, -1, 1, 2, std::numeric_limits<int64_t>::max()}),
ErfParams(ngraph::PartialShape {2, 3}, ngraph::element::u64,
std::vector<uint64_t> {std::numeric_limits<uint64_t>::min(), 0, 1, 2, 3, std::numeric_limits<uint64_t>::max()})),
ReferenceErfLayerTest::getTestCaseName);
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
{HSigmoid, {}},
{RoundHalfToEven, {}},
{RoundHalfAwayFromZero, {}},
{Erf, {}},
{GeluErf, {}},
{GeluTanh, {}}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
{HSigmoid, {}},
{RoundHalfToEven, {}},
{RoundHalfAwayFromZero, {}},
{Erf, {}},
{GeluErf, {}},
{GeluTanh, {}},
{Swish, {{0.4f}}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
'DepthToSpace-1',
'DetectionOutput-1',
'Divide-1',
'Erf-1',
'ExperimentalDetectronDetectionOutput-6',
'ExperimentalDetectronGenerateProposalsSingleImage-6',
'ExperimentalDetectronPriorGridGenerator-6',
Expand Down
8 changes: 6 additions & 2 deletions ngraph/core/include/ngraph/op/erf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ namespace ngraph
{
namespace v0
{
/// \brief Elementwise erf operation.
class NGRAPH_API Erf : public util::UnaryElementwiseArithmetic
{
public:
static constexpr NodeTypeInfo type_info{"Erf", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
NGRAPH_RTTI_DECLARATION;
/// \brief Constructs a floor operation.
Erf() = default;
/// \brief Constructs a floor operation.
///
/// \param arg Node that produces the input tensor.
Erf(const Output<Node>& arg);

bool visit_attributes(AttributeVisitor& visitor) override;
Expand Down
4 changes: 1 addition & 3 deletions ngraph/core/src/op/erf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using namespace std;
using namespace ngraph;

constexpr NodeTypeInfo op::Erf::type_info;
NGRAPH_RTTI_DEFINITION(op::v0::Erf, "Erf", 0, util::UnaryElementwiseArithmetic);

bool ngraph::op::v0::Erf::visit_attributes(AttributeVisitor& visitor)
{
Expand Down Expand Up @@ -51,7 +51,6 @@ namespace erfop

switch (arg0->get_element_type())
{
NGRAPH_TYPE_CASE(evaluate_erf, boolean, arg0, out, count);
NGRAPH_TYPE_CASE(evaluate_erf, i32, arg0, out, count);
NGRAPH_TYPE_CASE(evaluate_erf, i64, arg0, out, count);
NGRAPH_TYPE_CASE(evaluate_erf, u32, arg0, out, count);
Expand All @@ -75,7 +74,6 @@ bool op::Erf::has_evaluate() const
NGRAPH_OP_SCOPE(v0_Erf_has_evaluate);
switch (get_input_element_type(0))
{
case ngraph::element::boolean:
case ngraph::element::i32:
case ngraph::element::i64:
case ngraph::element::u32:
Expand Down
3 changes: 2 additions & 1 deletion ngraph/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ set(SRC
type_prop/dft.cpp
type_prop/dyn_reshape.cpp
type_prop/einsum.cpp
type_prop/erf.cpp
type_prop/exp.cpp
type_prop/experimental_detectron_generate_proposals.cpp
type_prop/experimental_detectron_roi_feature_extractor.cpp
Expand Down Expand Up @@ -252,6 +253,7 @@ set(SRC
visitors/op/detection_output.cpp
visitors/op/einsum.cpp
visitors/op/elu.cpp
visitors/op/erf.cpp
visitors/op/extractimagepatches.cpp
visitors/op/fake_quantize.cpp
visitors/op/floor.cpp
Expand Down Expand Up @@ -415,7 +417,6 @@ set(MULTI_TEST_SRC
backend/strided_slice.in.cpp
backend/dynamic.in.cpp
backend/elu.in.cpp
backend/erf.in.cpp
backend/exp.in.cpp
backend/experimental_detectron_detection_output.in.cpp
backend/experimental_detectron_prior_grid.in.cpp
Expand Down
52 changes: 0 additions & 52 deletions ngraph/test/backend/erf.in.cpp

This file was deleted.

9 changes: 9 additions & 0 deletions ngraph/test/type_prop/erf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "unary_ops.hpp"

using Type = ::testing::Types<ngraph::op::Erf>;

INSTANTIATE_TYPED_TEST_SUITE_P(type_prop_erf, UnaryOperator, Type);
12 changes: 12 additions & 0 deletions ngraph/test/visitors/op/erf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "unary_ops.hpp"

using Type = ::testing::Types<UnaryOperatorType<ngraph::op::v0::Erf, element::f32>>;

INSTANTIATE_TYPED_TEST_SUITE_P(visitor_without_atrribute,
UnaryOperatorVisitor,
Type,
UnaryOperatorTypeName);

0 comments on commit f874e3f

Please sign in to comment.