Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
14020554d2
7
.gitattributes
vendored
7
.gitattributes
vendored
@ -2,7 +2,6 @@
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
@ -11,9 +10,7 @@
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
*.py text eol=lf
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
@ -36,7 +33,6 @@
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
@ -45,7 +41,6 @@
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
@ -63,9 +58,9 @@
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
|
||||
*.PNG filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.gif filter=lfs diff=lfs merge=lfs -text
|
||||
*.vsdx filter=lfs diff=lfs merge=lfs -text
|
||||
*.bmp filter=lfs diff=lfs merge=lfs -text
|
||||
|
@ -13,9 +13,9 @@ include(CPackComponent)
|
||||
set(IE_CPACK_IE_DIR deployment_tools/inference_engine)
|
||||
function(ie_cpack_set_library_dir)
|
||||
if(WIN32)
|
||||
set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/$<CONFIG> PARENT_SCOPE)
|
||||
set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH_FOLDER}/$<CONFIG> PARENT_SCOPE)
|
||||
set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/$<CONFIG> PARENT_SCOPE)
|
||||
else()
|
||||
set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE)
|
||||
set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE)
|
||||
|
@ -31,19 +31,18 @@ macro(ie_parse_ci_build_number)
|
||||
set(IE_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(IE_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(IE_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
set(has_ci_version ON)
|
||||
else()
|
||||
set(IE_VERSION_MAJOR 0)
|
||||
set(IE_VERSION_MINOR 0)
|
||||
set(IE_VERSION_PATCH 0)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED repo_root)
|
||||
message(FATAL_ERROR "repo_root is not defined")
|
||||
endif()
|
||||
|
||||
if(DEFINED IEDevScripts_DIR AND DEFINED OpeenVINO_SOURCE_DIR AND NOT DEFINED custom_build)
|
||||
set(ie_version_hpp "${IE_MAIN_SOURCE_DIR}/include/ie_version.hpp")
|
||||
macro(ie_get_hpp_version)
|
||||
if(NOT DEFINED OpenVINO_SOURCE_DIR)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(ie_version_hpp "${OpenVINO_SOURCE_DIR}/inference-engine/include/ie_version.hpp")
|
||||
if(NOT EXISTS ${ie_version_hpp})
|
||||
message(FATAL_ERROR "File ie_version.hpp with IE_VERSION definitions is not found")
|
||||
endif()
|
||||
@ -57,6 +56,13 @@ macro(ie_parse_ci_build_number)
|
||||
string(REGEX REPLACE ".+IE_VERSION_PATCH[ ]+([0-9]+).*" "\\1"
|
||||
IE_VERSION_PATCH_HPP "${IE_VERSION_PARTS}")
|
||||
|
||||
set(ie_hpp_version_is_found ON)
|
||||
endmacro()
|
||||
|
||||
# detect OpenVINO version via ie_version.hpp
|
||||
ie_get_hpp_version()
|
||||
|
||||
if(ie_hpp_version_is_found)
|
||||
foreach(var IE_VERSION_MAJOR IE_VERSION_MINOR IE_VERSION_PATCH)
|
||||
if(DEFINED ${var} AND NOT ${var} EQUAL ${var}_HPP)
|
||||
message(FATAL_ERROR "${var} parsed from CI_BUILD_NUMBER (${${var}}) \
|
||||
@ -66,13 +72,10 @@ macro(ie_parse_ci_build_number)
|
||||
set(${var} ${${var}_HPP})
|
||||
endif()
|
||||
endforeach()
|
||||
elseif(has_ci_version)
|
||||
message(WARNING "OpeenVINO_SOURCE_DIR is not defined. No way to compare versions")
|
||||
else()
|
||||
message(WARNING "No way to detect OpenVINO version. Supposing 0.0.0.0")
|
||||
endif()
|
||||
|
||||
set(IE_VERSION "${IE_VERSION_MAJOR}.${IE_VERSION_MINOR}.${IE_VERSION_PATCH}")
|
||||
message(STATUS "OpenVINO version is ${IE_VERSION}")
|
||||
endmacro()
|
||||
|
||||
if (DEFINED ENV{CI_BUILD_NUMBER})
|
||||
|
0
docs/IE_DG/img/applying_low_latency.png
Executable file → Normal file
0
docs/IE_DG/img/applying_low_latency.png
Executable file → Normal file
0
docs/IE_DG/img/applying_low_latency_2.png
Executable file → Normal file
0
docs/IE_DG/img/applying_low_latency_2.png
Executable file → Normal file
0
docs/IE_DG/img/llt2_use_const_initializer.png
Executable file → Normal file
0
docs/IE_DG/img/llt2_use_const_initializer.png
Executable file → Normal file
0
docs/IE_DG/img/low_latency_limitation_1.png
Executable file → Normal file
0
docs/IE_DG/img/low_latency_limitation_1.png
Executable file → Normal file
0
docs/IE_DG/img/low_latency_limitation_2.png
Executable file → Normal file
0
docs/IE_DG/img/low_latency_limitation_2.png
Executable file → Normal file
Binary file not shown.
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 130 B |
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 130 B |
@ -4,33 +4,29 @@
|
||||
|
||||
**Category**: Arithmetic unary operation
|
||||
|
||||
**Short description**: *Asinh* performs element-wise hyperbolic inverse sine (arcsinh) operation with given tensor.
|
||||
**Short description**: *Asinh* performs element-wise inverse hyperbolic sine operation (arcsinh) on a given input tensor.
|
||||
|
||||
**Attributes**:
|
||||
|
||||
No attributes available.
|
||||
|
||||
**Inputs**
|
||||
|
||||
* **1**: A tensor of type *T*. **Required.**
|
||||
|
||||
**Outputs**
|
||||
|
||||
* **1**: The result of element-wise asinh operation. A tensor of type *T*.
|
||||
|
||||
**Types**
|
||||
|
||||
* *T*: any floating point type.
|
||||
|
||||
*Asinh* does the following with the input tensor *a*:
|
||||
**Detailed description**: *Asinh* performs element-wise inverse hyperbolic sine operation on a given input tensor, based on the following mathematical formula:
|
||||
|
||||
\f[
|
||||
a_{i} = asinh(a_{i})
|
||||
\f]
|
||||
|
||||
**Examples**
|
||||
**Attributes**: *Asinh* operation has no attributes.
|
||||
|
||||
*Example 1*
|
||||
**Inputs**
|
||||
|
||||
* **1**: A tensor of type *T* and arbitrary shape. **Required.**
|
||||
|
||||
**Outputs**
|
||||
|
||||
* **1**: The result of element-wise *Asinh* operation. A tensor of type *T* and the same shape as input tensor.
|
||||
|
||||
**Types**
|
||||
|
||||
* *T*: any numeric type.
|
||||
|
||||
**Example**
|
||||
|
||||
```xml
|
||||
<layer ... type="Asinh">
|
||||
|
@ -4,33 +4,29 @@
|
||||
|
||||
**Category**: Arithmetic unary operation
|
||||
|
||||
**Short description**: *Cosh* performs element-wise hyperbolic cosine operation with given tensor.
|
||||
**Short description**: *Cosh* performs element-wise hyperbolic cosine operation on a given input tensor.
|
||||
|
||||
**Attributes**:
|
||||
|
||||
No attributes available.
|
||||
|
||||
**Inputs**
|
||||
|
||||
* **1**: An tensor of type *T*. **Required.**
|
||||
|
||||
**Outputs**
|
||||
|
||||
* **1**: The result of element-wise cosh operation. A tensor of type *T*.
|
||||
|
||||
**Types**
|
||||
|
||||
* *T*: any numeric type.
|
||||
|
||||
*Cosh* does the following with the input tensor *a*:
|
||||
**Detailed description**: *Cosh* performs element-wise hyperbolic cosine (cosh) operation on a given input tensor, based on the following mathematical formula:
|
||||
|
||||
\f[
|
||||
a_{i} = cosh(a_{i})
|
||||
\f]
|
||||
|
||||
**Examples**
|
||||
**Attributes**: *Cosh* operation has no attributes.
|
||||
|
||||
*Example 1*
|
||||
**Inputs**
|
||||
|
||||
* **1**: A tensor of type *T* and arbitrary shape. **Required.**
|
||||
|
||||
**Outputs**
|
||||
|
||||
* **1**: The result of element-wise *Cosh* operation. A tensor of type *T* and the same shape as the input tensor.
|
||||
|
||||
**Types**
|
||||
|
||||
* *T*: any numeric type.
|
||||
|
||||
**Example**
|
||||
|
||||
```xml
|
||||
<layer ... type="Cosh">
|
||||
|
@ -4,46 +4,87 @@
|
||||
|
||||
**Category**: *Data movement*
|
||||
|
||||
**Short description**: The *BatchToSpace* operation reshapes the "batch" dimension 0 into N - 1 dimensions of shape `block_shape` + [batch] and interleaves these blocks back into the grid defined by the spatial dimensions `[1, ..., N - 1]` to obtain a result with the same rank as `data` input. The spatial dimensions of this intermediate result are then optionally cropped according to `crops_begin` and `crops_end` to produce the output. This is the reverse of the *SpaceToBatch* operation.
|
||||
**Short description**: *BatchToSpace* operation permutes the batch dimension on a given input `data` into blocks in the spatial dimensions specified by `block_shape` input. The spatial dimensions are then optionally cropped according to `crops_begin` and `crops_end` inputs to produce the output.
|
||||
|
||||
**Detailed description**:
|
||||
**Detailed description**
|
||||
|
||||
The *BatchToSpace* operation is similar to the TensorFlow* operation [BatchToSpaceND](https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd)
|
||||
*BatchToSpace* operation is equivalent to the following operation steps on the input `data` with shape `[batch, D_1, D_2, ..., D_{N-1}]` and `block_shape`, `crops_begin`, `crops_end` inputs with shape `[N]` to produce the output tensor \f$y\f$.
|
||||
|
||||
The operation is equivalent to the following transformation of the input tensors `data` with shape `[batch, D_1, D_2 ... D_{N-1}]` and `block_shape`, `crops_begin`, `crops_end` of shape `[N]` to *Y* output tensor.
|
||||
1. Reshape `data` input to produce a tensor of shape \f$[B_1, \dots, B_{N - 1}, \frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, D_2, \dots, D_{N - 1}]\f$
|
||||
\f[x^{\prime} = reshape(data, [B_1, \dots, B_{N - 1}, \frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, D_2, \dots, D_{N - 1}])\f]
|
||||
|
||||
note: B_0 is expected to be 1.
|
||||
x' = reshape(`data`, [B_1, ..., B_{N - 1}, batch / (B_1 * ... B_{N - 1}), D_1, D_2, ..., D_{N - 1}]), where B_i = block_shape[i]
|
||||
2. Permute dimensions of \f$x^{\prime}\f$ to produce a tensor of shape \f$[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1, B_1, D_2, B_2, \dots, D_{N-1}, B_{N - 1}]\f$
|
||||
\f[x^{\prime\prime} = transpose(x', [N, N + 1, 0, N + 2, 1, \dots, N + N - 1, N - 1])\f]
|
||||
|
||||
x'' = transpose(x', [N, N + 1, 0, N + 2, 1, ..., N + N - 1, N - 1])
|
||||
3. Reshape \f$x^{\prime\prime}\f$ to produce a tensor of shape \f$[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1 \times B_1, D_2 \times B_2, \dots, D_{N - 1} \times B_{N - 1}]\f$
|
||||
\f[x^{\prime\prime\prime} = reshape(x^{\prime\prime}, [\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, D_1 \times B_1, D_2 \times B_2, \dots, D_{N - 1} \times B_{N - 1}])\f]
|
||||
|
||||
x''' = reshape(x'', [batch / (B_1 * ... * B_{N - 1}), D_1 * B_1, D_2 * B_2, ... , D_{N - 1} * B_{N - 1}])
|
||||
4. Crop the start and end of spatial dimensions of \f$x^{\prime\prime\prime}\f$ according to `crops_begin` and `crops_end` inputs to produce the output \f$y\f$ of shape:
|
||||
\f[\left[\frac{batch}{\left(B_1 \times \dots \times B_{N - 1}\right)}, crop(D_1 \times B_1, CB_1, CE_1), crop(D_2 \times B_2, CB_2, CE_2), \dots , crop(D_{N - 1} \times B_{N - 1}, CB_{N - 1}, CE_{N - 1})\right]\f]
|
||||
|
||||
Crop the start and end of dimensions according to `crops_begin`, `crops_end` to produce the output of shape:
|
||||
note: `crops_begin[0], crops_end[0]` are expected to be 0.
|
||||
`y = [batch / (B_1 * ... * B_{N - 1}), crop(D_1 * B_1, crops_begin[1], crops_end[1]), crop(D_2 * B_2, crops_begin[2], crops_end[2]), ... , crop(D_{N - 1} * B_{N - 1}, crops_begin[N - 1], crops_end[N - 1])]`
|
||||
Where
|
||||
|
||||
**Attributes**
|
||||
- \f$B_i\f$ = block_shape[i]
|
||||
- \f$B_0\f$ is expected to be 1
|
||||
- \f$CB_i\f$ = crops_begin[i]
|
||||
- \f$CE_i\f$ = crops_end[i]
|
||||
- \f$CB_0\f$ and \f$CE_0\f$ are expected to be 0
|
||||
- \f$CB_i + CE_i \leq D_i \times B_i \f$
|
||||
|
||||
No attributes available.
|
||||
*BatchToSpace* operation is the reverse of *SpaceToBatch* operation.
|
||||
|
||||
**Attributes**: *BatchToSpace* operation has no attributes.
|
||||
|
||||
**Inputs**
|
||||
|
||||
* **1**: `data` - input N-D tensor `[batch, D_1, D_2 ... D_{N-1}]` of *T1* type with rank >= 2. **Required.**
|
||||
* **2**: `block_shape` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be >= 1.`block_shape[0]` is expected to be 1. **Required.**
|
||||
* **3**: `crops_begin` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be non-negative. crops_begin specifies the amount to crop from the beginning along each axis of `data` input . It is required that `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i]`. `crops_begin[0]` is expected to be 0. **Required.**
|
||||
* **4**: `crops_end` - input 1-D tensor of *T2* type with shape `[N]` that is equal to the size of `data` input shape. All values must be non-negative. crops_end specifies the amount to crop from the ending along each axis of `data` input. It is required that `crop_start[i] + crop_end[i] <= block_shape[i] * input_shape[i]`. `crops_end[0]` is expected to be 0. **Required.**
|
||||
* **1**: `data` - A tensor of type *T* and rank greater than or equal to 2. Layout is `[batch, D_1, D_2 ... D_{N-1}]` (number of batches, spatial axes). **Required.**
|
||||
* **2**: `block_shape` - Specifies the block sizes of `batch` axis of `data` input which are moved to the corresponding spatial axes. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 1.`block_shape[0]` is expected to be 1. **Required.**
|
||||
* **3**: `crops_begin` - Specifies the amount to crop from the beginning along each axis of `data` input. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 0. `crops_begin[0]` is expected to be 0. **Required.**
|
||||
* **4**: `crops_end` - Specifies the amount to crop from the ending along each axis of `data` input. A 1D tensor of type *T_INT* and shape `[N]`. All element values must be greater than or equal to 0. `crops_end[0]` is expected to be 0. **Required.**
|
||||
* **Note**: `N` corresponds to the rank of `data` input.
|
||||
* **Note**: `batch` axis of `data` input must be evenly divisible by the cumulative product of `block_shape` elements.
|
||||
* **Note**: It is required that `crops_begin[i] + crops_end[i] <= block_shape[i] * input_shape[i]`.
|
||||
|
||||
**Outputs**
|
||||
|
||||
* **1**: N-D tensor with shape `[batch / (block_shape[0] * block_shape[1] * ... * block_shape[N - 1]), D_1 * block_shape[1] - crops_begin[1] - crops_end[1], D_2 * block_shape[2] - crops_begin[2] - crops_end[2], ..., D_{N - 1} * block_shape[N - 1] - crops_begin[N - 1] - crops_end[N - 1]` of the same type as `data` input.
|
||||
* **1**: Permuted tensor of type *T* with the same rank as `data` input tensor, and shape `[batch / (block_shape[0] * block_shape[1] * ... * block_shape[N - 1]), D_1 * block_shape[1] - crops_begin[1] - crops_end[1], D_2 * block_shape[2] - crops_begin[2] - crops_end[2], ..., D_{N - 1} * block_shape[N - 1] - crops_begin[N - 1] - crops_end[N - 1]`.
|
||||
|
||||
**Types**
|
||||
|
||||
* *T1*: any supported type.
|
||||
* *T2*: any supported integer type.
|
||||
* *T*: any supported type.
|
||||
* *T_INT*: any supported integer type.
|
||||
|
||||
**Example**
|
||||
**Examples**
|
||||
|
||||
*Example: 2D input tensor `data`*
|
||||
|
||||
```xml
|
||||
<layer type="BatchToSpace" ...>
|
||||
<input>
|
||||
<port id="0"> <!-- data -->
|
||||
<dim>10</dim> <!-- batch -->
|
||||
<dim>2</dim> <!-- spatial dimension 1 -->
|
||||
</port>
|
||||
<port id="1"> <!-- block_shape value: [1, 5] -->
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
<port id="2"> <!-- crops_begin value: [0, 2] -->
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
<port id="3"> <!-- crops_end value: [0, 0] -->
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="3">
|
||||
<dim>2</dim> <!-- data.shape[0] / (block_shape.shape[0] * block_shape.shape[1]) -->
|
||||
<dim>8</dim> <!-- data.shape[1] * block_shape.shape[1] - crops_begin[1] - crops_end[1]-->
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
```
|
||||
|
||||
*Example: 5D input tensor `data`*
|
||||
|
||||
```xml
|
||||
<layer type="BatchToSpace" ...>
|
||||
|
@ -29,19 +29,12 @@ struct ConvData {
|
||||
size_t input_height;
|
||||
size_t input_width;
|
||||
size_t input_channel_count;
|
||||
size_t filter_height;
|
||||
size_t filter_width;
|
||||
size_t filter_count;
|
||||
size_t filter_dilation_width;
|
||||
size_t filter_dilation_height;
|
||||
size_t filter_stride_width;
|
||||
size_t filter_stride_height;
|
||||
size_t pads_begin_width;
|
||||
size_t pads_begin_height;
|
||||
size_t pads_end_width;
|
||||
size_t pads_end_height;
|
||||
ngraph::op::PadType padding_type;
|
||||
ngraph::Shape output_shape;
|
||||
ngraph::element::Type element_type;
|
||||
};
|
||||
|
||||
@ -55,27 +48,18 @@ static bool VerifyAndGetConvParams(std::shared_ptr<ngraph::opset7::Convolution>
|
||||
return false;
|
||||
}
|
||||
|
||||
conv_data.output_shape = conv->get_output_shape(0);
|
||||
conv_data.padding_type = conv->get_auto_pad();
|
||||
conv_data.input_channel_count = conv->input_value(0).get_shape()[1];
|
||||
conv_data.input_height = conv->input_value(0).get_shape()[2];
|
||||
conv_data.input_width = conv->input_value(0).get_shape()[3];
|
||||
conv_data.filter_count = conv->input_value(1).get_shape()[0];
|
||||
conv_data.filter_height = conv->input_value(1).get_shape()[2];
|
||||
conv_data.filter_width = conv->input_value(1).get_shape()[3];
|
||||
conv_data.filter_dilation_height = conv->get_dilations()[0];
|
||||
conv_data.filter_dilation_width = conv->get_dilations()[1];
|
||||
conv_data.filter_stride_height = conv->get_strides()[0];
|
||||
conv_data.filter_stride_width = conv->get_strides()[1];
|
||||
conv_data.pads_begin_height = conv->get_pads_begin()[0];
|
||||
conv_data.pads_begin_width = conv->get_pads_begin()[1];
|
||||
conv_data.pads_end_height = conv->get_pads_end()[0];
|
||||
conv_data.pads_end_width = conv->get_pads_end()[1];
|
||||
conv_data.element_type = conv->get_element_type();
|
||||
|
||||
IE_ASSERT(conv_data.filter_count == conv_data.output_shape[1]);
|
||||
|
||||
return true;
|
||||
return conv_data.pads_begin_height || conv_data.pads_end_height || conv_data.pads_begin_width || conv_data.pads_end_width;
|
||||
}
|
||||
|
||||
static bool TransposeOrderMatches(std::shared_ptr<ngraph::opset7::Transpose> transpose, std::vector<size_t> order) {
|
||||
@ -117,75 +101,9 @@ static bool VerifyMaxPool(std::shared_ptr<ngraph::opset7::MaxPool> max_pool) {
|
||||
auto pool_kernel = max_pool->get_kernel();
|
||||
|
||||
// Check if MaxPool vertical stride == pool size
|
||||
// (TODO: remove when 50386 and 50379 are fixed and also verify pool_kernel[0] > 8 limitation below, gna_limitations can be used then)
|
||||
// Check if padding is VALID
|
||||
return (max_pool->get_auto_pad() == ngraph::op::PadType::VALID &&
|
||||
pool_kernel.size() == 2 && pool_strides.size() == 2 &&
|
||||
pool_kernel[0] == pool_strides[0] && pool_kernel[0] <= 8);
|
||||
}
|
||||
|
||||
static size_t GetRequiredInputPadding(size_t input_size, size_t filter_size, size_t stride_size, size_t dilation_size, size_t output_size) {
|
||||
size_t partial_padding_size = (output_size - 1) * stride_size + (filter_size - 1) * dilation_size + 1;
|
||||
|
||||
// This way of padding size calculation avoids problem with fractional numbers
|
||||
return (partial_padding_size > input_size) ? (partial_padding_size - input_size) : 0;
|
||||
}
|
||||
|
||||
static size_t CalculateOutputSize(size_t input_size, size_t filter_size, size_t stride_size, size_t dilation_size, size_t padding_size) {
|
||||
return (input_size + padding_size - ((filter_size - 1) * dilation_size + 1)) / stride_size + 1;
|
||||
}
|
||||
|
||||
static bool CalculatePadding(ConvData& conv_data) {
|
||||
size_t output_height{ 0 };
|
||||
size_t output_width{ 0 };
|
||||
|
||||
switch (conv_data.padding_type) {
|
||||
case ngraph::op::PadType::EXPLICIT:
|
||||
// all paddings already set
|
||||
break;
|
||||
case ngraph::op::PadType::VALID:
|
||||
conv_data.pads_begin_height = 0;
|
||||
conv_data.pads_begin_width = 0;
|
||||
conv_data.pads_end_height = 0;
|
||||
conv_data.pads_end_width = 0;
|
||||
break;
|
||||
case ngraph::op::PadType::SAME_LOWER:
|
||||
case ngraph::op::PadType::SAME_UPPER:
|
||||
{
|
||||
output_height = conv_data.output_shape[2];
|
||||
output_width = conv_data.output_shape[3];
|
||||
|
||||
size_t pads_width = GetRequiredInputPadding(conv_data.input_width, conv_data.filter_width,
|
||||
conv_data.filter_stride_width, conv_data.filter_dilation_width, output_width);
|
||||
size_t pads_height = GetRequiredInputPadding(conv_data.input_height, conv_data.filter_height,
|
||||
conv_data.filter_stride_height, conv_data.filter_dilation_height, output_height);
|
||||
|
||||
conv_data.pads_begin_width = conv_data.pads_end_width = pads_width / 2;
|
||||
conv_data.pads_begin_height = conv_data.pads_end_height = pads_height / 2;
|
||||
|
||||
if (conv_data.padding_type == ngraph::op::PadType::SAME_LOWER) {
|
||||
conv_data.pads_begin_width += (pads_width % 2);
|
||||
conv_data.pads_begin_height += (pads_height % 2);
|
||||
} else {
|
||||
conv_data.pads_end_width += (pads_width % 2);
|
||||
conv_data.pads_end_height += (pads_height % 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
output_width = CalculateOutputSize(conv_data.input_width, conv_data.filter_width, conv_data.filter_stride_width,
|
||||
conv_data.filter_dilation_width, conv_data.pads_begin_width + conv_data.pads_end_width);
|
||||
output_height = CalculateOutputSize(conv_data.input_height, conv_data.filter_height, conv_data.filter_stride_height,
|
||||
conv_data.filter_dilation_height, conv_data.pads_begin_height + conv_data.pads_end_height);
|
||||
|
||||
IE_ASSERT(output_width == conv_data.output_shape[3]);
|
||||
IE_ASSERT(output_height == conv_data.output_shape[2]);
|
||||
|
||||
// Check if any calculated padding is non-zero, otherwise there is no need to decompose such convolution
|
||||
return conv_data.pads_begin_height || conv_data.pads_end_height || conv_data.pads_begin_width || conv_data.pads_end_width;
|
||||
pool_kernel.size() == 2 && pool_strides.size() == 2);
|
||||
}
|
||||
|
||||
static std::shared_ptr<ngraph::opset7::StridedSlice> FlatCrop(ngraph::Output<ngraph::Node> input, size_t offset, size_t size) {
|
||||
@ -227,7 +145,7 @@ static std::shared_ptr<ngraph::Node> CreatePaddedNet(std::shared_ptr<ngraph::ops
|
||||
ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{ 2 },
|
||||
ngraph::Shape{ 1ull, shape_size(leading_transpose->input_value(0).get_shape()) }), false);
|
||||
|
||||
// zero padding
|
||||
// Constant with zero padding
|
||||
auto const_holding_padding = std::make_shared<ngraph::opset7::Constant>(conv_data.element_type, ngraph::Shape{ 1, biggest_padding }, 0);
|
||||
|
||||
copy_runtime_info(conv, const_holding_padding);
|
||||
@ -342,9 +260,6 @@ static bool Convert(std::shared_ptr<ngraph::Node> leading_transpose,
|
||||
if (max_pool && !VerifyMaxPool(std::dynamic_pointer_cast<ngraph::opset7::MaxPool>(max_pool)))
|
||||
return false;
|
||||
|
||||
if (!CalculatePadding(conv_data))
|
||||
return false;
|
||||
|
||||
GeneratePadding(std::dynamic_pointer_cast<ngraph::opset7::Transpose>(leading_transpose),
|
||||
std::dynamic_pointer_cast<ngraph::opset7::Convolution>(conv), conv_data);
|
||||
|
||||
|
@ -5,12 +5,54 @@
|
||||
#include <memory>
|
||||
|
||||
#include "moc_transformations.hpp"
|
||||
#include "pruning.hpp"
|
||||
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/common_optimizations/gelu_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>
|
||||
#include <transformations/common_optimizations/remove_filtering_boxes_by_size.hpp>
|
||||
#include <transformations/common_optimizations/hsigmoid_fusion.hpp>
|
||||
#include <transformations/common_optimizations/hswish_fusion.hpp>
|
||||
#include <transformations/common_optimizations/convert_quantize_dequantize.hpp>
|
||||
#include <transformations/common_optimizations/pad_fusion.hpp>
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ngraph::pass::MOCTransformations, "MOCTransformations", 0);
|
||||
|
||||
bool ngraph::pass::MOCTransformations::run_on_function(std::shared_ptr<ngraph::Function> f) {
|
||||
// To avoid issues with dynamism we make nGraph Function dynamic and after we apply all
|
||||
// transformations we restore original shapes to the nGraph Function back
|
||||
std::unordered_map<ngraph::op::Parameter*, PartialShape> input_shapes;
|
||||
for (auto && param : f->get_parameters()) {
|
||||
input_shapes[param.get()] = param->get_partial_shape();
|
||||
param->set_partial_shape(PartialShape::dynamic(param->get_partial_shape().rank()));
|
||||
}
|
||||
f->validate_nodes_and_infer_types();
|
||||
|
||||
ngraph::pass::Manager manager(get_pass_config());
|
||||
|
||||
manager.register_pass<ngraph::pass::InitNodeInfo>();
|
||||
manager.register_pass<ngraph::pass::RemoveFilteringBoxesBySize>();
|
||||
manager.register_pass<ngraph::pass::ConvertQuantizeDequantize>();
|
||||
|
||||
auto common_fusions = manager.register_pass<ngraph::pass::GraphRewrite>();
|
||||
common_fusions->add_matcher<ngraph::pass::SoftPlusFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::SoftPlusToMishFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::SwishFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::HSwishFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::HSigmoidFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::PadFusion>();
|
||||
common_fusions->add_matcher<ngraph::pass::GeluFusion>();
|
||||
common_fusions->set_name("ngraph::pass::CommonFusions");
|
||||
|
||||
manager.run_passes(f);
|
||||
|
||||
// Restore original shapes to the nGraph Function
|
||||
for (auto && param : f->get_parameters()) {
|
||||
param->set_partial_shape(input_shapes.at(param.get()));
|
||||
}
|
||||
f->validate_nodes_and_infer_types();
|
||||
|
||||
return false;
|
||||
}
|
@ -71,8 +71,11 @@ public:
|
||||
std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
void cache_output_descriptor();
|
||||
|
||||
private:
|
||||
std::vector<std::tuple<ngraph::PartialShape, ngraph::element::Type>> m_inputs_desc;
|
||||
std::vector<std::tuple<ngraph::PartialShape, ngraph::element::Type>> m_output_desc;
|
||||
|
||||
FrameworkNodeAttrs m_attrs;
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ namespace ngraph {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API PadFusion;
|
||||
class TRANSFORMATIONS_API PadElimination;
|
||||
class TRANSFORMATIONS_API PadFusionAvgPool;
|
||||
class TRANSFORMATIONS_API PadFusionMaxPool;
|
||||
class TRANSFORMATIONS_API PadFusionConvolution;
|
||||
@ -22,6 +23,16 @@ class TRANSFORMATIONS_API PadFusionGroupConvolutionBackpropData;
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief PadElimination eliminates pad that does nothing
|
||||
*/
|
||||
class ngraph::pass::PadElimination: public ngraph::pass::MatcherPass {
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
PadElimination();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief PadFusion transformation replaces following graph:
|
||||
@ -113,5 +124,6 @@ public:
|
||||
add_matcher<ngraph::pass::PadFusionConvolutionBackpropData>();
|
||||
add_matcher<ngraph::pass::PadFusionGroupConvolution>();
|
||||
add_matcher<ngraph::pass::PadFusionGroupConvolutionBackpropData>();
|
||||
add_matcher<ngraph::pass::PadElimination>();
|
||||
}
|
||||
};
|
||||
|
@ -25,31 +25,71 @@ shared_ptr<Node> op::FrameworkNode::clone_with_new_inputs(const OutputVector& ne
|
||||
return node;
|
||||
}
|
||||
|
||||
void op::FrameworkNode::cache_output_descriptor() {
|
||||
for (size_t i = 0; i < get_output_size(); ++i) {
|
||||
m_output_desc.emplace_back(get_output_partial_shape(i), get_output_element_type(i));
|
||||
}
|
||||
}
|
||||
|
||||
void op::FrameworkNode::validate_and_infer_types() {
|
||||
INTERNAL_OP_SCOPE(FrameworkNode_validate_and_infer_types);
|
||||
// Save initial inputs descriptors
|
||||
bool initialize_input_desc = m_inputs_desc.empty();
|
||||
bool reset_output_shape_to_dynamic = false;
|
||||
bool reset_output_shape_to_original = false;
|
||||
for (uint64_t i = 0; i < get_input_size(); i++) {
|
||||
// TODO: store constant values
|
||||
const auto& new_input_desc =
|
||||
std::make_tuple(get_input_partial_shape(i), get_input_element_type(i));
|
||||
const auto& input_pshape = get_input_partial_shape(i);
|
||||
const auto& input_type = get_input_element_type(i);
|
||||
const auto& rank = input_pshape.rank();
|
||||
|
||||
if (initialize_input_desc) {
|
||||
m_inputs_desc.push_back(new_input_desc);
|
||||
} else {
|
||||
auto get_message = [&]() {
|
||||
const auto & get_error_message = [&]() {
|
||||
std::stringstream out;
|
||||
out << "Input descriptor for " << get_friendly_name()
|
||||
<< " node has been changed:" << std::endl;
|
||||
out << "Before: " << std::get<0>(m_inputs_desc[i]) << ", "
|
||||
<< std::get<1>(m_inputs_desc[i]) << std::endl;
|
||||
out << "After: " << std::get<0>(new_input_desc) << ", "
|
||||
<< std::get<1>(new_input_desc) << std::endl;
|
||||
out << "After: " << input_pshape << ", "
|
||||
<< input_type << std::endl;
|
||||
out << "Please specify InferenceEngine Extensions to support this case.";
|
||||
return out.str();
|
||||
};
|
||||
|
||||
NODE_VALIDATION_CHECK(this, m_inputs_desc[i] == new_input_desc, get_message());
|
||||
if (initialize_input_desc) {
|
||||
m_inputs_desc.emplace_back(input_pshape, input_type);
|
||||
} else {
|
||||
const auto& orig_input_pshape = std::get<0>(m_inputs_desc[i]);
|
||||
if (orig_input_pshape == input_pshape) {
|
||||
reset_output_shape_to_original = true;
|
||||
} else if (input_pshape.rank().is_dynamic()) {
|
||||
reset_output_shape_to_dynamic = true;
|
||||
} else if (rank.is_static() && orig_input_pshape.rank().is_static() &&
|
||||
rank.get_length() == orig_input_pshape.rank().get_length()) {
|
||||
for (int64_t dim = 0; dim < rank.get_length(); ++dim) {
|
||||
NODE_VALIDATION_CHECK(this, input_pshape[dim].is_dynamic() ||
|
||||
(orig_input_pshape[dim].is_static() &&
|
||||
orig_input_pshape[dim].get_length() == input_pshape[dim].get_length()),
|
||||
get_error_message());
|
||||
}
|
||||
reset_output_shape_to_dynamic = true;
|
||||
} else {
|
||||
NODE_VALIDATION_CHECK(this, m_inputs_desc[i] == std::make_tuple(input_pshape, input_type), get_error_message());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_output_shape_to_dynamic) {
|
||||
cache_output_descriptor();
|
||||
for (size_t i = 0; i < get_output_size(); ++i) {
|
||||
if (get_output_partial_shape(i).rank().is_static()) {
|
||||
set_output_type(i, get_output_element_type(i), PartialShape::dynamic());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_output_shape_to_original && !m_output_desc.empty()) {
|
||||
for (size_t i = 0; i < get_output_size(); ++i) {
|
||||
set_output_type(i, std::get<1>(m_output_desc[i]), std::get<0>(m_output_desc[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <ngraph/rt_info.hpp>
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include <ngraph/opsets/opset5.hpp>
|
||||
#include <ngraph/validation_util.hpp>
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
@ -385,3 +386,34 @@ pass::PadFusionGroupConvolutionBackpropData::PadFusionGroupConvolutionBackpropDa
|
||||
auto m = std::make_shared<pattern::Matcher>(conv_pattern, matcher_name);
|
||||
this->register_matcher(m, callback);
|
||||
}
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(pass::PadElimination, "PadElimination", 0);
|
||||
|
||||
pass::PadElimination::PadElimination() {
|
||||
MATCHER_SCOPE(PadElimination);
|
||||
auto pad_node_pattern = pattern::wrap_type<opset5::Pad>();
|
||||
|
||||
matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto pad = m.get_match_root();
|
||||
|
||||
auto pad_begin_const = ngraph::get_constant_from_source(pad->input_value(1));
|
||||
auto pad_end_const = ngraph::get_constant_from_source(pad->input_value(2));
|
||||
|
||||
if (!pad_begin_const || !pad_end_const) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto pad_begin_value = pad_begin_const->cast_vector<int64_t>();
|
||||
const auto pad_end_value = pad_end_const->cast_vector<int64_t>();
|
||||
|
||||
if (std::any_of(pad_begin_value.begin(), pad_begin_value.end(), [](int64_t value) { return value != 0; }) ||
|
||||
std::any_of(pad_end_value.begin(), pad_end_value.end(), [](int64_t value) { return value != 0; })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return replace_output_update_name(pad->output(0), pad->input_value(0));
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(pad_node_pattern, matcher_name);
|
||||
this->register_matcher(m, callback);
|
||||
}
|
@ -19,28 +19,22 @@ ngraph::pass::SoftPlusFusion::SoftPlusFusion() {
|
||||
// fuses ln(exp(x) + 1.0) operations into SoftPlus(x)
|
||||
auto input = ngraph::pattern::any_input();
|
||||
auto exp = std::make_shared<ngraph::opset4::Exp>(input);
|
||||
auto add_constant = ngraph::pattern::wrap_type<ngraph::opset4::Constant>();
|
||||
auto add_constant = ngraph::pattern::wrap_type<ngraph::opset4::Constant>(
|
||||
pattern::type_matches_any({element::f32, element::f16}));
|
||||
auto add = std::make_shared<ngraph::opset4::Add>(exp, add_constant);
|
||||
auto log = std::make_shared<ngraph::opset4::Log>(add);
|
||||
|
||||
ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher &m) {
|
||||
auto &pattern_to_output = m.get_pattern_value_map();
|
||||
const auto &pattern_to_output = m.get_pattern_value_map();
|
||||
auto exp_input = pattern_to_output.at(input);
|
||||
|
||||
auto constant = std::dynamic_pointer_cast<ngraph::opset4::Constant>(pattern_to_output.at(add_constant).get_node_shared_ptr());
|
||||
if (!constant) return false;
|
||||
|
||||
if (constant == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constant->get_element_type() == ngraph::element::f32 || constant->get_element_type() == ngraph::element::f16) {
|
||||
auto data = constant->cast_vector<float>();
|
||||
if (data.size() != 1 || data[0] != 1.0) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto softplus = std::make_shared<ngraph::opset4::SoftPlus>(exp_input);
|
||||
|
||||
|
@ -40,6 +40,7 @@ ngraph::pass::ConvertTopK3::ConvertTopK3() {
|
||||
last1 = new_topk->output(1);
|
||||
new_topk->set_friendly_name(topk->get_friendly_name());
|
||||
} else if (topk->get_output_target_inputs(0).size() == 0) {
|
||||
last0 = topk->output(0);
|
||||
last1 = std::make_shared<ngraph::opset2::Convert>(new_topk->output(1), topk->get_index_element_type());
|
||||
new_ops.push_back(last1.get_node_shared_ptr());
|
||||
|
||||
|
@ -37,6 +37,7 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
|
||||
{Negative, {}},
|
||||
{Acos, {}},
|
||||
{Asin, {}},
|
||||
{Asinh, {}},
|
||||
{Atan, {}},
|
||||
{Cos, {}},
|
||||
{Cosh, {}},
|
||||
|
@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
#include <ngraph_ops/framework_node.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
|
||||
|
||||
TEST(TransformationTests, FrameworkNode) {
|
||||
auto param = std::make_shared<ngraph::opset8::Parameter>(element::i64, Shape{1, 64});
|
||||
auto f_node = std::make_shared<ngraph::op::FrameworkNode>(OutputVector{param});
|
||||
f_node->set_output_type(0, element::i64, Shape{1, 64});
|
||||
|
||||
// Set partially dynamic shape
|
||||
param->set_partial_shape(PartialShape{Dimension::dynamic(), 64});
|
||||
param->validate_and_infer_types();
|
||||
|
||||
ASSERT_NO_THROW(f_node->validate_and_infer_types());
|
||||
ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic());
|
||||
|
||||
// Set dynamic shape
|
||||
param->set_partial_shape(PartialShape::dynamic(2));
|
||||
param->validate_and_infer_types();
|
||||
|
||||
ASSERT_NO_THROW(f_node->validate_and_infer_types());
|
||||
ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic());
|
||||
|
||||
// Set fully dynamic shape
|
||||
param->set_partial_shape(PartialShape::dynamic());
|
||||
param->validate_and_infer_types();
|
||||
|
||||
ASSERT_NO_THROW(f_node->validate_and_infer_types());
|
||||
ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape::dynamic());
|
||||
|
||||
// Set original static shape
|
||||
param->set_partial_shape(Shape{1, 64});
|
||||
param->validate_and_infer_types();
|
||||
|
||||
ASSERT_NO_THROW(f_node->validate_and_infer_types());
|
||||
ASSERT_EQ(f_node->get_output_partial_shape(0), PartialShape({1, 64}));
|
||||
|
||||
// Set different static shape
|
||||
param->set_partial_shape(Shape{2, 64});
|
||||
param->validate_and_infer_types();
|
||||
|
||||
ASSERT_THROW(f_node->validate_and_infer_types(), ngraph_error::exception);
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <common_test_utils/ngraph_test_utils.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
@ -21,6 +22,42 @@
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(TransformationTests, PadElimination) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
|
||||
Shape data_shape{1, 3, 14, 14};
|
||||
{
|
||||
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
|
||||
set_tensor_name(data, "param");
|
||||
auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0});
|
||||
auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0});
|
||||
auto pad = std::make_shared<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
|
||||
set_tensor_name(pad, "pad");
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
|
||||
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
|
||||
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
|
||||
set_tensor_name(conv, "conv");
|
||||
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
pass::Manager m;
|
||||
m.register_pass<pass::InitNodeInfo>();
|
||||
m.register_pass<pass::PadFusion>();
|
||||
m.run_passes(f);
|
||||
ASSERT_NO_THROW(check_rt_info(f));
|
||||
}
|
||||
{
|
||||
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
|
||||
set_tensor_names(data, {"param", "pad"});
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
|
||||
auto conv = std::make_shared<opset5::Convolution>(data, filters, Strides{1, 1},
|
||||
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1},
|
||||
op::PadType::EXPLICIT);
|
||||
set_tensor_name(conv, "conv");
|
||||
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
}
|
||||
|
||||
auto res = compare_functions(f, f_ref);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
TEST(TransformationTests, PadFusionAvgPoolExcludePad) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
@ -155,9 +192,11 @@ TEST(TransformationTests, PadFusionConvolutionBackpropData) {
|
||||
auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1});
|
||||
auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2});
|
||||
auto pad = std::make_shared<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
|
||||
set_tensor_name(pad, "pad");
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
|
||||
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
|
||||
CoordinateDiff{4, 4}, CoordinateDiff{3, 3}, Shape{1, 1});
|
||||
set_tensor_name(conv, "conv");
|
||||
|
||||
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
pass::Manager m;
|
||||
@ -171,6 +210,7 @@ TEST(TransformationTests, PadFusionConvolutionBackpropData) {
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
|
||||
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(data, filters, Strides{1, 1},
|
||||
CoordinateDiff{3, 3}, CoordinateDiff{1, 1}, Shape{1, 1});
|
||||
set_tensor_name(conv, "conv");
|
||||
|
||||
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
}
|
||||
@ -389,12 +429,15 @@ TEST(TransformationTests, NegativePadFusionConvolutionBackpropDataTooSmallPad) {
|
||||
Shape data_shape{1, 3, 14, 14};
|
||||
{
|
||||
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
|
||||
set_tensor_name(data, "data");
|
||||
auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2});
|
||||
auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2});
|
||||
auto pad = std::make_shared<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
|
||||
set_tensor_name(pad, "pad");
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
|
||||
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
|
||||
CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1});
|
||||
set_tensor_name(conv, "conv");
|
||||
|
||||
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
pass::Manager m;
|
||||
@ -405,12 +448,15 @@ TEST(TransformationTests, NegativePadFusionConvolutionBackpropDataTooSmallPad) {
|
||||
}
|
||||
{
|
||||
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
|
||||
set_tensor_name(data, "data");
|
||||
auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2});
|
||||
auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2});
|
||||
auto pad = std::make_shared<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
|
||||
set_tensor_name(pad, "pad");
|
||||
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
|
||||
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
|
||||
CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1});
|
||||
set_tensor_name(conv, "conv");
|
||||
|
||||
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
|
||||
{Negative, {}},
|
||||
{Acos, {}},
|
||||
{Asin, {}},
|
||||
{Asinh, {}},
|
||||
{Atan, {}},
|
||||
{Cos, {}},
|
||||
{Cosh, {}},
|
||||
@ -65,6 +66,7 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
|
||||
|
||||
// List of operations that should be tested also with integer precision
|
||||
const std::map<ActivationTypes, std::vector<std::vector<float>>> intActivationTypes = {
|
||||
{Asinh, {}},
|
||||
{Atan, {}},
|
||||
{Negative, {}},
|
||||
{Ceiling, {}},
|
||||
|
@ -16,6 +16,39 @@ const std::vector<InferenceEngine::Precision> net_precisions = {
|
||||
InferenceEngine::Precision::I32
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> data_shapes_2D = {
|
||||
{12, 4},
|
||||
{48, 3}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<int64_t>> block_shapes_2D = {
|
||||
{1, 2},
|
||||
{1, 6}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<int64_t>> crops_2D = {
|
||||
{0, 0},
|
||||
{0, 1}
|
||||
};
|
||||
|
||||
const auto batch_to_space_2d_tests = ::testing::Combine(
|
||||
::testing::ValuesIn(block_shapes_2D),
|
||||
::testing::ValuesIn(crops_2D),
|
||||
::testing::ValuesIn(crops_2D),
|
||||
::testing::ValuesIn(data_shapes_2D),
|
||||
::testing::ValuesIn(net_precisions),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
smoke_BatchToSpace_2D,
|
||||
BatchToSpaceLayerTest,
|
||||
batch_to_space_2d_tests,
|
||||
BatchToSpaceLayerTest::getTestCaseName);
|
||||
|
||||
const std::vector<std::vector<size_t>> data_shapes_4D = {
|
||||
{4, 1, 2, 2},
|
||||
{4, 3, 2, 2},
|
||||
@ -39,7 +72,7 @@ const std::vector<std::vector<int64_t>> crops_end_4D = {
|
||||
{0, 0, 0, 2}
|
||||
};
|
||||
|
||||
const auto space_to_batch_4d_spatial_dims_tests = ::testing::Combine(
|
||||
const auto batch_to_space_4d_spatial_dims_tests = ::testing::Combine(
|
||||
::testing::Values(block_shapes_4D[0]),
|
||||
::testing::ValuesIn(crops_begin_4D),
|
||||
::testing::ValuesIn(crops_end_4D),
|
||||
@ -51,7 +84,7 @@ const auto space_to_batch_4d_spatial_dims_tests = ::testing::Combine(
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU));
|
||||
|
||||
const auto space_to_batch_4d_channel_dim_tests = ::testing::Combine(
|
||||
const auto batch_to_space_4d_channel_dim_tests = ::testing::Combine(
|
||||
::testing::Values(block_shapes_4D[1]),
|
||||
::testing::Values(crops_begin_4D[0]),
|
||||
::testing::Values(crops_end_4D[0]),
|
||||
@ -66,13 +99,13 @@ const auto space_to_batch_4d_channel_dim_tests = ::testing::Combine(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
smoke_BatchToSpace_4D_spatial_dims,
|
||||
BatchToSpaceLayerTest,
|
||||
space_to_batch_4d_spatial_dims_tests,
|
||||
batch_to_space_4d_spatial_dims_tests,
|
||||
BatchToSpaceLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
smoke_BatchToSpace_4D_channel_dim,
|
||||
BatchToSpaceLayerTest,
|
||||
space_to_batch_4d_channel_dim_tests,
|
||||
batch_to_space_4d_channel_dim_tests,
|
||||
BatchToSpaceLayerTest::getTestCaseName);
|
||||
|
||||
const std::vector<std::vector<size_t>> data_shapes_5D = {
|
||||
@ -96,7 +129,7 @@ const std::vector<std::vector<int64_t>> crops_end_5D = {
|
||||
{0, 0, 0, 0, 1}
|
||||
};
|
||||
|
||||
const auto space_to_batch_5d_spatial_dims_tests = ::testing::Combine(
|
||||
const auto batch_to_space_5d_spatial_dims_tests = ::testing::Combine(
|
||||
::testing::Values(block_shapes_5D[0]),
|
||||
::testing::ValuesIn(crops_begin_5D),
|
||||
::testing::ValuesIn(crops_end_5D),
|
||||
@ -108,7 +141,7 @@ const auto space_to_batch_5d_spatial_dims_tests = ::testing::Combine(
|
||||
::testing::Values(InferenceEngine::Layout::ANY),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU));
|
||||
|
||||
const auto space_to_batch_5d_channel_dim_tests = ::testing::Combine(
|
||||
const auto batch_to_space_5d_channel_dim_tests = ::testing::Combine(
|
||||
::testing::Values(block_shapes_5D[1]),
|
||||
::testing::Values(crops_begin_5D[0]),
|
||||
::testing::Values(crops_end_5D[0]),
|
||||
@ -123,13 +156,13 @@ const auto space_to_batch_5d_channel_dim_tests = ::testing::Combine(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
smoke_BatchToSpace_5D_spatial_dims,
|
||||
BatchToSpaceLayerTest,
|
||||
space_to_batch_5d_spatial_dims_tests,
|
||||
batch_to_space_5d_spatial_dims_tests,
|
||||
BatchToSpaceLayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
smoke_BatchToSpace_5D_channel_dim,
|
||||
BatchToSpaceLayerTest,
|
||||
space_to_batch_5d_channel_dim_tests,
|
||||
batch_to_space_5d_channel_dim_tests,
|
||||
BatchToSpaceLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
@ -247,10 +247,10 @@ const std::vector<std::map<std::string, std::string>> configs2D = {
|
||||
};
|
||||
|
||||
const std::vector<op::PadType> padTypes = {
|
||||
op::PadType::VALID,
|
||||
op::PadType::EXPLICIT,
|
||||
op::PadType::SAME_LOWER,
|
||||
op::PadType::SAME_UPPER,
|
||||
op::PadType::VALID
|
||||
op::PadType::SAME_UPPER
|
||||
};
|
||||
|
||||
const std::vector<modelType> models = {
|
||||
@ -282,9 +282,9 @@ const std::vector<std::vector<size_t >> strides2D = { {1, 1}, {1, 2}, {2, 1}, {2
|
||||
const std::vector<std::vector<ptrdiff_t>> padBegins2D = { {1, 2} };
|
||||
const std::vector<std::vector<ptrdiff_t>> padEnds2D = { {3, 1} };
|
||||
const std::vector<std::vector<size_t >> dilations2D = { {1, 1} };
|
||||
const std::vector<size_t> numOutChannels2D = { 32 };
|
||||
const std::vector<std::vector<size_t >> biases2D = { {1, 32, 1, 1} };
|
||||
const std::vector<std::vector<size_t >> transpBiases2D = { {1, 1, 1, 32} };
|
||||
const std::vector<size_t> numOutChannels2D = { 8 };
|
||||
const std::vector<std::vector<size_t >> biases2D = { {1, 8, 1, 1} };
|
||||
const std::vector<std::vector<size_t >> transpBiases2D = { {1, 1, 1, 8} };
|
||||
const std::vector<std::vector<size_t >> maxpool2DPools = { {2, 2} };
|
||||
const std::vector<std::vector<size_t >> maxpool2DStrides = { {2, 1} };
|
||||
|
@ -35,6 +35,7 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
|
||||
{Negative, {}},
|
||||
{Acos, {}},
|
||||
{Asin, {}},
|
||||
{Asinh, {}},
|
||||
{Atan, {}},
|
||||
{Cos, {}},
|
||||
{Cosh, {}},
|
||||
|
@ -40,6 +40,7 @@ static std::map<ngraph::helpers::ActivationTypes, std::string> activationNames =
|
||||
{ngraph::helpers::ActivationTypes::Negative, "Negative"},
|
||||
{ngraph::helpers::ActivationTypes::Acos, "Acos"},
|
||||
{ngraph::helpers::ActivationTypes::Asin, "Asin"},
|
||||
{ngraph::helpers::ActivationTypes::Asinh, "Asinh"},
|
||||
{ngraph::helpers::ActivationTypes::Atan, "Atan"},
|
||||
{ngraph::helpers::ActivationTypes::Cos, "Cos"},
|
||||
{ngraph::helpers::ActivationTypes::Cosh, "Cosh"},
|
||||
|
@ -779,6 +779,14 @@ void check_rt_info(const std::shared_ptr<ngraph::Function>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void set_tensor_name(ngraph::Output<ngraph::Node> output, const std::string & name) {
|
||||
output.get_tensor_ptr()->set_names({name});
|
||||
}
|
||||
|
||||
void set_tensor_names(ngraph::Output<ngraph::Node> output, const std::unordered_set<std::string> & names) {
|
||||
output.get_tensor_ptr()->set_names(names);
|
||||
}
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(TestOpMultiOut, "TestOp", 0);
|
||||
|
||||
namespace attributes {
|
||||
|
@ -101,6 +101,10 @@ inline std::pair<bool, std::string> compare_functions(
|
||||
|
||||
void check_rt_info(const std::shared_ptr<ngraph::Function>& f);
|
||||
|
||||
void set_tensor_name(ngraph::Output<ngraph::Node> output, const std::string & name);
|
||||
|
||||
void set_tensor_names(ngraph::Output<ngraph::Node> output, const std::unordered_set<std::string> & names);
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
class InjectionPass;
|
||||
|
@ -6,6 +6,7 @@ VERIFIED_OP_REFERENCES = [
|
||||
'Acos-1',
|
||||
'Add-1',
|
||||
'Asin-1',
|
||||
'Asinh-3',
|
||||
'Assign-6',
|
||||
'AvgPool-1',
|
||||
'BatchNormInference-5',
|
||||
@ -23,6 +24,7 @@ VERIFIED_OP_REFERENCES = [
|
||||
'Convolution-1',
|
||||
'Constant-1',
|
||||
'Cos-1',
|
||||
'Cosh-1',
|
||||
'DeformableConvolution-1',
|
||||
'DeformablePSROIPooling-1',
|
||||
'DetectionOutput-1',
|
||||
|
@ -100,6 +100,7 @@ enum ActivationTypes {
|
||||
Negative,
|
||||
Acos,
|
||||
Asin,
|
||||
Asinh,
|
||||
Atan,
|
||||
Cos,
|
||||
Cosh,
|
||||
|
@ -48,6 +48,8 @@ std::shared_ptr<ngraph::Node> makeActivation(const ngraph::Output<Node> &in,
|
||||
return std::make_shared<ngraph::op::Acos>(in);
|
||||
case ngraph::helpers::ActivationTypes::Asin:
|
||||
return std::make_shared<ngraph::op::Asin>(in);
|
||||
case ngraph::helpers::ActivationTypes::Asinh:
|
||||
return std::make_shared<ngraph::op::Asinh>(in);
|
||||
case ngraph::helpers::ActivationTypes::Atan:
|
||||
return std::make_shared<ngraph::op::Atan>(in);
|
||||
case ngraph::helpers::ActivationTypes::Cos:
|
||||
|
@ -0,0 +1,453 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "transformations/convert_padded2valid_conv.hpp"
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset7.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
enum class modelType {
|
||||
TranspConvTransp = 0, /* Transpose(NHWC->NCHW) => Conv => Transpose(NCHW->NHWC) */
|
||||
TranspConvBcastAddTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => Transpose(NCHW->NHWC) */
|
||||
TranspConvBcastAddMaxPoolTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => MaxPooling => Transpose(NCHW->NHWC) (2D Max Pool case) */
|
||||
TranspConvBcastAddActTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => Activation Function => Transpose(NCHW->NHWC) */
|
||||
TranspConvBcastAddMaxPoolActTransp, /* Transpose(NHWC->NCHW) => Conv => Broadcasted Add (Bias) => MaxPool => Activation Function => Transpose(NCHW->NHWC) */
|
||||
TranspConvTranspBcastAdd, /* Transpose(NHWC->NCHW) => conv => Transpose(NCHW->NHWC) => Bias */
|
||||
TranspConvTranspBcastAddAct /* Transpose(NHWC->NCHW) => Conv => Transpose(NCHW->NHWC) => Bias => Activation Function */
|
||||
};
|
||||
|
||||
struct ConvData {
|
||||
size_t input_height;
|
||||
size_t input_width;
|
||||
size_t input_channel_count;
|
||||
size_t pads_begin_width;
|
||||
size_t pads_begin_height;
|
||||
size_t pads_end_width;
|
||||
size_t pads_end_height;
|
||||
};
|
||||
|
||||
void GetConvParams(std::shared_ptr<ngraph::opset7::Convolution> conv, ConvData& conv_data) {
|
||||
conv_data.input_channel_count = conv->input_value(0).get_shape()[1];
|
||||
conv_data.input_height = conv->input_value(0).get_shape()[2];
|
||||
conv_data.input_width = conv->input_value(0).get_shape()[3];
|
||||
conv_data.pads_begin_height = conv->get_pads_begin()[0];
|
||||
conv_data.pads_begin_width = conv->get_pads_begin()[1];
|
||||
conv_data.pads_end_height = conv->get_pads_end()[0];
|
||||
conv_data.pads_end_width = conv->get_pads_end()[1];
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::opset7::Result> createFunction(const modelType& model,
|
||||
const ngraph::Output<ngraph::Node>& input_node,
|
||||
const ngraph::Shape& filters_shape,
|
||||
const ngraph::Strides& conv_stride,
|
||||
const ngraph::CoordinateDiff& pads_begin,
|
||||
const ngraph::CoordinateDiff& pads_end,
|
||||
const ngraph::Strides& conv_dilation,
|
||||
const ngraph::Shape& bias_shape,
|
||||
const ngraph::Strides& maxpool_stride,
|
||||
const ngraph::Shape& maxpool_shape,
|
||||
const ngraph::op::PadType& pad_type,
|
||||
ConvData* conv_data) {
|
||||
auto transpose_in_order = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64, ngraph::Shape{4}, ngraph::Shape{0, 3, 1, 2});
|
||||
auto transpose_in = std::make_shared<ngraph::opset7::Transpose>(input_node, transpose_in_order);
|
||||
auto filters = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64,
|
||||
ngraph::Shape{4, input_node.get_shape()[3], filters_shape[0], filters_shape[1]});
|
||||
auto conv = std::make_shared<ngraph::opset7::Convolution>(transpose_in, filters, conv_stride, pads_begin, pads_end, conv_dilation, pad_type);
|
||||
if (conv_data)
|
||||
GetConvParams(conv, *conv_data);
|
||||
auto transpose_out_order = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64, ngraph::Shape{4}, ngraph::Shape{0, 2, 3, 1});
|
||||
auto bias_const = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64, bias_shape);
|
||||
ngraph::Output<ngraph::Node> last_op = std::make_shared<ngraph::opset7::Transpose>(conv, transpose_out_order);
|
||||
|
||||
switch (model) {
|
||||
case modelType::TranspConvBcastAddTransp:
|
||||
{
|
||||
auto bcast_add = std::make_shared<ngraph::opset7::Add>(conv, bias_const);
|
||||
last_op = std::make_shared<ngraph::opset7::Transpose>(bcast_add, transpose_out_order);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvBcastAddMaxPoolTransp:
|
||||
{
|
||||
auto bcast_add = std::make_shared<ngraph::opset7::Add>(conv, bias_const);
|
||||
auto maxpool = std::make_shared<ngraph::opset7::MaxPool>(bcast_add, maxpool_stride, ngraph::Shape{0, 0}, ngraph::Shape{0, 0}, maxpool_shape,
|
||||
ngraph::op::RoundingType::FLOOR, ngraph::op::PadType::VALID);
|
||||
auto transpose = std::make_shared<ngraph::opset7::Transpose>(maxpool, transpose_out_order);
|
||||
last_op = std::make_shared<ngraph::opset7::Relu>(transpose);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvBcastAddActTransp:
|
||||
{
|
||||
auto bcast_add = std::make_shared<ngraph::opset7::Add>(conv, bias_const);
|
||||
auto activation = std::make_shared<ngraph::opset7::Relu>(bcast_add);
|
||||
last_op = std::make_shared<ngraph::opset7::Transpose>(activation, transpose_out_order);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvBcastAddMaxPoolActTransp:
|
||||
{
|
||||
auto bcast_add = std::make_shared<ngraph::opset7::Add>(conv, bias_const);
|
||||
auto maxpool = std::make_shared<ngraph::opset7::MaxPool>(bcast_add, maxpool_stride, ngraph::Shape{0, 0}, ngraph::Shape{0, 0}, maxpool_shape,
|
||||
ngraph::op::RoundingType::FLOOR, ngraph::op::PadType::VALID);
|
||||
auto activation = std::make_shared<ngraph::opset7::Relu>(maxpool);
|
||||
last_op = std::make_shared<ngraph::opset7::Transpose>(activation, transpose_out_order);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvTranspBcastAdd:
|
||||
{
|
||||
last_op = std::make_shared<ngraph::opset7::Add>(last_op, bias_const);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvTranspBcastAddAct:
|
||||
{
|
||||
auto bcast_add = std::make_shared<ngraph::opset7::Add>(last_op, bias_const);
|
||||
last_op = std::make_shared<ngraph::opset7::Relu>(bcast_add);
|
||||
}
|
||||
break;
|
||||
|
||||
case modelType::TranspConvTransp:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_shared<ngraph::opset7::Result>(last_op);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> get_initial_function(const modelType& model,
|
||||
const ngraph::PartialShape& input_shape,
|
||||
const ngraph::Shape& filters_shape,
|
||||
const ngraph::Strides& conv_stride,
|
||||
const ngraph::CoordinateDiff& pads_begin,
|
||||
const ngraph::CoordinateDiff& pads_end,
|
||||
const ngraph::Strides& conv_dilation,
|
||||
const ngraph::Shape& bias_shape,
|
||||
const ngraph::Strides& maxpool_stride,
|
||||
const ngraph::Shape& maxpool_shape,
|
||||
const ngraph::op::PadType& pad_type,
|
||||
ConvData& conv_data) {
|
||||
auto inputParams = std::make_shared<ngraph::opset7::Parameter>(ngraph::element::i64, input_shape);
|
||||
auto result = createFunction(model, inputParams, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, bias_shape,
|
||||
maxpool_stride, maxpool_shape, pad_type, &conv_data);
|
||||
return std::make_shared<ngraph::Function>(ngraph::ResultVector{result}, ngraph::ParameterVector{inputParams});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ConvertPadded2ValidConvTestInvalidFixture : public CommonTestUtils::TestsCommon,
|
||||
public ::testing::WithParamInterface<std::tuple<modelType, ngraph::PartialShape, ngraph::Shape, ngraph::Strides,
|
||||
ngraph::CoordinateDiff, ngraph::CoordinateDiff,
|
||||
ngraph::Strides, ngraph::Shape,
|
||||
ngraph::Strides, ngraph::Shape,
|
||||
ngraph::op::PadType>> {
|
||||
public:
|
||||
void SetUp() override;
|
||||
public:
|
||||
std::shared_ptr<ngraph::Function> function, reference_function;
|
||||
modelType model;
|
||||
};
|
||||
|
||||
void ConvertPadded2ValidConvTestInvalidFixture::SetUp() {
|
||||
ngraph::PartialShape input_shape;
|
||||
ngraph::Shape filters_shape, bias_shape, maxpool_shape;
|
||||
ngraph::Strides conv_stride, conv_dilation, maxpool_stride;
|
||||
ngraph::CoordinateDiff pads_begin, pads_end;
|
||||
ngraph::op::PadType pad_type;
|
||||
ConvData conv_data;
|
||||
std::tie(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type) = this->GetParam();
|
||||
|
||||
function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data);
|
||||
reference_function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class ConvertPadded2ValidConvTestFixture: public CommonTestUtils::TestsCommon,
|
||||
public ::testing::WithParamInterface<std::tuple<modelType, ngraph::PartialShape, ngraph::Shape, ngraph::Strides,
|
||||
ngraph::CoordinateDiff, ngraph::CoordinateDiff,
|
||||
ngraph::Strides, ngraph::Shape,
|
||||
ngraph::Strides, ngraph::Shape,
|
||||
ngraph::op::PadType>> {
|
||||
public:
|
||||
void SetUp() override;
|
||||
std::shared_ptr<ngraph::Function> get_reference(const modelType& model,
|
||||
const ngraph::PartialShape& input_shape,
|
||||
const ngraph::Shape& filters_shape,
|
||||
const ngraph::Strides& conv_stride,
|
||||
const ngraph::CoordinateDiff& pads_begin,
|
||||
const ngraph::CoordinateDiff& pads_end,
|
||||
const ngraph::Strides& conv_dilation,
|
||||
const ngraph::Shape& bias_shape,
|
||||
const ngraph::Strides& maxpool_stride,
|
||||
const ngraph::Shape& maxpool_shape,
|
||||
const ngraph::op::PadType& pad_type,
|
||||
const ConvData& conv_data);
|
||||
public:
|
||||
std::shared_ptr<ngraph::Function> function, reference_function;
|
||||
modelType model;
|
||||
};
|
||||
|
||||
void ConvertPadded2ValidConvTestFixture::SetUp() {
|
||||
ngraph::PartialShape input_shape;
|
||||
ngraph::Shape filters_shape, bias_shape, maxpool_shape;
|
||||
ngraph::Strides conv_stride, conv_dilation, maxpool_stride;
|
||||
ngraph::CoordinateDiff pads_begin, pads_end;
|
||||
ngraph::op::PadType pad_type;
|
||||
ConvData conv_data;
|
||||
std::tie(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type) = this->GetParam();
|
||||
|
||||
function = get_initial_function(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data);
|
||||
reference_function = get_reference(model, input_shape, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation,
|
||||
bias_shape, maxpool_stride, maxpool_shape, pad_type, conv_data);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::opset7::StridedSlice> FlatCrop(ngraph::Output<ngraph::Node> input, size_t offset, size_t size) {
|
||||
return std::make_shared<ngraph::opset7::StridedSlice>(
|
||||
input, // data
|
||||
ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)0, offset}), // begin sice index
|
||||
ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)0, offset + size}), // end slice index
|
||||
ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {(size_t)1, (size_t)1}), // strides
|
||||
std::vector<int64_t>{1, 0}, // begin mask
|
||||
std::vector<int64_t>{1, 0}); // end mask
|
||||
}
|
||||
|
||||
void InsertPadding(ngraph::OutputVector& input_rows_to_concat, size_t size,
|
||||
const std::shared_ptr<ngraph::opset7::Constant> padding_const, size_t biggest_padding) {
|
||||
|
||||
if (size == biggest_padding) {
|
||||
input_rows_to_concat.push_back(padding_const);
|
||||
} else {
|
||||
auto slice = FlatCrop(padding_const, 0, size);
|
||||
input_rows_to_concat.push_back(slice);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> CreatePaddedNet(const ngraph::Output<ngraph::Node>& input_node,
|
||||
const ConvData& conv_data) {
|
||||
size_t flat_left_padding = conv_data.input_channel_count * conv_data.pads_begin_width;
|
||||
size_t flat_right_padding = conv_data.input_channel_count * conv_data.pads_end_width;
|
||||
size_t padded_row_size = flat_left_padding + conv_data.input_channel_count * conv_data.input_width + flat_right_padding;
|
||||
size_t flat_top_padding = padded_row_size * conv_data.pads_begin_height;
|
||||
size_t flat_bottom_padding = padded_row_size * conv_data.pads_end_height;
|
||||
size_t biggest_padding = std::max(std::max(flat_left_padding, flat_right_padding), std::max(flat_top_padding, flat_bottom_padding));
|
||||
|
||||
if (conv_data.input_height > 1 && (flat_top_padding > 1 || flat_bottom_padding > 1)) {
|
||||
biggest_padding = biggest_padding > padded_row_size ? biggest_padding : padded_row_size;
|
||||
}
|
||||
|
||||
if (!biggest_padding)
|
||||
return nullptr;
|
||||
|
||||
auto flat_input = std::make_shared<ngraph::opset7::Reshape>(input_node,
|
||||
ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape{2},
|
||||
ngraph::Shape{1ull, shape_size(input_node.get_shape())}), false);
|
||||
|
||||
// Constant with zero padding
|
||||
auto const_holding_padding = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64, ngraph::Shape{1, biggest_padding}, 0);
|
||||
|
||||
std::shared_ptr<ngraph::Node> original_row = flat_input;
|
||||
ngraph::OutputVector input_rows_to_concat;
|
||||
|
||||
// Add top padding
|
||||
for (size_t p = 0; p < conv_data.pads_begin_height; p++) {
|
||||
InsertPadding(input_rows_to_concat, padded_row_size, const_holding_padding, biggest_padding);
|
||||
}
|
||||
|
||||
if (flat_left_padding || flat_right_padding) {
|
||||
// Pad every row of input plain if neccessary
|
||||
for (size_t h = 0; h < conv_data.input_height; h++) {
|
||||
// left padding input right padding
|
||||
// | | |
|
||||
// +--------------+-----------+
|
||||
// |
|
||||
// concat
|
||||
|
||||
if (conv_data.input_height > 1)
|
||||
original_row = FlatCrop(flat_input, h * conv_data.input_width * conv_data.input_channel_count,
|
||||
conv_data.input_width * conv_data.input_channel_count);
|
||||
|
||||
ngraph::OutputVector single_row_concat_inputs;
|
||||
if (flat_left_padding) {
|
||||
InsertPadding(single_row_concat_inputs, flat_left_padding, const_holding_padding, biggest_padding);
|
||||
}
|
||||
single_row_concat_inputs.push_back(original_row);
|
||||
if (flat_right_padding) {
|
||||
InsertPadding(single_row_concat_inputs, flat_right_padding, const_holding_padding, biggest_padding);
|
||||
}
|
||||
auto padded_row_concat = std::make_shared<ngraph::opset7::Concat>(single_row_concat_inputs, 1);
|
||||
|
||||
input_rows_to_concat.push_back(padded_row_concat);
|
||||
}
|
||||
} else {
|
||||
input_rows_to_concat.push_back(original_row);
|
||||
}
|
||||
|
||||
// Bottom padding
|
||||
for (size_t p = 0; p < conv_data.pads_end_height; p++) {
|
||||
InsertPadding(input_rows_to_concat, padded_row_size, const_holding_padding, biggest_padding);
|
||||
}
|
||||
|
||||
auto padded_input_plane = std::make_shared<ngraph::opset7::Concat>(input_rows_to_concat, 1);
|
||||
return padded_input_plane;
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> ConvertPadded2ValidConvTestFixture::get_reference(const modelType& model,
|
||||
const ngraph::PartialShape& input_shape,
|
||||
const ngraph::Shape& filters_shape,
|
||||
const ngraph::Strides& conv_stride,
|
||||
const ngraph::CoordinateDiff& pads_begin,
|
||||
const ngraph::CoordinateDiff& pads_end,
|
||||
const ngraph::Strides& conv_dilation,
|
||||
const ngraph::Shape& bias_shape,
|
||||
const ngraph::Strides& maxpool_stride,
|
||||
const ngraph::Shape& maxpool_shape,
|
||||
const ngraph::op::PadType& pad_type,
|
||||
const ConvData& conv_data) {
|
||||
auto inputParams = std::make_shared<ngraph::opset7::Parameter>(ngraph::element::i64, input_shape);
|
||||
|
||||
// Add padding where neccessary
|
||||
|
||||
// padding
|
||||
// padding
|
||||
// ... row ...
|
||||
// ... row ...
|
||||
// ...........
|
||||
// ... row ...
|
||||
// padding
|
||||
// padding
|
||||
auto padded_input_plane = CreatePaddedNet(inputParams, conv_data);
|
||||
std::shared_ptr<ngraph::opset7::Result> result;
|
||||
|
||||
if (padded_input_plane) {
|
||||
auto shape_const = std::make_shared<ngraph::opset7::Constant>(ngraph::element::i64, ngraph::Shape{4},
|
||||
ngraph::Shape{static_cast<size_t>(1),
|
||||
conv_data.pads_begin_height + conv_data.input_height + conv_data.pads_end_height,
|
||||
conv_data.pads_begin_width + conv_data.input_width + conv_data.pads_end_width,
|
||||
conv_data.input_channel_count});
|
||||
auto padded_input_plane_reshaped = std::make_shared<ngraph::opset7::Reshape>(padded_input_plane, shape_const, false);
|
||||
result = createFunction(model, padded_input_plane_reshaped, filters_shape, conv_stride,
|
||||
ngraph::CoordinateDiff{0, 0}, ngraph::CoordinateDiff{0, 0}, conv_dilation, bias_shape,
|
||||
maxpool_stride, maxpool_shape, ngraph::op::PadType::EXPLICIT, nullptr);
|
||||
} else {
|
||||
// Valid padding
|
||||
result = createFunction(model, inputParams, filters_shape, conv_stride, pads_begin, pads_end, conv_dilation, bias_shape,
|
||||
maxpool_stride, maxpool_shape, pad_type, nullptr);
|
||||
}
|
||||
|
||||
return std::make_shared<ngraph::Function>(ngraph::ResultVector{result}, ngraph::ParameterVector{inputParams});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void execute_test(const modelType& model, std::shared_ptr<ngraph::Function> function, std::shared_ptr<ngraph::Function> reference_function) {
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::InitNodeInfo>();
|
||||
|
||||
switch (model) {
|
||||
default:
|
||||
case modelType::TranspConvTransp:
|
||||
manager.register_pass<GNAPluginNS::ConvertPadded2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvBcastAddTransp:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedWithBias2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvBcastAddMaxPoolTransp:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedWithBiasMaxPool2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvBcastAddActTransp:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedWithBiasAF2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvBcastAddMaxPoolActTransp:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedWithBiasMaxPoolAF2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvTranspBcastAdd:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedTransposedWithBias2ValidConv>();
|
||||
break;
|
||||
case modelType::TranspConvTranspBcastAddAct:
|
||||
manager.register_pass<GNAPluginNS::ConvertPaddedTransposedWithBiasAF2ValidConv>();
|
||||
break;
|
||||
}
|
||||
|
||||
manager.run_passes(function);
|
||||
const FunctionsComparator func_comparator = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES);
|
||||
const FunctionsComparator::Result result = func_comparator(function, reference_function);
|
||||
ASSERT_TRUE(result.valid);
|
||||
}
|
||||
|
||||
TEST_P(ConvertPadded2ValidConvTestFixture, CompareFunctions) {
|
||||
execute_test(model, function, reference_function);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ConvertPadded2ValidConvTestSuite, ConvertPadded2ValidConvTestFixture,
|
||||
::testing::Values(
|
||||
std::make_tuple(modelType::TranspConvTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvBcastAddTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvBcastAddMaxPoolTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvBcastAddActTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_LOWER),
|
||||
std::make_tuple(modelType::TranspConvBcastAddMaxPoolActTransp, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_UPPER),
|
||||
std::make_tuple(modelType::TranspConvTranspBcastAdd, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvTranspBcastAddAct, ngraph::PartialShape{1, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT)));
|
||||
|
||||
TEST_P(ConvertPadded2ValidConvTestInvalidFixture, CompareFunctions) {
|
||||
execute_test(model, function, reference_function);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ConvertPadded2ValidConvInvalidTestSuite, ConvertPadded2ValidConvTestInvalidFixture,
|
||||
::testing::Values(
|
||||
std::make_tuple(modelType::TranspConvTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_UPPER),
|
||||
std::make_tuple(modelType::TranspConvBcastAddTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvBcastAddMaxPoolTransp, ngraph::PartialShape{2, 16, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{5, 1}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvBcastAddActTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::SAME_LOWER),
|
||||
std::make_tuple(modelType::TranspConvBcastAddMaxPoolActTransp, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 5}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 4, 1, 1}, ngraph::Strides{1, 1}, ngraph::Shape{1, 4}, ngraph::op::PadType::SAME_UPPER),
|
||||
std::make_tuple(modelType::TranspConvTranspBcastAdd, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT),
|
||||
std::make_tuple(modelType::TranspConvTranspBcastAddAct, ngraph::PartialShape{2, 1, 16, 8}, ngraph::Shape{1, 2}, ngraph::Strides{1, 1},
|
||||
ngraph::CoordinateDiff{0, 2}, ngraph::CoordinateDiff{0, 3}, ngraph::Strides{1, 1},
|
||||
ngraph::Shape{1, 1, 1, 4}, ngraph::Strides{1, 1}, ngraph::Shape{1, 2}, ngraph::op::PadType::EXPLICIT)));
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
@ -9,7 +9,6 @@
|
||||
|
||||
namespace kernel_selector {
|
||||
// Sub-group size used by "kernel_name_bfyx_os_iyx_osv16" kernel.
|
||||
constexpr size_t sub_group_size = 16;
|
||||
|
||||
ConvolutionKernel_bfyx_os_iyx_osv16::ConvolutionKernel_bfyx_os_iyx_osv16()
|
||||
: ConvolutionKernelBase("convolution_gpu_bfyx_os_iyx_osv16") {
|
||||
@ -94,6 +93,9 @@ static void shrink_blocks_to_output_size(size_t output_x, size_t output_y, size_
|
||||
|
||||
block_x -= unused_x / simds_x;
|
||||
block_y -= unused_y / simds_y;
|
||||
|
||||
block_x = Align(block_x, 2);
|
||||
block_y = Align(block_y, 2);
|
||||
}
|
||||
|
||||
ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iyx_osv16::GetAutoTuneOptions(
|
||||
@ -107,9 +109,11 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy
|
||||
|
||||
const convolution_params& cp = static_cast<const convolution_params&>(p);
|
||||
|
||||
const auto& sub_group_size = GetSubGroupSize(cp);
|
||||
|
||||
if (cp.stride.x == 1 && cp.stride.y == 1) {
|
||||
if (cp.filterSize.x == 1 && cp.filterSize.y == 1) {
|
||||
option.blockWidth = 16;
|
||||
option.blockWidth = sub_group_size;
|
||||
option.blockHeight = 1;
|
||||
option.prefetch = 4;
|
||||
// if less than 16 values is required to compute one single row of output
|
||||
@ -143,13 +147,13 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy
|
||||
if (cp.filterSize.x != 1 || cp.filterSize.y != 1 || cp.output.Batch().v != 1) {
|
||||
shrink_blocks_to_output_size(cp.output.X().v, cp.output.Y().v, option.blockWidth, option.blockHeight);
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
ConvolutionKernelBase::DispatchData ConvolutionKernel_bfyx_os_iyx_osv16::SetDefault(const convolution_params& cp,
|
||||
int autoTuneIndex) const {
|
||||
DispatchData dispatchData = ConvolutionKernelBase::SetDefault(cp);
|
||||
const auto& sub_group_size = GetSubGroupSize(cp);
|
||||
|
||||
const auto of_maps = cp.output.Feature().v;
|
||||
const auto of_maps_per_group = of_maps / cp.groups;
|
||||
@ -196,6 +200,9 @@ bool ConvolutionKernel_bfyx_os_iyx_osv16::Validate(const Params& p, const option
|
||||
|
||||
JitConstants ConvolutionKernel_bfyx_os_iyx_osv16::GetJitConstants(const convolution_params& params,
|
||||
const DispatchData& dispatchData) const {
|
||||
const convolution_params& cp = static_cast<const convolution_params&>(params);
|
||||
const auto& sub_group_size = GetSubGroupSize(cp);
|
||||
|
||||
const auto of_maps = params.output.Feature().v;
|
||||
const auto of_maps_per_group = of_maps / params.groups;
|
||||
const size_t of_threads_per_batch = RoundUp(of_maps_per_group, sub_group_size);
|
||||
@ -209,7 +216,7 @@ JitConstants ConvolutionKernel_bfyx_os_iyx_osv16::GetJitConstants(const convolut
|
||||
jit.Merge(MakeFusedOpsJitConstants(params, {conf_scalar}));
|
||||
}
|
||||
|
||||
|
||||
jit.AddConstant(MakeJitConstant("OSV_SIZE", 16));
|
||||
jit.AddConstant(MakeJitConstant("SUB_GROUP_SIZE", dispatchData.lws[2]));
|
||||
jit.AddConstant(MakeJitConstant("OUTPUT_BLOCK_WIDTH", dispatchData.cldnnStyle.blockWidth));
|
||||
jit.AddConstant(MakeJitConstant("OUTPUT_BLOCK_HEIGHT", dispatchData.cldnnStyle.blockHeight));
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "api/cldnn/runtime/device_info.hpp"
|
||||
#include "convolution_kernel_base.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -34,6 +35,16 @@ protected:
|
||||
bool Validate(const Params& p, const optional_params& o) const override;
|
||||
bool NeedPaddedInput() const override { return true; }
|
||||
DispatchData SetDefault(const convolution_params& arg, int autoTuneIndex = -1) const override;
|
||||
size_t GetSubGroupSize(const convolution_params& params) const {
|
||||
if (params.engineInfo.computeUnitsCount <= 24) {
|
||||
// Smaller # EU tends to be computation bounds.
|
||||
// In such case, using larger worksize will result in larger computational inefficiency
|
||||
// w.r.t the unalined output feature
|
||||
return (params.output.Feature().v > 8) ? 16 : 8;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct AutoTuneOption {
|
||||
|
@ -83,12 +83,11 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)(
|
||||
uint fmg = feature_idx / SUB_GROUP_SIZE;
|
||||
const uint g = split_idx;
|
||||
#endif
|
||||
|
||||
UNIT_TYPE in[IN_BLOCK_ARRAY_SIZE];
|
||||
UNIT_TYPE out[OUTPUT_BLOCK_WIDTH * OUTPUT_BLOCK_HEIGHT];
|
||||
UNIT_TYPE w[PREFETCH];
|
||||
uint in_addr;
|
||||
uint weight_addr = fmg * FILTER_IFM_NUM * FILTER_SIZE_X * FILTER_SIZE_Y * SUB_GROUP_SIZE + lid;
|
||||
uint weight_addr = fmg * FILTER_IFM_NUM * FILTER_SIZE_X * FILTER_SIZE_Y * OSV_SIZE + lid;
|
||||
|
||||
#if GROUPED
|
||||
weight_addr += g * FILTER_GROUPS_PITCH;
|
||||
@ -156,7 +155,7 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)(
|
||||
in_addr += INPUT0_FEATURE_PITCH;
|
||||
|
||||
for(int pf=0; pf<PREFETCH; pf++) {
|
||||
w[pf] = weights[weight_addr]; weight_addr += SUB_GROUP_SIZE;
|
||||
w[pf] = weights[weight_addr]; weight_addr += OSV_SIZE;
|
||||
}
|
||||
|
||||
uint wi = 0;
|
||||
@ -182,12 +181,12 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)(
|
||||
}
|
||||
}
|
||||
w[wi % PREFETCH] = weights[weight_addr];
|
||||
weight_addr += SUB_GROUP_SIZE; // weights must be stored in just the right SIMD swizzled format for this to work, see host code for details.
|
||||
weight_addr += OSV_SIZE; // weights must be stored in just the right SIMD swizzled format for this to work, see host code for details.
|
||||
wi++;
|
||||
});
|
||||
});
|
||||
// addr went beyond due to prefetch so move it back to correct location.
|
||||
weight_addr -= PREFETCH * SUB_GROUP_SIZE;
|
||||
weight_addr -= PREFETCH * OSV_SIZE;
|
||||
}
|
||||
|
||||
uint out_split_offset = g * OUTPUT_FEATURE_PITCH * FILTER_OFM_NUM;
|
||||
|
@ -175,7 +175,6 @@ extensions/front/kaldi/tdnn_component_replacer.py
|
||||
extensions/front/LayerNorm.py
|
||||
extensions/front/Log1p.py
|
||||
extensions/front/MatMul_normalizer.py
|
||||
extensions/front/Mish_fusion.py
|
||||
extensions/front/MoveEmbeddedInputsToInputs.py
|
||||
extensions/front/mxnet/__init__.py
|
||||
extensions/front/mxnet/activation.py
|
||||
@ -329,12 +328,10 @@ extensions/front/onnx/priorbox_clustered_ext.py
|
||||
extensions/front/onnx/priorbox_ext.py
|
||||
extensions/front/onnx/priorgridgenerator_ext.py
|
||||
extensions/front/onnx/proposal_ext.py
|
||||
extensions/front/onnx/quantize_dequantize_linear.py
|
||||
extensions/front/onnx/quantize_ext.py
|
||||
extensions/front/onnx/quantize_linear_ext.py
|
||||
extensions/front/onnx/range_ext.py
|
||||
extensions/front/onnx/reduce_ext.py
|
||||
extensions/front/onnx/remove_filtering_boxes_by_size.py
|
||||
extensions/front/onnx/reshape_ext.py
|
||||
extensions/front/onnx/resize_ext.py
|
||||
extensions/front/onnx/reverse_sequence_ext.py
|
||||
@ -371,13 +368,11 @@ extensions/front/RollWithEmptyAxesReplacer.py
|
||||
extensions/front/scatter_normalizer.py
|
||||
extensions/front/SizeReplacer.py
|
||||
extensions/front/softmax.py
|
||||
extensions/front/Softplus_fusion.py
|
||||
extensions/front/softsign_replacer.py
|
||||
extensions/front/sparse_to_dense_replacer.py
|
||||
extensions/front/split_normalizer.py
|
||||
extensions/front/SqueezeNormalize.py
|
||||
extensions/front/sub.py
|
||||
extensions/front/Swish_fusion.py
|
||||
extensions/front/tf/__init__.py
|
||||
extensions/front/tf/activation_ext.py
|
||||
extensions/front/tf/argmax_ext.py
|
||||
|
@ -1,48 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from extensions.front.Softplus_fusion import SoftplusFusion
|
||||
from extensions.ops.activation_ops import Mish
|
||||
from mo.front.common.replacement import FrontReplacementSubgraph
|
||||
from mo.front.subgraph_matcher import SubgraphMatch
|
||||
from mo.graph.graph import Graph, rename_nodes
|
||||
|
||||
|
||||
class MishFusion(FrontReplacementSubgraph):
|
||||
"""
|
||||
The transformation looks for the pattern with Softplus defining the Mish function: Mish(x) = x * tanh(SoftPlus(x)).
|
||||
"""
|
||||
enabled = True
|
||||
|
||||
def run_after(self):
|
||||
return [SoftplusFusion]
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('mul', dict(op='Mul')),
|
||||
('tanh', dict(op='Tanh')),
|
||||
('softplus', dict(op='SoftPlus')),
|
||||
],
|
||||
edges=[
|
||||
('softplus', 'tanh'),
|
||||
('tanh', 'mul'),
|
||||
])
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
|
||||
mul = match['mul']
|
||||
mul_name = mul.soft_get('name', mul.id)
|
||||
softplus = match['softplus']
|
||||
|
||||
# determine the input port of Mul which gets the 'input' node output
|
||||
input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Tanh')
|
||||
|
||||
# check that the same tensor provided as input to Mul and SoftPlus
|
||||
if mul.in_port(input_port_idx).get_source() != softplus.in_port(0).get_source():
|
||||
return
|
||||
|
||||
mish = Mish(graph, {}).create_node()
|
||||
mish.in_port(0).connect(mul.in_port(input_port_idx).get_source())
|
||||
mul.out_port(0).get_connection().set_source(mish.out_port(0))
|
||||
|
||||
rename_nodes([(mul, mul_name + '/TBR'), (mish, mul_name)])
|
@ -1,43 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import numpy as np
|
||||
|
||||
from extensions.ops.activation_ops import SoftPlus
|
||||
from mo.front.common.replacement import FrontReplacementSubgraph
|
||||
from mo.front.subgraph_matcher import SubgraphMatch
|
||||
from mo.graph.graph import Graph, rename_nodes
|
||||
from mo.middle.pattern_match import check_value
|
||||
|
||||
|
||||
class SoftplusFusion(FrontReplacementSubgraph):
|
||||
"""
|
||||
The transformation looks for the pattern for the Softplus function: Softplus(x) = ln(1 + e^x)
|
||||
"""
|
||||
enabled = True
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('exp', dict(op='Exp')),
|
||||
('add', dict(op='Add')),
|
||||
('const_1', dict(op='Const', value=lambda v: check_value(v, lambda x: np.allclose(x, 1.0, atol=1e-6)))),
|
||||
('ln', dict(op='Log')),
|
||||
],
|
||||
edges=[
|
||||
('exp', 'add', {}),
|
||||
('const_1', 'add', {}),
|
||||
('add', 'ln', {}),
|
||||
])
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
|
||||
ln = match['ln']
|
||||
exp = match['exp']
|
||||
|
||||
ln_name = ln.soft_get('name', ln.id)
|
||||
|
||||
softplus = SoftPlus(graph, {}).create_node()
|
||||
softplus.in_port(0).connect(exp.in_port(0).get_source())
|
||||
ln.out_port(0).get_connection().set_source(softplus.out_port(0))
|
||||
|
||||
rename_nodes([(ln, ln_name + '/TBR'), (softplus, ln_name)])
|
@ -1,87 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from extensions.ops.activation_ops import Swish
|
||||
from mo.front.common.replacement import FrontReplacementSubgraph
|
||||
from mo.front.subgraph_matcher import SubgraphMatch
|
||||
from mo.graph.graph import Graph, rename_nodes
|
||||
|
||||
|
||||
class SwishWithSigmoidWithoutBeta(FrontReplacementSubgraph):
|
||||
"""
|
||||
The transformation looks for the pattern with Sigmoid defining the Swish function: Swish(x) = x * Sigmoid(x)
|
||||
"""
|
||||
enabled = True
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('sigmoid', dict(op='Sigmoid')),
|
||||
('mul', dict(op='Mul')),
|
||||
],
|
||||
edges=[
|
||||
('sigmoid', 'mul', {}),
|
||||
])
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
|
||||
sigmoid = match['sigmoid']
|
||||
mul = match['mul']
|
||||
mul_name = mul.soft_get('name', mul.id)
|
||||
|
||||
# determine the input port of Mul which gets the 'input' node output
|
||||
mul_input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Sigmoid')
|
||||
|
||||
# check that the same tensor provided as input to Mul and Sigmoid
|
||||
if mul.in_port(mul_input_port_idx).get_source() != sigmoid.in_port(0).get_source():
|
||||
return
|
||||
|
||||
swish = Swish(graph, {}).create_node()
|
||||
swish.in_port(0).connect(sigmoid.in_port(0).get_source())
|
||||
mul.out_port(0).get_connection().set_source(swish.out_port(0))
|
||||
|
||||
rename_nodes([(mul, mul_name + '/TBR'), (swish, mul_name)])
|
||||
|
||||
|
||||
class SwishWithSigmoidWithBeta(FrontReplacementSubgraph):
|
||||
"""
|
||||
The transformation looks for the pattern with Sigmoid defining the Swish function: Swish(x) = x * Sigmoid(x * beta)
|
||||
"""
|
||||
enabled = True
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('sigmoid', dict(op='Sigmoid')),
|
||||
('beta', dict()),
|
||||
('mul_beta', dict(op='Mul')),
|
||||
('mul', dict(op='Mul')),
|
||||
],
|
||||
edges=[
|
||||
('beta', 'mul_beta', {}),
|
||||
('mul_beta', 'sigmoid', {}),
|
||||
('sigmoid', 'mul', {}),
|
||||
])
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
|
||||
beta = match['beta']
|
||||
mul = match['mul']
|
||||
mul_beta = match['mul_beta']
|
||||
mul_name = mul.soft_get('name', mul.id)
|
||||
|
||||
# determine the input port of Muls which get the 'input' node output
|
||||
mul_beta_input_port_idx = int(mul_beta.in_port(0).get_connection().get_source().node.id == beta.id)
|
||||
mul_input_port_idx = int(mul.in_port(0).get_connection().get_source().node.soft_get('op') == 'Sigmoid')
|
||||
|
||||
# check that the same tensor provided as input to Mul and MulBeta
|
||||
if mul.in_port(mul_input_port_idx).get_source() != mul_beta.in_port(mul_beta_input_port_idx).get_source():
|
||||
return
|
||||
|
||||
swish = Swish(graph, {}).create_node()
|
||||
swish.in_port(0).connect(mul_beta.in_port(mul_beta_input_port_idx).get_source())
|
||||
|
||||
# connect Beta value
|
||||
swish.in_port(1).connect(mul_beta.in_port(1 - mul_beta_input_port_idx).get_source())
|
||||
|
||||
mul.out_port(0).get_connection().set_source(swish.out_port(0))
|
||||
|
||||
rename_nodes([(mul, mul_name + '/TBR'), (swish, mul_name)])
|
@ -1,87 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import logging as log
|
||||
|
||||
import numpy as np
|
||||
|
||||
from extensions.ops.fakequantize import FakeQuantize
|
||||
from mo.front.common.replacement import FrontReplacementSubgraph
|
||||
from mo.front.subgraph_matcher import SubgraphMatch
|
||||
from mo.graph.graph import Graph, rename_nodes
|
||||
from mo.ops.const import Const
|
||||
from mo.utils.error import Error
|
||||
|
||||
|
||||
class QuantizeDequantizeLinear(FrontReplacementSubgraph):
|
||||
"""
|
||||
Fuses QuantizeLinear and DequantizeLinear nodes into single FakeQuantize.
|
||||
Covers cases when the values for zero point and scale are same in both QuantizeLinear and DequantizeLinear.
|
||||
"""
|
||||
enabled = True
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('quantize', dict(op='QuantizeLinear')),
|
||||
('dequantize', dict(op='DequantizeLinear')),
|
||||
],
|
||||
edges=[
|
||||
('quantize', 'dequantize', {'in': 0}),
|
||||
]
|
||||
)
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
|
||||
|
||||
q = match['quantize']
|
||||
dq = match['dequantize']
|
||||
|
||||
q_scale = q.in_port(1).get_source().node
|
||||
q_zerop = q.in_port(2).get_source().node
|
||||
dq_scale = dq.in_port(1).get_source().node
|
||||
dq_zerop = dq.in_port(2).get_source().node
|
||||
|
||||
inp_port = q.in_port(0).get_source()
|
||||
name = inp_port.node.soft_get('name', inp_port.node.id)
|
||||
|
||||
# only constant as for zero_point/scale supported
|
||||
if q_scale.soft_get('type') == 'Const' and dq_scale.soft_get('type') == 'Const' and \
|
||||
q_zerop.soft_get('type') == 'Const' and dq_zerop.soft_get('type') == 'Const':
|
||||
|
||||
# only patterns with same scale/zero_point values for Q and DQ are supported
|
||||
if q_scale.value == dq_scale.value and q_zerop.value == dq_zerop.value:
|
||||
log.debug('Found Q-DQ pattern after {}'.format(name))
|
||||
|
||||
zero_point_type = q_zerop.value.dtype
|
||||
# data type affects range of output values: [-128..127] or [0..255]
|
||||
if zero_point_type == np.int8:
|
||||
output_min_value = -128.0
|
||||
output_max_value = 127.0
|
||||
elif zero_point_type == np.uint8:
|
||||
output_min_value = 0.0
|
||||
output_max_value = 255.0
|
||||
else:
|
||||
raise Error('Not supported type {} for zero point value in node {}'.format(
|
||||
zero_point_type, q_zerop.soft_get('name')))
|
||||
min_value = q_scale.value * (output_min_value - q_zerop.value)
|
||||
max_value = q_scale.value * (output_max_value - q_zerop.value)
|
||||
input_min = Const(graph, {'value': np.array(min_value)}).create_node()
|
||||
input_max = Const(graph, {'value': np.array(max_value)}).create_node()
|
||||
|
||||
FQ = FakeQuantize(graph, {
|
||||
'levels': 256,
|
||||
'name': match['quantize'].name + '_Dequantize/FakeQuantize'
|
||||
}).create_node()
|
||||
|
||||
FQ.in_port(0).connect(match['quantize'].in_port(0).get_source())
|
||||
FQ.in_port(1).connect(input_min.out_port(0))
|
||||
FQ.in_port(2).connect(input_max.out_port(0))
|
||||
FQ.in_port(3).connect(input_min.out_port(0))
|
||||
FQ.in_port(4).connect(input_max.out_port(0))
|
||||
|
||||
match['dequantize'].out_port(0).get_connection().set_source(FQ.out_port(0))
|
||||
dq_name = match['dequantize'].soft_get('name', match['dequantize'].id)
|
||||
rename_nodes([(match['dequantize'], dq_name + '/to_be_removed'), (FQ, dq_name)])
|
||||
else:
|
||||
raise Error('QuantizeLinear and DequantizeLinear (after {}) have different scale or zero-point values, '
|
||||
'cannot fuse into FakeQuantize!'.format(name))
|
@ -1,117 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from extensions.front.split_normalizer import AttributedVariadicSplitToVariadicSplit
|
||||
from extensions.ops.range import Range
|
||||
from mo.front.common.partial_infer.utils import int64_array
|
||||
from mo.front.common.replacement import FrontReplacementSubgraph
|
||||
from mo.front.tf.graph_utils import create_op_node_with_second_input
|
||||
from mo.graph.graph import Graph
|
||||
from mo.graph.graph import Node
|
||||
from mo.ops.const import Const
|
||||
from mo.ops.shape import Shape
|
||||
from mo.ops.squeeze import Squeeze
|
||||
from mo.utils.shape import node_to_get_batch_value
|
||||
|
||||
|
||||
def skip_nodes_by_condition(current_node: Node, condition: callable):
|
||||
while condition(current_node):
|
||||
current_node = current_node.in_node()
|
||||
return current_node
|
||||
|
||||
|
||||
class RemoveFilteringBoxesBySize(FrontReplacementSubgraph):
|
||||
"""
|
||||
The transformation looks for a sub-graph that selects boxes with nonzero height and width. The output node of this
|
||||
sub-graph is a Cast node that produces indices of nodes to be preserved. The transformation creates a new sub-graph
|
||||
that produces a tensor with values from 0 to input.shape[0] to select all boxes. The output of this sub-graph will
|
||||
be used in the NonMaxSuppression so the implementation of this layer should ignore boxes with negative sizes.
|
||||
"""
|
||||
enabled = True
|
||||
force_clean_up = True
|
||||
|
||||
def run_after(self):
|
||||
return [AttributedVariadicSplitToVariadicSplit]
|
||||
|
||||
def pattern(self):
|
||||
return dict(
|
||||
nodes=[
|
||||
('split', dict(op='VariadicSplit')),
|
||||
('sub_1', dict(op='Sub')),
|
||||
('sub_2', dict(op='Sub')),
|
||||
('add_1', dict(op='Add')),
|
||||
('add_2', dict(op='Add')),
|
||||
('concat', dict(op='Concat')),
|
||||
('split_2', dict(op='VariadicSplit')),
|
||||
('squeeze_1', dict(op='Squeeze')),
|
||||
('squeeze_2', dict(op='Squeeze')),
|
||||
('less_1', dict(op='Less')),
|
||||
('less_2', dict(op='Less')),
|
||||
('not_1', dict(op='LogicalNot')),
|
||||
('not_2', dict(op='LogicalNot')),
|
||||
('cast_11', dict(op='Cast')),
|
||||
('cast_12', dict(op='Cast')),
|
||||
('cast_21', dict(op='Cast')),
|
||||
('cast_22', dict(op='Cast')),
|
||||
('and', dict(op='LogicalAnd')),
|
||||
('cast_31', dict(op='Cast')),
|
||||
('cast_32', dict(op='Cast')),
|
||||
('nonzero', dict(op='NonZero')),
|
||||
('transpose', dict(op='Transpose')),
|
||||
('squeeze', dict(op='Squeeze')),
|
||||
('cast', dict(op='Cast')),
|
||||
],
|
||||
edges=[
|
||||
('split', 'sub_1', {'in': 0, 'out': 2}),
|
||||
('split', 'sub_1', {'in': 1, 'out': 0}),
|
||||
('split', 'sub_2', {'in': 0, 'out': 3}),
|
||||
('split', 'sub_2', {'in': 1, 'out': 1}),
|
||||
('sub_1', 'add_1', {}),
|
||||
('sub_2', 'add_2', {}),
|
||||
('split', 'concat', {'in': 0, 'out': 0}),
|
||||
('split', 'concat', {'in': 1, 'out': 1}),
|
||||
('add_1', 'concat', {'in': 2, 'out': 0}),
|
||||
('add_2', 'concat', {'in': 3, 'out': 0}),
|
||||
('concat', 'split_2', {}),
|
||||
('split_2', 'squeeze_1', {'in': 0, 'out': 2}),
|
||||
('split_2', 'squeeze_2', {'in': 0, 'out': 3}),
|
||||
('squeeze_1', 'less_1', {}),
|
||||
('squeeze_2', 'less_2', {}),
|
||||
('less_1', 'not_1', {}),
|
||||
('less_2', 'not_2', {}),
|
||||
('not_1', 'cast_11', {}),
|
||||
('cast_11', 'cast_12', {}),
|
||||
('not_2', 'cast_21', {}),
|
||||
('cast_21', 'cast_22', {}),
|
||||
('cast_12', 'and', {}),
|
||||
('cast_22', 'and', {}),
|
||||
('and', 'cast_31', {}),
|
||||
('cast_31', 'cast_32', {}),
|
||||
('cast_32', 'nonzero', {}),
|
||||
('nonzero', 'transpose', {}),
|
||||
('transpose', 'squeeze', {}),
|
||||
('squeeze', 'cast', {}),
|
||||
])
|
||||
|
||||
def replace_sub_graph(self, graph: Graph, match: dict):
|
||||
source_connection = match['split'].in_port(0).get_connection()
|
||||
source_node = source_connection.get_source().node
|
||||
cast_node = match['cast']
|
||||
|
||||
range_node = Range(graph, {'name': source_node.id + '/Range'}).create_node()
|
||||
start_node = Const(graph, {'name': range_node.id + '/Start', 'value': int64_array(0)}).create_node()
|
||||
|
||||
step_node = Const(graph, {'name': range_node.id + '/Step', 'value': int64_array(1)}).create_node()
|
||||
input_shape_node = Shape(graph, {'name': start_node.id + '/Shape'}).create_node()
|
||||
input_shape_node.in_port(0).connect(source_node.out_port(0))
|
||||
|
||||
limit_node_1D = node_to_get_batch_value(input_shape_node)
|
||||
limit_node = create_op_node_with_second_input(graph, Squeeze, int64_array([0]),
|
||||
{'name': source_node.id + '/batch_0D_value'}, limit_node_1D)
|
||||
|
||||
range_node.in_port(0).connect(start_node.out_port(0))
|
||||
range_node.in_port(1).connect(limit_node.out_port(0))
|
||||
range_node.in_port(2).connect(step_node.out_port(0))
|
||||
cast_node.out_port(0).get_connection().set_source(range_node.out_port(0))
|
||||
|
||||
graph.remove_nodes_from([node.id for node in match.values()])
|
@ -6,6 +6,8 @@
|
||||
:: Check if Python is installed
|
||||
setlocal
|
||||
|
||||
set ROOT_DIR=%~dp0
|
||||
|
||||
python --version 2>NUL
|
||||
if errorlevel 1 (
|
||||
echo Error^: Python is not installed. Please install Python 3.5 ^(64-bit^) or higher from https://www.python.org/downloads/
|
||||
@ -35,9 +37,15 @@ if not "%python_ver%"=="okay" (
|
||||
|
||||
:: install Python modules
|
||||
|
||||
set USE_VENV="false"
|
||||
set VENV_DIR=%USERPROFILE%\Documents\Intel\OpenVINO\venv_openvino
|
||||
|
||||
IF /I "%1%" EQU "" (
|
||||
set postfix=
|
||||
) ELSE (
|
||||
IF /I "%1%" EQU "venv" (
|
||||
set postfix=
|
||||
set USE_VENV="true"
|
||||
) ELSE (
|
||||
IF /I "%1%" EQU "caffe" (
|
||||
set postfix=_caffe
|
||||
@ -66,11 +74,22 @@ IF /I "%1%" EQU "" (
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
pip3 install --user -r ..\requirements%postfix%.txt
|
||||
IF /I "%2%" EQU "venv" (
|
||||
set USE_VENV="true"
|
||||
)
|
||||
|
||||
IF %USE_VENV% == "true" (
|
||||
python -m venv "%VENV_DIR%"
|
||||
call "%VENV_DIR%\Scripts\activate.bat"
|
||||
)
|
||||
|
||||
python -m pip install -U pip
|
||||
python -m pip install -r "%ROOT_DIR%..\requirements%postfix%.txt"
|
||||
|
||||
:: Chek MO version
|
||||
set python_command='python "%~dp0..\mo\utils\extract_release_version.py"'
|
||||
set python_command='python "%ROOT_DIR%..\mo\utils\extract_release_version.py"'
|
||||
FOR /F "delims=" %%i IN (%python_command%) DO set mo_release_version=%%i
|
||||
IF "%mo_release_version%" == "None.None" (
|
||||
set mo_is_custom="true"
|
||||
@ -80,12 +99,12 @@ IF "%mo_release_version%" == "None.None" (
|
||||
|
||||
:: Check if existing IE Python bindings satisfy requirements
|
||||
set errorlevel=
|
||||
python "%~dp0..\mo\utils\find_ie_version.py"
|
||||
python "%ROOT_DIR%..\mo\utils\find_ie_version.py"
|
||||
IF %errorlevel% EQU 0 goto ie_search_end
|
||||
|
||||
:: Check if OV already installed via pip
|
||||
set errorlevel=
|
||||
pip3 show openvino
|
||||
python -m pip show openvino
|
||||
IF %errorlevel% EQU 0 (
|
||||
IF %mo_is_custom% == "true" (
|
||||
echo [ WARNING ] OpenVINO ^(TM^) Toolkit version installed in pip is incompatible with the Model Optimizer
|
||||
@ -110,7 +129,7 @@ IF %mo_is_custom% == "true" (
|
||||
)
|
||||
|
||||
set errorlevel=
|
||||
pip3 install openvino==%mo_release_version%
|
||||
python -m pip install openvino==%mo_release_version%
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo [ WARNING ] Could not find the OpenVINO ^(TM^) toolkit version %mo_release_version% in pip
|
||||
echo [ WARNING ] The highest OpenVINO ^(TM^) toolkit version will be installed ^(may be incompatible with current Model Optimizer version^)
|
||||
@ -119,17 +138,17 @@ IF %errorlevel% NEQ 0 (
|
||||
)
|
||||
|
||||
set errorlevel=
|
||||
python "%~dp0..\mo\utils\find_ie_version.py"
|
||||
python "%ROOT_DIR%..\mo\utils\find_ie_version.py"
|
||||
IF %errorlevel% EQU 0 goto ie_search_end
|
||||
|
||||
echo [ WARNING ] The installed OpenVINO ^(TM^) toolkit version %mo_release_version% does not work as expected. Uninstalling...
|
||||
pip3 uninstall -y openvino
|
||||
python -m pip uninstall -y openvino
|
||||
echo [ WARNING ] Consider building the Inference Engine Python API from sources
|
||||
goto ie_search_end
|
||||
|
||||
:install_last_ov
|
||||
set errorlevel=
|
||||
pip3 install openvino
|
||||
python -m pip install openvino
|
||||
IF %errorlevel% NEQ 0 (
|
||||
echo [ WARNING ] Could not find OpenVINO ^(TM^) toolkit version available in pip for installation
|
||||
echo [ WARNING ] Consider building the Inference Engine Python API from sources
|
||||
@ -137,16 +156,26 @@ IF %errorlevel% NEQ 0 (
|
||||
)
|
||||
|
||||
set errorlevel=
|
||||
python "%~dp0..\mo\utils\find_ie_version.py"
|
||||
python "%ROOT_DIR%..\mo\utils\find_ie_version.py"
|
||||
IF %errorlevel% EQU 0 goto ie_search_end
|
||||
|
||||
echo [ WARNING ] The installed highest OpenVINO ^(TM^) toolkit version doesn't work as expected. Uninstalling...
|
||||
pip3 uninstall -y openvino
|
||||
python -m pip uninstall -y openvino
|
||||
echo [ WARNING ] Consider building the Inference Engine Python API from sources
|
||||
goto ie_search_end
|
||||
|
||||
:ie_search_end
|
||||
|
||||
IF %USE_VENV% == "true" (
|
||||
echo.
|
||||
echo Before running the Model Optimizer, please activate virtualenv environment by running "%VENV_DIR%\Scripts\activate.bat"
|
||||
) ELSE (
|
||||
echo.
|
||||
echo [ WARNING ] All Model Optimizer dependencies are installed globally.
|
||||
echo [ WARNING ] If you want to keep Model Optimizer in separate sandbox
|
||||
echo [ WARNING ] run install_prerequisites.bat "{caffe|tf|tf2|mxnet|kaldi|onnx}" venv
|
||||
)
|
||||
|
||||
echo *****************************************************************************************
|
||||
echo Optional: To speed up model conversion process, install protobuf-*.egg located in the
|
||||
echo "model-optimizer\install_prerequisites" folder or building protobuf library from sources.
|
||||
|
@ -35,6 +35,7 @@ for ((i=1;i <= $#;i++)) {
|
||||
esac
|
||||
}
|
||||
|
||||
VENV_DIR="$HOME/venv_openvino"
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]-$0}" )" && pwd )"
|
||||
|
||||
if [[ -f /etc/centos-release ]]; then
|
||||
@ -53,23 +54,8 @@ if [[ $DISTRO == "centos" ]]; then
|
||||
elif command -v python3.5 >/dev/null 2>&1; then
|
||||
python_binary=python3.5
|
||||
fi
|
||||
|
||||
if [ -z "$python_binary" ]; then
|
||||
sudo -E yum install -y https://centos7.iuscommunity.org/ius-release.rpm
|
||||
sudo -E yum install -y python36u python36u-pip
|
||||
sudo -E pip3.6 install virtualenv
|
||||
python_binary=python3.6
|
||||
fi
|
||||
# latest pip is needed to install tensorflow
|
||||
sudo -E "$python_binary" -m pip install --upgrade pip
|
||||
elif [[ $DISTRO == "ubuntu" ]]; then
|
||||
sudo -E apt update
|
||||
sudo -E apt -y --no-install-recommends install python3-pip python3-venv
|
||||
else
|
||||
python_binary=python3
|
||||
sudo -E "$python_binary" -m pip install --upgrade pip
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
python_binary=python3
|
||||
python3 -m pip install --upgrade pip
|
||||
fi
|
||||
|
||||
install_latest_ov() {
|
||||
@ -181,21 +167,21 @@ find_ie_bindings() {
|
||||
}
|
||||
|
||||
if [[ $V_ENV -eq 1 ]]; then
|
||||
"$python_binary" -m venv "$SCRIPTDIR/../venv${postfix}"
|
||||
source "$SCRIPTDIR/../venv${postfix}/bin/activate"
|
||||
venv_python_binary="$SCRIPTDIR/../venv${postfix}/bin/$python_binary"
|
||||
$venv_python_binary -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt"
|
||||
"$python_binary" -m venv "$VENV_DIR"
|
||||
source "$VENV_DIR/bin/activate"
|
||||
venv_python_binary="$VENV_DIR/bin/$python_binary"
|
||||
# latest pip is needed to install tensorflow
|
||||
"$venv_python_binary" -m pip install --upgrade pip
|
||||
"$venv_python_binary" -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt"
|
||||
find_ie_bindings "$venv_python_binary" false
|
||||
echo
|
||||
echo "Before running the Model Optimizer, please activate virtualenv environment by running \"source ${SCRIPTDIR}/../venv${postfix}/bin/activate\""
|
||||
echo "Before running the Model Optimizer, please activate virtualenv environment by running \"source $VENV_DIR/bin/activate\""
|
||||
else
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
python3 -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt"
|
||||
find_ie_bindings python3 false
|
||||
else
|
||||
sudo -E $python_binary -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt"
|
||||
find_ie_bindings $python_binary true
|
||||
fi
|
||||
# latest pip is needed to install tensorflow
|
||||
"$python_binary" -m pip install --upgrade pip
|
||||
"$python_binary" -m pip install -r "$SCRIPTDIR/../requirements${postfix}.txt"
|
||||
find_ie_bindings "$python_binary" false
|
||||
echo
|
||||
echo "[WARNING] All Model Optimizer dependencies are installed globally."
|
||||
echo "[WARNING] If you want to keep Model Optimizer in separate sandbox"
|
||||
echo "[WARNING] run install_prerequisites.sh \"{caffe|tf|tf2|mxnet|kaldi|onnx}\" venv"
|
||||
|
@ -70,8 +70,18 @@ def tf_tensor_content(tf_dtype, shape, pb_tensor):
|
||||
log.error(decode_err_msg, extra={'is_warning': True})
|
||||
value = np.array(type_helper[1](pb_tensor))
|
||||
|
||||
if len(shape) == 0 or shape.prod() == 0:
|
||||
if len(value) == 1:
|
||||
# Ignore an empty value, if len(shape) > 1
|
||||
# For example, value = [] and shape = [1, 1, 0]
|
||||
# This is needed to reshape this value later and to return reshaped value = [[[]]]
|
||||
# Otherwise there can be failures during partial inference, because we are storing an empty value with incorrect
|
||||
# shape
|
||||
if len(shape) == 0 or (len(shape) == 1 and shape.prod() == 0):
|
||||
try:
|
||||
value_length = len(value)
|
||||
except TypeError:
|
||||
# case, when value is a scalar
|
||||
value_length = 0
|
||||
if value_length == 1:
|
||||
# return scalar if shape is [] otherwise broadcast according to shape
|
||||
try:
|
||||
return np.array(value[0], dtype=type_helper[0])
|
||||
|
@ -1,66 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import unittest
|
||||
|
||||
from extensions.front.Mish_fusion import MishFusion
|
||||
from mo.utils.ir_engine.compare_graphs import compare_graphs
|
||||
from unit_tests.utils.graph import build_graph, regular_op, result, build_graph_with_edge_attrs
|
||||
|
||||
ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('mish', {'type': 'Mish', 'name': 'final_mul'}),
|
||||
**result('result')
|
||||
}
|
||||
ref_edges = [('input', 'mish'), ('mish', 'result')]
|
||||
|
||||
|
||||
class MishFusionTest(unittest.TestCase):
|
||||
nodes = {
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('softplus', {'op': 'SoftPlus'}),
|
||||
**regular_op('tanh', {'op': 'Tanh'}),
|
||||
**regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}
|
||||
|
||||
edges = [('input', 'softplus', {'in': 0, 'out': 0}),
|
||||
('input', 'mul', {'in': 0, 'out': 0}),
|
||||
('softplus', 'tanh', {'in': 0, 'out': 0}),
|
||||
('tanh', 'mul', {'in': 1, 'out': 0}),
|
||||
('mul', 'result', {'in': 0, 'out': 0})]
|
||||
|
||||
def test_mish_fusion(self):
|
||||
graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
|
||||
|
||||
graph_ref = build_graph(ref_nodes, ref_edges)
|
||||
graph.stage = 'front'
|
||||
|
||||
MishFusion().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
|
||||
graph.get_op_nodes(name='final_mul')[0].op == 'Mish')
|
||||
|
||||
def test_mish_fusion_different_source(self):
|
||||
# check case when different tensors goes to Mul and SoftPlus
|
||||
graph = build_graph_with_edge_attrs({
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('input_2', {'type': 'Parameter'}),
|
||||
**regular_op('softplus', {'op': 'SoftPlus'}),
|
||||
**regular_op('tanh', {'op': 'Tanh'}),
|
||||
**regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}, [('input', 'softplus', {'in': 0, 'out': 0}),
|
||||
('input_2', 'mul', {'in': 0, 'out': 0}),
|
||||
('softplus', 'tanh', {'in': 0, 'out': 0}),
|
||||
('tanh', 'mul', {'in': 1, 'out': 0}),
|
||||
('mul', 'result', {'in': 0, 'out': 0})], {})
|
||||
|
||||
graph_ref = graph.copy()
|
||||
graph.stage = 'front'
|
||||
|
||||
MishFusion().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
@ -1,57 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import unittest
|
||||
|
||||
from extensions.front.Softplus_fusion import SoftplusFusion
|
||||
from mo.front.common.partial_infer.utils import float_array
|
||||
from mo.utils.ir_engine.compare_graphs import compare_graphs
|
||||
from unit_tests.utils.graph import build_graph, const, regular_op, result, build_graph_with_edge_attrs
|
||||
|
||||
ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('softplus', {'type': 'SoftPlus', 'name': 'final_log'}),
|
||||
**result('result')
|
||||
}
|
||||
ref_edges = [('input', 'softplus'), ('softplus', 'result')]
|
||||
|
||||
|
||||
class SoftplusFusionTest(unittest.TestCase):
|
||||
nodes = {
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('exp', {'op': 'Exp'}),
|
||||
**const('const_1', float_array([1.0])),
|
||||
**regular_op('add', {'op': 'Add'}),
|
||||
**regular_op('ln', {'op': 'Log', 'name': 'final_log'}),
|
||||
**result('result'),
|
||||
}
|
||||
|
||||
edges = [('input', 'exp', {'in': 0, 'out': 0}),
|
||||
('const_1', 'add', {'in': 0, 'out': 0}),
|
||||
('exp', 'add', {'in': 1, 'out': 0}),
|
||||
('add', 'ln', {'in': 0, 'out': 0}),
|
||||
('ln', 'result', {'in': 0, 'out': 0})]
|
||||
|
||||
def test_softplus_fusion_test(self):
|
||||
graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
|
||||
|
||||
graph_ref = build_graph(ref_nodes, ref_edges)
|
||||
graph.stage = 'front'
|
||||
|
||||
SoftplusFusion().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
self.assertTrue(len(graph.get_op_nodes(name='final_log')) == 1 and
|
||||
graph.get_op_nodes(name='final_log')[0].op == 'SoftPlus')
|
||||
|
||||
def test_softplus_fusion_test_wrong_const(self):
|
||||
graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_1': {'value': float_array([0.9999])}})
|
||||
|
||||
graph_ref = graph.copy()
|
||||
graph.stage = 'front'
|
||||
|
||||
SoftplusFusion().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
|
@ -1,119 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import unittest
|
||||
|
||||
from extensions.front.Swish_fusion import SwishWithSigmoidWithoutBeta, SwishWithSigmoidWithBeta
|
||||
from mo.utils.ir_engine.compare_graphs import compare_graphs
|
||||
from unit_tests.utils.graph import build_graph, regular_op, result, build_graph_with_edge_attrs
|
||||
|
||||
ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('swish', {'type': 'Swish', 'name': 'final_mul'}),
|
||||
**result('result')
|
||||
}
|
||||
ref_edges = [('input', 'swish'), ('swish', 'result')]
|
||||
|
||||
|
||||
class SwishWithSigmoidWithoutBetaTest(unittest.TestCase):
|
||||
nodes = {
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('sigmoid', {'op': 'Sigmoid'}),
|
||||
**regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}
|
||||
|
||||
edges = [('input', 'mul', {'in': 0, 'out': 0}),
|
||||
('input', 'sigmoid', {'in': 0, 'out': 0}),
|
||||
('sigmoid', 'mul', {'in': 1, 'out': 0}),
|
||||
('mul', 'result', {'in': 0, 'out': 0})]
|
||||
|
||||
def test_swish_with_sigmoid_without_beta_test(self):
|
||||
graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
|
||||
|
||||
graph_ref = build_graph(ref_nodes, ref_edges)
|
||||
graph.stage = 'front'
|
||||
|
||||
SwishWithSigmoidWithoutBeta().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
|
||||
graph.get_op_nodes(name='final_mul')[0].op == 'Swish')
|
||||
|
||||
def test_swish_with_sigmoid_without_beta_different_tensors(self):
|
||||
graph = build_graph_with_edge_attrs({
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('input_2', {'type': 'Parameter'}),
|
||||
**regular_op('sigmoid', {'op': 'Sigmoid'}),
|
||||
**regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}, [('input_2', 'mul', {'in': 0, 'out': 0}),
|
||||
('input', 'sigmoid', {'in': 0, 'out': 0}),
|
||||
('sigmoid', 'mul', {'in': 1, 'out': 0}),
|
||||
('mul', 'result', {'in': 0, 'out': 0})], {})
|
||||
|
||||
graph_ref = graph.copy()
|
||||
graph.stage = 'front'
|
||||
|
||||
SwishWithSigmoidWithoutBeta().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
|
||||
class SwishWithSigmoidWithBetaTest(unittest.TestCase):
|
||||
nodes = {
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('beta', {'type': 'Parameter'}),
|
||||
**regular_op('mul_beta', {'op': 'Mul'}),
|
||||
**regular_op('sigmoid', {'op': 'Sigmoid'}),
|
||||
**regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}
|
||||
|
||||
edges = [('input', 'mul_beta', {'in': 0, 'out': 0}),
|
||||
('input', 'mul_2', {'in': 0, 'out': 0}),
|
||||
('beta', 'mul_beta', {'in': 1, 'out': 0}),
|
||||
('mul_beta', 'sigmoid', {'in': 0, 'out': 0}),
|
||||
('sigmoid', 'mul_2', {'in': 1, 'out': 0}),
|
||||
('mul_2', 'result', {'in': 0, 'out': 0})]
|
||||
|
||||
def test_swish_with_sigmoid_with_beta_test(self):
|
||||
graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
|
||||
|
||||
new_ref_nodes = ref_nodes.copy()
|
||||
new_ref_nodes.update(**regular_op('beta', {'type': 'Parameter'}))
|
||||
|
||||
graph_ref = build_graph(new_ref_nodes, ref_edges + [('beta', 'swish')])
|
||||
graph.stage = 'front'
|
||||
|
||||
SwishWithSigmoidWithBeta().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
||||
self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
|
||||
graph.get_op_nodes(name='final_mul')[0].op == 'Swish')
|
||||
|
||||
def test_swish_with_sigmoid_with_beta_different_tensors(self):
|
||||
graph = build_graph_with_edge_attrs({
|
||||
**regular_op('input', {'type': 'Parameter'}),
|
||||
**regular_op('input_2', {'type': 'Parameter'}),
|
||||
**regular_op('beta', {'type': 'Parameter'}),
|
||||
**regular_op('mul_beta', {'op': 'Mul'}),
|
||||
**regular_op('sigmoid', {'op': 'Sigmoid'}),
|
||||
**regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
|
||||
**result('result'),
|
||||
}, [('input', 'mul_beta', {'in': 0, 'out': 0}),
|
||||
('input_2', 'mul_2', {'in': 0, 'out': 0}),
|
||||
('beta', 'mul_beta', {'in': 1, 'out': 0}),
|
||||
('mul_beta', 'sigmoid', {'in': 0, 'out': 0}),
|
||||
('sigmoid', 'mul_2', {'in': 1, 'out': 0}),
|
||||
('mul_2', 'result', {'in': 0, 'out': 0})], {})
|
||||
|
||||
graph_ref = graph.copy()
|
||||
graph.stage = 'front'
|
||||
|
||||
SwishWithSigmoidWithBeta().find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result')
|
||||
self.assertTrue(flag, resp)
|
@ -1,115 +0,0 @@
|
||||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
from extensions.front.onnx.quantize_dequantize_linear import QuantizeDequantizeLinear
|
||||
from mo.utils.ir_engine.compare_graphs import compare_graphs
|
||||
from unit_tests.utils.graph import build_graph
|
||||
|
||||
# quantize and dequantize share tensors with scale/zp
|
||||
nodes0_attributes = {
|
||||
'input': {'kind': 'op', 'op': 'AnyOp'},
|
||||
'quantize': {'kind': 'op', 'op': 'QuantizeLinear'},
|
||||
'dequantize': {'kind': 'op', 'op': 'DequantizeLinear'},
|
||||
'scale_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'zerop_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'out': {'kind': 'op', 'op': 'AnyOp'},
|
||||
}
|
||||
|
||||
# quantize and dequantize do not share tensors with scale/zp
|
||||
nodes1_attributes = {
|
||||
'input': {'kind': 'op', 'op': 'AnyOp'},
|
||||
'quantize': {'kind': 'op', 'op': 'QuantizeLinear'},
|
||||
'dequantize': {'kind': 'op', 'op': 'DequantizeLinear'},
|
||||
'scale_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'zerop_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'scale_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'zerop_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'out': {'kind': 'op', 'op': 'AnyOp'},
|
||||
}
|
||||
|
||||
nodes_ref_attributes = {
|
||||
'input': {'kind': 'op', 'op': 'AnyOp'},
|
||||
'fq': {'kind': 'op', 'op': 'FakeQuantize'},
|
||||
'min_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'max_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
|
||||
'out': {'kind': 'op', 'op': 'AnyOp'},
|
||||
}
|
||||
|
||||
|
||||
class TestQuantizeDeQuantize2FakeQuantize(unittest.TestCase):
|
||||
|
||||
def test_quantizedequantize2fakequantize_0(self):
|
||||
# testing the code path with uint8 zero-point
|
||||
graph = build_graph(nodes1_attributes,
|
||||
[('input', 'quantize'),
|
||||
('quantize', 'dequantize'),
|
||||
('scale_param_q', 'quantize'),
|
||||
('zerop_param_q', 'quantize'),
|
||||
('scale_param_dq', 'dequantize'),
|
||||
('zerop_param_dq', 'dequantize'),
|
||||
('dequantize', 'out'),
|
||||
],
|
||||
{'scale_param_q': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)},
|
||||
'zerop_param_q': {'shape': np.array([1]), 'value': np.uint8(0)},
|
||||
'scale_param_dq': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)},
|
||||
'zerop_param_dq': {'shape': np.array([1]), 'value': np.uint8(0)},
|
||||
}, nodes_with_edges_only=True)
|
||||
|
||||
graph_ref = build_graph(nodes_ref_attributes,
|
||||
[('input', 'fq', {'in': 0}),
|
||||
('min_param', 'fq', {'out': 0, 'in': 1}),
|
||||
('min_param', 'fq', {'out': 0, 'in': 3}),
|
||||
('max_param', 'fq', {'out': 0, 'in': 2}),
|
||||
('max_param', 'fq', {'out': 0, 'in': 4}),
|
||||
('fq', 'out'),
|
||||
],
|
||||
{'fq': {'levels': 256},
|
||||
'min_param': {'value': np.float32(0.0)},
|
||||
'max_param': {'value': np.float32(1.0)},
|
||||
}, nodes_with_edges_only=True)
|
||||
|
||||
graph.stage = 'front'
|
||||
tested_class = QuantizeDequantizeLinear()
|
||||
tested_class.find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_quantizedequantize2fakequantize_1(self):
|
||||
# testing the code path with int8 zero-point
|
||||
graph = build_graph(nodes0_attributes,
|
||||
[('input', 'quantize'),
|
||||
('quantize', 'dequantize'),
|
||||
('scale_param', 'quantize'),
|
||||
('zerop_param', 'quantize'),
|
||||
('scale_param', 'dequantize'),
|
||||
('zerop_param', 'dequantize'),
|
||||
('dequantize', 'out'),
|
||||
],
|
||||
{'scale_param': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)},
|
||||
'zerop_param': {'shape': np.array([1]), 'value': np.int8(0)},
|
||||
}, nodes_with_edges_only=True)
|
||||
|
||||
graph_ref = build_graph(nodes_ref_attributes,
|
||||
[('input', 'fq', {'in': 0}),
|
||||
('min_param', 'fq', {'out': 0, 'in': 1}),
|
||||
('min_param', 'fq', {'out': 0, 'in': 3}),
|
||||
('max_param', 'fq', {'out': 0, 'in': 2}),
|
||||
('max_param', 'fq', {'out': 0, 'in': 4}),
|
||||
('fq', 'out'),
|
||||
],
|
||||
{'fq': {'levels': 256},
|
||||
'min_param': {'value': np.float32(-128.0 / 255)},
|
||||
'max_param': {'value': np.float32(127.0 / 255)},
|
||||
}, nodes_with_edges_only=True)
|
||||
|
||||
graph.stage = 'front'
|
||||
tested_class = QuantizeDequantizeLinear()
|
||||
tested_class.find_and_replace_pattern(graph)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
@ -211,3 +211,30 @@ class TensorContentParsing(unittest.TestCase):
|
||||
with self.assertLogs(log.getLogger(), level="ERROR") as cm:
|
||||
result = tf_tensor_content(pb_tensor.dtype, shape, pb_tensor)
|
||||
self.assertEqual([warning_message, warning_message], cm.output)
|
||||
|
||||
def test_empty_value(self):
|
||||
pb_tensor = PB({
|
||||
'dtype': 1,
|
||||
'float_val': []
|
||||
})
|
||||
|
||||
shape = int64_array([1, 1, 0])
|
||||
tf_dtype = pb_tensor.dtype
|
||||
ref = np.array([[[]]], dtype=np.float32)
|
||||
res = tf_tensor_content(tf_dtype, shape, pb_tensor)
|
||||
|
||||
self.assertEqual(res.shape, ref.shape)
|
||||
self.assertTrue(np.all(res == ref))
|
||||
|
||||
def test_scalar_value(self):
|
||||
pb_tensor = PB({
|
||||
'dtype': 3,
|
||||
'int_val': 4
|
||||
})
|
||||
|
||||
shape = int64_array([])
|
||||
tf_dtype = pb_tensor.dtype
|
||||
ref = np.array(4, dtype=np.int32)
|
||||
res = tf_tensor_content(tf_dtype, shape, pb_tensor)
|
||||
|
||||
self.assertEqual(ref, res)
|
||||
|
@ -8,7 +8,7 @@ set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_OLD ${CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY}
|
||||
set(CMAKE_PDB_OUTPUT_DIRECTORY_OLD ${CMAKE_PDB_OUTPUT_DIRECTORY})
|
||||
|
||||
set(PYTHON_VERSION python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
|
||||
message("Python version=${PYTHON_VERSION}")
|
||||
message(STATUS "Python version=${PYTHON_VERSION}")
|
||||
|
||||
if(WIN32)
|
||||
set(PYTHON_BRIDGE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$<CONFIG>/python_api/${PYTHON_VERSION}/)
|
||||
|
@ -45,6 +45,7 @@ namespace ngraph
|
||||
|
||||
const std::unordered_set<std::string>& get_names() const;
|
||||
void set_names(const std::unordered_set<std::string>& names);
|
||||
void add_names(const std::unordered_set<std::string>& names);
|
||||
void set_tensor_type(const element::Type& element_type, const PartialShape& pshape);
|
||||
void set_element_type(const element::Type& elemenet_type);
|
||||
void set_partial_shape(const PartialShape& partial_shape);
|
||||
|
@ -19,8 +19,8 @@ namespace ngraph
|
||||
class NGRAPH_API Asinh : public util::UnaryElementwiseArithmetic
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"Asinh", 3};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
|
||||
/// \brief Constructs an Asinh operation.
|
||||
Asinh() = default;
|
||||
/// \brief Constructs an Asinh operation.
|
||||
|
@ -16,8 +16,8 @@ namespace ngraph
|
||||
class NGRAPH_API Cosh : public util::UnaryElementwiseArithmetic
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"Cosh", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
|
||||
/// \brief Constructs a hyperbolic cosine operation.
|
||||
Cosh() = default;
|
||||
/// \brief Constructs a hyperbolic cosine operation.
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace ngraph
|
||||
{
|
||||
//
|
||||
// In various places, like ConstantFolding and DynElimination, it is
|
||||
// In various places, like ConstantFolding, it is
|
||||
// useful to transform DynSlice by converting it to a sequence of ops:
|
||||
//
|
||||
// Slice (to do the basic slicing)
|
||||
|
@ -13,7 +13,8 @@ namespace ngraph
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_integral<T>::value, bool>::type = true>
|
||||
void asinh(const T* arg, T* out, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
@ -21,6 +22,16 @@ namespace ngraph
|
||||
out[i] = std::asinh(arg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_integral<T>::value, bool>::type = true>
|
||||
void asinh(const T* arg, T* out, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
out[i] = std::roundl(std::asinh(arg[i]));
|
||||
}
|
||||
}
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
||||
|
@ -13,7 +13,8 @@ namespace ngraph
|
||||
{
|
||||
namespace reference
|
||||
{
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_integral<T>::value, bool>::type = true>
|
||||
void cosh(const T* arg, T* out, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
@ -21,6 +22,16 @@ namespace ngraph
|
||||
out[i] = std::cosh(arg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_integral<T>::value, bool>::type = true>
|
||||
void cosh(const T* arg, T* out, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
out[i] = std::roundl(std::cosh(arg[i]));
|
||||
}
|
||||
}
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
||||
|
@ -123,6 +123,14 @@ void descriptor::Tensor::set_names(const std::unordered_set<std::string>& names)
|
||||
m_names = names;
|
||||
}
|
||||
|
||||
void descriptor::Tensor::add_names(const std::unordered_set<std::string>& names)
|
||||
{
|
||||
for (const auto& name : names)
|
||||
{
|
||||
m_names.insert(name);
|
||||
}
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& out, const descriptor::Tensor& tensor)
|
||||
{
|
||||
std::string names;
|
||||
|
@ -167,11 +167,9 @@ void ngraph::replace_node(std::shared_ptr<Node> target,
|
||||
// Change I's connected upstream output to O_rep
|
||||
for (size_t i = 0; i < target->get_output_size(); i++)
|
||||
{
|
||||
for (auto& input : target->output(i).get_target_inputs())
|
||||
{
|
||||
input.replace_source_output(replacement->output(output_order[i]));
|
||||
}
|
||||
target->output(i).replace(replacement->output(output_order[i]));
|
||||
}
|
||||
|
||||
replacement->add_node_control_dependents(target);
|
||||
replacement->add_node_control_dependencies(target);
|
||||
target->clear_control_dependents();
|
||||
@ -912,7 +910,15 @@ bool ngraph::replace_output_update_name(Output<Node> output, const Output<Node>&
|
||||
replacement.get_tensor().set_name(output.get_node()->get_friendly_name());
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
// Save replacement tensor names before replacement as they will be
|
||||
// overrided by the output tensor names
|
||||
auto output_names = replacement.get_tensor_ptr()->get_names();
|
||||
output.replace(replacement);
|
||||
|
||||
// Restore back original replacement tensor names
|
||||
replacement.get_tensor().add_names(output_names);
|
||||
|
||||
copy_runtime_info({replacement.get_node_shared_ptr(), output.get_node_shared_ptr()},
|
||||
replacement.get_node_shared_ptr());
|
||||
return true;
|
||||
|
@ -76,6 +76,7 @@ namespace ngraph
|
||||
{
|
||||
input.replace_source_output(replacement);
|
||||
}
|
||||
replacement.get_tensor_ptr()->set_names(get_tensor_ptr()->get_names());
|
||||
}
|
||||
|
||||
using RTMap = std::map<std::string, std::shared_ptr<Variant>>;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "itt.hpp"
|
||||
#include "ngraph/op/asinh.hpp"
|
||||
#include "ngraph/op/util/elementwise_args.hpp"
|
||||
#include "ngraph/runtime/host_tensor.hpp"
|
||||
#include "ngraph/runtime/reference/asinh.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
@ -14,7 +15,7 @@
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
constexpr NodeTypeInfo op::v3::Asinh::type_info;
|
||||
NGRAPH_RTTI_DEFINITION(op::v3::Asinh, "Asinh", 3, util::UnaryElementwiseArithmetic);
|
||||
|
||||
op::v3::Asinh::Asinh(const Output<Node>& arg)
|
||||
: UnaryElementwiseArithmetic(arg)
|
||||
@ -32,25 +33,26 @@ shared_ptr<Node> op::v3::Asinh::clone_with_new_inputs(const OutputVector& new_ar
|
||||
namespace asinhop
|
||||
{
|
||||
template <element::Type_t ET>
|
||||
bool evaluate(const HostTensorPtr& arg0, const HostTensorPtr& out)
|
||||
inline bool evaluate(const HostTensorPtr& arg0, const HostTensorPtr& out, const size_t count)
|
||||
{
|
||||
runtime::reference::asinh(
|
||||
arg0->get_data_ptr<ET>(), out->get_data_ptr<ET>(), shape_size(arg0->get_shape()));
|
||||
runtime::reference::asinh(arg0->get_data_ptr<ET>(), out->get_data_ptr<ET>(), count);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool evaluate_asinh(const HostTensorPtr& arg0, const HostTensorPtr& out)
|
||||
{
|
||||
bool rc = true;
|
||||
size_t count = shape_size(arg0->get_shape());
|
||||
out->set_unary(arg0);
|
||||
|
||||
switch (arg0->get_element_type())
|
||||
{
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, i32, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, i64, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, u32, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, u64, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, f16, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, f32, arg0, out);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, i32, arg0, out, count);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, i64, arg0, out, count);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, u32, arg0, out, count);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, u64, arg0, out, count);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, f16, arg0, out, count);
|
||||
NGRAPH_TYPE_CASE(evaluate_asinh, f32, arg0, out, count);
|
||||
default: rc = false; break;
|
||||
}
|
||||
return rc;
|
||||
@ -65,7 +67,7 @@ bool op::v3::Asinh::evaluate(const HostTensorVector& outputs, const HostTensorVe
|
||||
|
||||
bool op::v3::Asinh::has_evaluate() const
|
||||
{
|
||||
NGRAPH_OP_SCOPE(v1_Asinh_has_evaluate);
|
||||
NGRAPH_OP_SCOPE(v3_Asinh_has_evaluate);
|
||||
switch (get_input_element_type(0))
|
||||
{
|
||||
case ngraph::element::i32:
|
||||
|
@ -88,8 +88,8 @@ void op::v1::BatchToSpace::validate_and_infer_types()
|
||||
if (data_rank.is_static())
|
||||
{
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
(data_rank.get_length() >= 4),
|
||||
"data input must have rank greater than or equal to 4. Got: ",
|
||||
(data_rank.get_length() >= 2),
|
||||
"data input must have rank greater or equal than 2. Got: ",
|
||||
data_rank.get_length());
|
||||
|
||||
if (inputs_same_ps.is_static())
|
||||
@ -197,7 +197,7 @@ namespace
|
||||
}
|
||||
auto data_shape = data->get_shape();
|
||||
auto data_rank = data_shape.size();
|
||||
if (!(data_rank == 4 || data_rank == 5))
|
||||
if (data_rank < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -346,7 +346,6 @@ bool ngraph::op::v1::BatchToSpace::evaluate(const HostTensorVector& outputs,
|
||||
bool ngraph::op::v1::BatchToSpace::has_evaluate() const
|
||||
{
|
||||
NGRAPH_OP_SCOPE(v1_BatchToSpace_has_evaluate);
|
||||
return !get_input_partial_shape(0).is_dynamic() &&
|
||||
(get_input_shape(0).size() == 4 || get_input_shape(0).size() == 5) &&
|
||||
return !get_input_partial_shape(0).is_dynamic() && get_input_shape(0).size() >= 2 &&
|
||||
get_input_shape(0).size() <= shape_size(get_input_shape(1));
|
||||
}
|
||||
|
@ -5,16 +5,16 @@
|
||||
#include "itt.hpp"
|
||||
|
||||
#include "ngraph/op/cosh.hpp"
|
||||
#include "ngraph/op/multiply.hpp"
|
||||
#include "ngraph/op/sinh.hpp"
|
||||
|
||||
#include "ngraph/runtime/host_tensor.hpp"
|
||||
#include "ngraph/runtime/reference/cosh.hpp"
|
||||
|
||||
#include "ngraph/validation_util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
constexpr NodeTypeInfo op::Cosh::type_info;
|
||||
NGRAPH_RTTI_DEFINITION(op::v0::Cosh, "Cosh", 0, util::UnaryElementwiseArithmetic);
|
||||
|
||||
op::Cosh::Cosh(const Output<Node>& arg)
|
||||
: UnaryElementwiseArithmetic(arg)
|
||||
@ -68,6 +68,7 @@ namespace coshop
|
||||
bool op::Cosh::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const
|
||||
{
|
||||
NGRAPH_OP_SCOPE(v0_Cosh_evaluate);
|
||||
NGRAPH_CHECK(validate_host_tensor_vector(outputs, 1) && validate_host_tensor_vector(inputs, 1));
|
||||
return coshop::evaluate_cosh(inputs[0], outputs[0], shape_size(get_output_shape(0)));
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,13 @@ void op::util::ScatterNDBase::validate_and_infer_types()
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
inputs_rank.is_dynamic() || indices_rank.is_dynamic() ||
|
||||
indices_shape[indices_rank.get_length() - 1].is_dynamic() ||
|
||||
indices_shape[indices_rank.get_length() - 1].get_length() <=
|
||||
inputs_rank.get_length(),
|
||||
"Last dimension of indices can be at most the rank of inputs");
|
||||
|
||||
if (inputs_rank.is_static() && indices_rank.is_static() && updates_rank.is_static())
|
||||
if (inputs_rank.is_static() && indices_rank.is_static() && updates_rank.is_static() &&
|
||||
indices_shape[indices_rank.get_length() - 1].is_static())
|
||||
{
|
||||
auto expected_updates_rank = indices_rank.get_length() + inputs_rank.get_length() -
|
||||
indices_shape[indices_rank.get_length() - 1].get_length() - 1;
|
||||
|
@ -3,9 +3,6 @@
|
||||
#
|
||||
|
||||
if(NOT WIN32)
|
||||
message(${CMAKE_SOURCE_DIR}/thirdparty/cmake_static_protobuf)
|
||||
message(BINARY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# There seems no suitable other way to identify exact output binary name for libprotobuf
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
# Use 'protobufd' directly as it is done in the same way in protobuf cmake files
|
||||
@ -15,8 +12,6 @@ if(NOT WIN32)
|
||||
set(PROTOBUF_STATIC_LIB_OUTPUT ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_STATIC_LIBRARY_PREFIX}protobuf${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif()
|
||||
|
||||
message("Static protobuf lib: ${PROTOBUF_STATIC_LIB_OUTPUT}")
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libprotobuf_static)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
|
@ -29,8 +29,6 @@ else()
|
||||
set(PDPD_PROTOC_EXECUTABLE $<TARGET_FILE:protoc>)
|
||||
endif()
|
||||
|
||||
message("PDPD_PROTOC_EXECUTABLE is [${PDPD_PROTOC_EXECUTABLE}]")
|
||||
|
||||
foreach(INFILE ${proto_files})
|
||||
get_filename_component(FILE_DIR ${INFILE} DIRECTORY)
|
||||
get_filename_component(FILE_WE ${INFILE} NAME_WE)
|
||||
|
@ -19,7 +19,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pybind11 EXCLUDE_FROM_ALL)
|
||||
|
||||
# PYTHON_VERSION_MAJOR and PYTHON_VERSION_MINOR are defined inside pybind11
|
||||
set(PYTHON_VERSION python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
|
||||
message("Python version=${PYTHON_VERSION}")
|
||||
message(STATUS "Python version=${PYTHON_VERSION}")
|
||||
|
||||
set(LIBRARY_OUTPUT_DIRECTORY_BIN ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
if(OpenVINO_SOURCE_DIR)
|
||||
|
@ -75,13 +75,10 @@ set(SRC
|
||||
op_eval/strided_slice.cpp
|
||||
op_eval/transpose.cpp
|
||||
op_eval/variadic_split.cpp
|
||||
op_is.cpp
|
||||
opset1.cpp
|
||||
partial_shape.cpp
|
||||
pass_config.cpp
|
||||
pass_liveness.cpp
|
||||
pass_manager.cpp
|
||||
pass_shape_relevance.cpp
|
||||
pattern.cpp
|
||||
provenance.cpp
|
||||
replace_node.cpp
|
||||
@ -95,6 +92,7 @@ set(SRC
|
||||
type_prop/adaptive_avg_pool.cpp
|
||||
type_prop/adaptive_max_pool.cpp
|
||||
type_prop/asin.cpp
|
||||
type_prop/asinh.cpp
|
||||
type_prop/assign.cpp
|
||||
type_prop/atan.cpp
|
||||
type_prop/avg_pool.cpp
|
||||
@ -112,6 +110,7 @@ set(SRC
|
||||
type_prop/convolution.cpp
|
||||
type_prop/convolution_backprop_data.cpp
|
||||
type_prop/cos.cpp
|
||||
type_prop/cosh.cpp
|
||||
type_prop/ctc_greedy_decoder.cpp
|
||||
type_prop/ctc_greedy_decoder_seq_len.cpp
|
||||
type_prop/ctc_loss.cpp
|
||||
@ -231,6 +230,7 @@ set(SRC
|
||||
visitors/value_map.cpp
|
||||
visitors/op/adaptive_avg_pool.cpp
|
||||
visitors/op/adaptive_max_pool.cpp
|
||||
visitors/op/asinh.cpp
|
||||
visitors/op/atan.cpp
|
||||
visitors/op/batch_norm.cpp
|
||||
visitors/op/batch_to_space.cpp
|
||||
@ -241,6 +241,7 @@ set(SRC
|
||||
visitors/op/convert.cpp
|
||||
visitors/op/convolution_backprop.cpp
|
||||
visitors/op/cos.cpp
|
||||
visitors/op/cosh.cpp
|
||||
visitors/op/cum_sum.cpp
|
||||
visitors/op/deformable_convolution.cpp
|
||||
visitors/op/deformable_psroi_pooling.cpp
|
||||
|
@ -49,3 +49,18 @@ NGRAPH_TEST(${BACKEND_NAME}, asinh)
|
||||
test_case.add_expected_output<float>(shape, expected);
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, asinh_i32)
|
||||
{
|
||||
Shape shape{11};
|
||||
auto A = make_shared<op::Parameter>(element::i32, shape);
|
||||
auto f = make_shared<Function>(make_shared<op::Asinh>(A), ParameterVector{A});
|
||||
|
||||
vector<int> input{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
|
||||
vector<int> expected{-2, -2, -2, -1, -1, 0, 1, 1, 2, 2, 2};
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(f);
|
||||
test_case.add_input<int>(input);
|
||||
test_case.add_expected_output<int>(shape, expected);
|
||||
test_case.run();
|
||||
}
|
||||
|
@ -79,6 +79,27 @@ NGRAPH_TEST_P(${BACKEND_NAME}, BatchToSpaceTestFloat, BatchToSpaceTestFloatCases
|
||||
BatchToSpaceTestExecute(GetParam());
|
||||
}
|
||||
|
||||
const test::NDArray<float, 2> input_with_shape_4x3(
|
||||
{{1.0f, 2.0f, 3.0f},
|
||||
{4.0f, 5.0f, 6.0f},
|
||||
{7.0f, 8.0f, 9.0f},
|
||||
{10.0f, 11.0f, 12.0f}});
|
||||
|
||||
const test::NDArray<int64_t, 1> zero_crops_2d({0, 0});
|
||||
|
||||
NGRAPH_INSTANTIATE_TEST_SUITE_P(
|
||||
${BACKEND_NAME},
|
||||
batch_to_space_2d_without_crops,
|
||||
BatchToSpaceTestFloat,
|
||||
testing::Values(
|
||||
BatchToSpaceParams<float>{input_with_shape_4x3,
|
||||
test::NDArray<int64_t, 1>({1, 2}),
|
||||
zero_crops_2d,
|
||||
zero_crops_2d,
|
||||
test::NDArray<float, 2>(
|
||||
{{1.0f, 7.0f, 2.0f, 8.0f, 3.0f, 9.0f},
|
||||
{4.0f, 10.0f, 5.0f, 11.0f, 6.0f, 12.0f}})}));
|
||||
|
||||
const test::NDArray<float, 4> input_with_shape_4x1x1x3(
|
||||
{{{{1.0f, 2.0f, 3.0f}}},
|
||||
{{{4.0f, 5.0f, 6.0f}}},
|
||||
|
@ -2,23 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
// clang-format off
|
||||
#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
|
||||
#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
|
||||
#endif
|
||||
|
||||
#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
|
||||
#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "util/engine/test_engines.hpp"
|
||||
@ -31,7 +14,7 @@ using namespace ngraph;
|
||||
static string s_manifest = "${MANIFEST}";
|
||||
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, cosh)
|
||||
NGRAPH_TEST(${BACKEND_NAME}, cosh_float)
|
||||
{
|
||||
Shape shape{6};
|
||||
auto A = make_shared<op::Parameter>(element::f32, shape);
|
||||
@ -49,3 +32,16 @@ NGRAPH_TEST(${BACKEND_NAME}, cosh)
|
||||
test_case.add_expected_output<float>(shape, expected);
|
||||
test_case.run();
|
||||
}
|
||||
|
||||
NGRAPH_TEST(${BACKEND_NAME}, cosh_int)
|
||||
{
|
||||
Shape shape{5};
|
||||
auto A = make_shared<op::Parameter>(element::i32, shape);
|
||||
auto f = make_shared<Function>(make_shared<op::Cosh>(A), ParameterVector{A});
|
||||
|
||||
auto test_case = test::TestCase<TestEngine>(f);
|
||||
test_case.add_input<int32_t>({1, 5, 2, 3, 3});
|
||||
test_case.add_expected_output<int32_t>(shape,
|
||||
{2, 74, 4, 10, 10});
|
||||
test_case.run();
|
||||
}
|
||||
|
@ -1,142 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/pass/constant_folding.hpp"
|
||||
#include "ngraph/pass/dyn_elimination.hpp"
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "pass/opset0_downgrade.hpp"
|
||||
#include "util/all_close_f.hpp"
|
||||
#include "util/test_tools.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
using namespace std;
|
||||
|
||||
TEST(dyn_elimination, transpose)
|
||||
{
|
||||
Shape shape_in{2, 4, 6, 8};
|
||||
auto param = make_shared<op::Parameter>(element::boolean, shape_in);
|
||||
|
||||
auto constant_perm =
|
||||
make_shared<op::Constant>(element::i64, Shape{4}, vector<int64_t>{2, 3, 1, 0});
|
||||
|
||||
auto transpose = make_shared<op::Transpose>(param, constant_perm);
|
||||
|
||||
auto f = make_shared<Function>(transpose, ParameterVector{param});
|
||||
|
||||
pass::Manager pass_manager;
|
||||
pass_manager.register_pass<pass::DynElimination>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Transpose>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::v1::Reshape>(f), 1);
|
||||
|
||||
auto new_reshape =
|
||||
as_type_ptr<op::v1::Reshape>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||
ASSERT_TRUE(new_reshape);
|
||||
|
||||
ASSERT_EQ(new_reshape->get_input_order(), (AxisVector{2, 3, 1, 0}));
|
||||
ASSERT_EQ(new_reshape->get_output_shape(0), (Shape{6, 8, 4, 2}));
|
||||
ASSERT_EQ(new_reshape->get_output_element_type(0), element::boolean);
|
||||
}
|
||||
|
||||
// For now, we can't handle the case where the input has dynamic shapes,
|
||||
// because the classic Reshape op demands a Shape. Probably won't be able to
|
||||
// deal with this until/unless we make a "StaticTranspose". Just make sure
|
||||
// we don't crash or mangle the graph.
|
||||
TEST(dyn_elimination, transpose_dyn_shape)
|
||||
{
|
||||
PartialShape shape_in{2, 4, Dimension::dynamic(), 8};
|
||||
|
||||
auto param = make_shared<op::Parameter>(element::boolean, shape_in);
|
||||
|
||||
auto constant_perm =
|
||||
make_shared<op::Constant>(element::i64, Shape{4}, vector<int64_t>{2, 3, 1, 0});
|
||||
|
||||
auto transpose = make_shared<op::Transpose>(param, constant_perm);
|
||||
|
||||
auto f = make_shared<Function>(transpose, ParameterVector{param});
|
||||
|
||||
pass::Manager pass_manager;
|
||||
pass_manager.register_pass<pass::DynElimination>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Transpose>(f), 1);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto new_transpose =
|
||||
as_type_ptr<op::Transpose>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||
ASSERT_TRUE(new_transpose);
|
||||
|
||||
ASSERT_EQ(new_transpose->get_output_element_type(0), element::boolean);
|
||||
ASSERT_TRUE(new_transpose->get_output_partial_shape(0).relaxes(
|
||||
PartialShape{Dimension::dynamic(), 8, 4, 2}));
|
||||
}
|
||||
|
||||
TEST(dyn_elimination, range)
|
||||
{
|
||||
auto constant_start = make_shared<op::Constant>(element::i64, Shape{}, vector<int64_t>{0});
|
||||
auto constant_stop = make_shared<op::Constant>(element::i64, Shape{}, vector<int64_t>{5});
|
||||
auto constant_step = make_shared<op::Constant>(element::i64, Shape{}, vector<int64_t>{2});
|
||||
|
||||
auto range = make_shared<op::Range>(constant_start, constant_stop, constant_step);
|
||||
|
||||
ASSERT_EQ(range->get_element_type(), element::i64);
|
||||
ASSERT_EQ(range->get_shape(), (Shape{3}));
|
||||
|
||||
auto f = make_shared<Function>(range, ParameterVector{});
|
||||
|
||||
pass::Manager pass_manager;
|
||||
pass_manager.register_pass<pass::DynElimination>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Range>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto replacement =
|
||||
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||
|
||||
ASSERT_NE(replacement, nullptr);
|
||||
ASSERT_EQ(replacement->get_element_type(), element::i64);
|
||||
ASSERT_EQ(replacement->get_shape(), (Shape{3}));
|
||||
|
||||
auto vals = replacement->get_vector<int64_t>();
|
||||
|
||||
ASSERT_EQ(vals, (vector<int64_t>{0, 2, 4}));
|
||||
}
|
||||
|
||||
TEST(dyn_elimination, range_f64)
|
||||
{
|
||||
auto constant_start = make_shared<op::Constant>(element::f64, Shape{}, vector<double>{-0.5});
|
||||
auto constant_stop = make_shared<op::Constant>(element::f64, Shape{}, vector<double>{2});
|
||||
auto constant_step = make_shared<op::Constant>(element::f64, Shape{}, vector<double>{0.25});
|
||||
|
||||
auto range = make_shared<op::Range>(constant_start, constant_stop, constant_step);
|
||||
|
||||
ASSERT_EQ(range->get_element_type(), element::f64);
|
||||
ASSERT_EQ(range->get_shape(), (Shape{10}));
|
||||
|
||||
auto f = make_shared<Function>(range, ParameterVector{});
|
||||
|
||||
pass::Manager pass_manager;
|
||||
pass_manager.register_pass<pass::DynElimination>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
ASSERT_EQ(count_ops_of_type<op::Range>(f), 0);
|
||||
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||
|
||||
auto replacement =
|
||||
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||
|
||||
ASSERT_NE(replacement, nullptr);
|
||||
ASSERT_EQ(replacement->get_element_type(), element::f64);
|
||||
ASSERT_EQ(replacement->get_shape(), (Shape{10}));
|
||||
|
||||
auto vals = replacement->get_vector<double>();
|
||||
|
||||
ASSERT_TRUE(test::all_close_f(
|
||||
vals, vector<double>{-0.5, -0.25, 0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75}));
|
||||
}
|
@ -1,577 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/op/util/op_types.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
#include "op/convolution.hpp"
|
||||
#include "op/group_conv.hpp"
|
||||
#include "util/test_tools.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
namespace
|
||||
{
|
||||
void op_is_Abs()
|
||||
{
|
||||
op::Abs node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Acos()
|
||||
{
|
||||
op::Acos node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Asin()
|
||||
{
|
||||
op::Asin node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Atan()
|
||||
{
|
||||
op::Atan node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_AvgPool()
|
||||
{
|
||||
op::AvgPool node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_BatchNormInference()
|
||||
{
|
||||
op::v0::BatchNormInference node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Broadcast()
|
||||
{
|
||||
op::v1::Broadcast node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Ceiling()
|
||||
{
|
||||
op::Ceiling node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Clamp()
|
||||
{
|
||||
op::Clamp node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Concat()
|
||||
{
|
||||
op::Concat node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Constant()
|
||||
{
|
||||
op::Constant node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Convert()
|
||||
{
|
||||
op::Convert node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Convolution()
|
||||
{
|
||||
op::v0::Convolution node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_ConvolutionBackpropData()
|
||||
{
|
||||
op::v0::ConvolutionBackpropData node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Cos()
|
||||
{
|
||||
op::Cos node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Cosh()
|
||||
{
|
||||
op::Cosh node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_CumSum()
|
||||
{
|
||||
op::CumSum node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_DepthToSpace()
|
||||
{
|
||||
op::DepthToSpace node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Elu()
|
||||
{
|
||||
op::Elu node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Erf()
|
||||
{
|
||||
op::Erf node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Exp()
|
||||
{
|
||||
op::Exp node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_FakeQuantize()
|
||||
{
|
||||
op::FakeQuantize node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Floor()
|
||||
{
|
||||
op::Floor node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_GRN()
|
||||
{
|
||||
op::GRN node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Gather()
|
||||
{
|
||||
op::v1::Gather node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Gelu()
|
||||
{
|
||||
op::Gelu node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_GroupConvolution()
|
||||
{
|
||||
op::v0::GroupConvolution node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_GroupConvolutionBackpropData()
|
||||
{
|
||||
op::v0::GroupConvolutionBackpropData node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_HardSigmoid()
|
||||
{
|
||||
op::HardSigmoid node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Interpolate()
|
||||
{
|
||||
op::v0::Interpolate node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Log()
|
||||
{
|
||||
op::Log node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_LRN()
|
||||
{
|
||||
op::LRN node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_LSTMSequence()
|
||||
{
|
||||
op::v0::LSTMSequence node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_MatMul()
|
||||
{
|
||||
op::MatMul node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_NormalizeL2()
|
||||
{
|
||||
op::v0::NormalizeL2 node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_MVN()
|
||||
{
|
||||
op::MVN node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Negative()
|
||||
{
|
||||
op::Negative node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Parameter()
|
||||
{
|
||||
op::Parameter node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_PRelu()
|
||||
{
|
||||
op::PRelu node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_PriorBox()
|
||||
{
|
||||
op::PriorBox node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Range()
|
||||
{
|
||||
op::Range node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Relu()
|
||||
{
|
||||
op::Relu node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Result()
|
||||
{
|
||||
op::Result node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_ReverseSequence()
|
||||
{
|
||||
op::ReverseSequence node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Selu()
|
||||
{
|
||||
op::Selu node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_ShapeOf()
|
||||
{
|
||||
op::ShapeOf node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_ShuffleChannels()
|
||||
{
|
||||
op::ShuffleChannels node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Sigmoid()
|
||||
{
|
||||
op::Sigmoid node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Sign()
|
||||
{
|
||||
op::Sign node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Sin()
|
||||
{
|
||||
op::Sin node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Sinh()
|
||||
{
|
||||
op::Sinh node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_SpaceToDepth()
|
||||
{
|
||||
op::SpaceToDepth node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Sqrt()
|
||||
{
|
||||
op::Sqrt node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_SquaredDifference()
|
||||
{
|
||||
op::SquaredDifference node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_TRUE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Squeeze()
|
||||
{
|
||||
op::Squeeze node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Tan()
|
||||
{
|
||||
op::Tan node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Tanh()
|
||||
{
|
||||
op::Tanh node;
|
||||
EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_TensorIterator()
|
||||
{
|
||||
op::TensorIterator node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Tile()
|
||||
{
|
||||
op::v0::Tile node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Unsqueeze()
|
||||
{
|
||||
op::v0::Unsqueeze node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
|
||||
void op_is_Xor()
|
||||
{
|
||||
op::Xor node;
|
||||
EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node));
|
||||
EXPECT_FALSE(op::is_binary_elementwise_comparison(&node));
|
||||
EXPECT_TRUE(op::is_binary_elementwise_logical(&node));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(op_is, check)
|
||||
{
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
#define NGRAPH_OP(a, b) op_is_##a();
|
||||
#include "opset0_tbl.hpp"
|
||||
#undef NGRAPH_OP
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ngraph/log.hpp"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "ngraph/pass/visualize_tree.hpp"
|
||||
#include "pass/liveness.hpp"
|
||||
|
||||
#include "util/test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
namespace ng = ngraph;
|
||||
|
||||
TEST(liveness, constant)
|
||||
{
|
||||
Shape shape{1};
|
||||
auto c = op::Constant::create(element::i32, shape, {5});
|
||||
auto f = make_shared<Function>(make_shared<op::Negative>(c), ParameterVector{});
|
||||
|
||||
pass::Manager pass_manager;
|
||||
pass_manager.register_pass<pass::Liveness>();
|
||||
pass_manager.run_passes(f);
|
||||
|
||||
auto tmp = f->get_ordered_ops();
|
||||
vector<shared_ptr<Node>> sorted{tmp.begin(), tmp.end()};
|
||||
ASSERT_EQ(3, sorted.size());
|
||||
EXPECT_EQ(0, sorted[0]->liveness_new_list.size());
|
||||
EXPECT_EQ(0, sorted[0]->liveness_free_list.size());
|
||||
|
||||
// op::Negative is live on output to op::Result
|
||||
// op::Negative is new
|
||||
EXPECT_EQ(1, sorted[1]->liveness_new_list.size());
|
||||
EXPECT_EQ(0, sorted[1]->liveness_free_list.size());
|
||||
|
||||
// op::Negative is live on input to op::Result
|
||||
EXPECT_EQ(0, sorted[2]->liveness_new_list.size());
|
||||
// op::Negative is freed
|
||||
EXPECT_EQ(1, sorted[2]->liveness_free_list.size());
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "pass/shape_relevance.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace ngraph;
|
||||
using namespace std;
|
||||
|
||||
TEST(shape_relevance, simple)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
auto param1 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
auto x = make_shared<op::v1::Add>(param0, param1);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0, param1});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
ASSERT_FALSE(param1->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_direct)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
auto param1 = make_shared<op::Parameter>(element::i64, Shape{4});
|
||||
auto x = make_shared<op::v1::Reshape>(param0, param1, true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0, param1});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
ASSERT_TRUE(param1->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_indirect)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
auto param1 = make_shared<op::Parameter>(element::i64, Shape{4});
|
||||
auto param2 = make_shared<op::Parameter>(element::i64, Shape{2});
|
||||
|
||||
auto c = make_shared<op::Concat>(NodeVector{param1, param2}, 0);
|
||||
auto x = make_shared<op::v1::Reshape>(param0, c, true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0, param1, param2});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
ASSERT_TRUE(param1->is_relevant_to_shapes());
|
||||
ASSERT_TRUE(param2->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_direct_v0)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto x = make_shared<op::v1::Reshape>(param0, make_shared<op::v0::ShapeOf>(param0), true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_direct_v3)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto x = make_shared<op::v1::Reshape>(param0, make_shared<op::v3::ShapeOf>(param0), true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_direct_i32_v3)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto x = make_shared<op::v1::Reshape>(
|
||||
param0, make_shared<op::v3::ShapeOf>(param0, element::i32), true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_indirect_v0)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto s = make_shared<op::v0::ShapeOf>(param0);
|
||||
auto r = make_shared<op::v1::Reverse>(
|
||||
s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX);
|
||||
auto x = make_shared<op::v1::Reshape>(param0, r, true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_indirect_v3)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto s = make_shared<op::v3::ShapeOf>(param0);
|
||||
auto r = make_shared<op::v1::Reverse>(
|
||||
s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX);
|
||||
auto x = make_shared<op::v1::Reshape>(param0, r, true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
||||
|
||||
TEST(shape_relevance, param_shape_of_indirect_i32_v3)
|
||||
{
|
||||
auto param0 = make_shared<op::Parameter>(element::f32, Shape{4, 6});
|
||||
|
||||
auto s = make_shared<op::v3::ShapeOf>(param0, element::i32);
|
||||
auto r = make_shared<op::v1::Reverse>(
|
||||
s, op::Constant::create(element::i64, {1}, {0}), op::v1::Reverse::Mode::INDEX);
|
||||
auto x = make_shared<op::v1::Reshape>(param0, r, true);
|
||||
|
||||
auto f = make_shared<Function>(x, ParameterVector{param0});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::ShapeRelevance>();
|
||||
manager.run_passes(f);
|
||||
|
||||
ASSERT_FALSE(param0->is_relevant_to_shapes());
|
||||
}
|
@ -15,7 +15,6 @@
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "ngraph/provenance.hpp"
|
||||
#include "pass/fused_op_decomposition.hpp"
|
||||
#include "util/provenance_enabler.hpp"
|
||||
|
||||
using namespace std;
|
||||
@ -380,61 +379,6 @@ TEST(provenance, builder)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(provenance, fused_copy_origin_tags)
|
||||
{
|
||||
test::ProvenanceEnabler provenance_enabler;
|
||||
|
||||
auto p1 = make_shared<op::Parameter>(element::f32, PartialShape{2, 3, 4});
|
||||
p1->add_provenance_tag("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});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::FusedOpDecomposition>();
|
||||
manager.run_passes(f);
|
||||
|
||||
traverse_nodes(f, [&](const std::shared_ptr<Node>& node) {
|
||||
auto tags = node->get_provenance_tags();
|
||||
if (node == p1)
|
||||
{
|
||||
EXPECT_EQ(tags.size(), 1);
|
||||
EXPECT_TRUE(tags.find("P1") != tags.end());
|
||||
}
|
||||
else if (node == r)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_TRUE(tags.find("G") != tags.end());
|
||||
EXPECT_TRUE(tags.find("<Decomposed from MVN>") != tags.end());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TEST(provenance, fused_decomposition_tag)
|
||||
{
|
||||
test::ProvenanceEnabler provenance_enabler;
|
||||
|
||||
auto p1 = make_shared<op::Parameter>(element::f32, PartialShape{2, 3, 4});
|
||||
auto fused_op = make_shared<op::MVN>(p1);
|
||||
auto result = make_shared<op::Result>(fused_op);
|
||||
auto f = make_shared<Function>(ResultVector{result}, ParameterVector{p1});
|
||||
|
||||
pass::Manager manager;
|
||||
manager.register_pass<pass::FusedOpDecomposition>();
|
||||
manager.run_passes(f);
|
||||
|
||||
const auto tag = "<Decomposed from MVN>";
|
||||
auto tag_check = [&tag](std::shared_ptr<ngraph::Node> node) {
|
||||
auto tags = node->get_provenance_tags();
|
||||
EXPECT_TRUE(tags.find(tag) != tags.end());
|
||||
};
|
||||
const auto decomposed_op = f->get_result()->get_input_node_shared_ptr(0);
|
||||
traverse_nodes(as_node_vector(decomposed_op->outputs()), tag_check, {p1});
|
||||
}
|
||||
|
||||
TEST(provenance, empty_group)
|
||||
{
|
||||
auto p1 = make_shared<op::Parameter>(element::i32, PartialShape{2, 3, 4});
|
||||
|
@ -108,3 +108,63 @@ TEST(replace_node, replace_nodes)
|
||||
ASSERT_EQ(z_replacement->get_input_node_shared_ptr(0), x_replacement);
|
||||
ASSERT_EQ(z_replacement->get_input_node_shared_ptr(1), mul);
|
||||
}
|
||||
|
||||
TEST(replace_node, simple_node_replacement)
|
||||
{
|
||||
auto param = std::make_shared<op::Parameter>(element::i64, Shape{1, 64});
|
||||
param->output(0).get_tensor().set_names({"a", "b"});
|
||||
auto relu = std::make_shared<op::Relu>(param);
|
||||
relu->output(0).get_tensor().set_names({"c", "d"});
|
||||
|
||||
auto new_relu = std::make_shared<op::Relu>(param);
|
||||
new_relu->output(0).get_tensor().set_names({"f"});
|
||||
replace_node(relu, new_relu);
|
||||
|
||||
ASSERT_EQ(new_relu->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"c", "d"}));
|
||||
}
|
||||
|
||||
TEST(replace_node, node_elimination)
|
||||
{
|
||||
auto param = std::make_shared<op::Parameter>(element::i64, Shape{1, 64});
|
||||
param->output(0).get_tensor().set_names({"a", "b"});
|
||||
auto relu1 = std::make_shared<op::Relu>(param);
|
||||
relu1->output(0).get_tensor().set_names({"c", "d"});
|
||||
auto relu2 = std::make_shared<op::Relu>(relu1);
|
||||
relu2->output(0).get_tensor().set_names({"e", "f"});
|
||||
|
||||
ASSERT_TRUE(replace_output_update_name(relu2->output(0), relu2->input_value(0)));
|
||||
ASSERT_EQ(relu1->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"c", "d", "e", "f"}));
|
||||
ASSERT_EQ(param->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"a", "b"}));
|
||||
}
|
||||
|
||||
TEST(replace_node, output_replacement)
|
||||
{
|
||||
auto param = std::make_shared<op::Parameter>(element::i64, Shape{1, 64});
|
||||
param->output(0).get_tensor().set_names({"a", "b"});
|
||||
auto relu = std::make_shared<op::Relu>(param);
|
||||
relu->output(0).get_tensor().set_names({"c", "d"});
|
||||
|
||||
auto new_relu = std::make_shared<op::Relu>(param);
|
||||
new_relu->output(0).get_tensor().set_names({"f"});
|
||||
|
||||
relu->output(0).replace(new_relu->output(0));
|
||||
|
||||
ASSERT_EQ(new_relu->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"c", "d"}));
|
||||
}
|
||||
|
||||
TEST(replace_node, source_replacement)
|
||||
{
|
||||
auto param = std::make_shared<op::Parameter>(element::i64, Shape{1, 64});
|
||||
param->output(0).get_tensor().set_names({"a", "b"});
|
||||
|
||||
auto param1 = std::make_shared<op::Parameter>(element::i64, Shape{1, 64});
|
||||
param1->output(0).get_tensor().set_names({"c", "d"});
|
||||
|
||||
auto relu = std::make_shared<op::Relu>(param);
|
||||
relu->input(0).replace_source_output(param1->output(0));
|
||||
|
||||
ASSERT_EQ(param->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"a", "b"}));
|
||||
ASSERT_EQ(param1->output(0).get_tensor().get_names(), std::unordered_set<std::string>({"c", "d"}));
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,26 +14,8 @@ set (SRC
|
||||
performance_counter.hpp
|
||||
dynamic/dynamic_backend.cpp
|
||||
dynamic/dynamic_backend.hpp
|
||||
op/avg_pool.cpp
|
||||
op/avg_pool.hpp
|
||||
op/convolution.cpp
|
||||
op/convolution.hpp
|
||||
op/group_conv.cpp
|
||||
op/group_conv.hpp
|
||||
pass/dyn_elimination.cpp
|
||||
pass/dyn_elimination.hpp
|
||||
pass/fused_op_decomposition.cpp
|
||||
pass/fused_op_decomposition.hpp
|
||||
pass/implicit_broadcast_elimination.cpp
|
||||
pass/implicit_broadcast_elimination.hpp
|
||||
pass/liveness.cpp
|
||||
pass/liveness.hpp
|
||||
pass/opset0_downgrade.cpp
|
||||
pass/opset0_downgrade.hpp
|
||||
pass/opset1_downgrade.cpp
|
||||
pass/opset1_downgrade.hpp
|
||||
pass/opset1_upgrade.cpp
|
||||
pass/opset1_upgrade.hpp
|
||||
pass/shape_relevance.cpp
|
||||
pass/shape_relevance.hpp
|
||||
)
|
||||
|
@ -15,8 +15,6 @@
|
||||
#include "ngraph/specialize_function.hpp"
|
||||
#include "ngraph/util.hpp"
|
||||
#include "pass/dyn_elimination.hpp"
|
||||
#include "pass/opset0_downgrade.hpp"
|
||||
#include "pass/opset1_downgrade.hpp"
|
||||
#include "pass/shape_relevance.hpp"
|
||||
|
||||
using namespace std;
|
||||
@ -239,10 +237,8 @@ bool runtime::dynamic::DynamicExecutable::call(
|
||||
pass::Manager passes;
|
||||
// Opset1Downgrade should be moved below DynElimination
|
||||
// when ConstantFolding for v3 ops will be ready
|
||||
passes.register_pass<pass::Opset1Downgrade>();
|
||||
passes.register_pass<pass::ConstantFolding>();
|
||||
passes.register_pass<pass::DynElimination>();
|
||||
passes.register_pass<pass::Opset0Downgrade>(); // Converts dynamic v1 variants to v0 ops
|
||||
passes.set_per_pass_validation(false);
|
||||
|
||||
// FIXME(amprocte): Vile, temporary hack: we need to do repeated rounds of
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "ngraph/shape.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "pass/opset1_upgrade.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
@ -63,7 +62,7 @@ namespace
|
||||
memcpy(blob_ptr, data, data_size * elem_type.size());
|
||||
return blob;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -84,15 +83,12 @@ namespace
|
||||
ie_ops.insert(opset7.begin(), opset7.end());
|
||||
return ie_ops;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
runtime::ie::IE_Executable::IE_Executable(shared_ptr<Function> func, string device)
|
||||
: m_device{device}
|
||||
{
|
||||
static std::set<NodeTypeInfo> ie_ops = get_ie_ops();
|
||||
pass::Manager passes;
|
||||
passes.register_pass<pass::Opset1Upgrade>();
|
||||
passes.run_passes(func);
|
||||
|
||||
for (const auto& node : func->get_ops())
|
||||
{
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "ngraph/runtime/reference/reorg_yolo.hpp"
|
||||
#include "ngraph/runtime/reference/tensor_iterator.hpp"
|
||||
#include "ngraph/runtime/tensor.hpp"
|
||||
#include "op/avg_pool.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
|
@ -1,34 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "atan2.hpp"
|
||||
#include "ngraph/op/add.hpp"
|
||||
#include "ngraph/op/divide.hpp"
|
||||
#include "ngraph/op/multiply.hpp"
|
||||
#include "ngraph/op/negative.hpp"
|
||||
#include "ngraph/op/sqrt.hpp"
|
||||
#include "ngraph/op/subtract.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
constexpr NodeTypeInfo op::v0::Atan2::type_info;
|
||||
|
||||
op::v0::Atan2::Atan2(const Output<Node>& y, const Output<Node>& x, const AutoBroadcastSpec& autob)
|
||||
: BinaryElementwiseArithmetic(y, x, autob)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v0::Atan2::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<Atan2>(new_args.at(0), new_args.at(1), this->get_autob());
|
||||
}
|
||||
|
||||
bool op::v0::Atan2::visit_attributes(AttributeVisitor& visitor)
|
||||
{
|
||||
BinaryElementwiseArithmetic::visit_attributes(visitor);
|
||||
return true;
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/op/util/binary_elementwise_arithmetic.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
namespace v0
|
||||
{
|
||||
/// \brief Elementwise full arctan operation
|
||||
class BACKEND_API Atan2 : public util::BinaryElementwiseArithmetic
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"Atan2", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
Atan2()
|
||||
: util::BinaryElementwiseArithmetic(AutoBroadcastSpec::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief atan2(y,x) is the angle from the origin to the point (x,y) (note reversed
|
||||
/// order).
|
||||
///
|
||||
/// \param y
|
||||
/// \param x
|
||||
Atan2(const Output<Node>& y,
|
||||
const Output<Node>& x,
|
||||
const AutoBroadcastSpec& autob = AutoBroadcastSpec());
|
||||
std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "avg_pool.hpp"
|
||||
#include "ngraph/attribute_visitor.hpp"
|
||||
#include "ngraph/graph_util.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
// *** AvgPool OP SET 0 ***
|
||||
constexpr NodeTypeInfo op::v0::AvgPool::type_info;
|
||||
|
||||
op::v0::AvgPool::AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation,
|
||||
const PadType& pad_type,
|
||||
bool ceil_mode)
|
||||
: Op({arg})
|
||||
, m_window_shape(window_shape)
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_include_padding_in_avg_computation(include_padding_in_avg_computation)
|
||||
, m_pad_type(pad_type)
|
||||
, m_ceil_mode(ceil_mode)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
op::v0::AvgPool::AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation,
|
||||
const PadType& pad_type)
|
||||
: AvgPool(arg,
|
||||
window_shape,
|
||||
window_movement_strides,
|
||||
padding_below,
|
||||
padding_above,
|
||||
include_padding_in_avg_computation,
|
||||
pad_type,
|
||||
false)
|
||||
{
|
||||
}
|
||||
|
||||
op::v0::AvgPool::AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation)
|
||||
: AvgPool(arg,
|
||||
window_shape,
|
||||
window_movement_strides,
|
||||
padding_below,
|
||||
padding_above,
|
||||
include_padding_in_avg_computation,
|
||||
PadType::EXPLICIT)
|
||||
{
|
||||
}
|
||||
|
||||
bool op::v0::AvgPool::visit_attributes(AttributeVisitor& visitor)
|
||||
{
|
||||
visitor.on_attribute("window_shape", m_window_shape);
|
||||
visitor.on_attribute("window_movement_strides", m_window_movement_strides);
|
||||
visitor.on_attribute("padding_below", m_padding_below);
|
||||
visitor.on_attribute("padding_above", m_padding_above);
|
||||
visitor.on_attribute("include_padding_in_avg_computation",
|
||||
m_include_padding_in_avg_computation);
|
||||
visitor.on_attribute("pad_type", m_pad_type);
|
||||
visitor.on_attribute("ceil_mode", m_ceil_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::validate_and_infer_types()
|
||||
{
|
||||
if (0 == m_window_movement_strides.size())
|
||||
{
|
||||
m_window_movement_strides = Strides(m_window_shape.size(), 1);
|
||||
}
|
||||
|
||||
if (0 == m_padding_below.size())
|
||||
{
|
||||
m_padding_below = Shape(m_window_shape.size(), 0);
|
||||
}
|
||||
|
||||
if (0 == m_padding_above.size())
|
||||
{
|
||||
m_padding_above = Shape(m_window_shape.size(), 0);
|
||||
}
|
||||
|
||||
const PartialShape& arg_shape = get_input_partial_shape(0);
|
||||
|
||||
if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER)
|
||||
{
|
||||
if (arg_shape.is_static())
|
||||
{
|
||||
CoordinateDiff padding_above, padding_below;
|
||||
infer_auto_padding(arg_shape.to_shape(),
|
||||
m_window_shape,
|
||||
m_window_movement_strides,
|
||||
Strides(m_window_shape.size(), 1), // No dilation
|
||||
m_pad_type,
|
||||
padding_above,
|
||||
padding_below);
|
||||
m_padding_above = Shape(padding_above.begin(), padding_above.end());
|
||||
m_padding_below = Shape(padding_below.begin(), padding_below.end());
|
||||
}
|
||||
}
|
||||
|
||||
// infer_batched_forward_pooling wants CoordinateDiffs for these, while the pooling ops for
|
||||
// now still take Shape (no negative padding).
|
||||
CoordinateDiff padding_below(m_padding_below.begin(), m_padding_below.end());
|
||||
CoordinateDiff padding_above(m_padding_above.begin(), m_padding_above.end());
|
||||
|
||||
set_output_type(0,
|
||||
get_input_element_type(0),
|
||||
infer_batched_pooling_forward(this,
|
||||
arg_shape,
|
||||
padding_below,
|
||||
padding_above,
|
||||
m_window_shape,
|
||||
m_window_movement_strides,
|
||||
m_include_padding_in_avg_computation,
|
||||
m_ceil_mode));
|
||||
}
|
||||
|
||||
op::v0::AvgPool::AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides)
|
||||
: AvgPool(arg, window_shape, window_movement_strides, Shape(), Shape(), false)
|
||||
{
|
||||
}
|
||||
|
||||
op::v0::AvgPool::AvgPool(const Output<Node>& arg, const Shape& window_shape)
|
||||
: AvgPool(arg, window_shape, Strides(), Shape(), Shape(), false)
|
||||
{
|
||||
}
|
||||
|
||||
const Shape& op::v0::AvgPool::get_window_shape() const
|
||||
{
|
||||
return m_window_shape;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_window_shape(const Shape& window_shape)
|
||||
{
|
||||
m_window_shape = window_shape;
|
||||
}
|
||||
|
||||
const Strides& op::v0::AvgPool::get_window_movement_strides() const
|
||||
{
|
||||
return m_window_movement_strides;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_window_movement_strides(const Strides& window_movement_strides)
|
||||
{
|
||||
m_window_movement_strides = window_movement_strides;
|
||||
}
|
||||
|
||||
const Shape& op::v0::AvgPool::get_padding_below() const
|
||||
{
|
||||
return m_padding_below;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_padding_below(const Shape& padding_below)
|
||||
{
|
||||
m_padding_below = padding_below;
|
||||
}
|
||||
|
||||
const Shape& op::v0::AvgPool::get_padding_above() const
|
||||
{
|
||||
return m_padding_above;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_padding_above(const Shape& padding_above)
|
||||
{
|
||||
m_padding_above = padding_above;
|
||||
}
|
||||
|
||||
bool op::v0::AvgPool::get_include_padding_in_avg_computation() const
|
||||
{
|
||||
return m_include_padding_in_avg_computation;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_include_padding_in_avg_computation(
|
||||
bool include_padding_in_avg_computation)
|
||||
{
|
||||
m_include_padding_in_avg_computation = include_padding_in_avg_computation;
|
||||
}
|
||||
|
||||
const op::PadType& op::v0::AvgPool::get_pad_type() const
|
||||
{
|
||||
return m_pad_type;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_pad_type(const op::PadType& pad_type)
|
||||
{
|
||||
m_pad_type = pad_type;
|
||||
}
|
||||
|
||||
bool op::v0::AvgPool::get_ceil_mode() const
|
||||
{
|
||||
return m_ceil_mode;
|
||||
}
|
||||
|
||||
void op::v0::AvgPool::set_ceil_mode(bool ceil_mode)
|
||||
{
|
||||
m_ceil_mode = ceil_mode;
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v0::AvgPool::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<v0::AvgPool>(new_args.at(0),
|
||||
m_window_shape,
|
||||
m_window_movement_strides,
|
||||
m_padding_below,
|
||||
m_padding_above,
|
||||
m_include_padding_in_avg_computation,
|
||||
m_pad_type,
|
||||
m_ceil_mode);
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v0::AvgPool::get_default_value() const
|
||||
{
|
||||
return Constant::create(get_element_type(), get_shape(), {0});
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/op/op.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
namespace v0
|
||||
{
|
||||
/// \brief Batched average pooling operation, with optional padding and window stride.
|
||||
///
|
||||
class BACKEND_API AvgPool : public Op
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"AvgPool", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
/// \brief Constructs a batched average pooling operation.
|
||||
AvgPool() = default;
|
||||
|
||||
/// \brief Constructs a batched average pooling operation.
|
||||
///
|
||||
/// \param arg The output producing the input data batch tensor.<br>
|
||||
/// `[d1, dn]`
|
||||
/// \param window_shape The window shape.<br>
|
||||
/// `[n]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_below The below-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_above The above-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param include_padding_in_avg_computation If true then averages include padding
|
||||
/// elements, each treated as the number zero. If false, padding elements are
|
||||
/// entirely ignored when computing averages. \param pad_type Padding type to use
|
||||
/// for additional padded dimensions \param ceil_mode Whether to use ceiling while
|
||||
/// computing output shape.
|
||||
AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation,
|
||||
const PadType& pad_type,
|
||||
bool ceil_mode);
|
||||
|
||||
/// \brief Constructs a batched average pooling operation.
|
||||
///
|
||||
/// \param arg The output producing the input data batch tensor.<br>
|
||||
/// `[d1, dn]`
|
||||
/// \param window_shape The window shape.<br>
|
||||
/// `[n]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_below The below-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_above The above-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param include_padding_in_avg_computation If true then averages include padding
|
||||
/// elements, each treated as the number zero. If false, padding elements are
|
||||
/// entirely ignored when computing averages. \param pad_type Padding type to use
|
||||
/// for additional padded dimensions
|
||||
AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation,
|
||||
const PadType& pad_type);
|
||||
|
||||
/// \brief Constructs a batched average pooling operation.
|
||||
///
|
||||
/// \param arg The output producing the input data batch tensor.<br>
|
||||
/// `[d1, dn]`
|
||||
/// \param window_shape The window shape.<br>
|
||||
/// `[n]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_below The below-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param padding_above The above-padding shape.<br>
|
||||
/// `[n]`
|
||||
/// \param include_padding_in_avg_computation If true then averages include padding
|
||||
/// elements, each treated as the number zero. If false, padding elements are
|
||||
/// entirely ignored when computing averages.
|
||||
AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides,
|
||||
const Shape& padding_below,
|
||||
const Shape& padding_above,
|
||||
bool include_padding_in_avg_computation = false);
|
||||
|
||||
/// \brief Constructs a batched, unpadded average pooling operation (i.e., all
|
||||
/// padding shapes are set to 0).
|
||||
///
|
||||
/// \param arg The output producing the input data batch tensor.<br>
|
||||
/// `[d1, ..., dn]`
|
||||
/// \param window_shape The window shape.<br>
|
||||
/// `[n]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[n]`
|
||||
AvgPool(const Output<Node>& arg,
|
||||
const Shape& window_shape,
|
||||
const Strides& window_movement_strides);
|
||||
|
||||
/// \brief Constructs an unstrided batched convolution operation (i.e., all window
|
||||
/// movement strides are 1 and all padding shapes are set to 0).
|
||||
///
|
||||
/// \param arg The output producing the input data batch tensor.<br>
|
||||
/// `[d1, ..., dn]`
|
||||
/// \param window_shape The window shape.<br>
|
||||
/// `[n]`
|
||||
AvgPool(const Output<Node>& arg, const Shape& window_shape);
|
||||
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
/// \return The window shape.
|
||||
const Shape& get_window_shape() const;
|
||||
void set_window_shape(const Shape& window_shape);
|
||||
/// \return The window movement strides.
|
||||
const Strides& get_window_movement_strides() const;
|
||||
void set_window_movement_strides(const Strides& window_movement_strides);
|
||||
/// \return The below-padding shape.
|
||||
const Shape& get_padding_below() const;
|
||||
void set_padding_below(const Shape& padding_below);
|
||||
/// \return The above-padding shape.
|
||||
const Shape& get_padding_above() const;
|
||||
void set_padding_above(const Shape& padding_above);
|
||||
bool get_include_padding_in_avg_computation() const;
|
||||
void
|
||||
set_include_padding_in_avg_computation(bool include_padding_in_avg_computation);
|
||||
/// \return The pad type for pooling.
|
||||
const PadType& get_pad_type() const;
|
||||
void set_pad_type(const PadType& pad_type);
|
||||
bool get_ceil_mode() const;
|
||||
void set_ceil_mode(bool ceil_mode);
|
||||
/// \return The default value for AvgPool.
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
virtual std::shared_ptr<Node> get_default_value() const override;
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
|
||||
protected:
|
||||
Shape m_window_shape;
|
||||
Strides m_window_movement_strides;
|
||||
Shape m_padding_below;
|
||||
Shape m_padding_above;
|
||||
bool m_include_padding_in_avg_computation{false};
|
||||
PadType m_pad_type{PadType::EXPLICIT};
|
||||
bool m_ceil_mode{false};
|
||||
};
|
||||
} // namespace v0
|
||||
} // namespace op
|
||||
} // namespace ngraph
|
@ -1,343 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "convolution.hpp"
|
||||
#include "ngraph/axis_vector.hpp"
|
||||
#include "ngraph/coordinate_diff.hpp"
|
||||
#include "ngraph/op/reshape.hpp"
|
||||
#include "ngraph/util.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
// *** Convolution OP SET 0 ***
|
||||
constexpr NodeTypeInfo op::v0::Convolution::type_info;
|
||||
|
||||
op::v0::Convolution::Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const PadType& pad_type)
|
||||
: Op({data_batch, filters})
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_window_dilation_strides(window_dilation_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_data_dilation_strides(data_dilation_strides)
|
||||
, m_pad_type(pad_type)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
bool op::v0::Convolution::visit_attributes(AttributeVisitor& visitor)
|
||||
{
|
||||
visitor.on_attribute("window_movement_strides", m_window_movement_strides);
|
||||
visitor.on_attribute("window_dilation_strides", m_window_dilation_strides);
|
||||
visitor.on_attribute("data_dilation_strides", m_data_dilation_strides);
|
||||
visitor.on_attribute("padding_below", m_padding_below);
|
||||
visitor.on_attribute("padding_above", m_padding_above);
|
||||
visitor.on_attribute("pad_type", m_pad_type);
|
||||
return true;
|
||||
}
|
||||
|
||||
void op::v0::Convolution::validate_and_infer_types()
|
||||
{
|
||||
const PartialShape& data_batch_shape = get_input_partial_shape(0);
|
||||
element::Type data_batch_et = get_input_element_type(0);
|
||||
const PartialShape& filters_shape = get_input_partial_shape(1);
|
||||
element::Type filters_et = get_input_element_type(1);
|
||||
|
||||
if (m_data_dilation_strides.size() == 0)
|
||||
{
|
||||
m_data_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape);
|
||||
}
|
||||
|
||||
if (m_window_movement_strides.size() == 0)
|
||||
{
|
||||
m_window_movement_strides = conv_default_strides(this, data_batch_shape, filters_shape);
|
||||
}
|
||||
|
||||
if (m_window_dilation_strides.size() == 0)
|
||||
{
|
||||
m_window_dilation_strides = conv_default_strides(this, data_batch_shape, filters_shape);
|
||||
}
|
||||
|
||||
if (m_padding_below.size() == 0)
|
||||
{
|
||||
m_padding_below = conv_default_padding(this, data_batch_shape, filters_shape);
|
||||
}
|
||||
|
||||
if (m_padding_above.size() == 0)
|
||||
{
|
||||
m_padding_above = conv_default_padding(this, data_batch_shape, filters_shape);
|
||||
}
|
||||
|
||||
if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER)
|
||||
{
|
||||
if (data_batch_shape.is_static() && filters_shape.is_static())
|
||||
{
|
||||
// TODO: data dilation
|
||||
m_padding_below.clear();
|
||||
m_padding_above.clear();
|
||||
auto filter_shape = filters_shape.to_shape();
|
||||
filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I}
|
||||
infer_auto_padding(data_batch_shape.to_shape(),
|
||||
filter_shape,
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides,
|
||||
m_pad_type,
|
||||
m_padding_above,
|
||||
m_padding_below);
|
||||
}
|
||||
}
|
||||
|
||||
element::Type result_et;
|
||||
PartialShape result_shape;
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
element::Type::merge(result_et, data_batch_et, filters_et),
|
||||
"Element types for data batch and filters do not match (data batch element type: ",
|
||||
data_batch_et,
|
||||
", filters element type: ",
|
||||
filters_et,
|
||||
").");
|
||||
|
||||
result_shape = infer_convolution_forward(this,
|
||||
data_batch_shape,
|
||||
m_data_dilation_strides,
|
||||
m_padding_below,
|
||||
m_padding_above,
|
||||
filters_shape,
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides);
|
||||
|
||||
set_output_type(0, result_et, result_shape);
|
||||
}
|
||||
|
||||
op::v0::Convolution::Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above)
|
||||
: Convolution(data_batch,
|
||||
filters,
|
||||
window_movement_strides,
|
||||
window_dilation_strides,
|
||||
padding_below,
|
||||
padding_above,
|
||||
Strides())
|
||||
{
|
||||
}
|
||||
|
||||
op::v0::Convolution::Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides)
|
||||
: Convolution(data_batch,
|
||||
filters,
|
||||
window_movement_strides,
|
||||
window_dilation_strides,
|
||||
CoordinateDiff(),
|
||||
CoordinateDiff())
|
||||
{
|
||||
}
|
||||
|
||||
op::v0::Convolution::Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides)
|
||||
: Convolution(data_batch,
|
||||
filters,
|
||||
window_movement_strides,
|
||||
Strides(),
|
||||
CoordinateDiff(),
|
||||
CoordinateDiff())
|
||||
{
|
||||
}
|
||||
|
||||
op::v0::Convolution::Convolution(const Output<Node>& data_batch, const Output<Node>& filters)
|
||||
: Convolution(data_batch, filters, Strides(), Strides(), CoordinateDiff(), CoordinateDiff())
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v0::Convolution::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<v0::Convolution>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides,
|
||||
m_padding_below,
|
||||
m_padding_above,
|
||||
m_data_dilation_strides,
|
||||
m_pad_type);
|
||||
}
|
||||
|
||||
constexpr NodeTypeInfo op::v0::ConvolutionBackpropData::type_info;
|
||||
shared_ptr<Node> op::v0::Convolution::get_default_value() const
|
||||
{
|
||||
return ngraph::make_constant_from_string("0", get_element_type(), get_shape());
|
||||
}
|
||||
|
||||
op::v0::ConvolutionBackpropData::ConvolutionBackpropData(
|
||||
const Shape& data_batch_shape,
|
||||
const Output<Node>& filters,
|
||||
const Output<Node>& output_delta,
|
||||
const Strides& window_movement_strides_forward,
|
||||
const Strides& window_dilation_strides_forward,
|
||||
const CoordinateDiff& padding_below_forward,
|
||||
const CoordinateDiff& padding_above_forward,
|
||||
const Strides& data_dilation_strides_forward)
|
||||
: Op({filters, output_delta})
|
||||
, m_data_batch_shape(data_batch_shape)
|
||||
, m_window_movement_strides_forward(window_movement_strides_forward)
|
||||
, m_window_dilation_strides_forward(window_dilation_strides_forward)
|
||||
, m_padding_below_forward(padding_below_forward)
|
||||
, m_padding_above_forward(padding_above_forward)
|
||||
, m_data_dilation_strides_forward(data_dilation_strides_forward)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
bool op::v0::ConvolutionBackpropData::visit_attributes(AttributeVisitor& visitor)
|
||||
{
|
||||
visitor.on_attribute("data_batch_shape", m_data_batch_shape);
|
||||
visitor.on_attribute("window_movement_strides_forward", m_window_movement_strides_forward);
|
||||
visitor.on_attribute("window_dilation_strides_forward", m_window_dilation_strides_forward);
|
||||
visitor.on_attribute("padding_below_forward", m_padding_below_forward);
|
||||
visitor.on_attribute("padding_above_forward", m_padding_above_forward);
|
||||
visitor.on_attribute("data_dilation_strides_forward", m_data_dilation_strides_forward);
|
||||
return true;
|
||||
}
|
||||
|
||||
void op::v0::ConvolutionBackpropData::validate_and_infer_types()
|
||||
{
|
||||
// Backprop to data is itself convolution, with inputs/outputs/attributes transmogrified as
|
||||
// follows.
|
||||
//
|
||||
// Forward Backward
|
||||
// "N" axis for data batch 0 0
|
||||
// "C" axis for data batch 1 1
|
||||
// "Co" axis for filters 0 0
|
||||
// "Ci" axis for filters 1 1
|
||||
// "N" axis for output 0 0
|
||||
// "C" axis for output 1 1
|
||||
// Data batch x delta
|
||||
// Data batch shape S_x S_o
|
||||
// Filters f reverse(f) [on spatial axes]
|
||||
// Filters shape S_f S_f
|
||||
// Window movement strides q_x p_x
|
||||
// Window dilation strides p_f p_f
|
||||
// Padding below a_x (S_f - 1)p_f - a_x
|
||||
// Padding above b_x (S_f - 1)p_f +
|
||||
// + ((a_x + (S_x - 1)p_x + b_x - (S_f - 1)p_f)
|
||||
// % q_x)
|
||||
// - b_x
|
||||
// Data dilation strides p_x q_x
|
||||
// Output shape S_o S_x
|
||||
//
|
||||
// To _validate_, we simply need to check/infer the output shape of the forward convolution,
|
||||
// then check to make sure that the incoming delta has the same shape as the forward output.
|
||||
const PartialShape& filters_shape = get_input_partial_shape(0);
|
||||
element::Type filters_et = get_input_element_type(0);
|
||||
const PartialShape& delta_shape = get_input_partial_shape(1);
|
||||
element::Type delta_et = get_input_element_type(1);
|
||||
|
||||
element::Type forward_result_et;
|
||||
PartialShape forward_result_shape;
|
||||
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
element::Type::merge(forward_result_et, delta_et, filters_et),
|
||||
"Element types for data batch and filters do not match (data batch element type: ",
|
||||
delta_et,
|
||||
", filters element type: ",
|
||||
filters_et,
|
||||
").");
|
||||
|
||||
forward_result_shape = infer_convolution_forward(this,
|
||||
m_data_batch_shape,
|
||||
m_data_dilation_strides_forward,
|
||||
m_padding_below_forward,
|
||||
m_padding_above_forward,
|
||||
filters_shape,
|
||||
m_window_movement_strides_forward,
|
||||
m_window_dilation_strides_forward);
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
forward_result_shape.compatible(delta_shape),
|
||||
"Inferred forward output shape (",
|
||||
forward_result_shape,
|
||||
") does not match shape of ",
|
||||
"delta (",
|
||||
delta_shape,
|
||||
").");
|
||||
|
||||
set_output_type(0, forward_result_et, m_data_batch_shape);
|
||||
}
|
||||
|
||||
shared_ptr<Node>
|
||||
op::v0::ConvolutionBackpropData::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<v0::ConvolutionBackpropData>(m_data_batch_shape,
|
||||
new_args.at(0),
|
||||
new_args.at(1),
|
||||
m_window_movement_strides_forward,
|
||||
m_window_dilation_strides_forward,
|
||||
m_padding_below_forward,
|
||||
m_padding_above_forward,
|
||||
m_data_dilation_strides_forward);
|
||||
}
|
||||
|
||||
CoordinateDiff op::v0::ConvolutionBackpropData::compute_backward_delta_out_pad_below() const
|
||||
{
|
||||
auto& in_shape = get_data_batch_shape();
|
||||
auto& filter_dilation = get_window_dilation_strides_forward();
|
||||
auto& filter_shape = get_input_shape(0);
|
||||
auto& in_pad_below = get_padding_below_forward();
|
||||
size_t spatial_dim_count = static_cast<size_t>(in_shape.size()) - 2;
|
||||
|
||||
CoordinateDiff backward_delta_out_pad_below;
|
||||
backward_delta_out_pad_below.resize(spatial_dim_count);
|
||||
|
||||
for (size_t i = 0; i < spatial_dim_count; i++)
|
||||
{
|
||||
backward_delta_out_pad_below[i] =
|
||||
(static_cast<ptrdiff_t>(filter_shape[i + 2]) - 1) * filter_dilation[i] -
|
||||
in_pad_below[i];
|
||||
}
|
||||
return backward_delta_out_pad_below;
|
||||
}
|
||||
|
||||
CoordinateDiff op::v0::ConvolutionBackpropData::compute_backward_delta_out_pad_above() const
|
||||
{
|
||||
auto& in_shape = get_data_batch_shape();
|
||||
auto& filter_dilation = get_window_dilation_strides_forward();
|
||||
auto& filter_shape = get_input_shape(0);
|
||||
auto& in_pad_below = get_padding_below_forward();
|
||||
auto& in_pad_above = get_padding_above_forward();
|
||||
auto& in_dilation = get_data_dilation_strides_forward();
|
||||
auto& stride = get_window_movement_strides_forward();
|
||||
size_t spatial_dim_count = static_cast<size_t>(in_shape.size()) - 2;
|
||||
|
||||
CoordinateDiff backward_delta_out_pad_above;
|
||||
backward_delta_out_pad_above.resize(spatial_dim_count);
|
||||
|
||||
for (size_t i = 0; i < spatial_dim_count; i++)
|
||||
{
|
||||
backward_delta_out_pad_above[i] =
|
||||
(static_cast<ptrdiff_t>(filter_shape[i + 2]) - 1) * filter_dilation[i] +
|
||||
((in_pad_below[i] + ((in_shape[i + 2]) - 1) * in_dilation[i] + in_pad_above[i] -
|
||||
(static_cast<ptrdiff_t>(filter_shape[i + 2]) - 1) * filter_dilation[i]) %
|
||||
stride[i]) -
|
||||
in_pad_above[i];
|
||||
}
|
||||
return backward_delta_out_pad_above;
|
||||
}
|
@ -1,304 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/coordinate_diff.hpp"
|
||||
#include "ngraph/op/op.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
namespace v0
|
||||
{
|
||||
/// \brief Batched convolution operation, with optional window dilation and stride.
|
||||
///
|
||||
class BACKEND_API Convolution : public Op
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"Convolution", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
/// \brief Constructs a batched convolution operation.
|
||||
Convolution() = default;
|
||||
/// \brief Constructs a batched convolution operation.
|
||||
///
|
||||
/// \param data_batch The node producing the input data batch tensor.<br>
|
||||
/// `[N, C_IN, D1, ... Df]`
|
||||
/// \param filters The node producing the filters tensor.<br>
|
||||
/// `[C_OUT, C_IN, F1, ... Ff]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[f]`
|
||||
/// \param window_dilation_strides The window dilation strides.<br>
|
||||
/// `[f]`
|
||||
/// \param padding_below The padding-below sizes.<br>
|
||||
/// `[f]`
|
||||
/// \param padding_above The padding-above sizes.<br>
|
||||
/// `[f]`
|
||||
/// \param data_dilation_strides The data dilation strides.<br>
|
||||
/// `[f]`
|
||||
/// \param pad_type The pad type for automatically computing padding sizes.<br>
|
||||
/// `[f]`
|
||||
///
|
||||
/// Output `[N, C_OUT, R1, ... Rf]`
|
||||
///
|
||||
Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const PadType& pad_type = PadType::EXPLICIT);
|
||||
|
||||
/// \brief Constructs a batched convolution operation with no data dilation (i.e.,
|
||||
/// all
|
||||
/// data dilation strides are 1).
|
||||
/// ngraph/test/runtime/interpreter/unit_test.manifest
|
||||
/// \param data_batch The node producing the input data batch tensor.<br>
|
||||
/// `[N, C_IN, D1, ... Df]`
|
||||
/// \param filters The node producing the filters tensor.<br>
|
||||
/// `[C_OUT, C_IN, F1, ... Ff]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[f]`
|
||||
/// \param window_dilation_strides The window dilation strides.<br>
|
||||
/// `[f]`
|
||||
/// \param padding_below The padding-below sizes.<br>
|
||||
/// `[f]`
|
||||
/// \param padding_above The padding-above sizes.<br>
|
||||
/// `[f]`
|
||||
///
|
||||
/// Output `[N, C_OUT, R1, ... Rf]`
|
||||
///
|
||||
Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above);
|
||||
|
||||
/// \brief Constructs a batched convolution operation with no padding or data
|
||||
/// dilation
|
||||
/// (i.e., padding above and below are 0 everywhere, and all data dilation
|
||||
/// strides are 1).
|
||||
///
|
||||
/// \param data_batch The node producing the input data batch tensor.<br>
|
||||
/// `[N, C_IN, D1, ... Df]`
|
||||
/// \param filters The node producing the filters tensor.<br>
|
||||
/// `[C_OUT, C_IN, F1, ... Ff]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[f]`
|
||||
/// \param window_dilation_strides The window dilation strides.<br>
|
||||
/// `[f]`
|
||||
///
|
||||
/// Output `[N, C_OUT, R1, ... Rf]`
|
||||
///
|
||||
Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides);
|
||||
|
||||
/// \brief Constructs a batched convolution operation with no window dilation,
|
||||
/// padding,
|
||||
/// or data dilation (i.e., padding above and below are 0 everywhere, and all
|
||||
/// window/data dilation strides are 1).
|
||||
///
|
||||
/// \param data_batch The node producing the input data batch tensor.<br>
|
||||
/// `[N, C_IN, D1, ... Df]`
|
||||
/// \param filters The node producing the filters tensor.<br>
|
||||
/// `[C_OUT, C_IN, F1, ... Ff]`
|
||||
/// \param window_movement_strides The window movement strides.<br>
|
||||
/// `[f]`
|
||||
///
|
||||
/// Output `[N, C_OUT, R1, ... Rf]`
|
||||
///
|
||||
Convolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides);
|
||||
|
||||
/// \brief Constructs a batched convolution operation with no window dilation or
|
||||
/// movement stride (i.e., padding above and below are 0 everywhere, and all
|
||||
/// window/data dilation strides and window movement strides are 1).
|
||||
///
|
||||
/// \param data_batch The node producing the input data batch tensor.<br>
|
||||
/// `[N, C_IN, D1, ... Df]`
|
||||
/// \param filters The node producing the filters tensor.<br>
|
||||
/// `[C_OUT, C_IN, F1, ... Ff]`
|
||||
///
|
||||
/// Output `[N, C_OUT, R1, ... Rf]`
|
||||
///
|
||||
Convolution(const Output<Node>& data_batch, const Output<Node>& filters);
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
/// \return The window movement strides.
|
||||
const Strides& get_window_movement_strides() const
|
||||
{
|
||||
return m_window_movement_strides;
|
||||
}
|
||||
void set_window_movement_strides(const Strides& window_movement_strides)
|
||||
{
|
||||
m_window_movement_strides = window_movement_strides;
|
||||
}
|
||||
/// \return The window dilation strides.
|
||||
const Strides& get_window_dilation_strides() const
|
||||
{
|
||||
return m_window_dilation_strides;
|
||||
}
|
||||
void set_window_dilation_strides(const Strides& window_dilation_strides)
|
||||
{
|
||||
m_window_dilation_strides = window_dilation_strides;
|
||||
}
|
||||
/// \return The padding-below sizes (possibly negative).
|
||||
const CoordinateDiff& get_padding_below() const { return m_padding_below; }
|
||||
void set_padding_below(const CoordinateDiff& padding_below)
|
||||
{
|
||||
m_padding_below = padding_below;
|
||||
}
|
||||
/// \return The padding-above sizes (possibly negative).
|
||||
const CoordinateDiff& get_padding_above() const { return m_padding_above; }
|
||||
void set_adding_above(const CoordinateDiff& padding_above)
|
||||
{
|
||||
m_padding_above = padding_above;
|
||||
}
|
||||
/// \return The input data dilation strides.
|
||||
const Strides& get_data_dilation_strides() const { return m_data_dilation_strides; }
|
||||
void set_data_dilation_strides(const Strides& data_dilation_strides)
|
||||
{
|
||||
m_data_dilation_strides = data_dilation_strides;
|
||||
}
|
||||
/// \return The pad type for convolution.
|
||||
const PadType& get_pad_type() const { return m_pad_type; }
|
||||
void set_pad_type(const PadType& pad_type) { m_pad_type = pad_type; }
|
||||
/// \return The default value for Convolution.
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
virtual std::shared_ptr<Node> get_default_value() const override;
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
|
||||
protected:
|
||||
Strides m_window_movement_strides;
|
||||
Strides m_window_dilation_strides;
|
||||
CoordinateDiff m_padding_below;
|
||||
CoordinateDiff m_padding_above;
|
||||
Strides m_data_dilation_strides;
|
||||
PadType m_pad_type;
|
||||
};
|
||||
|
||||
/// \brief Data batch backprop for batched convolution operation.
|
||||
class BACKEND_API ConvolutionBackpropData : public Op
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"ConvolutionBackpropData", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
/// \brief Constructs a batched-convolution data batch-backprop operation.
|
||||
ConvolutionBackpropData() = default;
|
||||
///
|
||||
/// \brief Constructs a batched-convolution data batch-backprop operation.
|
||||
///
|
||||
/// \param data_batch_shape The shape of the data batch from
|
||||
/// forward-prop.
|
||||
/// \param filters The node producing the filters from
|
||||
/// forward-prop.
|
||||
/// \param data The node producing output delta.
|
||||
/// \param window_movement_strides_forward The window movement strides from
|
||||
/// forward-prop.
|
||||
/// \param window_dilation_strides_forward The window dilation strides from
|
||||
/// forward-prop.
|
||||
/// \param padding_below_forward The padding-below sizes from
|
||||
/// forward-prop.
|
||||
/// \param padding_above_forward The padding-above sizes from
|
||||
/// forward-prop.
|
||||
/// \param data_dilation_strides_forward The data dilation strides from
|
||||
/// forward-prop.
|
||||
///
|
||||
ConvolutionBackpropData(const Shape& data_batch_shape,
|
||||
const Output<Node>& filters,
|
||||
const Output<Node>& data,
|
||||
const Strides& window_movement_strides_forward,
|
||||
const Strides& window_dilation_strides_forward,
|
||||
const CoordinateDiff& padding_below_forward,
|
||||
const CoordinateDiff& padding_above_forward,
|
||||
const Strides& data_dilation_strides_forward);
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
/// \return The data batch shape.
|
||||
const Shape& get_data_batch_shape() const { return m_data_batch_shape; }
|
||||
void set_data_batch_shape(const Shape& data_batch_shape)
|
||||
{
|
||||
m_data_batch_shape = data_batch_shape;
|
||||
}
|
||||
/// \return The window movement strides from the forward prop.
|
||||
const Strides& get_window_movement_strides_forward() const
|
||||
{
|
||||
return m_window_movement_strides_forward;
|
||||
}
|
||||
void set_window_movement_strides_forward(
|
||||
const Strides& window_movement_strides_forward)
|
||||
{
|
||||
m_window_movement_strides_forward = window_movement_strides_forward;
|
||||
}
|
||||
/// \return The window dilation strides from the forward prop.
|
||||
const Strides& get_window_dilation_strides_forward() const
|
||||
{
|
||||
return m_window_dilation_strides_forward;
|
||||
}
|
||||
void set_window_dilation_strides_forward(
|
||||
const Strides& window_dilation_strides_forward)
|
||||
{
|
||||
m_window_dilation_strides_forward = window_dilation_strides_forward;
|
||||
}
|
||||
/// \return The padding-below sizes (possibly negative) from the forward prop.
|
||||
const CoordinateDiff& get_padding_below_forward() const
|
||||
{
|
||||
return m_padding_below_forward;
|
||||
}
|
||||
void set_padding_below_forward(const CoordinateDiff& padding_below_forward)
|
||||
{
|
||||
m_padding_below_forward = padding_below_forward;
|
||||
}
|
||||
/// \return The padding-above sizes (possibly negative) from the forward prop.
|
||||
const CoordinateDiff& get_padding_above_forward() const
|
||||
{
|
||||
return m_padding_above_forward;
|
||||
}
|
||||
void set_padding_above_forward(const CoordinateDiff& padding_above_forward)
|
||||
{
|
||||
m_padding_above_forward = padding_above_forward;
|
||||
}
|
||||
/// \return The input data dilation strides from the forward prop.
|
||||
const Strides& get_data_dilation_strides_forward() const
|
||||
{
|
||||
return m_data_dilation_strides_forward;
|
||||
}
|
||||
void set_data_dilation_strides_forward(const Strides& data_dilation_strides_forward)
|
||||
{
|
||||
m_data_dilation_strides_forward = data_dilation_strides_forward;
|
||||
}
|
||||
|
||||
// Compute the pad_above values to be used if in a convolution
|
||||
CoordinateDiff compute_backward_delta_out_pad_above() const;
|
||||
CoordinateDiff compute_backward_delta_out_pad_below() const;
|
||||
|
||||
protected:
|
||||
Shape m_data_batch_shape;
|
||||
Strides m_window_movement_strides_forward;
|
||||
Strides m_window_dilation_strides_forward;
|
||||
CoordinateDiff m_padding_below_forward;
|
||||
CoordinateDiff m_padding_above_forward;
|
||||
Strides m_data_dilation_strides_forward;
|
||||
};
|
||||
} // namespace v0
|
||||
} // namespace op
|
||||
} // namespace ngraph
|
@ -1,319 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "convolution.hpp"
|
||||
#include "group_conv.hpp"
|
||||
#include "ngraph/attribute_visitor.hpp"
|
||||
#include "ngraph/builder/reshape.hpp"
|
||||
#include "ngraph/builder/split.hpp"
|
||||
#include "ngraph/op/concat.hpp"
|
||||
#include "ngraph/op/convolution.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// v0::GroupConvolution
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
constexpr NodeTypeInfo op::v0::GroupConvolution::type_info;
|
||||
|
||||
op::v0::GroupConvolution::GroupConvolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const size_t groups,
|
||||
const PadType& pad_type)
|
||||
: FusedOp({data_batch, filters})
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_window_dilation_strides(window_dilation_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_data_dilation_strides(data_dilation_strides)
|
||||
, m_groups(groups)
|
||||
, m_pad_type(pad_type)
|
||||
, m_groups_in_filters(false)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
op::v0::GroupConvolution::GroupConvolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const PadType& pad_type)
|
||||
: FusedOp({data_batch, filters})
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_window_dilation_strides(window_dilation_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_data_dilation_strides(data_dilation_strides)
|
||||
, m_groups(0)
|
||||
, m_pad_type(pad_type)
|
||||
, m_groups_in_filters(true)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void op::v0::GroupConvolution::pre_validate_and_infer_types()
|
||||
{
|
||||
auto data_shape = get_input_partial_shape(0);
|
||||
auto filters_shape = get_input_partial_shape(1);
|
||||
|
||||
if (data_shape.is_static() && filters_shape.is_static())
|
||||
{
|
||||
// Update groups
|
||||
if (m_groups_in_filters)
|
||||
{
|
||||
m_groups = get_input_partial_shape(1)[0].get_length();
|
||||
}
|
||||
|
||||
// Data channels
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
data_shape.to_shape()[1] % get_groups() == 0,
|
||||
"Data channels not a multiple of group size");
|
||||
// Output channels
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
filters_shape.to_shape()[0] % get_groups() == 0,
|
||||
"# Filters not a multiple of group size");
|
||||
|
||||
// Input Filters
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
(filters_shape.to_shape()[m_groups_in_filters ? 2 : 1] *
|
||||
get_groups()) == data_shape.to_shape()[1],
|
||||
"Incorrect number of channels per filter");
|
||||
}
|
||||
else
|
||||
{
|
||||
set_output_type(0, get_input_element_type(0), PartialShape::dynamic());
|
||||
}
|
||||
}
|
||||
|
||||
void op::v0::GroupConvolution::post_validate_and_infer_types()
|
||||
{
|
||||
auto data_shape = get_input_partial_shape(0);
|
||||
auto filters_shape = get_input_partial_shape(1);
|
||||
if (data_shape.is_static() && filters_shape.is_static())
|
||||
{
|
||||
if (m_pad_type == PadType::SAME_UPPER || m_pad_type == PadType::SAME_LOWER)
|
||||
{
|
||||
m_padding_below.clear();
|
||||
m_padding_above.clear();
|
||||
auto filter_shape = filters_shape.to_shape();
|
||||
filter_shape.erase(filter_shape.begin(), filter_shape.begin() + 2); // Remove {O,I}
|
||||
infer_auto_padding(data_shape.to_shape(),
|
||||
filter_shape,
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides,
|
||||
m_pad_type,
|
||||
m_padding_above,
|
||||
m_padding_below);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shape op::v0::GroupConvolution::get_weights_dimensions() const
|
||||
{
|
||||
auto data_shape = get_input_shape(0);
|
||||
auto weights_shape = get_input_shape(1);
|
||||
// check if weights already includes groups
|
||||
if (m_groups_in_filters)
|
||||
{
|
||||
return weights_shape;
|
||||
}
|
||||
// reshape weights into 5d tensors that includes groups
|
||||
const size_t OC = 0;
|
||||
const size_t OC_IN_OUTPUT = 1;
|
||||
const size_t IC = 1;
|
||||
Shape weights_shape_groups{weights_shape};
|
||||
// adjust output and channel given a number of groups
|
||||
|
||||
weights_shape_groups.at(OC) = get_shape().at(OC_IN_OUTPUT) / get_groups();
|
||||
weights_shape_groups.at(IC) = data_shape.at(IC) / get_groups();
|
||||
// push_front the number of groups
|
||||
weights_shape_groups.insert(weights_shape_groups.begin(), get_groups());
|
||||
return weights_shape_groups;
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v0::GroupConvolution::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
check_new_args_count(this, new_args);
|
||||
|
||||
if (m_groups_in_filters)
|
||||
{
|
||||
return make_shared<op::v0::GroupConvolution>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
get_window_movement_strides(),
|
||||
get_window_dilation_strides(),
|
||||
get_padding_below(),
|
||||
get_padding_above(),
|
||||
get_data_dilation_strides(),
|
||||
get_pad_type());
|
||||
}
|
||||
else
|
||||
{
|
||||
return make_shared<op::v0::GroupConvolution>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
get_window_movement_strides(),
|
||||
get_window_dilation_strides(),
|
||||
get_padding_below(),
|
||||
get_padding_above(),
|
||||
get_data_dilation_strides(),
|
||||
get_groups(),
|
||||
get_pad_type());
|
||||
}
|
||||
}
|
||||
|
||||
OutputVector op::v0::GroupConvolution::decompose_op() const
|
||||
{
|
||||
auto data = input_value(0);
|
||||
auto filters = input_value(1);
|
||||
auto filters_shape = get_input_shape(1);
|
||||
// Split one convolution op to N ops where N is the number of groups
|
||||
// and concat results after computation.
|
||||
NodeVector convolution_nodes;
|
||||
|
||||
// slice data
|
||||
auto sliced_data = builder::opset1::split(data, get_groups(), 1);
|
||||
// slice filters
|
||||
auto sliced_filters = builder::opset1::split(filters, get_groups(), 0);
|
||||
auto shape = Shape(std::next(std::begin(filters_shape), 1), std::end(filters_shape));
|
||||
for (std::size_t group{0}; group < get_groups(); ++group)
|
||||
{
|
||||
auto sliced_filter = sliced_filters[group];
|
||||
if (m_groups_in_filters)
|
||||
{
|
||||
// Remove group dimension after slicing
|
||||
sliced_filter = builder::opset1::reshape(sliced_filters[group], shape);
|
||||
}
|
||||
convolution_nodes.push_back(
|
||||
std::make_shared<ngraph::op::v0::Convolution>(sliced_data[group],
|
||||
sliced_filter,
|
||||
m_window_movement_strides,
|
||||
m_window_dilation_strides,
|
||||
m_padding_below,
|
||||
m_padding_above,
|
||||
m_data_dilation_strides,
|
||||
m_pad_type));
|
||||
}
|
||||
std::size_t concatenation_axis = 1;
|
||||
return {std::make_shared<ngraph::op::Concat>(convolution_nodes, concatenation_axis)};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// v0::GroupConvolutionBackpropData
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
constexpr NodeTypeInfo op::v0::GroupConvolutionBackpropData::type_info;
|
||||
|
||||
op::v0::GroupConvolutionBackpropData::GroupConvolutionBackpropData(
|
||||
const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Output<Node>& output_delta,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const size_t groups)
|
||||
: FusedOp({data_batch, filters, output_delta})
|
||||
, m_window_movement_strides(window_movement_strides)
|
||||
, m_window_dilation_strides(window_dilation_strides)
|
||||
, m_padding_below(padding_below)
|
||||
, m_padding_above(padding_above)
|
||||
, m_groups(groups)
|
||||
{
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void op::v0::GroupConvolutionBackpropData::pre_validate_and_infer_types()
|
||||
{
|
||||
element::Type data_element_type = get_input_element_type(2);
|
||||
element::Type filters_elem_type = get_input_element_type(1);
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
data_element_type.is_dynamic() || data_element_type.is_real(),
|
||||
"Output delta element type must be f16, bf16, f32, f64 or dynamic (got ",
|
||||
data_element_type,
|
||||
").");
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
filters_elem_type.is_dynamic() || filters_elem_type.is_real(),
|
||||
"Filters element type must be f16, bf16, f32, f64 or dynamic (got ",
|
||||
filters_elem_type,
|
||||
").");
|
||||
|
||||
PartialShape data_pshape = get_input_partial_shape(0);
|
||||
PartialShape filters_pshape = get_input_partial_shape(1);
|
||||
PartialShape delta_pshape = get_input_partial_shape(2);
|
||||
|
||||
if (data_pshape.is_dynamic() || filters_pshape.is_dynamic() || delta_pshape.is_dynamic())
|
||||
{
|
||||
set_output_type(0, data_element_type, PartialShape::dynamic());
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<Node>
|
||||
op::v0::GroupConvolutionBackpropData::clone_with_new_inputs(const OutputVector& new_args) const
|
||||
{
|
||||
if (new_args.size() != 3)
|
||||
{
|
||||
throw ngraph_error("Incorrect number of new arguments");
|
||||
}
|
||||
|
||||
return make_shared<op::v0::GroupConvolutionBackpropData>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
get_window_movement_strides(),
|
||||
get_window_dilation_strides(),
|
||||
get_padding_below(),
|
||||
get_padding_above(),
|
||||
get_groups());
|
||||
}
|
||||
|
||||
OutputVector op::v0::GroupConvolutionBackpropData::decompose_op() const
|
||||
{
|
||||
auto filters = input_value(1);
|
||||
auto output_delta = input_value(2);
|
||||
auto data_shape = get_input_shape(0);
|
||||
|
||||
NodeVector sliced_inputs;
|
||||
|
||||
auto groups = get_groups();
|
||||
// slice data shape
|
||||
data_shape[1] /= groups;
|
||||
// slice delta
|
||||
auto sliced_delta = builder::opset1::split(output_delta, groups, 1);
|
||||
// slice filters
|
||||
auto sliced_filters = builder::opset1::split(filters, groups, 0);
|
||||
|
||||
auto num_spatials = get_window_movement_strides().size();
|
||||
|
||||
for (size_t i = 0; i < groups; ++i)
|
||||
{
|
||||
auto sliced_conv = std::make_shared<op::v0::ConvolutionBackpropData>(
|
||||
data_shape,
|
||||
sliced_filters[i],
|
||||
sliced_delta[i],
|
||||
get_window_movement_strides(),
|
||||
get_window_dilation_strides(),
|
||||
get_padding_below(),
|
||||
get_padding_above(),
|
||||
Strides(num_spatials, 1)); // default data dilation strides
|
||||
|
||||
sliced_inputs.push_back(sliced_conv);
|
||||
}
|
||||
|
||||
size_t concatenation_axis = 1;
|
||||
return {std::make_shared<ngraph::op::Concat>(sliced_inputs, concatenation_axis)};
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/op/convolution.hpp"
|
||||
#include "ngraph/op/op.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
#include "ngraph/op/util/fused_op.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace op
|
||||
{
|
||||
namespace v0
|
||||
{
|
||||
/// \brief Group Convolution
|
||||
class BACKEND_API GroupConvolution : public ngraph::op::util::FusedOp
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"GroupConvolution", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
GroupConvolution() = default;
|
||||
GroupConvolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const size_t groups,
|
||||
const PadType& pad_type = PadType::EXPLICIT);
|
||||
|
||||
// constructor which accept groups included in filters shape.
|
||||
GroupConvolution(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const Strides& data_dilation_strides,
|
||||
const PadType& pad_type = PadType::EXPLICIT);
|
||||
Shape get_weights_dimensions() const;
|
||||
const Strides& get_window_movement_strides() const
|
||||
{
|
||||
return m_window_movement_strides;
|
||||
}
|
||||
const Strides& get_window_dilation_strides() const
|
||||
{
|
||||
return m_window_dilation_strides;
|
||||
}
|
||||
const CoordinateDiff& get_padding_below() const { return m_padding_below; }
|
||||
const CoordinateDiff& get_padding_above() const { return m_padding_above; }
|
||||
const Strides& get_data_dilation_strides() const { return m_data_dilation_strides; }
|
||||
Output<Node> get_filters() { return input_value(1); }
|
||||
Output<Node> get_data_batch() { return input_value(0); }
|
||||
size_t get_groups() const { return m_groups; };
|
||||
const PadType& get_pad_type() const { return m_pad_type; }
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
virtual OutputVector decompose_op() const override;
|
||||
|
||||
virtual void pre_validate_and_infer_types() override;
|
||||
virtual void post_validate_and_infer_types() override;
|
||||
|
||||
bool has_groups_in_filters() const { return m_groups_in_filters; }
|
||||
|
||||
protected:
|
||||
Strides m_window_movement_strides;
|
||||
Strides m_window_dilation_strides;
|
||||
CoordinateDiff m_padding_below;
|
||||
CoordinateDiff m_padding_above;
|
||||
Strides m_data_dilation_strides;
|
||||
size_t m_groups;
|
||||
PadType m_pad_type{PadType::NOTSET};
|
||||
|
||||
private:
|
||||
bool m_groups_in_filters;
|
||||
};
|
||||
|
||||
/// \brief Group Convolution data batch backprop
|
||||
class BACKEND_API GroupConvolutionBackpropData : public ngraph::op::util::FusedOp
|
||||
{
|
||||
public:
|
||||
static constexpr NodeTypeInfo type_info{"GroupConvolutionBackpropData", 0};
|
||||
const NodeTypeInfo& get_type_info() const override { return type_info; }
|
||||
GroupConvolutionBackpropData() = default;
|
||||
GroupConvolutionBackpropData(const Output<Node>& data_batch,
|
||||
const Output<Node>& filters,
|
||||
const Output<Node>& output_delta,
|
||||
const Strides& window_movement_strides,
|
||||
const Strides& window_dilation_strides,
|
||||
const CoordinateDiff& padding_below,
|
||||
const CoordinateDiff& padding_above,
|
||||
const size_t groups);
|
||||
|
||||
const Strides& get_window_movement_strides() const
|
||||
{
|
||||
return m_window_movement_strides;
|
||||
}
|
||||
const Strides& get_window_dilation_strides() const
|
||||
{
|
||||
return m_window_dilation_strides;
|
||||
}
|
||||
const CoordinateDiff& get_padding_below() const { return m_padding_below; }
|
||||
const CoordinateDiff& get_padding_above() const { return m_padding_above; }
|
||||
size_t get_groups() const { return m_groups; };
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
virtual OutputVector decompose_op() const override;
|
||||
|
||||
virtual void pre_validate_and_infer_types() override;
|
||||
|
||||
protected:
|
||||
Strides m_window_movement_strides;
|
||||
Strides m_window_dilation_strides;
|
||||
CoordinateDiff m_padding_below;
|
||||
CoordinateDiff m_padding_above;
|
||||
size_t m_groups;
|
||||
};
|
||||
}
|
||||
} // namespace op
|
||||
} // namespace ngraph
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
@ -1,101 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
// This collection contains one entry for each op. If an op is added it must be
|
||||
// added to this list.
|
||||
//
|
||||
// In order to use this list you want to define a macro named exactly NGRAPH_OP
|
||||
// When you are done you should undef the macro
|
||||
// As an example if you wanted to make a list of all op names as strings you could do this:
|
||||
//
|
||||
// #define NGRAPH_OP(a,b) #a,
|
||||
// std::vector<std::string> op_names{
|
||||
// #include "this include file name"
|
||||
// };
|
||||
// #undef NGRAPH_OP
|
||||
//
|
||||
// This sample expands to a list like this:
|
||||
// "Abs",
|
||||
// "Acos",
|
||||
// ...
|
||||
//
|
||||
// #define NGRAPH_OP(a,b) b::a,
|
||||
// std::vector<std::string> op_names{
|
||||
// #include "this include file name"
|
||||
// };
|
||||
// #undef NGRAPH_OP
|
||||
//
|
||||
// This sample expands to a list like this:
|
||||
// ngraph::op::Abs,
|
||||
// ngraph::op::Acos,
|
||||
// ...
|
||||
//
|
||||
// It's that easy. You can use this for fun and profit.
|
||||
|
||||
#ifndef NGRAPH_OP
|
||||
#warning "NGRAPH_OP not defined"
|
||||
#define NGRAPH_OP(x, y)
|
||||
#endif
|
||||
|
||||
NGRAPH_OP(Abs, ngraph::op)
|
||||
NGRAPH_OP(Acos, ngraph::op)
|
||||
NGRAPH_OP(Asin, ngraph::op)
|
||||
NGRAPH_OP(Atan, ngraph::op)
|
||||
NGRAPH_OP(AvgPool, ngraph::op::v0)
|
||||
NGRAPH_OP(BatchNormInference, ngraph::op::v0)
|
||||
NGRAPH_OP(Broadcast, ngraph::op::v1)
|
||||
NGRAPH_OP(Ceiling, ngraph::op)
|
||||
NGRAPH_OP(Clamp, ngraph::op)
|
||||
NGRAPH_OP(Concat, ngraph::op)
|
||||
NGRAPH_OP(Constant, ngraph::op)
|
||||
NGRAPH_OP(Convert, ngraph::op)
|
||||
NGRAPH_OP(Convolution, ngraph::op::v0)
|
||||
NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v0)
|
||||
NGRAPH_OP(Cos, ngraph::op)
|
||||
NGRAPH_OP(Cosh, ngraph::op)
|
||||
NGRAPH_OP(CumSum, ngraph::op::v0)
|
||||
NGRAPH_OP(DepthToSpace, ngraph::op)
|
||||
NGRAPH_OP(Elu, ngraph::op)
|
||||
NGRAPH_OP(Erf, ngraph::op)
|
||||
NGRAPH_OP(Exp, ngraph::op)
|
||||
NGRAPH_OP(FakeQuantize, ngraph::op)
|
||||
NGRAPH_OP(Floor, ngraph::op)
|
||||
NGRAPH_OP(GRN, ngraph::op)
|
||||
NGRAPH_OP(Gather, ngraph::op::v1)
|
||||
NGRAPH_OP(Gelu, ngraph::op)
|
||||
NGRAPH_OP(GroupConvolution, ngraph::op::v0)
|
||||
NGRAPH_OP(GroupConvolutionBackpropData, ngraph::op::v0)
|
||||
NGRAPH_OP(HardSigmoid, ngraph::op)
|
||||
NGRAPH_OP(Interpolate, ngraph::op::v0)
|
||||
NGRAPH_OP(Log, ngraph::op)
|
||||
NGRAPH_OP(LRN, ngraph::op)
|
||||
NGRAPH_OP(LSTMSequence, ngraph::op::v0)
|
||||
NGRAPH_OP(MatMul, ngraph::op)
|
||||
NGRAPH_OP(MVN, ngraph::op)
|
||||
NGRAPH_OP(Negative, ngraph::op)
|
||||
NGRAPH_OP(NormalizeL2, ngraph::op::v0)
|
||||
NGRAPH_OP(Parameter, ngraph::op)
|
||||
NGRAPH_OP(PRelu, ngraph::op)
|
||||
NGRAPH_OP(PriorBox, ngraph::op)
|
||||
NGRAPH_OP(Range, ngraph::op)
|
||||
NGRAPH_OP(Relu, ngraph::op)
|
||||
NGRAPH_OP(Result, ngraph::op)
|
||||
NGRAPH_OP(ReverseSequence, ngraph::op)
|
||||
NGRAPH_OP(Selu, ngraph::op)
|
||||
NGRAPH_OP(ShapeOf, ngraph::op)
|
||||
NGRAPH_OP(ShuffleChannels, ngraph::op)
|
||||
NGRAPH_OP(Sigmoid, ngraph::op)
|
||||
NGRAPH_OP(Sign, ngraph::op)
|
||||
NGRAPH_OP(Sin, ngraph::op)
|
||||
NGRAPH_OP(Sinh, ngraph::op)
|
||||
NGRAPH_OP(SpaceToDepth, ngraph::op)
|
||||
NGRAPH_OP(Sqrt, ngraph::op)
|
||||
NGRAPH_OP(SquaredDifference, ngraph::op)
|
||||
NGRAPH_OP(Squeeze, ngraph::op)
|
||||
NGRAPH_OP(Tan, ngraph::op)
|
||||
NGRAPH_OP(Tanh, ngraph::op)
|
||||
NGRAPH_OP(TensorIterator, ngraph::op)
|
||||
NGRAPH_OP(Tile, ngraph::op::v0)
|
||||
NGRAPH_OP(Unsqueeze, ngraph::op::v0)
|
||||
NGRAPH_OP(Xor, ngraph::op)
|
@ -1,80 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "fused_op_decomposition.hpp"
|
||||
#include "ngraph/graph_util.hpp"
|
||||
#include "ngraph/op/util/op_types.hpp"
|
||||
#include "ngraph/provenance.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
pass::FusedOpDecomposition::FusedOpDecomposition(op_query_t callback)
|
||||
: m_has_direct_support{callback}
|
||||
{
|
||||
}
|
||||
|
||||
bool pass::FusedOpDecomposition::run_on_node(shared_ptr<Node> node)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
if (op::supports_decompose(node))
|
||||
{
|
||||
if (m_has_direct_support && m_has_direct_support(*node))
|
||||
{
|
||||
// Op supported by backend. Do not decompose
|
||||
return modified;
|
||||
}
|
||||
|
||||
OutputVector output_vector = node->decompose_op();
|
||||
NodeVector subgraph_outputs = as_node_vector(output_vector);
|
||||
|
||||
if (ngraph::get_provenance_enabled())
|
||||
{
|
||||
// Capture the input values as an edge for provenance
|
||||
auto base_input_values = node->input_values();
|
||||
auto provenance_tags = node->get_provenance_tags();
|
||||
const std::string tag = "<Decomposed from " + std::string(node->get_type_name()) + ">";
|
||||
provenance_tags.insert(tag);
|
||||
|
||||
// Transfer the new provenance tags to the newly created ops
|
||||
for (auto output_node : subgraph_outputs)
|
||||
{
|
||||
output_node->add_provenance_tags_above(base_input_values, provenance_tags);
|
||||
}
|
||||
}
|
||||
|
||||
// Run recursively until no more fused ops
|
||||
auto subgraph = extract_subgraph(subgraph_outputs, as_node_vector(node->input_values()));
|
||||
for (auto subgraph_node : subgraph)
|
||||
{
|
||||
run_on_node(subgraph_node);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (auto output_node : subgraph_outputs)
|
||||
{
|
||||
for (size_t j = 0; j < output_node->outputs().size(); j++, i++)
|
||||
{
|
||||
std::set<Input<Node>> fop_users = node->outputs().at(i).get_target_inputs();
|
||||
for (auto fop_user : fop_users)
|
||||
{
|
||||
fop_user.replace_source_output(output_node->output(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i != node->get_output_size())
|
||||
{
|
||||
throw ngraph_error("While replacing " + node->get_name() +
|
||||
", mismatch between op output count and outputs of the decomposed "
|
||||
"subgraph. Expected: " +
|
||||
to_string(node->get_output_size()) + " Got: " + to_string(i));
|
||||
}
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/pass/pass.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace pass
|
||||
{
|
||||
/// \brief The FusedOpDecomposition pass is used to decompose a fused op
|
||||
/// into a sub-graph of supported ops if the fused op is not supported by
|
||||
/// the backend.
|
||||
///
|
||||
/// \details By default, the pass decomposes a fused op if it is not
|
||||
/// supported by the backend and runs recursively until no more fused ops
|
||||
/// can be found or the new ops are supported by the backend.
|
||||
/// If the backend supports a fused op, then it can provide a callback
|
||||
/// function while registering the pass. The callback function can then
|
||||
/// provide logic to prevent decomposing the supported op.
|
||||
/// It also adds provenance tags along the way to each op for easy reference
|
||||
/// and debugging.
|
||||
///
|
||||
/// In the example shown below, the original graph has a fused GeLU op.
|
||||
/// After applying this pass, the GeLU op is decomposed into group of ops which
|
||||
/// together perform the same operation as GeLU.
|
||||
/// <table>
|
||||
/// <tr><th>Before the pass</th>
|
||||
/// <th> After the pass</th>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td> \image html decompose_gelu_pre.svg </td>
|
||||
/// <td> \image html decompose_gelu_post.svg </td>
|
||||
/// </tr>
|
||||
/// </table>
|
||||
class BACKEND_API FusedOpDecomposition : public NodePass
|
||||
{
|
||||
public: /// \brief Function signature type for callback used to check whether provided node
|
||||
/// is supported by backend.
|
||||
using op_query_t = std::function<bool(const Node& node)>;
|
||||
|
||||
///
|
||||
/// \brief Constructor for the Fused operation decomposition pass.
|
||||
///
|
||||
/// \param[in] callback The function object used to determine whether current backend
|
||||
/// provide direct support for passed node. Should have signature:
|
||||
/// bool fn(const Node&)
|
||||
///
|
||||
FusedOpDecomposition(op_query_t callback = nullptr);
|
||||
bool run_on_node(std::shared_ptr<ngraph::Node> node) override;
|
||||
|
||||
private:
|
||||
/// \brief A function returning whether provided Node is supported by current backend.
|
||||
/// The returned bool value is used to control whether decompose operator or not.
|
||||
op_query_t m_has_direct_support = nullptr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
@ -1,61 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "implicit_broadcast_elimination.hpp"
|
||||
|
||||
#include "ngraph/builder/autobroadcast.hpp"
|
||||
#include "ngraph/graph_util.hpp"
|
||||
#include "ngraph/op/util/binary_elementwise_arithmetic.hpp"
|
||||
#include "ngraph/op/util/binary_elementwise_comparison.hpp"
|
||||
#include "ngraph/op/util/binary_elementwise_logical.hpp"
|
||||
#include "ngraph/op/util/op_types.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
bool ngraph::pass::ImplicitBroadcastElimination::run_on_node(std::shared_ptr<Node> node)
|
||||
{
|
||||
if (ngraph::op::supports_auto_broadcast(node))
|
||||
{
|
||||
if (node->get_autob().m_type != op::AutoBroadcastType::NONE)
|
||||
{
|
||||
auto new_args = pass::explicit_broadcast(node);
|
||||
for (size_t i = 0; i < new_args.size(); i++)
|
||||
{
|
||||
node->input(i).replace_source_output(new_args[i]->output(0));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NodeVector ngraph::pass::explicit_broadcast(std::shared_ptr<Node>& node)
|
||||
{
|
||||
NodeVector rc;
|
||||
if (ngraph::op::supports_auto_broadcast(node))
|
||||
{
|
||||
auto autob = node->get_autob();
|
||||
if (autob.m_type == op::AutoBroadcastType::NONE)
|
||||
{
|
||||
for (auto& val : node->input_values())
|
||||
rc.emplace_back(val.get_node_shared_ptr());
|
||||
}
|
||||
else if (autob.m_type == op::AutoBroadcastType::NUMPY)
|
||||
{
|
||||
rc = as_node_vector(builder::numpy_broadcast_outputs(node->input_values()));
|
||||
}
|
||||
else if (autob.m_type == op::AutoBroadcastType::PDPD)
|
||||
{
|
||||
rc = as_node_vector(builder::pdpd_broadcast(node->input_values(), autob.m_axis));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ngraph_error("Unsupported implicit broadcast type");
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/pass/pass.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace pass
|
||||
{
|
||||
NodeVector explicit_broadcast(std::shared_ptr<Node>& node);
|
||||
class ImplicitBroadcastElimination;
|
||||
}
|
||||
}
|
||||
|
||||
class BACKEND_API ngraph::pass::ImplicitBroadcastElimination : public ngraph::pass::NodePass
|
||||
{
|
||||
public:
|
||||
bool run_on_node(std::shared_ptr<ngraph::Node> node) override;
|
||||
};
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
@ -1,119 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "liveness.hpp"
|
||||
#include "ngraph/descriptor/input.hpp"
|
||||
#include "ngraph/descriptor/output.hpp"
|
||||
#include "ngraph/function.hpp"
|
||||
#include "ngraph/graph_util.hpp"
|
||||
#include "ngraph/log.hpp"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/op/constant.hpp"
|
||||
#include "ngraph/op/parameter.hpp"
|
||||
#include "ngraph/op/result.hpp"
|
||||
#include "ngraph/util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
bool pass::Liveness::run_on_function(shared_ptr<Function> function)
|
||||
{
|
||||
auto ops = function->get_ordered_ops();
|
||||
|
||||
unordered_set<descriptor::Tensor*> persistent_tensors;
|
||||
unordered_set<descriptor::Tensor*> output_tensors;
|
||||
for (const shared_ptr<op::Parameter>& node : function->get_parameters())
|
||||
{
|
||||
for (auto& output : node->outputs())
|
||||
{
|
||||
descriptor::Tensor& tensor = output.get_tensor();
|
||||
persistent_tensors.insert(&tensor);
|
||||
}
|
||||
}
|
||||
for (const shared_ptr<op::Result>& node : function->get_results())
|
||||
{
|
||||
for (auto& output : node->outputs())
|
||||
{
|
||||
descriptor::Tensor& tensor = output.get_tensor();
|
||||
persistent_tensors.insert(&tensor);
|
||||
output_tensors.insert(&tensor);
|
||||
}
|
||||
}
|
||||
for (const shared_ptr<Node>& node : ops)
|
||||
{
|
||||
if (auto constant_node = as_type_ptr<op::Constant>(node))
|
||||
{
|
||||
for (auto& output : constant_node->outputs())
|
||||
{
|
||||
descriptor::Tensor& tensor = output.get_tensor();
|
||||
persistent_tensors.insert(&tensor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unordered_set<descriptor::Tensor*> currently_live;
|
||||
for (auto it = ops.rbegin(); it != ops.rend(); it++)
|
||||
{
|
||||
const shared_ptr<Node>& node = *it;
|
||||
node->liveness_new_list.clear();
|
||||
node->liveness_free_list.clear();
|
||||
unordered_set<descriptor::Tensor*> input_tensor_decls;
|
||||
for (auto& input : node->inputs())
|
||||
{
|
||||
descriptor::Tensor& tensor = input.get_tensor();
|
||||
if (persistent_tensors.find(&tensor) == persistent_tensors.end())
|
||||
{
|
||||
input_tensor_decls.insert(&tensor);
|
||||
}
|
||||
}
|
||||
|
||||
unordered_set<descriptor::Tensor*> output_tensor_decls;
|
||||
for (auto& output : node->outputs())
|
||||
{
|
||||
descriptor::Tensor& tensor = output.get_tensor();
|
||||
if (persistent_tensors.find(&tensor) == persistent_tensors.end())
|
||||
{
|
||||
output_tensor_decls.insert(&tensor);
|
||||
}
|
||||
}
|
||||
|
||||
unordered_set<descriptor::Tensor*> free_tensor_decls;
|
||||
unordered_set<descriptor::Tensor*> new_tensor_decls;
|
||||
unordered_set<descriptor::Tensor*> all_tensor_decls = input_tensor_decls;
|
||||
all_tensor_decls.insert(output_tensor_decls.begin(), output_tensor_decls.end());
|
||||
|
||||
for (descriptor::Tensor* tensor_decl : all_tensor_decls)
|
||||
{
|
||||
if (currently_live.find(tensor_decl) == currently_live.end())
|
||||
{
|
||||
// this is the last node that value is seen in
|
||||
// delete it at the end of the op
|
||||
currently_live.insert(tensor_decl);
|
||||
if (output_tensors.find(tensor_decl) == output_tensors.end())
|
||||
{
|
||||
// Don't free output tensors
|
||||
free_tensor_decls.insert(tensor_decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (descriptor::Tensor* output_decl : output_tensor_decls)
|
||||
{
|
||||
auto currently_live_it = currently_live.find(output_decl);
|
||||
if (currently_live_it != currently_live.end())
|
||||
{
|
||||
new_tensor_decls.insert(output_decl);
|
||||
currently_live.erase(currently_live_it);
|
||||
}
|
||||
}
|
||||
node->liveness_free_list = free_tensor_decls;
|
||||
node->liveness_new_list = new_tensor_decls;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/descriptor/tensor.hpp"
|
||||
#include "ngraph/pass/pass.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace pass
|
||||
{
|
||||
class Liveness;
|
||||
}
|
||||
}
|
||||
|
||||
class BACKEND_API ngraph::pass::Liveness : public FunctionPass
|
||||
{
|
||||
public:
|
||||
bool run_on_function(std::shared_ptr<ngraph::Function>) override;
|
||||
};
|
@ -1,132 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
|
||||
#include "ngraph/builder/autobroadcast.hpp"
|
||||
#include "ngraph/builder/reshape.hpp"
|
||||
#include "ngraph/graph_util.hpp"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
#include "ngraph/op/util/op_types.hpp"
|
||||
#include "ngraph/ops.hpp"
|
||||
#include "ngraph/provenance.hpp"
|
||||
#include "ngraph/slice_plan.hpp"
|
||||
#include "ngraph/type.hpp"
|
||||
#include "ngraph/validation_util.hpp"
|
||||
#include "op/avg_pool.hpp"
|
||||
#include "pass/implicit_broadcast_elimination.hpp"
|
||||
#include "pass/opset0_downgrade.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
namespace opset0_downgrade
|
||||
{
|
||||
template <typename OpV0, typename OpV1>
|
||||
shared_ptr<Node> op_cast_binary_elementwise_node(const shared_ptr<OpV1>& node)
|
||||
{
|
||||
const auto input_arg0 = node->input_value(0);
|
||||
const auto input_arg1 = node->input_value(1);
|
||||
const auto autob = node->get_autob();
|
||||
auto replacement_node = make_shared<OpV0>(input_arg0, input_arg1, autob);
|
||||
replace_node(node, replacement_node);
|
||||
return replacement_node;
|
||||
}
|
||||
|
||||
template <typename OpV0, typename OpV1>
|
||||
shared_ptr<Node> op_cast_reduction_node(const shared_ptr<OpV1>& node)
|
||||
{
|
||||
auto replacement_node = make_shared<OpV0>(node->input_value(0), node->input_value(1));
|
||||
if (node->get_keep_dims())
|
||||
{
|
||||
string v1_op_name = string{node->get_type_name()} + ":v1";
|
||||
string v0_op_name = string{OpV0{}.get_type_name()} + ":v0";
|
||||
|
||||
NGRAPH_CHECK(node->reduction_axes_constant(),
|
||||
"Unable to convert ",
|
||||
v1_op_name,
|
||||
"to ",
|
||||
v0_op_name,
|
||||
" if reduction axes are not constant (for keep_dims=true). Node: ",
|
||||
*node);
|
||||
auto output_pshape = replacement_node->get_output_partial_shape(0);
|
||||
NGRAPH_CHECK(output_pshape.is_static(),
|
||||
"Unable to convert ",
|
||||
v1_op_name,
|
||||
"to ",
|
||||
v0_op_name,
|
||||
" if output shape is dynamic (for keep_dims=true). Node: ",
|
||||
*node);
|
||||
const auto output_shape = output_pshape.to_shape();
|
||||
auto reshaped_output_shape = output_shape;
|
||||
for (const auto& axis : node->get_reduction_axes())
|
||||
{
|
||||
reshaped_output_shape.insert(reshaped_output_shape.begin() + axis, 1);
|
||||
}
|
||||
auto shape_pattern = op::Constant::create(
|
||||
element::u64, {reshaped_output_shape.size()}, reshaped_output_shape);
|
||||
auto reshaped_product =
|
||||
make_shared<op::v1::Reshape>(replacement_node->output(0), shape_pattern, false);
|
||||
return reshaped_product;
|
||||
}
|
||||
else
|
||||
{
|
||||
return replacement_node;
|
||||
}
|
||||
}
|
||||
|
||||
// Default is that we did nothing
|
||||
shared_ptr<Node> op_cast(shared_ptr<Node> node) { return nullptr; }
|
||||
shared_ptr<Node> op_cast(shared_ptr<op::v1::LogicalXor> node)
|
||||
{
|
||||
return op_cast_binary_elementwise_node<op::v0::Xor, op::v1::LogicalXor>(node);
|
||||
}
|
||||
|
||||
using DispatchMap = map<NodeTypeInfo, std::function<bool(shared_ptr<Node> node)>>;
|
||||
|
||||
template <typename T>
|
||||
bool op_cast_thunk(shared_ptr<Node> node)
|
||||
{
|
||||
auto downgraded_node = op_cast(as_type_ptr<T>(node));
|
||||
if (downgraded_node)
|
||||
{
|
||||
if (ngraph::get_provenance_enabled())
|
||||
{
|
||||
const std::string provenance_tag =
|
||||
"<Opset0_Downgrade (v1 " + std::string(node->get_type_name()) + ")>";
|
||||
downgraded_node->add_provenance_tags_above(node->input_values(), {provenance_tag});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DispatchMap& get_dispatch_map()
|
||||
{
|
||||
static DispatchMap dispatch_map{
|
||||
#define NGRAPH_OP(NAME, NAMESPACE) {NAMESPACE::NAME::type_info, op_cast_thunk<NAMESPACE::NAME>},
|
||||
#include "ngraph/opsets/opset1_tbl.hpp"
|
||||
#undef NGRAPH_OP
|
||||
};
|
||||
return dispatch_map;
|
||||
}
|
||||
} // namespace opset0_downgrade
|
||||
|
||||
bool pass::Opset0Downgrade::run_on_node(shared_ptr<Node> node)
|
||||
{
|
||||
bool modified = false;
|
||||
auto& dispatch_map = opset0_downgrade::get_dispatch_map();
|
||||
auto it = dispatch_map.find(node->get_type_info());
|
||||
if (it != dispatch_map.end())
|
||||
{
|
||||
modified = it->second(node);
|
||||
}
|
||||
return modified;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "backend_visibility.hpp"
|
||||
#include "ngraph/pass/pass.hpp"
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace pass
|
||||
{
|
||||
class BACKEND_API Opset0Downgrade : public NodePass
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// \brief Constructor for the Opv1 downgrade transformation pass.
|
||||
///
|
||||
/// \details This transformation pass iterates over all nodes in a graph
|
||||
/// and updates version 1 ops to their version 0 equivalents.
|
||||
/// All ops in the final graph have op version 0.
|
||||
Opset0Downgrade() = default;
|
||||
bool run_on_node(std::shared_ptr<ngraph::Node> node) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user