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:
@@ -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 |
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
89
docs/ops/activation/GELU_7.md
Normal file
89
docs/ops/activation/GELU_7.md
Normal 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>
|
||||
|
||||
```
|
||||
@@ -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
158
docs/ops/opset7.md
Normal 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)
|
||||
@@ -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>();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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>();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)])
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
@@ -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. " +
|
||||
|
||||
@@ -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 []
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
29
ngraph/core/include/ngraph/opsets/opset7.hpp
Normal file
29
ngraph/core/include/ngraph/opsets/opset7.hpp
Normal 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
|
||||
185
ngraph/core/include/ngraph/opsets/opset7_tbl.hpp
Normal file
185
ngraph/core/include/ngraph/opsets/opset7_tbl.hpp
Normal 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)
|
||||
@@ -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))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ packages = [
|
||||
"ngraph.opset4",
|
||||
"ngraph.opset5",
|
||||
"ngraph.opset6",
|
||||
"ngraph.opset7",
|
||||
"ngraph.utils",
|
||||
"ngraph.impl",
|
||||
"ngraph.impl.op",
|
||||
|
||||
166
ngraph/python/src/ngraph/opset7/__init__.py
Normal file
166
ngraph/python/src/ngraph/opset7/__init__.py
Normal 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
|
||||
80
ngraph/python/src/ngraph/opset7/ops.py
Normal file
80
ngraph/python/src/ngraph/opset7/ops.py
Normal 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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
72
ngraph/test/op_eval/gelu.cpp
Normal file
72
ngraph/test/op_eval/gelu.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user