Adding v7::Gelu operation (#4497)

* Added support for Gelu-6 to the MO

* Adding Gelu-6 to ngraph and python API + some tests

* Fixed typo in the Gelu approximation mode

* Fixed Gelu-6 reference implementation for Tanh mode

* Added transformation to downgrade v6::Gelu to v2::Gelu

* Added specification for the Gelu-6

* Code style fixes

* The Gelu-6 operation specification update

* Fixed compilation issue in reference implementation for Gelu

* Fix compilation issues for some OSs

* Code style fix

* One more cpplint issue fix

* Fixed Gelu6 reference implementation compilation on Windows.

* Code style fix

* Fixed various ngraph unit tests

* Code style check

* Reverted Gelu-2 to be fused op

* Fixed Gelu6 downgrade transformation

* Added unit test for Gelu6Downgrade transformation

* Update copyright year

* Updated copyright year

* Replaced tab characters with 4 spaces in IR reader tests

* Code style fixes

* Added default value for GeluApproximation mode for Gelu-6 op

* Fixed code style for Gelu-6

* Changed order of parameters for the Gelu evaluate to potentially avoid backward compatibility issues with ARM plugin

* Fixed code style

* Introduced opset7. Moved Gelu6 to opset7

* Fixed non-updated transformation

* Fixed opset version in ngraph Python API for Gelu operation

* Fixed typo in the opset number in the documentation

* Reverted some changes related to Gelu6

* Updated MO to produce Gelu7

* Updated unit tests for Gelu

* Updated Gelu7 specification

* Changed gelu reference implementation. Added opset7 to Python packages

* Updated Python API tests for Gelu operation

* Code style fix

* Marked get_approximation_mode function as const

* Added missing "const" qualifier

* Fixed code style issues in tests

* Added extractor for MxNet operation Gelu

* Spelling issues fix

* Updated MxNet supported symbols

* Added NGRAPH_OP_SCOPE for Gelu7 validate_and_infer_types

* Fixed a typo in the comment
This commit is contained in:
Evgeny Lazarev
2021-03-09 22:45:45 +03:00
committed by GitHub
parent a5e2497788
commit 99f94ca09c
40 changed files with 1501 additions and 197 deletions

View File

@@ -98,7 +98,7 @@ Standard MXNet\* symbols:
| InstanceNorm | No |
| L2Normalization | only 4D input is supported |
| LRN | No |
| LeakyReLU | No |
| LeakyReLU | supported "act_type" = "prelu", "elu", "leaky", "gelu" |
| Pad | No |
| Pooling | No |
| ROIPooling | No |

View File

@@ -82,6 +82,7 @@ limitations under the License.
<!-- Intermediate Representation and Operations Sets -->
<tab id="intermediate_representaton_and_operations_sets" type="usergroup" title="Intermediate Representation and Operations Sets" url="@ref openvino_docs_MO_DG_IR_and_opsets">
<tab type="usergroup" title="Available Operations Sets" url="@ref openvino_docs_ops_opset">
<tab type="user" title="opset7 Specification" url="@ref openvino_docs_ops_opset7"/>
<tab type="user" title="opset6 Specification" url="@ref openvino_docs_ops_opset6"/>
<tab type="user" title="opset5 Specification" url="@ref openvino_docs_ops_opset5"/>
<tab type="user" title="opset4 Specification" url="@ref openvino_docs_ops_opset4"/>
@@ -145,6 +146,7 @@ limitations under the License.
<tab type="user" title="GatherElements-6" url="@ref openvino_docs_ops_movement_GatherElements_6"/>
<tab type="user" title="GatherND-5" url="@ref openvino_docs_ops_movement_GatherND_5"/>
<tab type="user" title="Gelu-2" url="@ref openvino_docs_ops_activation_GELU_2"/>
<tab type="user" title="Gelu-7" url="@ref openvino_docs_ops_activation_GELU_7"/>
<tab type="user" title="GreaterEqual-1" url="@ref openvino_docs_ops_comparison_GreaterEqual_1"/>
<tab type="user" title="Greater-1" url="@ref openvino_docs_ops_comparison_Greater_1"/>
<tab type="user" title="GroupConvolutionBackpropData-1" url="@ref openvino_docs_ops_convolution_GroupConvolutionBackpropData_1"/>

View File

@@ -0,0 +1,89 @@
## GELU- Gaussian Error Linear Unit <a name="Gelu"></a> {#openvino_docs_ops_activation_GELU_7}
**Versioned name**: *Gelu-7*
**Category**: *Activation*
**Short description**: Calculates Gaussian error linear.
**Detailed description**: `Gelu(x) = x * Φ(x)`, where `Φ(x)` is the Cumulative Distribution Function for Gaussian Distribution.
The Gelu operation is introduced in the [paper](https://arxiv.org/abs/1606.08415).
**Attributes**
* *approximation_mode*
* **Description**: Specifies the formulae to calculate the output.
* **Range of values**:
* `erf` -- calculate output using the Gauss error function.
* `tanh` -- calculate output using tanh approximation
* **Type**: `string`
* **Default value**: `erf`
* **Required**: *no*
**Mathematical Formulation**
For the `erf` approximation mode:
\f[
Gelu(x) = 0.5 \cdot x \cdot (1.0 + erf((x) / \sqrt{2})
\f]
For the `tanh` approximation mode:
\f[
Gelu(x) \approx 0.5 \cdot x \cdot (1.0 + tanh(\sqrt{2.0/pi} \cdot (x + 0.044715 \cdot x ^ 3))
\f]
**Inputs**:
* **1**: Multidimensional input tensor of type *T*. Required.
**Outputs**:
* **1**: Floating point tensor with shape and type *T* matching the input tensor.
**Types**
* *T*: any floating point type.
**Examples**
```xml
<layer ... type="Gelu">
<data approximation_mode="tanh"/>
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
```
```xml
<layer ... type="Gelu">
<data approximation_mode="erf"/>
<input>
<port id="0">
<dim>3</dim>
<dim>7</dim>
<dim>9</dim>
</port>
</input>
<output>
<port id="1">
<dim>3</dim>
<dim>7</dim>
<dim>9</dim>
</port>
</output>
</layer>
```

View File

@@ -6,6 +6,7 @@ This topic provides a complete list of available sets of operations supported in
| OpenVINO™ Version | Actual Operations Set |
| :---------------- | :------------------------------- |
| 2021.4 | [opset7](opset7.md) |
| 2021.3 | [opset6](opset6.md) |
| 2021.2 | [opset5](opset5.md) |
| 2021.1 | [opset4](opset4.md) |

158
docs/ops/opset7.md Normal file
View File

@@ -0,0 +1,158 @@
# Operation Set `opset7` Specification {#openvino_docs_ops_opset7}
This specification document describes `opset7` operation set supported in OpenVINO.
Support for each particular operation from the list below depends on the capabilities available in a inference plugin
and may vary among different hardware platforms and devices. Examples of operation instances are expressed as IR V10 xml
snippets. Such IR is generated by the Model Optimizer. The semantics match corresponding nGraph operation classes
declared in `namespace opset7`.
## Table of Contents <a name="toc"></a>
* [Abs](arithmetic/Abs_1.md)
* [Acos](arithmetic/Acos_1.md)
* [Acosh](arithmetic/Acosh_3.md)
* [Add](arithmetic/Add_1.md)
* [Asin](arithmetic/Asin_1.md)
* [Asinh](arithmetic/Asinh_3.md)
* [Assign](infrastructure/Assign_3.md)
* [Atan](arithmetic/Atan_1.md)
* [Atanh](arithmetic/Atanh_3.md)
* [AvgPool](pooling/AvgPool_1.md)
* [BatchNormInference](normalization/BatchNormInference_5.md)
* [BatchToSpace](movement/BatchToSpace_2.md)
* [BinaryConvolution](convolution/BinaryConvolution_1.md)
* [Broadcast](movement/Broadcast_3.md)
* [Bucketize](condition/Bucketize_3.md)
* [CTCGreedyDecoder](sequence/CTCGreedyDecoder_1.md)
* [CTCGreedyDecoderSeqLen](sequence/CTCGreedyDecoderSeqLen_6.md)
* [CTCLoss](sequence/CTCLoss_4.md)
* [Ceiling](arithmetic/Ceiling_1.md)
* [Clamp](activation/Clamp_1.md)
* [Concat](movement/Concat_1.md)
* [Constant](infrastructure/Constant_1.md)
* [Convert](type/Convert_1.md)
* [ConvertLike](type/ConvertLike_1.md)
* [Convolution](convolution/Convolution_1.md)
* [ConvolutionBackpropData](convolution/ConvolutionBackpropData_1.md)
* [Cos](arithmetic/Cos_1.md)
* [Cosh](arithmetic/Cosh_1.md)
* [CumSum](arithmetic/CumSum_3.md)
* [DeformableConvolution](convolution/DeformableConvolution_1.md)
* [DeformablePSROIPooling](detection/DeformablePSROIPooling_1.md)
* [DepthToSpace](movement/DepthToSpace_1.md)
* [DetectionOutput](detection/DetectionOutput_1.md)
* [Divide](arithmetic/Divide_1.md)
* [Elu](activation/Elu_1.md)
* [EmbeddingBagOffsetsSum](sparse/EmbeddingBagOffsetsSum_3.md)
* [EmbeddingBagPackedSum](sparse/EmbeddingBagPackedSum_3.md)
* [EmbeddingSegmentsSum](sparse/EmbeddingSegmentsSum_3.md)
* [Equal](comparison/Equal_1.md)
* [Erf](arithmetic/Erf_1.md)
* [Exp](activation/Exp_1.md)
* [ExtractImagePatches](movement/ExtractImagePatches_3.md)
* [FakeQuantize](quantization/FakeQuantize_1.md)
* [Floor](arithmetic/Floor_1.md)
* [FloorMod](arithmetic/FloorMod_1.md)
* [Gather](movement/Gather_1.md)
* [GatherElements](movement/GatherElements_6.md)
* [GatherND_5](movement/GatherND_5.md)
* [GatherTree](movement/GatherTree_1.md)
* [Gelu](activation/GELU_7.md)
* [Greater](comparison/Greater_1.md)
* [GreaterEqual](comparison/GreaterEqual_1.md)
* [GRN](normalization/GRN_1.md)
* [GroupConvolution](convolution/GroupConvolution_1.md)
* [GroupConvolutionBackpropData](convolution/GroupConvolutionBackpropData_1.md)
* [GRUCell](sequence/GRUCell_3.md)
* [GRUSequence](sequence/GRUSequence_5.md)
* [HardSigmoid](activation/HardSigmoid_1.md)
* [HSigmoid](activation/HSigmoid_5.md)
* [HSwish](activation/HSwish_4.md)
* [Interpolate](image/Interpolate_4.md)
* [Less](comparison/Less_1.md)
* [LessEqual](comparison/LessEqual_1.md)
* [Log](arithmetic/Log_1.md)
* [LogicalAnd](logical/LogicalAnd_1.md)
* [LogicalNot](logical/LogicalNot_1.md)
* [LogicalOr](logical/LogicalOr_1.md)
* [LogicalXor](logical/LogicalXor_1.md)
* [LogSoftmax](activation/LogSoftmax_5.md)
* [Loop](infrastructure/Loop_5.md)
* [LRN](normalization/LRN_1.md)
* [LSTMCell](sequence/LSTMCell_1.md)
* [LSTMSequence](sequence/LSTMSequence_1.md)
* [MatMul](matrix/MatMul_1.md)
* [MaxPool](pooling/MaxPool_1.md)
* [Maximum](arithmetic/Maximum_1.md)
* [Minimum](arithmetic/Minimum_1.md)
* [Mish](activation/Mish_4.md)
* [Mod](arithmetic/Mod_1.md)
* [MVN](normalization/MVN_6.md)
* [Multiply](arithmetic/Multiply_1.md)
* [Negative](arithmetic/Negative_1.md)
* [NonMaxSuppression](sort/NonMaxSuppression_5.md)
* [NonZero](condition/NonZero_3.md)
* [NormalizeL2](normalization/NormalizeL2_1.md)
* [NotEqual](comparison/NotEqual_1.md)
* [OneHot](sequence/OneHot_1.md)
* [Pad](movement/Pad_1.md)
* [Parameter](infrastructure/Parameter_1.md)
* [Power](arithmetic/Power_1.md)
* [PReLU](activation/PReLU_1.md)
* [PriorBoxClustered](detection/PriorBoxClustered_1.md)
* [PriorBox](detection/PriorBox_1.md)
* [Proposal](detection/Proposal_4.md)
* [PSROIPooling](detection/PSROIPooling_1.md)
* [Range](generation/Range_4.md)
* [ReLU](activation/ReLU_1.md)
* [ReadValue](infrastructure/ReadValue_3.md)
* [ReduceL1](reduction/ReduceL1_4.md)
* [ReduceL2](reduction/ReduceL2_4.md)
* [ReduceLogicalAnd](reduction/ReduceLogicalAnd_1.md)
* [ReduceLogicalOr](reduction/ReduceLogicalOr_1.md)
* [ReduceMax](reduction/ReduceMax_1.md)
* [ReduceMean](reduction/ReduceMean_1.md)
* [ReduceMin](reduction/ReduceMin_1.md)
* [ReduceProd](reduction/ReduceProd_1.md)
* [ReduceSum](reduction/ReduceSum_1.md)
* [RegionYolo](detection/RegionYolo_1.md)
* [ReorgYolo](detection/ReorgYolo_1.md)
* [Reshape](shape/Reshape_1.md)
* [Result](infrastructure/Result_1.md)
* [ReverseSequence](movement/ReverseSequence_1.md)
* [RNNCell](sequence/RNNCell_3.md)
* [RNNSequence](sequence/RNNSequence_5.md)
* [ROIAlign](detection/ROIAlign_3.md)
* [ROIPooling](detection/ROIPooling_1.md)
* [Round](arithmetic/Round_5.md)
* [ScatterElementsUpdate](movement/ScatterElementsUpdate_3.md)
* [ScatterNDUpdate](movement/ScatterNDUpdate_3.md)
* [ScatterUpdate](movement/ScatterUpdate_3.md)
* [Select](condition/Select_1.md)
* [Selu](arithmetic/Selu_1.md)
* [ShapeOf](shape/ShapeOf_3.md)
* [ShuffleChannels](movement/ShuffleChannels_1.md)
* [Sigmoid](activation/Sigmoid_1.md)
* [Sign](arithmetic/Sign_1.md)
* [Sin](arithmetic/Sin_1.md)
* [Sinh](arithmetic/Sinh_1.md)
* [SoftMax](activation/SoftMax_1.md)
* [SoftPlus](activation/SoftPlus_4.md)
* [SpaceToBatch](movement/SpaceToBatch_2.md)
* [SpaceToDepth](movement/SpaceToDepth_1.md)
* [Split](movement/Split_1.md)
* [Sqrt](arithmetic/Sqrt_1.md)
* [SquaredDifference](arithmetic/SquaredDifference_1.md)
* [Squeeze](shape/Squeeze_1.md)
* [StridedSlice](movement/StridedSlice_1.md)
* [Subtract](arithmetic/Subtract_1.md)
* [Swish](activation/Swish_4.md)
* [Tan](arithmetic/Tan_1.md)
* [Tanh](arithmetic/Tanh_1.md)
* [TensorIterator](infrastructure/TensorIterator_1.md)
* [Tile](movement/Tile_1.md)
* [TopK](sort/TopK_3.md)
* [Transpose](movement/Transpose_1.md)
* [Unsqueeze](shape/Unsqueeze_1.md)
* [VariadicSplit](movement/VariadicSplit_1.md)

View File

@@ -38,6 +38,7 @@
#include <transformations/op_conversions/convert_depth_to_space.hpp>
#include <transformations/op_conversions/convert_space_to_depth.hpp>
#include <transformations/op_conversions/convert_gelu.hpp>
#include <transformations/op_conversions/gelu7_downgrade.hpp>
#include <transformations/op_conversions/hswish_decomposition.hpp>
#include <transformations/op_conversions/hsigmoid_decomposition.hpp>
#include <transformations/op_conversions/mvn6_decomposition.hpp>
@@ -220,6 +221,7 @@ static void Transformation(CNNNetwork& clonedNetwork, const Config& conf) {
// List of enabled/disabled transformations
pass_config->disable<ngraph::pass::ConvertGELU>();
pass_config->disable<ngraph::pass::Gelu7Downgrade>();
pass_config->disable<ngraph::pass::HSwishDecomposition>();
pass_config->disable<ngraph::pass::ReduceL1Decomposition>();
pass_config->disable<ngraph::pass::ReduceL2Decomposition>();

View File

@@ -865,6 +865,7 @@ V10Parser::V10Parser(const std::vector<IExtensionPtr>& exts) : _exts(exts) {
opsets["opset4"] = ngraph::get_opset4();
opsets["opset5"] = ngraph::get_opset5();
opsets["opset6"] = ngraph::get_opset6();
opsets["opset7"] = ngraph::get_opset7();
// Load custom opsets
for (const auto& ext : exts) {

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <transformations_visibility.hpp>
#include <ngraph/pass/graph_rewrite.hpp>
namespace ngraph {
namespace pass {
class TRANSFORMATIONS_API Gelu7Downgrade;
} // namespace pass
} // namespace ngraph
/**
* @ingroup ie_transformation_common_api
* @brief Gelu7Downgrade converts v7::Gelu operation to v2::Gelu unconditionally. This is done because only limited
* set of plugins support v7::Gelu which has an attribute specifying approximation mode. For other plugins the
* behaviour is to use v2 version of the operation which does not support the approximation mode.
*/
class ngraph::pass::Gelu7Downgrade : public ngraph::pass::MatcherPass {
public:
NGRAPH_RTTI_DECLARATION;
Gelu7Downgrade();
};

View File

@@ -15,7 +15,6 @@
#include "transformations/common_optimizations/fq_reshape_fusion.hpp"
#include "transformations/common_optimizations/depth_to_space_fusion.hpp"
#include "transformations/common_optimizations/optimize_strided_slice.hpp"
#include "transformations/common_optimizations/mish_fusion.hpp"
#include "transformations/common_optimizations/softplus_fusion.hpp"
#include "transformations/common_optimizations/softplus_to_mish_fusion.hpp"
#include "transformations/common_optimizations/swish_fusion.hpp"
@@ -45,6 +44,7 @@
#include "transformations/op_conversions/convert_gelu.hpp"
#include "transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp"
#include "transformations/op_conversions/batch_norm_decomposition.hpp"
#include "transformations/op_conversions/gelu7_downgrade.hpp"
#include "transformations/op_conversions/reduce_l1_decomposition.hpp"
#include "transformations/op_conversions/reduce_l2_decomposition.hpp"
#include "transformations/op_conversions/hswish_decomposition.hpp"
@@ -102,6 +102,7 @@ bool ngraph::pass::CommonOptimizations::run_on_function(std::shared_ptr<ngraph::
manager.register_pass<ngraph::pass::ConvertInterpolate1ToInterpolate4, false>();
auto decomp = manager.register_pass<ngraph::pass::GraphRewrite>();
decomp->add_matcher<ngraph::pass::Gelu7Downgrade>();
decomp->add_matcher<ngraph::pass::BidirectionalSequenceDecomposition>();
decomp->add_matcher<ngraph::pass::ReduceL1Decomposition>();
decomp->add_matcher<ngraph::pass::ReduceL2Decomposition>();

View File

@@ -6,7 +6,6 @@
#include <memory>
#include <ngraph/opsets/opset2.hpp>
#include <transformations/op_conversions/convert_gelu.hpp>
#include <transformations/utils/utils.hpp>
#include <ngraph/ngraph.hpp>
#include <ngraph/rt_info.hpp>

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "transformations/op_conversions/gelu7_downgrade.hpp"
#include <memory>
#include <ngraph/opsets/opset2.hpp>
#include <ngraph/opsets/opset7.hpp>
#include <ngraph/rt_info.hpp>
#include <ngraph/pattern/op/wrap_type.hpp>
#include "itt.hpp"
NGRAPH_RTTI_DEFINITION(ngraph::pass::Gelu7Downgrade, "Gelu7Downgrade", 0);
ngraph::pass::Gelu7Downgrade::Gelu7Downgrade() {
MATCHER_SCOPE(Gelu7Downgrade);
auto gelu = ngraph::pattern::wrap_type<opset7::Gelu>();
ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) {
auto& pattern_to_output = m.get_pattern_value_map();
auto gelu_node = std::dynamic_pointer_cast<ngraph::opset7::Gelu>(pattern_to_output.at(gelu).get_node_shared_ptr());
if (gelu_node == nullptr || transformation_callback(gelu_node)) {
return false;
}
auto new_gelu_node = std::make_shared<ngraph::opset2::Gelu>(gelu_node->input_value(0));
new_gelu_node->set_friendly_name(gelu_node->get_friendly_name());
ngraph::copy_runtime_info(gelu_node, new_gelu_node);
ngraph::replace_node(gelu_node, new_gelu_node);
return true;
};
auto m = std::make_shared<ngraph::pattern::Matcher>(gelu, matcher_name);
register_matcher(m, callback);
}

View File

@@ -392,9 +392,10 @@ const std::vector<Edge> create_edge_mapping(
std::string get_opset_name(
const ngraph::Node* n,
const std::map<std::string, ngraph::OpSet>& custom_opsets) {
auto opsets = std::array<std::reference_wrapper<const ngraph::OpSet>, 6>{
auto opsets = std::array<std::reference_wrapper<const ngraph::OpSet>, 7>{
ngraph::get_opset1(), ngraph::get_opset2(), ngraph::get_opset3(),
ngraph::get_opset4(), ngraph::get_opset5(), ngraph::get_opset6()};
ngraph::get_opset4(), ngraph::get_opset5(), ngraph::get_opset6(),
ngraph::get_opset7()};
auto special_opset = get_special_opset_for_op(n->get_type_info());
if (!special_opset.empty()) {

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
@@ -32,103 +32,103 @@ TEST_F(NGraphReaderTests, ReadGeluNetwork) {
std::string model_v7 = R"V0G0N(
<?xml version="1.0"?>
<net name="Network" version="6" batch="1">
<layers>
<layer name="in1" type="Input" precision="FP32" id="0">
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Multiply_304" type="Power" precision="FP32" id="1">
<data power="1" scale="0.5" shift="0" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Divide_307" type="Power" precision="FP32" id="2">
<data power="1" scale="0.707107" shift="0" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Erf_308" type="Erf" precision="FP32" id="3">
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Add_310" type="Power" precision="FP32" id="4">
<data power="1" scale="1" shift="1" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="activation" type="Eltwise" precision="FP32" id="5">
<data operation="prod" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
<port id="1">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0" />
<edge from-layer="0" from-port="0" to-layer="1" to-port="0" />
<edge from-layer="1" from-port="1" to-layer="5" to-port="0" />
<edge from-layer="2" from-port="1" to-layer="3" to-port="0" />
<edge from-layer="3" from-port="1" to-layer="4" to-port="0" />
<edge from-layer="4" from-port="1" to-layer="5" to-port="1" />
</edges>
<statistics />
<layers>
<layer name="in1" type="Input" precision="FP32" id="0">
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Multiply_304" type="Power" precision="FP32" id="1">
<data power="1" scale="0.5" shift="0" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Divide_307" type="Power" precision="FP32" id="2">
<data power="1" scale="0.707107" shift="0" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Erf_308" type="Erf" precision="FP32" id="3">
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="Add_310" type="Power" precision="FP32" id="4">
<data power="1" scale="1" shift="1" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
<layer name="activation" type="Eltwise" precision="FP32" id="5">
<data operation="prod" />
<input>
<port id="0">
<dim>1</dim>
<dim>128</dim>
</port>
<port id="1">
<dim>1</dim>
<dim>128</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>1</dim>
<dim>128</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0" />
<edge from-layer="0" from-port="0" to-layer="1" to-port="0" />
<edge from-layer="1" from-port="1" to-layer="5" to-port="0" />
<edge from-layer="2" from-port="1" to-layer="3" to-port="0" />
<edge from-layer="3" from-port="1" to-layer="4" to-port="0" />
<edge from-layer="4" from-port="1" to-layer="5" to-port="1" />
</edges>
<statistics />
</net>
)V0G0N";
@@ -136,3 +136,174 @@ TEST_F(NGraphReaderTests, ReadGeluNetwork) {
compareIRs(model_v10, model_v7, 0);
}
TEST_F(NGraphReaderTests, ReadGelu6TanhNetwork) {
std::string model = R"V0G0N(
<net name="saved_model" version="10">
<layers>
<layer id="0" name="input_a" type="Parameter" version="opset1">
<data shape="1,3,4" element_type="f32"/>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="gelu" type="Gelu" version="opset7">
<data approximation_mode="tanh"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="2" name="gelu/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
<edge from-layer="1" from-port="1" to-layer="2" to-port="0"/>
</edges>
</net>
)V0G0N";
std::string modelV7 = R"V0G0N(
<net name="saved_model" version="7">
<layers>
<layer id="0" name="input_a" type="Input" version="opset1">
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="gelu" type="Gelu" version="opset7">
<data approximation_mode="tanh"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
</edges>
</net>
)V0G0N";
compareIRs(model, modelV7);
}
TEST_F(NGraphReaderTests, ReadGelu6ErfNetwork) {
std::string model = R"V0G0N(
<net name="saved_model" version="10">
<layers>
<layer id="0" name="input_a" type="Parameter" version="opset1">
<data shape="1,3,4" element_type="f32"/>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="gelu" type="Gelu" version="opset7">
<data approximation_mode="erf"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="2" name="gelu/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
<edge from-layer="1" from-port="1" to-layer="2" to-port="0"/>
</edges>
</net>
)V0G0N";
std::string modelV7 = R"V0G0N(
<net name="saved_model" version="7">
<layers>
<layer id="0" name="input_a" type="Input" version="opset1">
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="gelu" type="Gelu" version="opset7">
<data approximation_mode="erf"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="1" precision="FP32">
<dim>1</dim>
<dim>3</dim>
<dim>4</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
</edges>
</net>
)V0G0N";
compareIRs(model, modelV7);
}

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset2.hpp>
#include <ngraph/opsets/opset7.hpp>
#include <transformations/op_conversions/gelu7_downgrade.hpp>
#include <transformations/init_node_info.hpp>
#include <ngraph/pass/manager.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
using namespace testing;
TEST(TransformationTests, Gelu7Downgrade) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset7::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 3});
auto gelu = std::make_shared<ngraph::opset7::Gelu>(input, ngraph::op::GeluApproximationMode::ERF);
gelu->set_friendly_name("gelu7");
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{gelu}, ngraph::ParameterVector{input});
ngraph::pass::Manager manager;
manager.register_pass<ngraph::pass::InitNodeInfo>();
manager.register_pass<ngraph::pass::Gelu7Downgrade>();
manager.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto input = std::make_shared<ngraph::opset7::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 3});
auto gelu = std::make_shared<ngraph::opset2::Gelu>(input);
gelu->set_friendly_name("gelu7");
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{gelu}, ngraph::ParameterVector{input});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
auto result_node_of_converted_f = f->get_output_op(0);
auto output_node = result_node_of_converted_f->input(0).get_source_output().get_node_shared_ptr();
ASSERT_TRUE(output_node->get_friendly_name() == "gelu7") << "Transformation Gelu7Downgrade should keep output names.\n";
}

View File

@@ -73,6 +73,7 @@ void TestEnvironment::TearDown() {
opsets.push_back(ngraph::get_opset4());
opsets.push_back(ngraph::get_opset5());
opsets.push_back(ngraph::get_opset6());
opsets.push_back(ngraph::get_opset7());
std::set<ngraph::NodeTypeInfo> opsInfo;
for (const auto &opset : opsets) {
const auto &type_info_set = opset.get_type_info_set();

View File

@@ -126,7 +126,7 @@ class GeLUMergerErf(FrontReplacementPattern):
# check that the values match the approximation
if fabs(div_param - sqrt2) < 1e-06 and mul_param == 0.5 and add_param == 1.0:
log.debug('Confirmed Erf-based GELU pattern after {} with name {}'.format(inp_node.op, inp_name))
gelu = GeLUOP(graph, dict(name=inp_name + '/GELU_')).create_node()
gelu = GeLUOP(graph, dict(name=inp_name + '/GELU_', approximation='erf')).create_node()
div.in_port(0).get_connection().set_destination(gelu.in_port(0))
out_node.out_port(0).get_connection().set_source(gelu.out_port(0))
rename_nodes([(out_node, node_name + '/TBD'), (gelu, node_name)])

View File

@@ -23,7 +23,7 @@ from mo.utils.ir_engine.compare_graphs import compare_graphs
from mo.utils.unittest.graph import build_graph, const, regular_op, result, build_graph
ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
**regular_op('gelu', {'type': 'Gelu', 'name': 'final_mul'}),
**regular_op('gelu', {'type': 'Gelu', 'approximation': 'erf', 'name': 'final_mul'}),
**result('result')
}
ref_edges = [('input', 'gelu'), ('gelu', 'result')]
@@ -65,6 +65,7 @@ class GeLUMergerErfTest(unittest.TestCase):
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
self.assertTrue(flag, resp)
self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation == 'erf')
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')
@@ -89,6 +90,7 @@ class GeLUMergerErfTest(unittest.TestCase):
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
self.assertTrue(flag, resp)
self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation == 'erf')
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')
@@ -113,5 +115,6 @@ class GeLUMergerErfTest(unittest.TestCase):
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
self.assertTrue(flag, resp)
self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation == 'erf')
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')

View File

@@ -74,6 +74,6 @@ class GeLUMergerTanh(FrontReplacementSubgraph):
# check that the values match the approximation
if fabs(mul0_param - sqrt2pi) < 1e-06 and fabs(mul_param - 0.044715) < 1e-06 and mul1_param == 0.5:
log.debug('Confirmed TanH-based GELU pattern after {} with name {}'.format(inp.op, inp.name))
gelu = GeLUOP(graph, dict(name=inp.name + '/GELU_')).create_node()
gelu = GeLUOP(graph, dict(name=inp.name + '/GELU_', approximation='tanh')).create_node()
inp_port.connect(gelu.in_port(0))
match['mul2'].out_port(0).get_connection().set_source(gelu.out_port(0))

View File

@@ -15,11 +15,10 @@
"""
import unittest
import numpy as np
from math import sqrt
from extensions.front.GeLUMerger_Erf import GeLUMergerErf
import numpy as np
from extensions.front.GeLUMerger_Tanh import GeLUMergerTanh
from mo.utils.ir_engine.compare_graphs import compare_graphs
from mo.utils.unittest.graph import build_graph
@@ -55,42 +54,13 @@ nodes_attributes_tanh = {
nodes_attributes_ref = {
'inp': {'kind': 'op', 'op': 'AnyOp'},
'gelu': {'kind': 'op', 'op': 'Gelu'},
'gelu': {'kind': 'op', 'op': 'Gelu', 'approximation': 'tanh'},
'out': {'kind': 'op', 'op': 'AnyOp'},
}
class TestGeLUMergerReplacement(unittest.TestCase):
def test_GeLUMergerErf_test_1(self):
graph = build_graph(nodes_attributes_erf,
[('inp', 'mul0', {'out': 0}),
('inp', 'div', {'out': 0}),
('mul', 'mul0'),
('div', 'erf'),
('erf', 'add'),
('add', 'mul0'),
('mul_param', 'mul'),
('div_param', 'div'),
('add_param', 'add'),
('mul0', 'out'),
],
{'mul_param': {'shape': np.array([1]), 'value': np.array(0.5)},
'add_param': {'shape': np.array([1]), 'value': np.array(1.0)},
'div_param': {'shape': np.array([1]), 'value': np.array(sqrt(2.0))}
},
nodes_with_edges_only=True)
graph_ref = build_graph(nodes_attributes_ref,
[('inp', 'gelu'),
('gelu', 'out')],
{}, nodes_with_edges_only=True)
graph.stage = 'front'
replacer = GeLUMergerErf()
replacer.find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
self.assertTrue(flag, resp)
def test_GeLUMergerTanh_test_2(self):
def test_GeLUMergerTanh(self):
graph = build_graph(nodes_attributes_tanh,
[('inp', 'mul2', {'out': 0}),
('inp', 'add', {'out': 0}),
@@ -122,4 +92,4 @@ class TestGeLUMergerReplacement(unittest.TestCase):
replacer.find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
self.assertTrue(flag, resp)
self.assertTrue(flag, resp)

View File

@@ -15,6 +15,7 @@
"""
from extensions.ops.activation_ops import Elu, LeakyReLU, ReLU
from extensions.ops.gelu import GeLUOP
from extensions.ops.prelu import PReLU
from mo.front.extractor import FrontExtractorOp
from mo.front.mxnet.extractors.utils import get_mxnet_layer_attrs
@@ -50,6 +51,8 @@ class LeakyReLUFrontExtractor(FrontExtractorOp):
ReLU.update_node_stat(node)
else:
LeakyReLU.update_node_stat(node, {'negative_slope': negative_slope})
elif act_type == 'gelu':
GeLUOP.update_node_stat(node, {'approximation': 'erf'})
else:
raise Error(
"Operation '{}' not supported. Please register it as custom op. " +

View File

@@ -24,11 +24,17 @@ class GeLUOP(Op):
def __init__(self, graph: Graph, attrs: dict):
mandatory_props = {
'type': __class__.op,
'op': __class__.op,
'type': self.op,
'op': self.op,
'in_ports_count': 1,
'out_ports_count': 1,
'version': 'opset2',
'version': 'opset7',
'infer': copy_shape_infer
}
super().__init__(graph, mandatory_props, attrs)
super().__init__(graph, mandatory_props, attrs)
def backend_attrs(self):
if self.get_opset() == 'opset7':
return ['approximation']
else:
return []

View File

@@ -19,13 +19,13 @@
#include "ngraph/node.hpp"
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/fused_op.hpp"
NGRAPH_SUPPRESS_DEPRECATED_START
#include "ngraph/op/util/unary_elementwise_arithmetic.hpp"
namespace ngraph
{
namespace op
{
NGRAPH_SUPPRESS_DEPRECATED_START
namespace v0
{
/// \brief Gaussian Error Linear Unit
@@ -36,7 +36,7 @@ namespace ngraph
static constexpr NodeTypeInfo type_info{"Gelu", 0};
const NodeTypeInfo& get_type_info() const override { return type_info; }
Gelu();
/// \brief Constructs an Gelu operation.
/// \brief Constructs a Gelu operation.
///
/// \param data Input tensor
Gelu(const Output<Node>& data);
@@ -51,7 +51,64 @@ namespace ngraph
};
}
using v0::Gelu;
}
}
NGRAPH_SUPPRESS_DEPRECATED_END
NGRAPH_SUPPRESS_DEPRECATED_END
/// \brief Specifies the approximation to calculate Gelu
enum class GeluApproximationMode
{
TANH,
ERF
};
NGRAPH_API std::ostream& operator<<(std::ostream& s, const GeluApproximationMode& type);
namespace v7
{
/// \brief Gaussian Error Linear Unit
/// f(x) = 0.5 * x * (1 + erf( x / sqrt(2) ) for "approximation" = "erf"
/// f(x) = 0.5 * x * (1 + tanh([sqrt(2 / pi)] * [x + 0.044715^3]) for "approximation" =
/// "tanh"
class NGRAPH_API Gelu : public util::UnaryElementwiseArithmetic
{
public:
NGRAPH_RTTI_DECLARATION;
Gelu() = default;
/// \brief Constructs a Gelu operation.
///
/// \param data Input tensor
/// \param mode Approximation mode
Gelu(const Output<Node>& data,
GeluApproximationMode mode = GeluApproximationMode::ERF);
bool visit_attributes(AttributeVisitor& visitor) override;
void validate_and_infer_types() override;
bool evaluate(const HostTensorVector& outputs,
const HostTensorVector& inputs) const override;
std::shared_ptr<Node>
clone_with_new_inputs(const OutputVector& new_args) const override;
GeluApproximationMode get_approximation_mode() const;
private:
GeluApproximationMode m_approximation_mode = GeluApproximationMode::ERF;
};
}
}
template <>
class NGRAPH_API AttributeAdapter<op::GeluApproximationMode>
: public EnumAttributeAdapterBase<op::GeluApproximationMode>
{
public:
AttributeAdapter(op::GeluApproximationMode& value)
: EnumAttributeAdapterBase<op::GeluApproximationMode>(value)
{
}
static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<op::GeluApproximationMode>",
0};
const DiscreteTypeInfo& get_type_info() const override { return type_info; }
};
}

View File

@@ -134,4 +134,5 @@ namespace ngraph
const NGRAPH_API OpSet& get_opset4();
const NGRAPH_API OpSet& get_opset5();
const NGRAPH_API OpSet& get_opset6();
const NGRAPH_API OpSet& get_opset7();
}

View File

@@ -0,0 +1,29 @@
//*****************************************************************************
// Copyright 2017-2021 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/ops.hpp"
namespace ngraph
{
namespace opset7
{
#define NGRAPH_OP(a, b) using b::a;
#include "ngraph/opsets/opset7_tbl.hpp"
#undef NGRAPH_OP
} // namespace opset7
} // namespace ngraph

View File

@@ -0,0 +1,185 @@
//*****************************************************************************
// Copyright 2017-2021 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.
//*****************************************************************************
#ifndef NGRAPH_OP
#warning "NGRAPH_OP not defined"
#define NGRAPH_OP(x, y)
#endif
NGRAPH_OP(Abs, ngraph::op::v0)
NGRAPH_OP(Acos, ngraph::op::v0)
NGRAPH_OP(Add, ngraph::op::v1)
NGRAPH_OP(Asin, ngraph::op::v0)
NGRAPH_OP(Atan, ngraph::op::v0)
NGRAPH_OP(AvgPool, ngraph::op::v1)
NGRAPH_OP(BatchNormInference, ngraph::op::v5)
NGRAPH_OP(BinaryConvolution, ngraph::op::v1)
NGRAPH_OP(Broadcast, ngraph::op::v3)
NGRAPH_OP(Bucketize, ngraph::op::v3)
NGRAPH_OP(CTCGreedyDecoder, ngraph::op::v0)
NGRAPH_OP(Ceiling, ngraph::op::v0)
NGRAPH_OP(Clamp, ngraph::op::v0)
NGRAPH_OP(Concat, ngraph::op::v0)
NGRAPH_OP(Constant, ngraph::op)
NGRAPH_OP(Convert, ngraph::op::v0)
NGRAPH_OP(ConvertLike, ngraph::op::v1)
NGRAPH_OP(Convolution, ngraph::op::v1)
NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v1)
NGRAPH_OP(Cos, ngraph::op::v0)
NGRAPH_OP(Cosh, ngraph::op::v0)
NGRAPH_OP(CumSum, ngraph::op::v0)
NGRAPH_OP(DeformableConvolution, ngraph::op::v1)
NGRAPH_OP(DeformablePSROIPooling, ngraph::op::v1)
NGRAPH_OP(DepthToSpace, ngraph::op::v0)
NGRAPH_OP(DetectionOutput, ngraph::op::v0)
NGRAPH_OP(Divide, ngraph::op::v1)
NGRAPH_OP(Elu, ngraph::op::v0)
NGRAPH_OP(Erf, ngraph::op::v0)
NGRAPH_OP(Equal, ngraph::op::v1)
NGRAPH_OP(Exp, ngraph::op::v0)
NGRAPH_OP(ExtractImagePatches, ngraph::op::v3)
NGRAPH_OP(FakeQuantize, ngraph::op::v0)
NGRAPH_OP(Floor, ngraph::op::v0)
NGRAPH_OP(FloorMod, ngraph::op::v1)
NGRAPH_OP(Gather, ngraph::op::v1)
NGRAPH_OP(GatherTree, ngraph::op::v1)
NGRAPH_OP(Greater, ngraph::op::v1)
NGRAPH_OP(GreaterEqual, ngraph::op::v1)
NGRAPH_OP(GroupConvolution, ngraph::op::v1)
NGRAPH_OP(GroupConvolutionBackpropData, ngraph::op::v1)
NGRAPH_OP(GRN, ngraph::op::v0)
NGRAPH_OP(HardSigmoid, ngraph::op::v0)
NGRAPH_OP(Less, ngraph::op::v1)
NGRAPH_OP(LessEqual, ngraph::op::v1)
NGRAPH_OP(Log, ngraph::op::v0)
NGRAPH_OP(LogicalAnd, ngraph::op::v1)
NGRAPH_OP(LogicalNot, ngraph::op::v1)
NGRAPH_OP(LogicalOr, ngraph::op::v1)
NGRAPH_OP(LogicalXor, ngraph::op::v1)
NGRAPH_OP(LRN, ngraph::op::v0)
NGRAPH_OP(LSTMCell, ngraph::op::v4)
NGRAPH_OP(MatMul, ngraph::op::v0)
NGRAPH_OP(MaxPool, ngraph::op::v1)
NGRAPH_OP(Maximum, ngraph::op::v1)
NGRAPH_OP(Minimum, ngraph::op::v1)
NGRAPH_OP(Mod, ngraph::op::v1)
NGRAPH_OP(Multiply, ngraph::op::v1)
NGRAPH_OP(Negative, ngraph::op::v0)
NGRAPH_OP(NormalizeL2, ngraph::op::v0)
NGRAPH_OP(NotEqual, ngraph::op::v1)
NGRAPH_OP(OneHot, ngraph::op::v1)
NGRAPH_OP(PRelu, ngraph::op::v0)
NGRAPH_OP(PSROIPooling, ngraph::op::v0)
NGRAPH_OP(Pad, ngraph::op::v1)
NGRAPH_OP(Parameter, ngraph::op::v0)
NGRAPH_OP(Power, ngraph::op::v1)
NGRAPH_OP(PriorBox, ngraph::op::v0)
NGRAPH_OP(PriorBoxClustered, ngraph::op::v0)
NGRAPH_OP(Proposal, ngraph::op::v4)
NGRAPH_OP(Range, ngraph::op::v4)
NGRAPH_OP(Relu, ngraph::op::v0)
NGRAPH_OP(ReduceMax, ngraph::op::v1)
NGRAPH_OP(ReduceLogicalAnd, ngraph::op::v1)
NGRAPH_OP(ReduceLogicalOr, ngraph::op::v1)
NGRAPH_OP(ReduceMean, ngraph::op::v1)
NGRAPH_OP(ReduceMin, ngraph::op::v1)
NGRAPH_OP(ReduceProd, ngraph::op::v1)
NGRAPH_OP(ReduceSum, ngraph::op::v1)
NGRAPH_OP(RegionYolo, ngraph::op::v0)
NGRAPH_OP(ReorgYolo, ngraph::op::v0)
NGRAPH_OP(Reshape, ngraph::op::v1)
NGRAPH_OP(Result, ngraph::op::v0)
NGRAPH_OP(ReverseSequence, ngraph::op::v0)
NGRAPH_OP(ROIPooling, ngraph::op::v0)
NGRAPH_OP(ScatterNDUpdate, ngraph::op::v3)
NGRAPH_OP(Select, ngraph::op::v1)
NGRAPH_OP(Selu, ngraph::op::v0)
NGRAPH_OP(Sign, ngraph::op::v0)
NGRAPH_OP(Sigmoid, ngraph::op::v0)
NGRAPH_OP(Sin, ngraph::op::v0)
NGRAPH_OP(Sinh, ngraph::op::v0)
NGRAPH_OP(Softmax, ngraph::op::v1)
NGRAPH_OP(Sqrt, ngraph::op::v0)
NGRAPH_OP(SpaceToDepth, ngraph::op::v0)
NGRAPH_OP(Split, ngraph::op::v1)
NGRAPH_OP(SquaredDifference, ngraph::op::v0)
NGRAPH_OP(Squeeze, ngraph::op::v0)
NGRAPH_OP(StridedSlice, ngraph::op::v1)
NGRAPH_OP(Subtract, ngraph::op::v1)
NGRAPH_OP(Tan, ngraph::op::v0)
NGRAPH_OP(Tanh, ngraph::op::v0)
NGRAPH_OP(TensorIterator, ngraph::op::v0)
NGRAPH_OP(Tile, ngraph::op::v0)
NGRAPH_OP(Transpose, ngraph::op::v1)
NGRAPH_OP(Unsqueeze, ngraph::op::v0)
NGRAPH_OP(VariadicSplit, ngraph::op::v1)
// New operations added in opset2
NGRAPH_OP(BatchToSpace, ngraph::op::v1)
NGRAPH_OP(SpaceToBatch, ngraph::op::v1)
// New operations added in opset3
NGRAPH_OP(EmbeddingBagPackedSum, ngraph::op::v3)
NGRAPH_OP(EmbeddingSegmentsSum, ngraph::op::v3)
NGRAPH_OP(EmbeddingBagOffsetsSum, ngraph::op::v3)
NGRAPH_OP(GRUCell, ngraph::op::v3)
NGRAPH_OP(NonZero, ngraph::op::v3)
NGRAPH_OP(RNNCell, ngraph::op::v0)
NGRAPH_OP(ROIAlign, ngraph::op::v3)
NGRAPH_OP(ScatterElementsUpdate, ngraph::op::v3)
NGRAPH_OP(ScatterUpdate, ngraph::op::v3)
NGRAPH_OP(ShuffleChannels, ngraph::op::v0)
NGRAPH_OP(ShapeOf, ngraph::op::v3)
NGRAPH_OP(TopK, ngraph::op::v3)
// New operations added in opset4
NGRAPH_OP(Acosh, ngraph::op::v3)
NGRAPH_OP(Asinh, ngraph::op::v3)
NGRAPH_OP(Atanh, ngraph::op::v3)
NGRAPH_OP(CTCLoss, ngraph::op::v4)
NGRAPH_OP(HSwish, ngraph::op::v4)
NGRAPH_OP(Interpolate, ngraph::op::v4)
NGRAPH_OP(Mish, ngraph::op::v4)
NGRAPH_OP(ReduceL1, ngraph::op::v4)
NGRAPH_OP(ReduceL2, ngraph::op::v4)
NGRAPH_OP(SoftPlus, ngraph::op::v4)
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(Loop, ngraph::op::v5)
NGRAPH_OP(LSTMSequence, ngraph::op::v5)
NGRAPH_OP(NonMaxSuppression, ngraph::op::v5)
NGRAPH_OP(RNNSequence, ngraph::op::v5)
NGRAPH_OP(Round, ngraph::op::v5)
// New operations added in opset6
NGRAPH_OP(CTCGreedyDecoderSeqLen, ngraph::op::v6)
NGRAPH_OP(ExperimentalDetectronDetectionOutput, ngraph::op::v6)
NGRAPH_OP(ExperimentalDetectronGenerateProposalsSingleImage, ngraph::op::v6)
NGRAPH_OP(ExperimentalDetectronPriorGridGenerator, ngraph::op::v6)
NGRAPH_OP(ExperimentalDetectronROIFeatureExtractor, ngraph::op::v6)
NGRAPH_OP(ExperimentalDetectronTopKROIs, ngraph::op::v6)
NGRAPH_OP(GatherElements, ngraph::op::v6)
NGRAPH_OP(MVN, ngraph::op::v6)
NGRAPH_OP(Assign, ngraph::op::v6) // new version
NGRAPH_OP(ReadValue, ngraph::op::v6) // new version
// New operations added in opset7
NGRAPH_OP(Gelu, ngraph::op::v7)

View File

@@ -18,6 +18,7 @@
#include <cmath>
#include <cstddef>
#include <ngraph/op/gelu.hpp>
namespace ngraph
{
@@ -26,11 +27,25 @@ namespace ngraph
namespace reference
{
template <typename T>
void gelu(const T* arg, T* out, size_t count)
void gelu(const T* arg, T* out, op::GeluApproximationMode mode, size_t count)
{
for (size_t i = 0; i < count; i++)
if (mode == op::GeluApproximationMode::ERF)
{
out[i] = 0.5 * arg[i] * (1 + erf(arg[i] / std::sqrt(2)));
for (size_t i = 0; i < count; i++)
{
out[i] = 0.5 * arg[i] * (1 + erf(arg[i] / std::sqrt(2.0)));
}
}
else if (mode == op::GeluApproximationMode::TANH)
{
const auto pi = atan(1.0) * 4.0;
const auto sqpi = std::sqrt(2.0 / pi);
for (size_t i = 0; i < count; i++)
{
auto& x = arg[i];
out[i] =
0.5 * x * (1.0 + std::tanh(sqpi * (x + 0.044715 * std::pow(x, 3))));
}
}
}
}

View File

@@ -17,6 +17,7 @@
#include <cmath>
#include "itt.hpp"
#include <ngraph/validation_util.hpp>
#include "ngraph/builder/make_constant.hpp"
#include "ngraph/op/add.hpp"
#include "ngraph/op/divide.hpp"
@@ -26,6 +27,7 @@
#include "ngraph/op/multiply.hpp"
#include "ngraph/op/negative.hpp"
#include "ngraph/op/subtract.hpp"
#include "ngraph/runtime/reference/gelu.hpp"
using namespace std;
using namespace ngraph;
@@ -34,18 +36,18 @@ NGRAPH_SUPPRESS_DEPRECATED_START
constexpr NodeTypeInfo op::Gelu::type_info;
op::Gelu::Gelu()
op::v0::Gelu::Gelu()
: FusedOp()
{
}
op::Gelu::Gelu(const Output<Node>& data)
op::v0::Gelu::Gelu(const Output<Node>& data)
: FusedOp({data})
{
constructor_validate_and_infer_types();
}
bool ngraph::op::v0::Gelu::visit_attributes(AttributeVisitor& visitor)
bool op::v0::Gelu::visit_attributes(AttributeVisitor& visitor)
{
NGRAPH_OP_SCOPE(v0_Gelu_visit_attributes);
return true;
@@ -72,17 +74,17 @@ OutputVector op::Gelu::decompose_op() const
return {std::make_shared<op::v1::Multiply>(multiply, add)};
}
shared_ptr<Node> op::Gelu::clone_with_new_inputs(const OutputVector& new_args) const
shared_ptr<Node> op::v0::Gelu::clone_with_new_inputs(const OutputVector& new_args) const
{
NGRAPH_OP_SCOPE(v0_Gelu_clone_with_new_inputs);
if (new_args.size() != 1)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<Gelu>(new_args.at(0));
return make_shared<op::v0::Gelu>(new_args.at(0));
}
void op::Gelu::pre_validate_and_infer_types()
void op::v0::Gelu::pre_validate_and_infer_types()
{
element::Type input_element_type = get_input_element_type(0);
PartialShape input_pshape = get_input_partial_shape(0);
@@ -93,8 +95,110 @@ void op::Gelu::pre_validate_and_infer_types()
input_element_type,
").");
if (input_pshape.is_dynamic())
set_output_type(0, input_element_type, input_pshape);
}
// ------------------------------ V7 ------------------------------
namespace ngraph
{
template <>
NGRAPH_API EnumNames<op::GeluApproximationMode>& EnumNames<op::GeluApproximationMode>::get()
{
set_output_type(0, input_element_type, input_pshape);
static auto enum_names = EnumNames<op::GeluApproximationMode>(
"op::GeluApproximationMode",
{{"TANH", op::GeluApproximationMode::TANH}, {"ERF", op::GeluApproximationMode::ERF}});
return enum_names;
}
constexpr DiscreteTypeInfo AttributeAdapter<op::GeluApproximationMode>::type_info;
std::ostream& op::operator<<(std::ostream& s, const op::GeluApproximationMode& type)
{
return s << as_string(type);
}
} // namespace ngraph
NGRAPH_RTTI_DEFINITION(op::v7::Gelu, "Gelu", 7);
op::v7::Gelu::Gelu(const Output<Node>& data, GeluApproximationMode mode)
: UnaryElementwiseArithmetic(data)
, m_approximation_mode(mode)
{
constructor_validate_and_infer_types();
}
bool op::v7::Gelu::visit_attributes(AttributeVisitor& visitor)
{
NGRAPH_OP_SCOPE(v7_Gelu_visit_attributes);
visitor.on_attribute("approximation_mode", m_approximation_mode);
return true;
}
shared_ptr<Node> op::v7::Gelu::clone_with_new_inputs(const OutputVector& new_args) const
{
NGRAPH_OP_SCOPE(v7_Gelu_clone_with_new_inputs);
if (new_args.size() != 1)
{
throw ngraph_error("Incorrect number of new arguments");
}
return make_shared<op::v7::Gelu>(new_args.at(0), m_approximation_mode);
}
void op::v7::Gelu::validate_and_infer_types()
{
NGRAPH_OP_SCOPE(v7_Gelu_validate_and_infer_types);
element::Type input_element_type = get_input_element_type(0);
PartialShape input_pshape = get_input_partial_shape(0);
NODE_VALIDATION_CHECK(this,
input_element_type.is_dynamic() || input_element_type.is_real(),
"Argument element type must be f16, bf16, f32, f64 or dynamic (got ",
input_element_type,
").");
set_output_type(0, input_element_type, input_pshape);
}
op::GeluApproximationMode op::v7::Gelu::get_approximation_mode() const
{
return m_approximation_mode;
}
namespace gelu
{
template <element::Type_t ET>
inline bool evaluate(const HostTensorPtr& arg0,
const HostTensorPtr& out,
op::GeluApproximationMode mode,
const size_t count)
{
using T = typename element_type_traits<ET>::value_type;
runtime::reference::gelu<T>(arg0->get_data_ptr<ET>(), out->get_data_ptr<ET>(), mode, count);
return true;
}
bool evaluate_gelu(const HostTensorPtr& arg0,
const HostTensorPtr& out,
op::GeluApproximationMode mode,
const size_t count)
{
bool rc = true;
out->set_unary(arg0);
switch (arg0->get_element_type())
{
NGRAPH_TYPE_CASE(evaluate_gelu, f16, arg0, out, mode, count);
NGRAPH_TYPE_CASE(evaluate_gelu, f32, arg0, out, mode, count);
default: rc = false; break;
}
return rc;
}
}
bool op::v7::Gelu::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const
{
NGRAPH_OP_SCOPE(v7_Gelu_evaluate);
return gelu::evaluate_gelu(
inputs[0], outputs[0], m_approximation_mode, shape_size(get_output_shape(0)));
}

View File

@@ -157,3 +157,22 @@ const ngraph::OpSet& ngraph::get_opset6()
}
return opset;
}
const ngraph::OpSet& ngraph::get_opset7()
{
static std::mutex init_mutex;
static bool opset_is_initialized = false;
static OpSet opset;
if (!opset_is_initialized)
{
std::lock_guard<std::mutex> guard(init_mutex);
if (!opset_is_initialized)
{
#define NGRAPH_OP(NAME, NAMESPACE) opset.insert<NAMESPACE::NAME>();
#include "ngraph/opsets/opset7_tbl.hpp"
#undef NGRAPH_OP
opset_is_initialized = true;
}
}
return opset;
}

View File

@@ -46,6 +46,7 @@ packages = [
"ngraph.opset4",
"ngraph.opset5",
"ngraph.opset6",
"ngraph.opset7",
"ngraph.utils",
"ngraph.impl",
"ngraph.impl.op",

View File

@@ -0,0 +1,166 @@
# ******************************************************************************
# Copyright 2017-2021 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.
# ******************************************************************************
from ngraph.opset1.ops import absolute
from ngraph.opset1.ops import absolute as abs
from ngraph.opset1.ops import acos
from ngraph.opset4.ops import acosh
from ngraph.opset1.ops import add
from ngraph.opset1.ops import asin
from ngraph.opset4.ops import asinh
from ngraph.opset3.ops import assign
from ngraph.opset1.ops import atan
from ngraph.opset4.ops import atanh
from ngraph.opset1.ops import avg_pool
from ngraph.opset5.ops import batch_norm_inference
from ngraph.opset2.ops import batch_to_space
from ngraph.opset1.ops import binary_convolution
from ngraph.opset3.ops import broadcast
from ngraph.opset3.ops import bucketize
from ngraph.opset1.ops import ceiling
from ngraph.opset1.ops import ceiling as ceil
from ngraph.opset1.ops import clamp
from ngraph.opset1.ops import concat
from ngraph.opset1.ops import constant
from ngraph.opset1.ops import convert
from ngraph.opset1.ops import convert_like
from ngraph.opset1.ops import convolution
from ngraph.opset1.ops import convolution_backprop_data
from ngraph.opset1.ops import cos
from ngraph.opset1.ops import cosh
from ngraph.opset1.ops import ctc_greedy_decoder
from ngraph.opset6.ops import ctc_greedy_decoder_seq_len
from ngraph.opset4.ops import ctc_loss
from ngraph.opset3.ops import cum_sum
from ngraph.opset3.ops import cum_sum as cumsum
from ngraph.opset1.ops import deformable_convolution
from ngraph.opset1.ops import deformable_psroi_pooling
from ngraph.opset1.ops import depth_to_space
from ngraph.opset1.ops import detection_output
from ngraph.opset1.ops import divide
from ngraph.opset1.ops import elu
from ngraph.opset3.ops import embedding_bag_offsets_sum
from ngraph.opset3.ops import embedding_bag_packed_sum
from ngraph.opset3.ops import embedding_segments_sum
from ngraph.opset3.ops import extract_image_patches
from ngraph.opset1.ops import equal
from ngraph.opset1.ops import erf
from ngraph.opset1.ops import exp
from ngraph.opset1.ops import fake_quantize
from ngraph.opset1.ops import floor
from ngraph.opset1.ops import floor_mod
from ngraph.opset1.ops import gather
from ngraph.opset6.ops import gather_elements
from ngraph.opset5.ops import gather_nd
from ngraph.opset1.ops import gather_tree
from ngraph.opset7.ops import gelu
from ngraph.opset1.ops import greater
from ngraph.opset1.ops import greater_equal
from ngraph.opset1.ops import grn
from ngraph.opset1.ops import group_convolution
from ngraph.opset1.ops import group_convolution_backprop_data
from ngraph.opset3.ops import gru_cell
from ngraph.opset5.ops import gru_sequence
from ngraph.opset1.ops import hard_sigmoid
from ngraph.opset5.ops import hsigmoid
from ngraph.opset4.ops import hswish
from ngraph.opset1.ops import interpolate
from ngraph.opset1.ops import less
from ngraph.opset1.ops import less_equal
from ngraph.opset1.ops import log
from ngraph.opset1.ops import logical_and
from ngraph.opset1.ops import logical_not
from ngraph.opset1.ops import logical_or
from ngraph.opset1.ops import logical_xor
from ngraph.opset5.ops import log_softmax
from ngraph.opset5.ops import loop
from ngraph.opset1.ops import lrn
from ngraph.opset4.ops import lstm_cell
from ngraph.opset1.ops import lstm_sequence
from ngraph.opset1.ops import matmul
from ngraph.opset1.ops import max_pool
from ngraph.opset1.ops import maximum
from ngraph.opset1.ops import minimum
from ngraph.opset4.ops import mish
from ngraph.opset1.ops import mod
from ngraph.opset1.ops import multiply
from ngraph.opset6.ops import mvn
from ngraph.opset1.ops import negative
from ngraph.opset5.ops import non_max_suppression
from ngraph.opset3.ops import non_zero
from ngraph.opset1.ops import normalize_l2
from ngraph.opset1.ops import not_equal
from ngraph.opset1.ops import one_hot
from ngraph.opset1.ops import pad
from ngraph.opset1.ops import parameter
from ngraph.opset1.ops import power
from ngraph.opset1.ops import prelu
from ngraph.opset1.ops import prior_box
from ngraph.opset1.ops import prior_box_clustered
from ngraph.opset1.ops import psroi_pooling
from ngraph.opset4.ops import proposal
from ngraph.opset1.ops import range
from ngraph.opset3.ops import read_value
from ngraph.opset4.ops import reduce_l1
from ngraph.opset4.ops import reduce_l2
from ngraph.opset1.ops import reduce_logical_and
from ngraph.opset1.ops import reduce_logical_or
from ngraph.opset1.ops import reduce_max
from ngraph.opset1.ops import reduce_mean
from ngraph.opset1.ops import reduce_min
from ngraph.opset1.ops import reduce_prod
from ngraph.opset1.ops import reduce_sum
from ngraph.opset1.ops import region_yolo
from ngraph.opset2.ops import reorg_yolo
from ngraph.opset1.ops import relu
from ngraph.opset1.ops import reshape
from ngraph.opset1.ops import result
from ngraph.opset1.ops import reverse_sequence
from ngraph.opset3.ops import rnn_cell
from ngraph.opset5.ops import rnn_sequence
from ngraph.opset3.ops import roi_align
from ngraph.opset2.ops import roi_pooling
from ngraph.opset5.ops import round
from ngraph.opset3.ops import scatter_elements_update
from ngraph.opset3.ops import scatter_update
from ngraph.opset1.ops import select
from ngraph.opset1.ops import selu
from ngraph.opset3.ops import shape_of
from ngraph.opset3.ops import shuffle_channels
from ngraph.opset1.ops import sigmoid
from ngraph.opset1.ops import sign
from ngraph.opset1.ops import sin
from ngraph.opset1.ops import sinh
from ngraph.opset1.ops import softmax
from ngraph.opset4.ops import softplus
from ngraph.opset2.ops import space_to_batch
from ngraph.opset1.ops import space_to_depth
from ngraph.opset1.ops import split
from ngraph.opset1.ops import sqrt
from ngraph.opset1.ops import squared_difference
from ngraph.opset1.ops import squeeze
from ngraph.opset1.ops import strided_slice
from ngraph.opset1.ops import subtract
from ngraph.opset4.ops import swish
from ngraph.opset1.ops import tan
from ngraph.opset1.ops import tanh
from ngraph.opset1.ops import tensor_iterator
from ngraph.opset1.ops import tile
from ngraph.opset3.ops import topk
from ngraph.opset1.ops import transpose
from ngraph.opset1.ops import unsqueeze
from ngraph.opset1.ops import variadic_split

View File

@@ -0,0 +1,80 @@
# ******************************************************************************
# Copyright 2017-2021 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.
# ******************************************************************************
"""Factory functions for all ngraph ops."""
from typing import Callable, Iterable, List, Optional, Set, Union
import numpy as np
from functools import partial
from ngraph.impl import Node, Shape
from ngraph.impl.op import Constant, Parameter
from ngraph.opset_utils import _get_node_factory
from ngraph.utils.decorators import binary_op, nameable_op, unary_op
from ngraph.utils.input_validation import (
assert_list_of_ints,
check_valid_attributes,
is_non_negative_value,
is_positive_value,
)
from ngraph.utils.node_factory import NodeFactory
from ngraph.utils.tensor_iterator_types import (
GraphBody,
TensorIteratorSliceInputDesc,
TensorIteratorMergedInputDesc,
TensorIteratorInvariantInputDesc,
TensorIteratorBodyOutputDesc,
TensorIteratorConcatOutputDesc,
)
from ngraph.utils.types import (
NodeInput,
NumericData,
NumericType,
ScalarData,
TensorShape,
as_node,
as_nodes,
get_dtype,
get_element_type,
get_element_type_str,
make_constant_node,
)
_get_node_factory_opset7 = partial(_get_node_factory, "opset7")
# -------------------------------------------- ops ------------------------------------------------
@nameable_op
def gelu(
data: Node,
approximation_mode: str,
name: Optional[str] = None,
) -> Node:
"""Return a node which performs Gelu activation function.
@param data: The node with data tensor.
@param approximation_mode: defines which approximation to use ('tanh' or 'erf')
@param name: Optional output node name.
@return The new node performing a Gelu activation with the input tensor.
"""
inputs = as_nodes(data)
attributes = {
"approximation_mode": approximation_mode
}
return _get_node_factory_opset7().create("Gelu", inputs, attributes)

View File

@@ -93,6 +93,7 @@ namespace
{"opset4", OpsetFunction(ngraph::get_opset4)},
{"opset5", OpsetFunction(ngraph::get_opset5)},
{"opset6", OpsetFunction(ngraph::get_opset6)},
{"opset7", OpsetFunction(ngraph::get_opset7)},
};
auto it = s_opsets.find(opset_ver);
@@ -103,7 +104,7 @@ namespace
return it->second();
}
const ngraph::OpSet& m_opset = ngraph::get_opset6();
const ngraph::OpSet& m_opset = ngraph::get_opset7();
};
} // namespace

View File

@@ -195,3 +195,4 @@ xfail_issue_49750 = xfail_test(reason="RuntimeError: Unsupported dynamic ops: v4
xfail_issue_49752 = xfail_test(reason="RuntimeError: Unsupported dynamic ops: v1::Pad")
xfail_issue_49753 = xfail_test(reason="RuntimeError: Unsupported dynamic ops: v1::StridedSlice")
xfail_issue_49754 = xfail_test(reason="RuntimeError: Unsupported dynamic ops: v1::TopKIE")
xfail_issue_49913 = xfail_test(reason="CPU supports Gelu with tanh mode only")

View File

@@ -222,36 +222,6 @@ def test_batch_to_space():
assert np.allclose(result, expected)
def test_gelu_operator_with_parameters():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
data_shape = [2, 2]
parameter_data = ng.parameter(data_shape, name="Data", dtype=np.float32)
model = ng.gelu(parameter_data)
computation = runtime.computation(model, parameter_data)
result = computation(data_value)
expected = np.array([[-1.4901161e-06, 8.4134471e-01], [-4.5500278e-02, 2.9959502]], dtype=np.float32)
assert np.allclose(result, expected, 0.007, 0.007)
def test_gelu_operator_with_array():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
model = ng.gelu(data_value)
computation = runtime.computation(model)
result = computation()
expected = np.array([[-1.4901161e-06, 8.4134471e-01], [-4.5500278e-02, 2.9959502]], dtype=np.float32)
assert np.allclose(result, expected, 0.007, 0.007)
def test_clamp_operator():
runtime = get_runtime()

View File

@@ -18,8 +18,9 @@ import pytest
import ngraph as ng
from ngraph.impl import Shape, Type
from tests.runtime import get_runtime
from tests.test_ngraph.util import run_op_node
from tests import xfail_issue_44970
from tests import xfail_issue_44970, xfail_issue_49913
@pytest.mark.parametrize(
@@ -185,3 +186,64 @@ def test_hsigmoid():
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == [3, 10]
assert node.get_output_element_type(0) == Type.f32
@xfail_issue_49913
def test_gelu_operator_with_parameters():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
data_shape = [2, 2]
parameter_data = ng.parameter(data_shape, name="Data", dtype=np.float32)
model = ng.gelu(parameter_data, "erf")
computation = runtime.computation(model, parameter_data)
result = computation(data_value)
expected = np.array([[-1.6391277e-06, 8.4134471e-01], [-4.5500278e-02, 2.9959502]], dtype=np.float32)
assert np.allclose(result, expected)
@xfail_issue_49913
def test_gelu_operator_with_array():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
model = ng.gelu(data_value, "erf")
computation = runtime.computation(model)
result = computation()
expected = np.array([[-1.6391277e-06, 8.4134471e-01], [-4.5500278e-02, 2.9959502]], dtype=np.float32)
assert np.allclose(result, expected)
def test_gelu_tanh_operator_with_parameters():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
data_shape = [2, 2]
parameter_data = ng.parameter(data_shape, name="Data", dtype=np.float32)
model = ng.gelu(parameter_data, "tanh")
computation = runtime.computation(model, parameter_data)
result = computation(data_value)
expected = np.array([[0.0, 0.841192], [-0.04540223, 2.9963627]], dtype=np.float32)
assert np.allclose(result, expected, 1e-6, 1e-6)
def test_gelu_tanh_operator_with_array():
runtime = get_runtime()
data_value = np.array([[-5, 1], [-2, 3]], dtype=np.float32)
model = ng.gelu(data_value, "tanh")
computation = runtime.computation(model)
result = computation()
expected = np.array([[0.0, 0.841192], [-0.04540223, 2.9963627]], dtype=np.float32)
assert np.allclose(result, expected, 1e-6, 1e-6)

View File

@@ -73,6 +73,7 @@ set(SRC
op.cpp
op_eval/bucketize.cpp
op_eval/floor_mod.cpp
op_eval/gelu.cpp
op_eval/hsigmoid.cpp
op_eval/hswish.cpp
op_eval/interpolate.cpp

View File

@@ -0,0 +1,72 @@
//*****************************************************************************
// Copyright 2017-2021 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 <string>
#include <vector>
#include "gtest/gtest.h"
#include "ngraph/op/gelu.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/validation_util.hpp"
#include "util/test_tools.hpp"
using namespace std;
using namespace ngraph;
TEST(op_eval, gelu_tanh)
{
auto p = make_shared<op::Parameter>(element::f32, Shape{});
auto gelu = make_shared<op::v7::Gelu>(p, op::GeluApproximationMode::TANH);
auto fun = make_shared<Function>(OutputVector{gelu}, ParameterVector{p});
std::vector<std::vector<float>> inputs{{-1.0}, {-0.5}, {0}, {0.5}, {1.0}};
std::vector<std::vector<float>> expected_result{
{-0.15880796}, {-0.154286}, {0}, {0.345714}, {0.841192}};
for (size_t i = 0; i < inputs.size(); i++)
{
auto result = make_shared<HostTensor>();
ASSERT_TRUE(
fun->evaluate({result}, {make_host_tensor<element::Type_t::f32>(Shape{}, inputs[i])}));
EXPECT_EQ(result->get_element_type(), element::f32);
EXPECT_EQ(result->get_shape(), (Shape{}));
auto result_data = read_vector<float>(result);
EXPECT_NEAR(result_data[0], expected_result[i][0], 0.000001);
}
}
TEST(op_eval, gelu_erf)
{
auto p = make_shared<op::Parameter>(element::f32, Shape{});
auto gelu = make_shared<op::v7::Gelu>(p, op::GeluApproximationMode::ERF);
auto fun = make_shared<Function>(OutputVector{gelu}, ParameterVector{p});
std::vector<std::vector<float>> inputs{{-1.0}, {-0.5}, {0}, {0.5}, {1.0}};
std::vector<std::vector<float>> expected_result{
{-0.15865529}, {-0.15426877}, {0}, {0.34573123}, {0.8413447}};
for (size_t i = 0; i < inputs.size(); i++)
{
auto result = make_shared<HostTensor>();
ASSERT_TRUE(
fun->evaluate({result}, {make_host_tensor<element::Type_t::f32>(Shape{}, inputs[i])}));
EXPECT_EQ(result->get_element_type(), element::f32);
EXPECT_EQ(result->get_shape(), (Shape{}));
auto result_data = read_vector<float>(result);
EXPECT_NEAR(result_data[0], expected_result[i][0], 0.000001);
}
}

View File

@@ -398,7 +398,7 @@ TEST(provenance, fused_copy_origin_tags)
auto p1 = make_shared<op::Parameter>(element::f32, PartialShape{2, 3, 4});
p1->add_provenance_tag("P1");
auto g = make_shared<op::Gelu>(p1);
auto g = make_shared<op::MVN>(p1);
g->add_provenance_tag("G");
auto r = make_shared<op::Result>(g);
auto f = make_shared<Function>(ResultVector{r}, ParameterVector{p1});
@@ -420,7 +420,7 @@ TEST(provenance, fused_copy_origin_tags)
else
{
EXPECT_TRUE(tags.find("G") != tags.end());
EXPECT_TRUE(tags.find("<Decomposed from Gelu>") != tags.end());
EXPECT_TRUE(tags.find("<Decomposed from MVN>") != tags.end());
}
});
}

View File

@@ -1108,6 +1108,20 @@ namespace
using T = typename element_type_traits<ET>::value_type;
runtime::reference::gelu<T>(inputs[0]->get_data_ptr<T>(),
outputs[0]->get_data_ptr<T>(),
op::GeluApproximationMode::ERF,
shape_size(inputs[0]->get_shape()));
return true;
}
template <element::Type_t ET>
bool evaluate(const shared_ptr<op::v7::Gelu>& op,
const HostTensorVector& outputs,
const HostTensorVector& inputs)
{
using T = typename element_type_traits<ET>::value_type;
runtime::reference::gelu<T>(inputs[0]->get_data_ptr<T>(),
outputs[0]->get_data_ptr<T>(),
op->get_approximation_mode(),
shape_size(inputs[0]->get_shape()));
return true;
}

View File

@@ -311,6 +311,8 @@ std::set<NodeTypeInfo> test::IE_Engine::get_ie_ops() const
ie_ops.insert(opset5.begin(), opset5.end());
const auto& opset6 = get_opset6().get_type_info_set();
ie_ops.insert(opset6.begin(), opset6.end());
const auto& opset7 = get_opset7().get_type_info_set();
ie_ops.insert(opset7.begin(), opset7.end());
return ie_ops;
}