Merge commit 'd198d57fe18d2b2479e6b4f63965a0c117731cba' into auto-batch-master

This commit is contained in:
myshevts 2021-10-28 11:47:11 +03:00
commit a72a7a9950
989 changed files with 17455 additions and 8966 deletions

View File

@ -206,6 +206,10 @@ jobs:
displayName: 'PaddlePaddle Frontend UT'
continueOnError: false
- script: . $(SETUPVARS) && $(INSTALL_TEST_DIR)/tensorflow_tests --gtest_print_time=1 --gtest_output=xml:TEST-Tensorflow.xml
displayName: 'Tensorflow Frontend UT'
continueOnError: false
# . $(SETUPVARS) && python3 $(WORK_DIR)/gtest-parallel/gtest_parallel.py $(INSTALL_TEST_DIR)/InferenceEngineUnitTests --workers=16 --dump_json_test_results=InferenceEngineUnitTests.json --gtest_filter=*smoke* -- --gtest_print_time=1
- script: . $(SETUPVARS) && $(INSTALL_TEST_DIR)/InferenceEngineUnitTests --gtest_print_time=1 --gtest_output=xml:TEST-InferenceEngineUnitTests.xml
displayName: 'IE UT old'

179
.ci/azure/linux_lohika.yml Normal file
View File

@ -0,0 +1,179 @@
resources:
repositories:
- repository: openvino_contrib
type: github
endpoint: openvinotoolkit
name: openvinotoolkit/openvino_contrib
- repository: testdata
type: github
endpoint: openvinotoolkit
name: openvinotoolkit/testdata
jobs:
- job: Lin_lohika
# About 150% of total time
timeoutInMinutes: 90
pool:
name: LIN_LOHIKA
variables:
system.debug: true
VSTS_HTTP_RETRY: 5
VSTS_HTTP_TIMEOUT: 200
BUILD_TYPE: Release
REPO_DIR: $(Build.Repository.LocalPath)
OPENVINO_CONTRIB_REPO_DIR: $(REPO_DIR)/../openvino_contrib
MODELS_PATH: $(REPO_DIR)/../testdata
WORK_DIR: $(Pipeline.Workspace)/_w
BUILD_DIR: $(WORK_DIR)/build
BUILD_SAMPLES_DIR: $(WORK_DIR)/build_samples
BUILD_LAYER_TESTS_DIR: $(WORK_DIR)/build_layer_tests
INSTALL_DIR: $(WORK_DIR)/install_pkg
INSTALL_TEST_DIR: $(INSTALL_DIR)/tests
LAYER_TESTS_DIR: $(INSTALL_TEST_DIR)/layer_tests
SETUPVARS: $(INSTALL_DIR)/setupvars.sh
steps:
- script: |
curl -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2019-06-01"
whoami
uname -a
echo Python3 info ; which python3 ; python3 --version
echo Python info ; which python ; python --version
echo Java info ; which java ; java -version
echo gcc info ; which gcc ; gcc --version
echo cmake info ; which cmake ; cmake --version
lsb_release
env
cat /proc/cpuinfo
cat /proc/meminfo
cat /etc/fstab
vmstat -s
df
lsblk -o NAME,HCTL,SIZE,MOUNTPOINT | grep -i "sd"
free -h
displayName: 'System info'
- script: |
rm -rf $(WORK_DIR) ; mkdir $(WORK_DIR)
rm -rf $(BUILD_DIR) ; mkdir $(BUILD_DIR)
rm -rf $(BUILD_SAMPLES_DIR) ; mkdir $(BUILD_SAMPLES_DIR)
echo TargetBranch: $(System.PullRequest.TargetBranch)
echo SourceBranch: $(Build.SourceBranch)
displayName: 'Make dir'
- checkout: self
clean: true
lfs: false
submodules: recursive
path: openvino
- checkout: openvino_contrib
clean: true
lfs: false
submodules: recursive
path: openvino_contrib
- script: |
set -e
$(REPO_DIR)/install_build_dependencies.sh
# Move jdk into contrib
sudo apt --assume-yes install openjdk-11-jdk
# For opencv-python: python3-setuptools and pip upgrade
python3 -m pip install --upgrade pip
python3 -m pip install -r $(REPO_DIR)/inference-engine/ie_bridges/python/requirements.txt
python3 -m pip install -r $(REPO_DIR)/inference-engine/ie_bridges/python/wheel/requirements-dev.txt
# For running Python API tests
python3 -m pip install -r $(REPO_DIR)/inference-engine/ie_bridges/python/src/requirements-dev.txt
# For running PaddlePaddle frontend unit tests
python3 -m pip install -r $(REPO_DIR)/ngraph/test/frontend/paddlepaddle/requirements_dev.txt
# For running ONNX frontend unit tests
python3 -m pip install -r $(REPO_DIR)/ngraph/test/requirements_test_onnx.txt
# For MO unit tests
python3 -m pip install -r $(REPO_DIR)/model-optimizer/requirements.txt
python3 -m pip install -r $(REPO_DIR)/model-optimizer/requirements_dev.txt
# Speed up build
wget https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip
unzip ninja-linux.zip
sudo cp -v ninja /usr/local/bin/
# Speed up tests
git clone https://github.com/google/gtest-parallel.git
workingDirectory: $(WORK_DIR)
displayName: 'Install dependencies'
# Should be after 'Install dependencies' because Git lfs is not installed
- checkout: testdata
clean: true
lfs: true
path: testdata
- task: CMake@1
inputs:
# CMake must get Python 3.x version by default
cmakeArgs: >
-GNinja
-DVERBOSE_BUILD=ON
-DCMAKE_BUILD_TYPE=$(BUILD_TYPE)
-DENABLE_PYTHON=ON
-DPYTHON_EXECUTABLE=/usr/bin/python3.8
-DENABLE_WHEEL=ON
-DENABLE_TESTS=ON
-DNGRAPH_ONNX_FRONTEND_ENABLE=ON
-DENABLE_FASTER_BUILD=ON
-DENABLE_STRICT_DEPENDENCIES=OFF
-DENABLE_REQUIREMENTS_INSTALL=OFF
-DIE_EXTRA_MODULES=$(OPENVINO_CONTRIB_REPO_DIR)/modules
$(REPO_DIR)
workingDirectory: $(BUILD_DIR)
- script: ls -alR $(REPO_DIR)/inference-engine/temp/
displayName: 'List temp SDKs'
- script: ninja
workingDirectory: $(BUILD_DIR)
displayName: 'Build Lin'
- script: ls -alR $(REPO_DIR)/bin/
displayName: 'List bin files'
- script: cmake -DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) -P cmake_install.cmake
workingDirectory: $(BUILD_DIR)
displayName: 'Install'
- script: ls -alR $(INSTALL_DIR)
displayName: 'List install files'
- script: |
set -e
mkdir $(INSTALL_DIR)/opencv/
cmake -DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) -DCOMPONENT=tests -P cmake_install.cmake
cp -R $(REPO_DIR)/inference-engine/temp/opencv_4.5.2_ubuntu20/opencv/* $(INSTALL_DIR)/opencv/
workingDirectory: $(BUILD_DIR)
displayName: 'Install tests'
- script: ls -alR $(INSTALL_DIR)
displayName: 'List install files'
- script: rm -fr $(BUILD_DIR)
displayName: 'Clean build dir'
continueOnError: false
- script: . $(SETUPVARS) && $(INSTALL_TEST_DIR)/unit-test --gtest_print_time=1 --gtest_filter=-backend_api.config_unsupported:*IE_GPU* --gtest_output=xml:TEST-NGraphUT.xml
workingDirectory: $(INSTALL_TEST_DIR)
displayName: 'nGraph UT'
continueOnError: false
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: 'JUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
testResultsFiles: '**/TEST-*.xml'
#searchFolder: '$(BUILD_DIR)'
mergeTestResults: false # Optional
#failTaskOnFailedTests: false # Optional
#testRunTitle: 'Pre/Post-Commit' # Optional
buildPlatform: 'x64' # Optional
buildConfiguration: 'Linux' # Optional
#publishRunAttachments: true # Optional

View File

@ -153,6 +153,10 @@ jobs:
displayName: 'PaddlePaddle Frontend UT'
continueOnError: false
- script: call $(SETUPVARS) && $(INSTALL_TEST_DIR)\tensorflow_tests --gtest_print_time=1 --gtest_output=xml:TEST-Tensorflow.xml
displayName: 'Tensorflow Frontend UT'
continueOnError: false
- script: |
set PATH=$(IB_DIR);%PATH%
call $(SETUPVARS) && "$(IB_TESTCONSOLE)" $(INSTALL_TEST_DIR)\InferenceEngineUnitTests.exe --gtest_output=xml:TEST-InferenceEngineUnitTests-IB.xml

14
.ci/pot/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,14 @@
#!groovy
properties([
parameters([
string(defaultValue: '',
description: 'Pipeline shared library version (branch/tag/commit). Determined automatically if empty',
name: 'library_version')
])
])
loadOpenVinoLibrary {
potEntrypoint(this)
}

6
.gitattributes vendored
View File

@ -67,9 +67,11 @@
#POT attributes
tools/pot/tests/data/test_cases_refs/* filter=lfs diff=lfs merge=lfs -text
tools/pot/tests/data/models/*/* filter=lfs diff=lfs merge=lfs -text
tools/pot/tests/data/reference_models/* filter=lfs diff=lfs merge=lfs -text
tools/pot/tests/data/video/* filter=lfs diff=lfs merge=lfs -text
tools/pot/tests/data/reference_fake_quantize_conf/* filter=lfs diff=lfs merge=lfs -text
/tools/pot/tests/** -pot_package
/configs/accuracy_checker/** -pot_package
/configs/quantization/** -pot_package
/tools/pot/tools/auxilary/** -pot_package
/tools/pot/tools/run_series_experiments.py -pot_package
/tools/pot/.pylintrc -pot_package

3
.gitignore vendored
View File

@ -1,7 +1,8 @@
# build/artifact dirs
_*
# but ensure we don't skip __init__.py
# but ensure we don't skip __init__.py and __main__.py
!__init__.py
!__main__.py
# developer tools
*.idea

View File

@ -46,6 +46,9 @@
# `openvino::frontend::paddlepaddle`
# PaddlePaddle FrontEnd target (optional)
#
# `openvino::frontend::tensorflow`
# TensorFlow FrontEnd target (optional)
#
# Result variables:
# ------
#
@ -63,6 +66,9 @@
# `OpenVINO_Frontend_PaddlePaddle_FOUND`
# OpenVINO PaddlePaddle frontend is available
#
# `OpenVINO_Frontend_TensorFlow_FOUND`
# OpenVINO TensorFlow frontend is available
#
# `OpenVINO_Frontend_IR_FOUND`
# OpenVINO IR frontend is available
#
@ -170,6 +176,7 @@ set(${CMAKE_FIND_PACKAGE_NAME}_Runtime_FOUND ON)
set(${CMAKE_FIND_PACKAGE_NAME}_ONNX_FOUND @NGRAPH_ONNX_FRONTEND_ENABLE@)
set(${CMAKE_FIND_PACKAGE_NAME}_PaddlePaddle_FOUND @NGRAPH_PDPD_FRONTEND_ENABLE@)
set(${CMAKE_FIND_PACKAGE_NAME}_TensorFlow_FOUND @NGRAPH_TF_FRONTEND_ENABLE@)
set(${CMAKE_FIND_PACKAGE_NAME}_IR_FOUND @NGRAPH_IR_FRONTEND_ENABLE@)
set(${CMAKE_FIND_PACKAGE_NAME}_Frontend_ONNX_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_ONNX_FOUND})
set(${CMAKE_FIND_PACKAGE_NAME}_Frontend_PaddlePaddle_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_PaddlePaddle_FOUND})

View File

@ -1,34 +1,52 @@
# Paddle Support in the OpenVINO™ {#openvino_docs_IE_DG_Paddle_Support}
# Paddle Support in OpenVINO™ {#openvino_docs_IE_DG_Paddle_Support}
Starting from the 2022.1 release, OpenVINO™ supports reading native Paddle models.
`Core::ReadNetwork()` method provides a uniform way to read models from IR or Paddle format, it is a recommended approach to reading models.
The `Core::ReadNetwork()` method provides a uniform way to read models from either the Paddle format or IR, which is the recommended approach.
## Read Paddle Models from IR
After [Converting a Paddle Model](../MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md) to [Intermediate Representation (IR)](../MO_DG/IR_and_opsets.md), it can be read as recommended. Example:
The Paddle Model can be read after it is [converted](../MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md) to [Intermediate Representation (IR)](../MO_DG/IR_and_opsets.md).
**C++ Example:**
```cpp
InferenceEngine::Core core;
auto network = core.ReadNetwork("model.xml");
```
## Read Paddle Models from Paddle Format (Paddle `inference model` model type)
**Python Example:**
**Example:**
```sh
from openvino.inference_engine import IECore
ie = IECore()
net = ie.read_network("model.xml")
```
## Read Paddle Models from The Paddle Format (Paddle `inference model` model type)
**C++ Example:**
```cpp
InferenceEngine::Core core;
auto network = core.ReadNetwork("model.pdmodel");
```
**Reshape feature:**
**Python Example:**
OpenVINO™ does not provide a mechanism to specify pre-processing, such as mean values subtraction and reverse input channels, for the Paddle format.
```sh
from openvino.inference_engine import IECore
ie = IECore()
net = ie.read_network("model.pdmodel")
```
**The Reshape feature:**
OpenVINO™ does not provide a mechanism to specify pre-processing, such as mean values subtraction or reverse input channels, for the Paddle format.
If a Paddle model contains dynamic shapes for input, use the `CNNNetwork::reshape` method for shape specialization.
## NOTE
## NOTES
* Paddle [`inference model`](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.1/doc/doc_en/inference_en.md) mainly contains two kinds of files `model.pdmodel`(model file) and `model.pdiparams`(params file), which are used for inference.
* Supported Paddle models list and how to export these models are described in [Convert a Paddle Model](../MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md).
* The Paddle [`inference model`](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.1/doc/doc_en/inference_en.md) mainly contains two kinds of files `model.pdmodel`(model file) and `model.pdiparams`(params file), which are used for inference.
* The list of supported Paddle models and a description of how to export them can be found in [Convert a Paddle Model](../MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md).
* For `Normalize` Paddle Models, the input data should be in FP32 format.
* When reading Paddle models from Paddle format, make sure that `model.pdmodel` and `model.pdiparams` are in the same folder directory.
* When reading Paddle models from The Paddle format, make sure that `model.pdmodel` and `model.pdiparams` are in the same folder directory.

View File

@ -1,79 +1,101 @@
Remote Blob API of GPU Plugin {#openvino_docs_IE_DG_supported_plugins_GPU_RemoteBlob_API}
================================
The GPU plugin implementation of the `RemoteContext` and `RemoteBlob` interfaces supports GPU
pipeline developers who need video memory sharing and interoperability with existing native APIs
The GPU plugin implementation of the `RemoteContext` and `RemoteBlob` interfaces supports GPU
pipeline developers who need video memory sharing and interoperability with existing native APIs
such as OpenCL\*, Microsoft DirectX\*, or VAAPI\*.
Using these interfaces allows to avoid any memory copy overhead when plugging the OpenVINO™ inference
into an existing GPU pipeline. It also enables OpenCL kernels participating in the pipeline to become
Using these interfaces allows to avoid any memory copy overhead when plugging the OpenVINO™ inference
into an existing GPU pipeline. It also enables OpenCL kernels participating in the pipeline to become
native buffer consumers or producers of the OpenVINO™ inference.
Since the GPU plugin works on top of the clDNN library, the functionality above is also implemented
Since the GPU plugin works on top of the clDNN library, the functionality above is also implemented
using OpenCL and its sharing extensions provided by Intel®.
There are two interoperability scenarios that are supported for the Remote Blob API:
* GPU plugin context and memory objects can be constructed from low-level device, display, or memory
handles and used to create the OpenVINO™ `ExecutableNetwork` or `Blob` class.
* GPU plugin context and memory objects can be constructed from low-level device, display, or memory
handles and used to create the OpenVINO™ `ExecutableNetwork` or `Blob` class.
* OpenCL context or buffer handles can be obtained from existing GPU plugin objects, and used in OpenCL processing.
Class and function declarations for the API are defined in the following files:
* Windows\*: `gpu/gpu_context_api_ocl.hpp` and `gpu/gpu_context_api_dx.hpp`
* Windows\*: `gpu/gpu_context_api_ocl.hpp` and `gpu/gpu_context_api_dx.hpp`
* Linux\*: `gpu/gpu_context_api_ocl.hpp` and `gpu/gpu_context_api_va.hpp`
The most common way to enable the interaction of your application with the Remote Blob API is to use user-side utility classes
and functions that consume or produce native handles directly.
The most common way to enable the interaction of your application with the Remote Blob API is to use user-side utility classes
and functions that consume or produce native handles directly.
## Execution Context User-Side Wrappers
GPU plugin classes that implement the `RemoteContext` interface are responsible for context sharing.
Obtaining a pointer to a context object is the first step of sharing pipeline objects.
The context object of the GPU plugin directly wraps OpenCL context, setting a scope for sharing
Obtaining a pointer to a context object is the first step of sharing pipeline objects.
The context object of the GPU plugin directly wraps OpenCL context, setting a scope for sharing
`ExecutableNetwork` and `RemoteBlob` objects.
To create such objects within user context, explicitly provide the context to the plugin using the
`make_shared_context()` overloaded function. Depending on the platform, the function accepts the
`cl_context` handle, the pointer to the `ID3D11Device` interface, or the `VADisplay` handle, and
To create such objects within user context, explicitly provide the context to the plugin using the
`make_shared_context()` overloaded function. Depending on the platform, the function accepts the
`cl_context` handle, the pointer to the `ID3D11Device` interface, or the `VADisplay` handle, and
returns a smart pointer to the `RemoteContext` plugin object.
If you do not provide any user context, the plugin uses its default internal context.
The plugin attempts to use the same internal context object as long as plugin options are kept the same.
Therefore, all ExecutableNetwork objects created during this time share the same context.
Therefore, all ExecutableNetwork objects created during this time share the same context.
Once the plugin options are changed, the internal context is replaced by the new one.
To request the current default context of the plugin, call the `GetDefaultContext()` method of the core engine.
To request the current default context of the plugin, call the `GetDefaultContext()` method of the core engine.
To request the internal context of the given `ExecutableNetwork`, use the `GetContext()` method.
## Shared Blob User-Side Wrappers
The classes that implement the `RemoteBlob` interface are both wrappers for native API
memory handles (which can be obtained from them at any time) and act just like regular OpenVINO™
The classes that implement the `RemoteBlob` interface are both wrappers for native API
memory handles (which can be obtained from them at any time) and act just like regular OpenVINO™
`Blob` objects.
Once you obtain the context, you can use it to compile a new `ExecutableNetwork` or create `RemoteBlob`
Once you obtain the context, you can use it to compile a new `ExecutableNetwork` or create `RemoteBlob`
objects.
For network compilation, use a dedicated flavor of `LoadNetwork()`, which accepts the context as an
For network compilation, use a dedicated flavor of `LoadNetwork()`, which accepts the context as an
additional parameter.
To create a shared blob from a native memory handle, use `make_shared_blob()` overloaded functions
To create a shared blob from a native memory handle, use `make_shared_blob()` overloaded functions
that can accept the `cl::Buffer`, `cl::Image2D`, `cl_mem` handles, and either `ID3D11Buffer`,
`ID3D11Texture2D` pointers or the `VASurfaceID` handle.
All `make_shared_blob()` flavors return a smart pointer to the `Blob` object, which can be directly
`ID3D11Texture2D` pointers or the `VASurfaceID` handle.
All `make_shared_blob()` flavors return a smart pointer to the `Blob` object, which can be directly
passed to the `SetBlob() `method of an inference request object.
## Direct NV12 video surface input
To support the direct consumption of a hardware video decoder output, plugin accepts two-plane video
surfaces as arguments for the `make_shared_blob_nv12()` function, which creates an `NV12Blob` object
To support the direct consumption of a hardware video decoder output, plugin accepts two-plane video
surfaces as arguments for the `make_shared_blob_nv12()` function, which creates an `NV12Blob` object
and returns a smart pointer to it, which is cast to `Blob::Ptr`.
To ensure that the plugin generates the correct execution graph for the NV12 dual-plane input, set
To ensure that the plugin generates the correct execution graph for the NV12 dual-plane input, set
the `CLDNNConfigParams::KEY_CLDNN_NV12_TWO_INPUTS` plugin configuration flag to `PluginConfigParams::YES`.
## Context & queue sharing
GPU plugin supports creation of shared context from `cl_command_queue` handle. In that case
opencl context handle is extracted from given queue via OpenCL™ API, and the queue itself is used inside
the plugin for further execution of inference primitives. Sharing of the queue changes behavior of `StartAsync()`
method to guarantee that submission of inference primitives into given queue is finished before
returning of control back to calling thread.
This sharing mechanism allows to do pipeline synchonization on app side and avoid blocking of host thread
on waiting for completion of inference. Pseudocode may look as follows:
@snippet snippets/GPU_RemoteBlob_API3.cpp part0
### Limitations
- Some primitives in GPU plugin may block host thread on waiting for previous primitives before adding its kernels
to the command queue. In such cases `StartAsync()` call takes much more time to return control to the calling thread
as internally it waits for partial or full network completion.
Examples of operations: Loop, TensorIterator, DetectionOutput, NonMaxSuppression
- Synchonization of pre/post processing jobs and inference pipleine inside shared queue is the user responsibility
- Throughput mode is not available when queue sharing is used, i.e. only single stream can be used for each executable network.
## Low-Level Methods and Their Parameter Description
The high-level wrappers above bring a direct dependency on native APIs to the user program.
If you want to avoid the dependency, you still can directly use the `CreateContext()`,
The high-level wrappers above bring a direct dependency on native APIs to the user program.
If you want to avoid the dependency, you still can directly use the `CreateContext()`,
`CreateBlob()`, and `getParams()` methods.
On this level, native handles are re-interpreted as void pointers and all arguments are passed
On this level, native handles are re-interpreted as void pointers and all arguments are passed
using `std::map` containers that are filled with `std::string, InferenceEngine::Parameter` pairs.
Two types of map entries are possible: descriptor and container. The first map entry is a
descriptor, which sets the expected structure and possible parameter values of the map.
@ -84,6 +106,7 @@ descriptor, which sets the expected structure and possible parameter values of
|----------------|---------------------------------------------------------------------|
| `CONTEXT_TYPE` | Describes the type of the shared context in a map. Can be `OCL` (for pure OpenCL context) or `VA_SHARED` (for context shared with a video decoding device). |
| `OCL_CONTEXT` | Contains the OpenCL context handle. |
| `OCL_QUEUE` | Contains the OpenCL queue handle if queue sharing is needed. |
| `VA_DEVICE` | Contains the native video decoding device handle. Can be `VADisplay` or `ID3D11Device` (a pointer). |
| `SHARED_MEM_TYPE` | Describes the type of the shared memory buffer in a map. Can be `OCL_BUFFER` (clBuffer), `OCL_IMAGE2D` (clImage2D), `VA_SURFACE()`, or `DX_BUFFER`. |
| `MEM_HANDLE` | Contains the OpenCL memory handle. |

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
# Converting a Paddle* Model {#openvino_docs_MO_DG_prepare_model_convert_model_Convert_Model_From_Paddle}
A summary of the steps for optimizing and deploying a model that was trained with Paddle\*:
A summary of the steps for optimizing and deploying a model trained with Paddle\*:
1. [Configure the Model Optimizer](../Config_Model_Optimizer.md) for Paddle\*.
2. [Convert a Paddle\* Model](#Convert_From_Paddle) to produce an optimized [Intermediate Representation (IR)](../../IR_and_opsets.md) of the model based on the trained network topology, weights, and biases values.
2. [Convert a Paddle\* Model](#Convert_From_Paddle) to produce an optimized [Intermediate Representation (IR)](../../IR_and_opsets.md) of the model based on the trained network topology, weights, and biases.
3. Test the model in the Intermediate Representation format using the [Inference Engine](../../../IE_DG/Deep_Learning_Inference_Engine_DevGuide.md) in the target environment via provided Inference Engine [sample applications](../../../IE_DG/Samples_Overview.md).
4. [Integrate](../../../IE_DG/Samples_Overview.md) the [Inference Engine](../../../IE_DG/Deep_Learning_Inference_Engine_DevGuide.md) in your application to deploy the model in the target environment.
@ -38,12 +38,12 @@ python3 mo.py --input_model <INPUT_MODEL>.pdmodel --output_dir <OUTPUT_MODEL_DIR
Parameters to convert your model:
* [Framework-agnostic parameters](Converting_Model_General.md): These parameters are used to convert a model trained with any supported framework.
> **NOTE:** `--scale`, `--scale_values`, `--mean_values`, `--mean_file` are unsupported in the current version of mo_paddle.
> **NOTE:** `--scale`, `--scale_values`, `--mean_values`, `--mean_file` are not supported in the current version of mo_paddle.
### Example of Converting a Paddle* Model
Below is the example command to convert yolo v3 Paddle\* network to OpenVINO IR network with Model Optimizer.
```sh
python3 mo.py --model_name yolov3_darknet53_270e_coco --output_dir <OUTPUT_MODEL_DIR> --framework=paddle --data_type=FP32 --reverse_input_channels --input_shape=[2,3,608,608],[1,2],[1,2] --input=image,im_shape,scale_factor --output=save_infer_model/scale_0.tmp_1,save_infer_model/scale_1.tmp_1 --input_model=yolov3.pdmodel
python3 mo.py --model_name yolov3_darknet53_270e_coco --output_dir <OUTPUT_MODEL_DIR> --framework=paddle --data_type=FP32 --reverse_input_channels --input_shape=[1,3,608,608],[1,2],[1,2] --input=image,im_shape,scale_factor --output=save_infer_model/scale_0.tmp_1,save_infer_model/scale_1.tmp_1 --input_model=yolov3.pdmodel
```
## Supported Paddle\* Layers
@ -51,12 +51,4 @@ Refer to [Supported Framework Layers](../Supported_Frameworks_Layers.md) for the
## Frequently Asked Questions (FAQ)
The Model Optimizer provides explanatory messages if it is unable to run to completion due to issues like typographical errors, incorrectly used options, or other issues. The message describes the potential cause of the problem and gives a link to the [Model Optimizer FAQ](../Model_Optimizer_FAQ.md). The FAQ has instructions on how to resolve most issues. The FAQ also includes links to relevant sections in the Model Optimizer Developer Guide to help you understand what went wrong.
## Summary
In this document, you learned:
* Basic information about how the Model Optimizer works with Paddle\* models
* Which Paddle\* models are supported
* How to convert a trained Paddle\* model using the Model Optimizer with framework-agnostic command-line options
When Model Optimizer is unable to run to completion due to issues like typographical errors, incorrectly used options, etc., it provides explanatory messages. They describe the potential cause of the problem and give a link to the [Model Optimizer FAQ](../Model_Optimizer_FAQ.md), which provides instructions on how to resolve most issues. The FAQ also includes links to relevant sections in the Model Optimizer Developer Guide to help you understand what went wrong.

View File

@ -167,6 +167,7 @@ limitations under the License.
<tab type="user" title="Gather-8" url="@ref openvino_docs_ops_movement_Gather_8"/>
<tab type="user" title="GatherElements-6" url="@ref openvino_docs_ops_movement_GatherElements_6"/>
<tab type="user" title="GatherND-5" url="@ref openvino_docs_ops_movement_GatherND_5"/>
<tab type="user" title="GatherND-8" url="@ref openvino_docs_ops_movement_GatherND_8"/>
<tab type="user" title="Gelu-2" url="@ref openvino_docs_ops_activation_GELU_2"/>
<tab type="user" title="Gelu-7" url="@ref openvino_docs_ops_activation_GELU_7"/>
<tab type="user" title="GreaterEqual-1" url="@ref openvino_docs_ops_comparison_GreaterEqual_1"/>
@ -221,6 +222,7 @@ limitations under the License.
<tab type="user" title="Power-1" url="@ref openvino_docs_ops_arithmetic_Power_1"/>
<tab type="user" title="PriorBoxClustered-1" url="@ref openvino_docs_ops_detection_PriorBoxClustered_1"/>
<tab type="user" title="PriorBox-1" url="@ref openvino_docs_ops_detection_PriorBox_1"/>
<tab type="user" title="PriorBox-8" url="@ref openvino_docs_ops_detection_PriorBox_8"/>
<tab type="user" title="Proposal-1" url="@ref openvino_docs_ops_detection_Proposal_1"/>
<tab type="user" title="Proposal-4" url="@ref openvino_docs_ops_detection_Proposal_4"/>
<tab type="user" title="RandomUniform-8" url="@ref openvino_docs_ops_generation_RandomUniform_8"/>

View File

@ -0,0 +1,184 @@
## PriorBox<a name="PriorBox"></a> {#openvino_docs_ops_detection_PriorBox_8}
**Versioned name**: *PriorBox-8*
**Category**: *Object detection*
**Short description**: *PriorBox* operation generates prior boxes of specified sizes and aspect ratios across all dimensions.
**Detailed description**:
*PriorBox* computes coordinates of prior boxes by the following rules:
1. First, it calculates *center_x* and *center_y* of a prior box:
\f[
W \equiv Width \quad Of \quad Image \\
H \equiv Height \quad Of \quad Image
\f]
* If step equals 0:
\f[
center_x=(w+0.5) \\
center_y=(h+0.5)
\f]
* else:
\f[
center_x=(w+offset)*step \\
center_y=(h+offset)*step \\
w \subset \left( 0, W \right ) \\
h \subset \left( 0, H \right )
\f]
2. Then, it calculates coordinates of prior boxes for each \f$ s \subset \left( 0, min\_sizes \right ) \f$:
\f[
xmin = \frac{\frac{center_x - s}{2}}{W}
\f]
\f[
ymin = \frac{\frac{center_y - s}{2}}{H}
\f]
\f[
xmax = \frac{\frac{center_x + s}{2}}{W}
\f]
\f[
ymin = \frac{\frac{center_y + s}{2}}{H}
\f]
3. If *clip* attribute is set to true, each output value is clipped between \f$ \left< 0, 1 \right> \f$.
**Attributes**:
* *min_size (max_size)*
* **Description**: *min_size (max_size)* is the minimum (maximum) box size in pixels.
* **Range of values**: positive floating-point numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *aspect_ratio*
* **Description**: *aspect_ratio* is a variance of aspect ratios. Duplicate values are ignored.
* **Range of values**: a set of positive integer numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *flip*
* **Description**: *flip* is a flag that denotes that each *aspect_ratio* is duplicated and flipped. For example, *flip* equals 1 and *aspect_ratio* equals `[4.0,2.0]`, meaning that the aspect_ratio is equal to `[4.0,2.0,0.25,0.5]`.
* **Range of values**:
* false or 0 - each *aspect_ratio* is flipped
* true or 1 - each *aspect_ratio* is not flipped
* **Type**: `boolean`
* **Default value**: false
* **Required**: *no*
* *clip*
* **Description**: *clip* is a flag that denotes if each value in the output tensor should be clipped to the `[0,1]` interval.
* **Range of values**:
* false or 0 - clipping is not performed
* true or 1 - each value in the output tensor is clipped to the `[0,1]` interval.
* **Type**: `boolean`
* **Default value**: false
* **Required**: *no*
* *step*
* **Description**: *step* is a distance between box centers.
* **Range of values**: floating-point non-negative number
* **Type**: `float`
* **Default value**: 0
* **Required**: *no*
* *offset*
* **Description**: *offset* is a shift of a box to the top left corner respectively.
* **Range of values**: floating-point non-negative number
* **Type**: `float`
* **Required**: *yes*
* *variance*
* **Description**: *variance* denotes a variance of adjusting bounding boxes. The attribute could contain 0, 1, or 4 elements.
* **Range of values**: floating-point positive numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *scale_all_sizes*
* **Description**: *scale_all_sizes* is a flag that denotes type of inference. For example, *scale_all_sizes* equals 0 means that *max_size* attribute is ignored.
* **Range of values**:
* false - *max_size* is ignored
* true - *max_size* is used
* **Type**: `boolean`
* **Default value**: true
* **Required**: *no*
* *fixed_ratio*
* **Description**: *fixed_ratio* is an aspect ratio of a box.
* **Range of values**: a list of positive floating-point numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *fixed_size*
* **Description**: *fixed_size* is an initial box size in pixels.
* **Range of values**: a list of positive floating-point numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *density*
* **Description**: *density* is the square root of the number of boxes of each type.
* **Range of values**: a list of positive floating-point numbers
* **Type**: `float[]`
* **Default value**: []
* **Required**: *no*
* *min_max_aspect_ratios_order*
* **Description**: *min_max_aspect_ratios_order* is a flag that denotes the order of output prior box. If set true, the output prior box is in [min, max, aspect_ratios] order, which is consistent with Caffe. Note that the order affects the weights order of the preceding convolution layer and does not affect the final detection results.
* **Range of values**:
* false - the output prior box is in [min, aspect_ratios, max] order
* true - the output prior box is in [min, max, aspect_ratios] order
* **Type**: `boolean`
* **Default value**: true
* **Required**: *no*
**Inputs**:
* **1**: `output_size` - 1D tensor of type *T_INT* with two elements `[height, width]`. Specifies the spatial size of generated grid with boxes. **Required.**
* **2**: `image_size` - 1D tensor of type *T_INT* with two elements `[image_height, image_width]`. Specifies shape of the image for which boxes are generated. **Required.**
**Outputs**:
* **1**: 2D tensor of shape `[2, 4 * height * width * priors_per_point]` and type *T_OUT* with box coordinates. The `priors_per_point` is the number of boxes generated per each grid element. The number depends on operation attribute values.
**Types**
* *T_INT*: any supported integer type.
* *T_OUT*: supported floating-point type.
**Example**
```xml
<layer type="PriorBox" ...>
<data aspect_ratio="2.0" clip="false" density="" fixed_ratio="" fixed_size="" flip="true" max_size="38.46" min_size="16.0" offset="0.5" step="16.0" variance="0.1,0.1,0.2,0.2"/>
<input>
<port id="0">
<dim>2</dim> <!-- values: [24, 42] -->
</port>
<port id="1">
<dim>2</dim> <!-- values: [384, 672] -->
</port>
</input>
<output>
<port id="2">
<dim>2</dim>
<dim>16128</dim>
</port>
</output>
</layer>
```

View File

@ -52,11 +52,15 @@ output = [[[3, 4]],
* *batch_dims*
* **Description**: *batch_dims* (denoted as `b`) is a leading number of dimensions of `data` tensor and `indices` representing the batches,
and *GatherND* starts to gather from the `b+1` dimension.
It requires the first `b` dimensions in `data` and `indices` tensors to be equal.
In case non default value for *batch_dims* the output shape is calculated as
* **Description**: *batch_dims* (denoted as `b`) is a leading number of dimensions of `data` tensor
and `indices` representing the batches, and *GatherND* starts to gather from the `b+1` dimension.
It requires the first `b` dimensions in `data` and `indices` tensors to be equal.
In case of non-default value for *batch_dims*, the output shape is calculated as
`(multiplication of indices.shape[:b]) + indices.shape[b:-1] + data.shape[(indices.shape[-1] + b):]`.
**NOTE:** The calculation of output shape is incorrect for non-default *batch_dims* value greater than one.
For correct calculations use [GatherND_8](GatherND_8.md) operation**
* **Range of values**: integer number and belongs to `[0; min(data.rank, indices.rank))`
* **Type**: int
* **Default value**: 0

View File

@ -0,0 +1,235 @@
## GatherND <a name="GatherND"></a> {#openvino_docs_ops_movement_GatherND_8}
**Versioned name**: *GatherND-8*
**Category**: *Data movement*
**Short description**: *GatherND* gathers slices from input tensor into a tensor of the shape specified by indices.
**Detailed description**: *GatherND* gathers slices from `data` by `indices` and forms a tensor of the shape specified by `indices`.
`indices` is `K`-dimensional integer tensor or `K-1`-dimensional tensor of tuples with indices by which the operation
gathers elements or slices from `data` tensor. A position `i_0, ..., i_{K-2}` in the `indices` tensor corresponds to
a tuple with indices `indices[i_0, ..., i_{K-2}]` of a length equal to `indices.shape[-1]`. By this tuple with indices
the operation gathers a slice or an element from `data` tensor and inserts it into the output at the position
`i_0, ..., i_{K-2}` as described in the following formula:
`output[i_0, ..., i_{K-2},:,...,:] = data[indices[i_0, ..., i_{K-2}],:,...,:]`
The last dimension of `indices` tensor must be not greater than a rank of `data` tensor, meaning
`indices.shape[-1] <= data.rank`.
The shape of the output is calculated as `indices.shape[:batch_dims] + indices.shape[batch_dims:-1]`
if `indices.shape[-1] == data.rank - batch_dims` else
`indices.shape[:batch_dims] + list(indices.shape)[batch_dims:-1] + list(data.shape)[batch_dims + indices.shape[-1]:]`.
**Attributes**:
* *batch_dims*
* **Description**: *batch_dims* (denoted as `b`) is a leading number of dimensions of `data` tensor and `indices`
representing the batches, and *GatherND* starts to gather from the `b+1` dimension. It requires the first `b`
dimensions in `data` and `indices` tensors to be equal.
* **Range of values**: integer number that belongs to `[0; min(data.rank, indices.rank))`
* **Type**: int
* **Default value**: 0
* **Required**: *no*
**Inputs**:
* **1**: `data` tensor of type *T*. A tensor of a rank not less than 1. **Required.**
* **2**: `indices` tensor of type *T_IND*. A tensor of a rank not less than 1.
It requires all indices from this tensor to be in the range `[0, s-1]` where `s` is the corresponding dimension to
which this index is applied.
**Required.**
**Outputs**:
* **1**: Tensor with gathered values of type *T*.
**Types**
* *T*: any supported type.
* *T_IND*: any supported integer types.
**Examples**
Example 1 shows how *GatherND* operates with elements from `data` tensor:
```
indices = [[0, 0],
[1, 0]]
data = [[1, 2],
[3, 4]]
output = [1, 3]
```
Example 2 shows how *GatherND* operates with slices from `data` tensor:
```
indices = [[1], [0]]
data = [[1, 2],
[3, 4]]
output = [[3, 4],
[1, 2]]
```
Example 3 shows how *GatherND* operates when `indices` tensor has leading dimensions:
```
indices = [[[1]], [[0]]]
data = [[1, 2],
[3, 4]]
output = [[[3, 4]],
[[1, 2]]]
```
Example 4 shows how *GatherND* operates gathering elements for non-default *batch_dims* value:
```
batch_dims = 1
indices = [[1], <--- this is applied to the first batch
[0]] <--- this is applied to the second batch, shape = (2, 1)
data = [[1, 2], <--- the first batch
[3, 4]] <--- the second batch, shape = (2, 2)
output = [2, 3], shape = (2)
```
Example 5 shows how *GatherND* operates gathering slices for non-default *batch_dims* value:
```
batch_dims = 1
indices = [[1], <--- this is applied to the first batch
[0]] <--- this is applied to the second batch, shape = (2, 1)
data = [[[1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]] <--- the first batch
[[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]] <--- the second batch, shape = (2, 3, 4)
output = [[ 5, 6, 7, 8], [13, 14, 15, 16]], shape = (2, 4)
```
More complex examples 6 and 7 show how *GatherND* operates gathering slices with leading dimensions for non-default
*batch_dims* value:
```
batch_dims = 2
indices = [[[[1]], <--- this is applied to the first batch
[[0]],
[[2]]],
[[[0]],
[[2]],
[[2]]] <--- this is applied to the sixth batch
], shape = (2, 3, 1, 1)
data = [[[ 1, 2, 3, 4], <--- this is the first batch
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]]
[[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]] <--- this is the sixth batch
] <--- the second batch, shape = (2, 3, 4)
output = [[[ 2], [ 5], [11]], [[13], [19], [23]]], shape = (2, 3, 1)
```
```
batch_dims = 3
indices = [[[[1],
[0]],
[[3],
[2]]]
], shape = (1, 2, 2, 1)
data = [[[[ 1 2 3 4],
[ 5 6 7 8]],
[[ 9 10 11 12],
[13 14 15 16]]]
], shape = (1, 2, 2, 4)
output = [[[ 2 5],
[12 15]]
], shape = (1, 2, 2)
```
```xml
<layer id="1" type="GatherND">
<data batch_dims="0" />
<input>
<port id="0">
<dim>1000</dim>
<dim>256</dim>
<dim>10</dim>
<dim>15</dim>
</port>
<port id="1">
<dim>25</dim>
<dim>125</dim>
<dim>3</dim>
</port>
</input>
<output>
<port id="3">
<dim>25</dim>
<dim>125</dim>
<dim>15</dim>
</port>
</output>
</layer>
```
```xml
<layer id="1" type="GatherND">
<data batch_dims="2" />
<input>
<port id="0">
<dim>30</dim>
<dim>2</dim>
<dim>100</dim>
<dim>35</dim>
</port>
<port id="1">
<dim>30</dim>
<dim>2</dim>
<dim>3</dim>
<dim>1</dim>
</port>
</input>
<output>
<port id="3">
<dim>60</dim>
<dim>3</dim>
<dim>35</dim>
</port>
</output>
</layer>
```
```xml
<layer id="1" type="GatherND">
<data batch_dims="3" />
<input>
<port id="0">
<dim>1</dim>
<dim>64</dim>
<dim>64</dim>
<dim>320</dim>
</port>
<port id="1">
<dim>1</dim>
<dim>64</dim>
<dim>64</dim>
<dim>1</dim>
<dim>1</dim>
</port>
</input>
<output>
<port id="3">
<dim>1</dim>
<dim>64</dim>
<dim>64</dim>
<dim>1</dim>
</port>
</output>
</layer>
```

View File

@ -65,7 +65,7 @@ declared in `namespace opset8`.
* [FloorMod](arithmetic/FloorMod_1.md)
* [Gather](movement/Gather_8.md)
* [GatherElements](movement/GatherElements_6.md)
* [GatherND_5](movement/GatherND_5.md)
* [GatherND_8](movement/GatherND_8.md)
* [GatherTree](movement/GatherTree_1.md)
* [Gelu](activation/GELU_7.md)
* [Greater](comparison/Greater_1.md)
@ -114,7 +114,7 @@ declared in `namespace opset8`.
* [Power](arithmetic/Power_1.md)
* [PReLU](activation/PReLU_1.md)
* [PriorBoxClustered](detection/PriorBoxClustered_1.md)
* [PriorBox](detection/PriorBox_1.md)
* [PriorBox](detection/PriorBox_8.md)
* [Proposal](detection/Proposal_4.md)
* [PSROIPooling](detection/PSROIPooling_1.md)
* [RandomUniform](generation/RandomUniform_8.md)

View File

@ -6,6 +6,21 @@
**Short description**: *GRUCell* represents a single GRU Cell that computes the output using the formula described in the [paper](https://arxiv.org/abs/1406.1078).
**Detailed description**: *GRUCell* computes the output *Ht* for the current time step based on the followint formula:
```
Formula:
* - matrix multiplication
(.) - Hadamard product(element-wise)
[,] - concatenation
f, g - are activation functions.
zt = f(Xt*(Wz^T) + Ht-1*(Rz^T) + Wbz + Rbz)
rt = f(Xt*(Wr^T) + Ht-1*(Rr^T) + Wbr + Rbr)
ht = g(Xt*(Wh^T) + (rt (.) Ht-1)*(Rh^T) + Rbh + Wbh) # default, when linear_before_reset = 0
ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*(Rh^T) + Rbh)) + Wbh) # when linear_before_reset != 0
Ht = (1 - zt) (.) ht + zt (.) Ht-1
```
**Attributes**
* *hidden_size*
@ -20,7 +35,7 @@
* **Description**: activation functions for gates
* **Range of values**: any combination of *relu*, *sigmoid*, *tanh*
* **Type**: a list of strings
* **Default value**: *sigmoid,tanh*
* **Default value**: *sigmoid* for f, *tanh* for g
* **Required**: *no*
* *activations_alpha, activations_beta*
@ -57,7 +72,7 @@
* **4**: `R` - 2D tensor of type *T* `[3 * hidden_size, hidden_size]`, the recurrence weights for matrix multiplication, gate order: zrh. **Required.**
* **5**: `B` - 1D tensor of type *T*. If *linear_before_reset* is set to 1, then the shape is `[4 * hidden_size]` - the sum of biases for z and r gates (weights and recurrence weights), the biases for h gate are placed separately. Otherwise the shape is `[3 * hidden_size]`, the sum of biases (weights and recurrence weights). **Required.**
* **5**: `B` - 1D tensor of type *T*. If *linear_before_reset* is set to 1, then the shape is `[4 * hidden_size]` - the sum of biases for z and r gates (weights and recurrence weights), the biases for h gate are placed separately. Otherwise the shape is `[3 * hidden_size]`, the sum of biases (weights and recurrence weights). **Optional.**
**Outputs**

View File

@ -11,7 +11,8 @@ file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
if(NOT CLDNN__IOCL_ICD_INCDIRS OR TRUE)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/GPU_RemoteBlob_API0.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GPU_RemoteBlob_API1.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GPU_RemoteBlob_API2.cpp")
"${CMAKE_CURRENT_SOURCE_DIR}/GPU_RemoteBlob_API2.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GPU_RemoteBlob_API3.cpp")
endif()
# remove OpenCV related sources

View File

@ -0,0 +1,76 @@
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 120
#include <ie_core.hpp>
#include <CL/cl2.hpp>
#include <gpu/gpu_context_api_ocl.hpp>
int main() {
using namespace InferenceEngine;
//! [part0]
// ...
// initialize the core and read the network
InferenceEngine::Core ie;
auto net = ie.ReadNetwork("network.xml");
// initialize opencl context and create queue
cl::Context ctx = get_my_OpenCL_context();
cl::CommandQueue queue = get_my_OpenCL_queue();
// share the queue with GPU plugin and compile ExecutableNetwork
auto remote_context = gpu::make_shared_context(ie, "GPU", queue.get());
auto exec_net_shared = ie.LoadNetwork(net, remote_context);
// create the OpenCL buffers within the context
cl::Buffer shared_in_buffer(ctx, CL_MEM_READ_WRITE, image_size * num_channels, NULL, &err);
cl::Buffer shared_out_buffer(ctx, CL_MEM_READ_WRITE, image_size * num_channels, NULL, &err);
// wrap in and out buffers into RemoteBlob and set them to infer request
auto shared_in_blob = gpu::make_shared_blob(input_info->getTensorDesc(), remote_context, shared_in_buffer);
auto shared_out_blob = gpu::make_shared_blob(out_data->getTensorDesc(), remote_context, shared_out_buffer);
auto infer_request = exec_net_shared.CreateInferRequest();
infer_request.SetBlob(input_name, shared_in_blob);
infer_request.SetBlob(output_name, shared_out_blob);
// ...
// execute user kernel
cl::Kernel kernel_preproc(program, kernel_name_preproc.c_str());
kernel_preproc.setArg(0, shared_in_buffer);
queue.enqueueNDRangeKernel(kernel_preproc,
cl::NDRange(0),
cl::NDRange(image_size),
cl::NDRange(1),
nullptr, // wait events *
&profileEvent);
// Blocking clFinish() call is not required, but this barrier is added to the queue to guarantee that user kernel is finished
// before any inference primitive is started
queue.enqueueBarrierWithWaitList(nullptr, nullptr);
// ...
// pass results to the inference
// since the remote context is created with queue sharing, StartAsync() guarantees that scheduling is finished
infer_request.StartAsync();
// execute some postprocessing kernel.
// infer_request.Wait() is not called, synchonization between inference and post-processing is done via
// enqueueBarrierWithWaitList call.
cl::Kernel kernel_postproc(program, kernel_name_postproc.c_str());
kernel_postproc.setArg(0, shared_out_buffer);
queue.enqueueBarrierWithWaitList(nullptr, nullptr);
queue.enqueueNDRangeKernel(kernel_postproc,
cl::NDRange(0),
cl::NDRange(image_size),
cl::NDRange(1),
nullptr, // wait events *
&profileEvent);
// Wait for pipeline completion
queue.finish();
//! [part0]
return 0;
}

View File

@ -25,7 +25,7 @@ using namespace TemplateExtension;
//! [extension:ctor]
Extension::Extension() {
#ifdef OPENVINO_ONNX_FRONTEND_ENABLED
ngraph::onnx_import::register_operator(Operation::type_info.name,
ngraph::onnx_import::register_operator(Operation::get_type_info_static().name,
1,
"custom_domain",
[](const ngraph::onnx_import::Node& node) -> ngraph::OutputVector {
@ -34,7 +34,7 @@ Extension::Extension() {
return {std::make_shared<Operation>(ng_inputs.at(0), add)};
});
# ifdef OPENCV_IMPORT_ENABLED
ngraph::onnx_import::register_operator(FFTOp::type_info.name,
ngraph::onnx_import::register_operator(FFTOp::get_type_info_static().name,
1,
"custom_domain",
[](const ngraph::onnx_import::Node& node) -> ngraph::OutputVector {
@ -50,9 +50,9 @@ Extension::Extension() {
//! [extension:dtor]
Extension::~Extension() {
#ifdef OPENVINO_ONNX_FRONTEND_ENABLED
ngraph::onnx_import::unregister_operator(Operation::type_info.name, 1, "custom_domain");
ngraph::onnx_import::unregister_operator(Operation::get_type_info_static().name, 1, "custom_domain");
# ifdef OPENCV_IMPORT_ENABLED
ngraph::onnx_import::unregister_operator(FFTOp::type_info.name, 1, "custom_domain");
ngraph::onnx_import::unregister_operator(FFTOp::get_type_info_static().name, 1, "custom_domain");
# endif // OPENCV_IMPORT_ENABLED
#endif // OPENVINO_ONNX_FRONTEND_ENABLED
}

View File

@ -7,8 +7,6 @@
using namespace TemplateExtension;
constexpr ngraph::NodeTypeInfo FFTOp::type_info;
FFTOp::FFTOp(const ngraph::Output<ngraph::Node>& inp, bool _inverse) : Op({inp}) {
constructor_validate_and_infer_types();
inverse = _inverse;

View File

@ -11,10 +11,7 @@ namespace TemplateExtension {
class FFTOp : public ngraph::op::Op {
public:
static constexpr ngraph::NodeTypeInfo type_info{"FFT", 0};
const ngraph::NodeTypeInfo& get_type_info() const override {
return type_info;
}
OPENVINO_OP("FFT", "custom_opset");
FFTOp() = default;
FFTOp(const ngraph::Output<ngraph::Node>& inp, bool inverse);

View File

@ -7,8 +7,6 @@
using namespace TemplateExtension;
//! [op:ctor]
NGRAPH_RTTI_DEFINITION(TemplateExtension::Operation, "Template", 0);
Operation::Operation(const ngraph::Output<ngraph::Node>& arg, int64_t add) : Op({arg}), add(add) {
constructor_validate_and_infer_types();
}

View File

@ -11,7 +11,7 @@ namespace TemplateExtension {
class Operation : public ngraph::op::Op {
public:
NGRAPH_RTTI_DECLARATION;
OPENVINO_OP("Template", "custom_opset");
Operation() = default;
Operation(const ngraph::Output<ngraph::Node>& arg, int64_t add);

View File

@ -21,16 +21,14 @@ addIeTargetTest(
TEMPLATE
)
if(ENABLE_TEMPLATE_OPENCV_TESTS)
find_package(OpenCV QUIET COMPONENTS core imgproc)
find_package(OpenCV QUIET COMPONENTS core imgproc)
if(OpenCV_FOUND)
message("-- Reference preprocessing: OpenCV tests are enabled")
target_compile_definitions(${TARGET_NAME} PRIVATE OPENCV_TEMPLATE_TESTS)
target_link_libraries(${TARGET_NAME} PRIVATE opencv_imgproc opencv_core)
else()
message("-- Reference preprocessing: OpenCV tests are disabled")
endif()
if(OpenCV_FOUND)
message("-- Reference preprocessing: OpenCV tests are enabled")
target_compile_definitions(${TARGET_NAME} PRIVATE OPENCV_TEMPLATE_TESTS)
target_link_libraries(${TARGET_NAME} PRIVATE opencv_imgproc opencv_core)
else()
message("-- Reference preprocessing: OpenCV tests are disabled")
endif()
# [cmake:functional_tests]

View File

@ -0,0 +1,181 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "base_reference_test.hpp"
#include "openvino/op/adaptive_avg_pool.hpp"
#include "openvino/op/constant.hpp"
using namespace ov;
using namespace reference_tests;
namespace {
struct AdaptiveAvgPoolParams {
template <class IT>
AdaptiveAvgPoolParams(const Shape& input_shape,
const Shape& output_shape,
const element::Type& input_type,
const element::Type& ouput_type,
const std::vector<IT>& input_values,
const std::vector<IT>& output_values,
const Shape& adaptive_shape,
const std::vector<int64_t>& adaptive_values)
: m_input_shape(input_shape),
m_output_shape(output_shape),
m_input_type(input_type),
m_output_type(ouput_type),
m_input_data(CreateTensor(input_type, input_values)),
m_expected_data(CreateTensor(ouput_type, output_values)),
m_adaptive_shape(adaptive_shape),
m_adaptive_values(adaptive_values) {}
Shape m_input_shape;
Shape m_output_shape;
element::Type m_input_type;
element::Type m_output_type;
runtime::Tensor m_input_data;
runtime::Tensor m_expected_data;
Shape m_adaptive_shape;
std::vector<int64_t> m_adaptive_values;
};
class ReferenceAdaptiveAvgPoolLayerTest : public testing::TestWithParam<AdaptiveAvgPoolParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.m_input_shape,
params.m_input_type,
params.m_adaptive_shape,
params.m_adaptive_values);
inputData = {params.m_input_data};
refOutData = {params.m_expected_data};
}
static std::string getTestCaseName(const testing::TestParamInfo<AdaptiveAvgPoolParams>& obj) {
auto params = obj.param;
std::ostringstream result;
result << "shape=" << params.m_input_shape << "_";
result << "iType=" << params.m_input_type << "_";
result << "shape=" << params.m_output_shape << "_";
result << "oType=" << params.m_output_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const Shape& input_shape,
const element::Type& input_type,
const Shape& adaptive_shape,
const std::vector<int64_t> adaptive_values) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto out = op::v0::Constant::create<int64_t>(element::Type_t::i64, adaptive_shape, adaptive_values);
const auto adaptive_avg_pool = std::make_shared<op::v8::AdaptiveAvgPool>(in, out);
return std::make_shared<Function>(NodeVector{adaptive_avg_pool}, ParameterVector{in});
}
};
TEST_P(ReferenceAdaptiveAvgPoolLayerTest, AdaptiveAvgPoolWithHardcodedRefs) {
Exec();
}
template <element::Type_t IN_ET>
std::vector<AdaptiveAvgPoolParams> generateParamsForAdaptiveAvgPool() {
using T = typename element_type_traits<IN_ET>::value_type;
std::vector<AdaptiveAvgPoolParams> params{
AdaptiveAvgPoolParams(ov::Shape{2, 3, 7},
ov::Shape{2, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{0, 4, 1, 3, -2, -5, -2, -2, 1, -3, 1, -3, -4, 0, -2, 1, -1, -2, 3, -1, -3,
-1, -2, 3, 4, -3, -4, 1, 2, 0, -4, -5, -2, -2, -3, 2, 3, 1, -5, 2, -4, -2},
std::vector<T>{1.66666663,
0.66666669,
-3.,
-1.33333337,
-1.66666663,
-2.33333325,
-0.66666669,
0.,
-0.33333334,
0.,
1.33333337,
-2.,
-0.66666669,
-3.66666675,
-2.33333325,
2.,
-0.66666669,
-1.33333337},
ov::Shape{1},
{3}),
AdaptiveAvgPoolParams(
ov::Shape{1, 3, 7, 10},
ov::Shape{1, 3, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{-2, -3, -4, 3, -5, 4, 0, -4, -2, -4, -5, 0, -3, 0, -2, 0, 0, -5, -4, -1, 3, -1, 0, -1,
0, -2, 0, 4, 1, 4, 0, -1, -4, 2, -2, -5, -1, -1, -2, 1, 2, -2, -1, 2, 0, -1, 0, -5,
4, 4, 3, 0, -4, -4, -4, -2, 0, 1, -2, -1, 4, -2, -4, 1, -1, -3, -4, -1, 1, -4,
-2, -4, -5, 0, -4, 3, 4, -5, -4, -2, 0, 2, -4, -3, 3, -1, 1, -4, -5, 4, 2, -5, 2, -3,
0, 4, 3, 3, 1, 2, -1, -4, 1, -3, -3, -2, 3, 4, -2, -5, 1, 4, 4, -2, 2, 1, -5, -2,
-5, 1, 1, -2, -3, -3, -1, -5, 1, -3, -5, -3, -4, -1, 4, -3, 4, -1, 4, 3, 1, 4,
-2, -4, -4, 4, -3, 4, 2, -3, -2, 4, -3, 0, 1, -4, 4, 4, 0, 3, -1, 3, 3, -5, 0, 3,
-3, 1, -2, 4, -5, -5, 1, 0, -1, 0, -3, -2, 0, -3, 3, -2, -2, 0, -3, 4, -1, 2, -2, 2,
-3, -1, -4, -2, 0, 2, 0, 2, 0, -3, 4, 3, -5, -3, -5, 1, -5, -3, -5, 4, -3, 3},
std::vector<T>{-1.08333337, -0.25000000, -0.91666669, -0.08333334, -0.66666669,
0.75000000, -0.41666666, -1.33333337, -0.58333331,
-1.66666663, 0.58333331, -0.16666667, -0.33333334, -0.41666666,
-0.16666667, -0.33333334, -0.66666669, -0.75000000,
-0.91666669, 0.83333331, -0.16666667, 0., -0.25000000,
-1.16666663, -1.41666663, -0.41666666, -0.08333334},
ov::Shape{2},
{3, 3}),
AdaptiveAvgPoolParams(
ov::Shape{2, 2, 3, 3, 3},
ov::Shape{2, 2, 2, 2, 2},
IN_ET,
IN_ET,
std::vector<T>{-5, 1, -3, -4, 4, -4, 3, -3, -1, 0, 0, -2, -4, 2, 0, -4, -5, -2, -4, -4, 0, -2, 3, -3, 4, -1, -4,
-1, -1, -5, 4, -1, -2, -3, 0, 4, -1, -5, -4, 1, 1, 4, -5, -5, -5, 4, -3, -3, -3, 4, 0, -3, -5, 1,
4, 2, 1, -5, -5, 1, 0, -4, -1, 2, -4, -2, 4, 3, 1, -3, -3, -2, -4, -3, -3, 3, -1, 1, 2, 2, -4,
-5, -4, 1, 3, -4, -1, 2, 4, -5, 0, 1, -2, 0, 0, -2, 3, -2, -5, -3, -5, -2, -1, 3, -2, 4, 3, -3},
std::vector<T>{-0.750, -0.250, -1.375, -1.125, -1.125, -0.500, -0.875, -1.250,
-0.375, -1.625, -1., -0.500, -0.250, -0.750, -1.875, -0.625,
0.125, -0.375, -1.625, -1.250, 0., -1., 0.875, -0.375,
-1.125, -1.375, 0.750, -1.875, -0.625, -1.125, 1.250, -1.},
ov::Shape{3},
{2, 2, 2}),
};
return params;
}
std::vector<AdaptiveAvgPoolParams> generateCombinedParamsForAdaptiveAvgPool() {
const std::vector<std::vector<AdaptiveAvgPoolParams>> allTypeParams{
generateParamsForAdaptiveAvgPool<element::Type_t::f32>(),
generateParamsForAdaptiveAvgPool<element::Type_t::f16>(),
generateParamsForAdaptiveAvgPool<element::Type_t::bf16>()
};
std::vector<AdaptiveAvgPoolParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_AdaptiveAvgPool_With_Hardcoded_Refs,
ReferenceAdaptiveAvgPoolLayerTest,
::testing::ValuesIn(generateCombinedParamsForAdaptiveAvgPool()),
ReferenceAdaptiveAvgPoolLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,217 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "base_reference_test.hpp"
#include "openvino/op/adaptive_max_pool.hpp"
#include "openvino/op/constant.hpp"
using namespace ov;
using namespace reference_tests;
namespace {
struct AdaptiveMaxPoolParams {
template <class IT>
AdaptiveMaxPoolParams(const Shape& input_shape,
const Shape& output_shape,
const element::Type& input_type,
const element::Type& output_type,
const std::vector<IT>& input_values,
const std::vector<IT>& output_values,
const std::vector<int64_t>& output_indices,
const Shape& adaptive_shape,
const std::vector<int64_t>& adaptive_values)
: m_input_shape(input_shape),
m_output_shape(output_shape),
m_input_type(input_type),
m_output_type(output_type),
m_input_data(CreateTensor(input_type, input_values)),
m_expected_data(CreateTensor(output_type, output_values)),
m_expected_indices(CreateTensor(element::Type_t::i64, output_indices)),
m_adaptive_shape(adaptive_shape),
m_adaptive_values(adaptive_values) {}
Shape m_input_shape;
Shape m_output_shape;
element::Type m_input_type;
element::Type m_output_type;
runtime::Tensor m_input_data;
runtime::Tensor m_expected_data;
runtime::Tensor m_expected_indices;
Shape m_adaptive_shape;
std::vector<int64_t> m_adaptive_values;
};
class ReferenceAdaptiveMaxPoolLayerTest : public testing::TestWithParam<AdaptiveMaxPoolParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.m_input_shape,
params.m_input_type,
params.m_adaptive_shape,
params.m_adaptive_values);
inputData = {params.m_input_data};
refOutData = {params.m_expected_data, params.m_expected_indices};
}
static std::string getTestCaseName(const testing::TestParamInfo<AdaptiveMaxPoolParams>& obj) {
auto params = obj.param;
std::ostringstream result;
result << "shape=" << params.m_input_shape << "_";
result << "iType=" << params.m_input_type << "_";
result << "shape=" << params.m_output_shape << "_";
result << "oType=" << params.m_output_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const Shape& input_shape,
const element::Type& input_type,
const Shape& adaptive_shape,
const std::vector<int64_t> adaptive_values) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto out = op::v0::Constant::create<int64_t>(element::Type_t::i64, adaptive_shape, adaptive_values);
const auto adaptive_max_pool = std::make_shared<op::v8::AdaptiveMaxPool>(in, out);
return std::make_shared<Function>(adaptive_max_pool->outputs(), ParameterVector{in});
}
};
TEST_P(ReferenceAdaptiveMaxPoolLayerTest, AdaptiveMaxPoolWithHardcodedRefs) {
Exec();
}
template <element::Type_t IN_ET>
std::vector<AdaptiveMaxPoolParams> generateParamsForAdaptiveMaxPoolWithExpectedResult() {
using T = typename element_type_traits<IN_ET>::value_type;
std::vector<AdaptiveMaxPoolParams> params{
AdaptiveMaxPoolParams(
ov::Shape{2, 3, 7},
ov::Shape{2, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{0, 4, 1, 3, -2, -5, -2, -2, 1, -3, 1, -3, -4, 0, -2, 1, -1, -2, 3, -1, -3,
-1, -2, 3, 4, -3, -4, 1, 2, 0, -4, -5, -2, -2, -3, 2, 3, 1, -5, 2, -4, -2},
std::vector<T>{4,
3,
-2,
1,
1,
0,
1,
3,
3,
3,
4,
1,
2,
-2,
-2,
3,
2,
2},
std::vector<int64_t>{1,
3,
4,
1,
3,
6,
1,
4,
4,
2,
3,
6,
0,
4,
4,
1,
4,
4},
ov::Shape{1},
std::vector<int64_t>{3}),
AdaptiveMaxPoolParams(
ov::Shape{1, 3, 7, 10},
ov::Shape{1, 3, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{0, -2, -5, -5, 2, 3, 2, -3, 1, -2, -4, -1, -1, -1, 2, -4, 3, -5, -1, -1, 1, 2, 4, -2,
-3, -2, 0, -5, 2, -4, -1, -4, 4, 2, 1, -2, 2, -3, 0, 1, -3, 3, -1, 4, 0, 2, 0, 3,
4, -4, 1, 4, -1, -5, -2, 4, -3, 3, 2, 1, 0, 4, 2, -5, 2, -5, -2, -1, 4, 2,
0, 4, -2, 0, -5, -3, 4, -4, -2, -2, 2, 1, 4, 3, 2, -5, -4, -4, 0, 1, 4, -4, -3, 3,
3, 4, -2, -3, -4, -2, 0, 1, -1, 3, -2, 2, 0, -3, -1, -1, 0, 0, 2, 2, -2, 1, -3, 1,
2, 4, 3, -5, -4, 1, -4, 2, 0, -2, -5, 2, -3, -2, -3, -4, 2, -2, -4, 2, -4, -3,
1, -5, -1, -5, 2, 1, 3, 4, 3, 0, -5, 4, -3, -4, -1, 2, -4, 2, 0, -5, -3, 0, 2, -3,
-5, 3, -2, -1, -5, -4, -5, 0, -5, -1, -3, 3, 3, -4, -3, -4, -5, 4, -1, 1, -1, -4, 1, -3,
-4, -1, -2, -3, -5, 2, 2, -5, 1, 1, -5, -4, 0, 2, 4, 2, 0, 2, 4, 0, -5, 2},
std::vector<T>{4, 3, 3, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 3, 2, 4,
4, 3, 4, 4, 3, 3, 4, 4, 4},
std::vector<int64_t>{22, 5, 16, 22, 43, 48, 43, 43, 48,
1, 6, 6, 20, 25, 49, 50, 43, 49,
11, 6, 7, 41, 25, 36, 41, 66, 66},
ov::Shape{2},
std::vector<int64_t>{3, 3}),
AdaptiveMaxPoolParams(
ov::Shape{2, 2, 3, 3, 3},
ov::Shape{2, 2, 2, 2, 2},
IN_ET,
IN_ET,
std::vector<T>{-5, 1, -3, -4, 4, -4, 3, -3, -1, 0, 0, -2, -4, 2,
0, -4, -5, -2, -4, -4, 0, -2, 3, -3, 4, -1, -4,
-1, -1, -5, 4, -1, -2, -3, 0, 4, -1, -5, -4, 1, 1,
4, -5, -5, -5, 4, -3, -3, -3, 4, 0, -3, -5, 1,
4, 2, 1, -5, -5, 1, 0, -4, -1, 2, -4, -2, 4, 3,
1, -3, -3, -2, -4, -3, -3, 3, -1, 1, 2, 2, -4,
-5, -4, 1, 3, -4, -1, 2, 4, -5, 0, 1, -2, 0, 0,
-2, 3, -2, -5, -3, -5, -2, -1, 3, -2, 4, 3, -3},
std::vector<T>{4, 4, 4, 4, 3, 3, 4, 3,
4, 4, 4, 4, 4, 4, 4, 4,
4, 3, 4, 3, 4, 3, 4, 3,
3, 1, 4, 4, 3, 3, 4, 3},
std::vector<int64_t>{4, 4, 4, 4, 22, 22, 24, 22,
3, 14, 3, 8, 18, 14, 22, 14,
0, 13, 12, 13, 12, 13, 12, 13,
3, 2, 7, 7, 22, 22, 24, 22},
ov::Shape{3},
std::vector<int64_t>{2, 2, 2})
};
return params;
}
std::vector<AdaptiveMaxPoolParams> generateCombinedParamsForAdaptiveMaxPool() {
const std::vector<std::vector<AdaptiveMaxPoolParams>> allTypeParams{
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::f32>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::f16>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::bf16>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::i64>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::i32>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::i16>(),
generateParamsForAdaptiveMaxPoolWithExpectedResult<element::Type_t::i8>(),
};
std::vector<AdaptiveMaxPoolParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_AdaptiveMaxPool_With_Hardcoded_Refs,
ReferenceAdaptiveMaxPoolLayerTest,
::testing::ValuesIn(generateCombinedParamsForAdaptiveMaxPool()),
ReferenceAdaptiveMaxPoolLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,271 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "base_reference_test.hpp"
#include "openvino/op/avg_pool.hpp"
using namespace ov;
using namespace reference_tests;
namespace {
struct AvgPoolParams {
template <class IT>
AvgPoolParams(const Shape& input_shape,
const Shape& output_shape,
const element::Type& input_type,
const element::Type& ouput_type,
const std::vector<IT>& input_values,
const std::vector<IT>& output_values,
const Strides& strides,
const Shape& pads_begin,
const Shape& pads_end,
const Shape& kernel,
const bool exclude_pad,
const op::RoundingType& rounding_type,
const op::PadType& pad_type)
: m_input_shape(input_shape),
m_output_shape(output_shape),
m_input_type(input_type),
m_output_type(ouput_type),
m_input_data(CreateTensor(input_type, input_values)),
m_expected_data(CreateTensor(ouput_type, output_values)),
m_strides(strides),
m_pads_begin(pads_begin),
m_pads_end(pads_end),
m_kernel(kernel),
m_exclude_pad(exclude_pad),
m_rounding_type(rounding_type),
m_pad_type(pad_type) {}
Shape m_input_shape;
Shape m_output_shape;
element::Type m_input_type;
element::Type m_output_type;
runtime::Tensor m_input_data;
runtime::Tensor m_expected_data;
Strides m_strides;
Shape m_pads_begin;
Shape m_pads_end;
Shape m_kernel;
bool m_exclude_pad;
op::RoundingType m_rounding_type;
op::PadType m_pad_type;
};
class ReferenceAvgPoolLayerTest : public testing::TestWithParam<AvgPoolParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.m_input_shape,
params.m_input_type,
params.m_strides,
params.m_pads_begin,
params.m_pads_end,
params.m_kernel,
params.m_exclude_pad,
params.m_rounding_type,
params.m_pad_type);
inputData = {params.m_input_data};
refOutData = {params.m_expected_data};
}
static std::string getTestCaseName(const testing::TestParamInfo<AvgPoolParams>& obj) {
auto params = obj.param;
std::ostringstream result;
result << "iShape=" << params.m_input_shape << "_";
result << "iType=" << params.m_input_type << "_";
result << "iShape=" << params.m_output_shape << "_";
result << "oType=" << params.m_output_type << "_";
result << "excludePad=" << params.m_exclude_pad << "_";
result << "roundingType=" << params.m_rounding_type << "_";
result << "padType=" << params.m_pad_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const Shape& input_shape,
const element::Type& input_type,
const Strides& strides,
const Shape& pads_begin,
const Shape& pads_end,
const Shape& kernel,
const bool exclude_pad,
const op::RoundingType rounding_type,
const op::PadType pad_type) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto avgPool = std::make_shared<op::v1::AvgPool>(in,
strides,
pads_begin,
pads_end,
kernel,
exclude_pad,
rounding_type,
pad_type);
return std::make_shared<Function>(NodeVector{avgPool}, ParameterVector{in});
}
};
TEST_P(ReferenceAvgPoolLayerTest, AvgPoolWithHardcodedRefs) {
Exec();
}
template<typename T>
std::vector<T> getContinuousIncreasingValue(size_t elementSize, float step) {
std::vector<T> a(elementSize);
std::iota(std::begin(a), std::end(a), step);
return a;
}
template <element::Type_t IN_ET>
std::vector<AvgPoolParams> generateParamsForAvgPool() {
using T = typename element_type_traits<IN_ET>::value_type;
std::vector<AvgPoolParams> params{
AvgPoolParams(ov::Shape{1, 1, 3, 3},
ov::Shape{1, 1, 2, 2},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9},
std::vector<T>{3, 4, 6, 7},
Strides{1, 1},
Shape{0, 0},
Shape{0, 0},
Shape{2, 2},
true,
op::RoundingType::FLOOR,
op::PadType::NOTSET),
AvgPoolParams(ov::Shape{1, 1, 4, 4},
ov::Shape{1, 1, 2, 2},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
std::vector<T>{6, 7, 10, 11},
Strides{1, 1},
Shape{0, 0},
Shape{0, 0},
Shape{3, 3},
true,
op::RoundingType::CEIL,
op::PadType::NOTSET),
AvgPoolParams(ov::Shape{1, 1, 2, 2},
ov::Shape{1, 1, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4},
std::vector<T>{1, 1.5, 2, 2, 2.5, 3, 3, 3.5, 4},
Strides{1, 1},
Shape{1, 1},
Shape{1, 1},
Shape{2, 2},
true,
op::RoundingType::CEIL,
op::PadType::NOTSET),
AvgPoolParams(ov::Shape{1, 1, 1, 5},
ov::Shape{1, 1, 1, 3},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5},
std::vector<T>{1.5, 3, 4.5},
Strides{1, 2},
Shape{1, 1},
Shape{1, 1},
Shape{3, 3},
true,
op::RoundingType::CEIL,
op::PadType::EXPLICIT),
AvgPoolParams(ov::Shape{1, 1, 1, 5},
ov::Shape{1, 1, 1, 3},
IN_ET,
IN_ET,
std::vector<T>{2.5, 2, 12, 4, 5},
std::vector<T>{0.5, 2, 1},
Strides{1, 2},
Shape{1, 1},
Shape{1, 1},
Shape{3, 3},
false,
op::RoundingType::CEIL,
op::PadType::EXPLICIT),
AvgPoolParams(ov::Shape{1, 1, 3, 3},
ov::Shape{1, 1, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9},
std::vector<T>{3, 4, 2.25, 6, 7, 3.75, 3.75, 4.25, 2.25},
Strides{1, 1},
Shape{0, 0},
Shape{0, 0},
Shape{2, 2},
false,
op::RoundingType::CEIL,
op::PadType::SAME_UPPER),
AvgPoolParams(ov::Shape{1, 1, 3, 3},
ov::Shape{1, 1, 3, 3},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9},
std::vector<T>{0.25, 0.75, 1.25, 1.25, 3, 4, 2.75, 6, 7},
Strides{1, 1},
Shape{0, 0},
Shape{0, 0},
Shape{2, 2},
false,
op::RoundingType::CEIL,
op::PadType::SAME_LOWER),
AvgPoolParams(ov::Shape{1, 1, 2, 2, 2},
ov::Shape{1, 1, 2, 2, 1},
IN_ET,
IN_ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T>{1.5, 3.5, 5.5, 7.5},
Strides{1, 1, 1},
Shape{0, 0, 0},
Shape{0, 0, 0},
Shape{1, 1, 2},
true,
op::RoundingType::CEIL,
op::PadType::VALID),
AvgPoolParams(ov::Shape{1, 1, 3, 3},
ov::Shape{1, 1, 3, 3},
IN_ET,
IN_ET,
getContinuousIncreasingValue<T>(1 * 1 * 3 * 3, 1),
std::vector<T>{1.0f, 2.5f, 0, 5.5f, 7.0f, 0, 0, 0, 0},
Strides{2, 2},
Shape{1, 1},
Shape{1, 1},
Shape{2, 2},
true,
op::RoundingType::CEIL,
op::PadType::NOTSET),
};
return params;
}
std::vector<AvgPoolParams> generateCombinedParamsForAvgPool() {
const std::vector<std::vector<AvgPoolParams>> allTypeParams{
generateParamsForAvgPool<element::Type_t::f32>(),
generateParamsForAvgPool<element::Type_t::f16>(),
generateParamsForAvgPool<element::Type_t::bf16>()
};
std::vector<AvgPoolParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_AvgPool_With_Hardcoded_Refs,
ReferenceAvgPoolLayerTest,
::testing::ValuesIn(generateCombinedParamsForAvgPool()),
ReferenceAvgPoolLayerTest::getTestCaseName);
} // namespace

View File

@ -133,7 +133,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<ngraph::float16> {-1, -2, 0, 3}, std::vector<int8_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::i8,
std::vector<ngraph::bfloat16> {-1, -2, 0, 3}, std::vector<int8_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i8, std::vector<float> {-1, -2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i8, std::vector<float> {-1, -2, 2.2, 3.8},
std::vector<int8_t> {-1, -2, 2, 3}),
// destination i16
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {8}, ov::element::u1, ov::element::i16, std::vector<uint8_t> {0x81},
@ -162,7 +162,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<ngraph::float16> {-1, -2, 0, 3}, std::vector<int16_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::i16,
std::vector<ngraph::bfloat16> {-1, -2, 0, 3}, std::vector<int16_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i16, std::vector<float> {-1, -2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i16, std::vector<float> {-1, -2, 2.2, 3.8},
std::vector<int16_t> {-1, -2, 2, 3}),
// destination i32
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {8}, ov::element::u1, ov::element::i32, std::vector<uint8_t> {0x81},
@ -191,7 +191,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<ngraph::float16> {-1, -2, 0, 3}, std::vector<int32_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::i32,
std::vector<ngraph::bfloat16> {-1, -2, 0, 3}, std::vector<int32_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i32, std::vector<float> {-1, -2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i32, std::vector<float> {-1, -2, 2.2, 3.8},
std::vector<int32_t> {-1, -2, 2, 3}),
// destination i64
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {8}, ov::element::u1, ov::element::i64, std::vector<uint8_t> {0x81},
@ -220,7 +220,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<ngraph::float16> {-1, -2, 0, 3}, std::vector<int64_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::i64,
std::vector<ngraph::bfloat16> {-1, -2, 0, 3}, std::vector<int64_t> {-1, -2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i64, std::vector<float> {-1, -2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::i64, std::vector<float> {-1, -2, 2.2, 3.8},
std::vector<int64_t> {-1, -2, 2, 3}),
// destination u1
@ -310,7 +310,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<uint8_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::u8,
std::vector<ngraph::bfloat16> {1, 2, 0, 3}, std::vector<uint8_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u8, std::vector<float> {1, 2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u8, std::vector<float> {1, 2, 2.2, 3.8},
std::vector<uint8_t> {1, 2, 2, 3}),
// destination u16
@ -340,7 +340,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<uint16_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::u16,
std::vector<ngraph::bfloat16> {1, 2, 0, 3}, std::vector<uint16_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u16, std::vector<float> {1, 2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u16, std::vector<float> {1, 2, 2.2, 3.8},
std::vector<uint16_t> {1, 2, 2, 3}),
// destination u32
@ -370,7 +370,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<uint32_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::u32,
std::vector<ngraph::bfloat16> {1, 2, 0, 3}, std::vector<uint32_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u32, std::vector<float> {1, 2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u32, std::vector<float> {1, 2, 2.2, 3.8},
std::vector<uint32_t> {1, 2, 2, 3}),
// destination u64
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {8}, ov::element::u1, ov::element::u64, std::vector<uint8_t> {0x81},
@ -399,7 +399,7 @@ INSTANTIATE_TEST_SUITE_P(
std::vector<uint64_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::bf16, ov::element::u64,
std::vector<ngraph::bfloat16> {1, 2, 0, 3}, std::vector<uint64_t> {1, 2, 0, 3}),
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u64, std::vector<float> {1, 2, 2, 3},
ConvertParams(ConversionTypes::CONVERT, ov::PartialShape {4}, ov::element::f32, ov::element::u64, std::vector<float> {1, 2, 2.2, 3.8},
std::vector<uint64_t> {1, 2, 2, 3})),
ReferenceConversionLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,227 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "base_reference_test.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/fake_quantize.hpp"
using namespace ov;
using namespace reference_tests;
namespace {
struct FakeQuantizeParams {
template <class IT>
FakeQuantizeParams(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const std::vector<IT>& input_data,
const std::vector<IT>& expected_data,
const std::shared_ptr<op::v0::Constant>& input_low,
const std::shared_ptr<op::v0::Constant>& input_high,
const std::shared_ptr<op::v0::Constant>& output_low,
const std::shared_ptr<op::v0::Constant>& output_high,
const std::size_t& levels,
const op::AutoBroadcastSpec& broadcast = op::AutoBroadcastSpec::NONE)
: m_input_shape(input_shape),
m_expected_shape(expected_shape),
m_input_type(input_type),
m_expected_type(expected_type),
m_input_data(CreateTensor(input_type, input_data)),
m_expected_data(CreateTensor(expected_type, expected_data)),
m_input_low(input_low),
m_input_high(input_high),
m_output_low(output_low),
m_output_high(output_high),
m_levels(levels),
m_broadcast(broadcast) {}
Shape m_input_shape;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type;
runtime::Tensor m_input_data;
runtime::Tensor m_expected_data;
std::shared_ptr<op::v0::Constant> m_input_low;
std::shared_ptr<op::v0::Constant> m_input_high;
std::shared_ptr<op::v0::Constant> m_output_low;
std::shared_ptr<op::v0::Constant> m_output_high;
std::size_t m_levels;
op::AutoBroadcastSpec m_broadcast;
};
class ReferenceFakeQuantizeLayerTest : public testing::TestWithParam<FakeQuantizeParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.m_input_shape,
params.m_expected_shape,
params.m_input_type,
params.m_expected_type,
params.m_input_low,
params.m_input_high,
params.m_output_low,
params.m_output_high,
params.m_levels,
params.m_broadcast);
inputData = {params.m_input_data};
refOutData = {params.m_expected_data};
}
static std::string getTestCaseName(const testing::TestParamInfo<FakeQuantizeParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "expected_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "expected_type=" << param.m_expected_type << "; ";
result << "input_low=" << param.m_input_low << "; ";
result << "input_high=" << param.m_input_high << "; ";
result << "output_low=" << param.m_output_low << "; ";
result << "ouput_high=" << param.m_output_high << "; ";
result << "broadcast=" << param.m_broadcast.m_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const std::shared_ptr<op::v0::Constant>& input_low,
const std::shared_ptr<op::v0::Constant>& input_high,
const std::shared_ptr<op::v0::Constant>& output_low,
const std::shared_ptr<op::v0::Constant>& output_high,
const std::size_t& levels,
const op::AutoBroadcastSpec& broadcast) {
auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
if (broadcast == op::AutoBroadcastSpec::NONE) {
return std::make_shared<Function>(
NodeVector{std::make_shared<op::v0::FakeQuantize>(in, input_low, input_high, output_low, output_high, levels)},
ParameterVector{in});
} else {
return std::make_shared<Function>(
NodeVector{std::make_shared<op::v0::FakeQuantize>(in, input_low, input_high, output_low, output_high, levels, broadcast)},
ParameterVector{in});
}
}
};
TEST_P(ReferenceFakeQuantizeLayerTest, FakeQuantizeWithHardcodedRefs) {
Exec();
}
template <typename T>
std::vector<T> iota_vector(size_t size) {
std::vector<T> d(size);
std::iota(begin(d), end(d), 0);
return d;
}
template <element::Type_t IN_ET>
std::vector<FakeQuantizeParams> generateParamsForFakeQuantize() {
using T = typename element_type_traits<IN_ET>::value_type;
std::vector<FakeQuantizeParams> params {
FakeQuantizeParams(ov::Shape{1, 2, 3, 4},
ov::Shape{1, 2, 3, 4},
IN_ET,
IN_ET,
iota_vector<T>(shape_size(ov::Shape{1, 2, 3, 4})),
std::vector<T>{2.f, 2.f, 2.f, 2.f, 6.6666669f, 6.6666669f,
6.6666669f, 6.6666669f, 6.6666669f, 6.6666669f, 6.6666669f, 6.6666669f,
11.33333301f, 11.33333301f, 11.33333301f, 11.33333301f, 11.33333301f, 11.33333301f,
11.33333301f, 11.33333301f, 16.f, 16.f, 16.f, 16.f},
op::v0::Constant::create(IN_ET, Shape{}, {0.f}),
op::v0::Constant::create(IN_ET, Shape{}, {23.f}),
op::v0::Constant::create(IN_ET, Shape{}, {2.f}),
op::v0::Constant::create(IN_ET, Shape{}, {16.f}),
4),
FakeQuantizeParams(ov::Shape{1, 2, 3, 4},
ov::Shape{1, 2, 3, 4},
IN_ET,
IN_ET,
iota_vector<T>(shape_size(Shape{1, 2, 3, 4})),
std::vector<T>{2.f, 2.f, 2.f, 2.f, 2.f, 5.5f, 5.5f, 5.5f, 5.5f, 9.f, 9.f, 9.f,
12.5f, 12.5f, 12.5f, 12.5f, 16.f, 16.f, 16.f, 16.f, 16.f, 16.f, 16.f, 16.f},
op::v0::Constant::create(IN_ET, Shape{}, {3.f}),
op::v0::Constant::create(IN_ET, Shape{}, {17.f}),
op::v0::Constant::create(IN_ET, Shape{}, {2.f}),
op::v0::Constant::create(IN_ET, Shape{}, {16.f}),
5),
FakeQuantizeParams(ov::Shape{1, 2, 5, 5},
ov::Shape{1, 2, 5, 5},
IN_ET,
IN_ET,
iota_vector<T>(shape_size(Shape{1, 2, 5, 5})),
std::vector<T>{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 10.0f, 10.0f, 15.0f, 20.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 50.0f,
50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 55.0f, 55.0f, 60.0f, 60.0f, 60.0f, 65.0f, 65.0f,
70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f},
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {5.f, 30.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {10.f, 40.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {0.f, 50.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {20.f, 70.f}),
5),
FakeQuantizeParams(ov::Shape{1, 2, 5, 5},
ov::Shape{1, 2, 5, 5},
IN_ET,
IN_ET,
iota_vector<T>(shape_size(Shape{1, 2, 5, 5})),
std::vector<T>{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 10.0f, 10.0f, 15.0f, 20.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 50.0f,
50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 55.0f, 55.0f, 60.0f, 60.0f, 60.0f, 65.0f, 65.0f,
70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f},
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {5.f, 30.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {10.f, 40.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {0.f, 50.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {20.f, 70.f}),
5,
op::AutoBroadcastSpec(op::AutoBroadcastType::PDPD, 1)),
FakeQuantizeParams(ov::Shape{1, 2, 5, 5},
ov::Shape{1, 2, 5, 5},
IN_ET,
IN_ET,
iota_vector<T>(shape_size(Shape{1, 2, 5, 5})),
std::vector<T>{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 10.0f, 10.0f, 15.0f, 20.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 50.0f,
50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 55.0f, 55.0f, 60.0f, 60.0f, 60.0f, 65.0f, 65.0f,
70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f, 70.0f},
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {5.f, 30.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {10.f, 40.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {0.f, 50.f}),
op::v0::Constant::create(IN_ET, Shape{2, 1, 1}, {20.f, 70.f}),
5,
op::AutoBroadcastSpec(op::AutoBroadcastType::PDPD, -1))
};
return params;
}
std::vector<FakeQuantizeParams> generateCombinedParamsForFakeQuantize() {
const std::vector<std::vector<FakeQuantizeParams>> allTypeParams{
generateParamsForFakeQuantize<element::Type_t::f32>(),
generateParamsForFakeQuantize<element::Type_t::f16>()
};
std::vector<FakeQuantizeParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_FakeQuantize_With_Hardcoded_Refs,
ReferenceFakeQuantizeLayerTest,
::testing::ValuesIn(generateCombinedParamsForFakeQuantize()),
ReferenceFakeQuantizeLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,432 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/reshape.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
//using T1 = typename element_type_traits<IT>::value_type;
namespace {
struct ReshapeParams {
template <class T>
ReshapeParams(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const std::vector<T>& input_value,
const std::vector<T>& expected_value,
const bool zero_flag) {
m_input_shape = input_shape;
m_expected_shape = expected_shape;
m_input_type = input_type;
m_expected_type = expected_type;
m_zero_flag = zero_flag;
m_input_value = input_shape.size() > 0
? CreateTensor(input_shape, input_type, input_value)
: CreateTensor(input_type, input_value);
m_expected_value = expected_shape.size() > 0
? CreateTensor(expected_shape, expected_type, expected_value)
: CreateTensor(expected_type, expected_value);
}
template<class T>
ReshapeParams(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const bool zero_flag,
T step,
const Shape& extra_shape = Shape{}) {
m_input_shape = input_shape;
m_expected_shape = expected_shape;
m_input_type = input_type;
m_expected_type = expected_type;
m_zero_flag = zero_flag;
std::vector<T> value(shape_size(input_shape));
std::iota(value.begin(), value.end(), static_cast<T>(step));
m_input_value = CreateTensor(input_shape, input_type, value);
m_expected_value = CreateTensor(expected_shape, expected_type, value);
if (extra_shape.size() > 0) {
m_expected_shape = extra_shape;
}
}
Shape m_input_shape;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value;
bool m_zero_flag;
};
struct ReshapeShuffleParams {
template<class T>
ReshapeShuffleParams(const Shape& input_shape1,
const Shape& input_shape2,
const Shape& input_shape3,
const Shape& expected_shape,
const element::Type_t& input_type,
const element::Type_t& expected_type,
const bool zero_flag,
T step) {
m_input_shape1 = input_shape1;
m_input_shape2 = input_shape2;
m_input_shape3 = input_shape3;
m_expected_shape = expected_shape;
m_input_type = input_type;
m_expected_type = expected_type;
m_zero_flag = zero_flag;
std::vector<T> value(shape_size(input_shape1));
std::iota(value.begin(), value.end(), static_cast<T>(step));
m_input_value = CreateTensor(input_shape1, input_type, value);
m_expected_value = CreateTensor(expected_shape, expected_type, value);
}
Shape m_input_shape1;
Shape m_input_shape2;
Shape m_input_shape3;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value;
bool m_zero_flag;
};
class ReferenceReshapeLayerTest : public testing::TestWithParam<ReshapeParams>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params.m_input_type,
params.m_expected_type,
params.m_input_shape,
params.m_expected_shape,
params.m_zero_flag);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value};
}
static std::string getTestCaseName(const testing::TestParamInfo<ReshapeParams>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "output_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "output_type=" << param.m_expected_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type& input_type,
const element::Type& expected_type,
const Shape& input_shape,
const Shape& expected_shape,
const bool zero_flag) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto reshape = std::make_shared<op::v1::Reshape>(
in,
op::v0::Constant::create(element::Type_t::u64, {expected_shape.size()}, expected_shape),
zero_flag);
return std::make_shared<Function>(NodeVector{reshape}, ParameterVector{in});
}
};
class ReferenceReshapeShuffleLayerTest : public testing::TestWithParam<ReshapeShuffleParams>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params.m_input_type,
params.m_expected_type,
params.m_input_shape1,
params.m_input_shape2,
params.m_input_shape3,
params.m_expected_shape,
params.m_zero_flag);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value};
}
static std::string getTestCaseName(const testing::TestParamInfo<ReshapeShuffleParams>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape1 << "; ";
result << "output_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "output_type=" << param.m_expected_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type& input_type,
const element::Type& expected_type,
const Shape& input_shape1,
const Shape& input_shape2,
const Shape& input_shape3,
const Shape& expected_shape,
const bool zero_flag) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape1);
const auto reshape1 = std::make_shared<op::v1::Reshape>(
in,
op::v0::Constant::create(element::Type_t::u64, {input_shape2.size()}, input_shape2),
zero_flag);
const auto reshape2 = std::make_shared<op::v1::Reshape>(
reshape1,
op::v0::Constant::create(element::Type_t::u64, {input_shape3.size()}, input_shape3),
zero_flag);
const auto reshape3 = std::make_shared<op::v1::Reshape>(
reshape2,
op::v0::Constant::create(element::Type_t::u64, {expected_shape.size()}, expected_shape),
zero_flag);
return std::make_shared<Function>(NodeVector{reshape3}, ParameterVector{in});
}
};
TEST_P(ReferenceReshapeLayerTest, CompareWithHardcodedRefs) {
Exec();
}
TEST_P(ReferenceReshapeShuffleLayerTest, CompareWithHardcodedRefs) {
Exec();
}
template <element::Type_t ET>
std::vector<ReshapeParams> generateParamsForReshape() {
using T = typename element_type_traits<ET>::value_type;
std::vector<ReshapeParams> params{
ReshapeParams(Shape{2, 2, 3},
Shape{12},
ET,
ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
false),
ReshapeParams(Shape{1, 1, 1},
Shape{},
ET,
ET,
std::vector<T>{6},
std::vector<T>{6},
false),
ReshapeParams(Shape{},
Shape{1, 1, 1, 1, 1, 1},
ET,
ET,
std::vector<T>{42},
std::vector<T>{42},
false),
ReshapeParams(Shape{3},
Shape{3, 1},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{3},
Shape{1, 3},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{3},
Shape{1, 3, 1},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{3, 3},
Shape{3, 3},
ET,
ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9},
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9},
false),
ReshapeParams(Shape{1},
Shape{},
ET,
ET,
std::vector<T>{1},
std::vector<T>{1},
false),
ReshapeParams(Shape{},
Shape{},
ET,
ET,
std::vector<T>{1},
std::vector<T>{1},
false),
ReshapeParams(Shape{2, 2, 3, 3, 2, 4},
Shape{3, 2, 2, 4, 3, 2},
ET,
ET,
false,
static_cast<T>(1)),
ReshapeParams(Shape{2, 2, 5, 5},
Shape{2, 5, 5, 2},
ET,
ET,
true,
static_cast<T>(1),
Shape{0, 5, 0, 2})
};
return params;
}
template <element::Type_t ET>
std::vector<ReshapeParams> generateParamsForReshape8Bit() {
using T = typename element_type_traits<ET>::value_type;
std::vector<ReshapeParams> params{
ReshapeParams(Shape{2, 2, 3},
Shape{12},
ET,
ET,
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
false),
ReshapeParams(Shape{1, 1, 1},
Shape{},
ET,
ET,
std::vector<T>{6},
std::vector<T>{6},
false),
ReshapeParams(Shape{},
Shape{1, 1, 1, 1, 1, 1},
ET,
ET,
std::vector<T>{42},
std::vector<T>{42},
false),
ReshapeParams(Shape{3},
Shape{3, 1},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{3},
Shape{1, 3},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{3},
Shape{1, 3, 1},
ET,
ET,
std::vector<T>{1, 2, 3},
std::vector<T>{1, 2, 3},
false),
ReshapeParams(Shape{1},
Shape{},
ET,
ET,
std::vector<T>{1},
std::vector<T>{1},
false),
ReshapeParams(Shape{},
Shape{},
ET,
ET,
std::vector<T>{1},
std::vector<T>{1},
false)
};
return params;
}
template <element::Type_t ET>
std::vector<ReshapeShuffleParams> generateParamsForReshapeShuffle() {
using T = typename element_type_traits<ET>::value_type;
std::vector<ReshapeShuffleParams> params{
ReshapeShuffleParams(Shape{1, 112, 56, 56},
Shape{1, 4, 28, 56, 56},
Shape{1, 28, 4, 56, 56},
Shape{1, 112, 56, 56},
ET,
ET,
false,
static_cast<T>(1))
};
return params;
}
std::vector<ReshapeParams> generateCombinedParamsForReshape() {
const std::vector<std::vector<ReshapeParams>> allTypeParams{
generateParamsForReshape<element::Type_t::f32>(),
generateParamsForReshape<element::Type_t::i64>(),
generateParamsForReshape<element::Type_t::i32>(),
generateParamsForReshape<element::Type_t::i16>(),
generateParamsForReshape<element::Type_t::u64>(),
generateParamsForReshape<element::Type_t::u32>(),
generateParamsForReshape<element::Type_t::u16>(),
generateParamsForReshape8Bit<element::Type_t::i8>(),
generateParamsForReshape8Bit<element::Type_t::u8>()
};
std::vector<ReshapeParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
std::vector<ReshapeShuffleParams> generateCombinedParamsForReshapeShuffle() {
const std::vector<std::vector<ReshapeShuffleParams>> allTypeParams{
generateParamsForReshapeShuffle<element::Type_t::f32>(),
generateParamsForReshapeShuffle<element::Type_t::i64>(),
generateParamsForReshapeShuffle<element::Type_t::i32>(),
generateParamsForReshapeShuffle<element::Type_t::i16>(),
generateParamsForReshapeShuffle<element::Type_t::i8>(),
generateParamsForReshapeShuffle<element::Type_t::u64>(),
generateParamsForReshapeShuffle<element::Type_t::u32>(),
generateParamsForReshapeShuffle<element::Type_t::u16>(),
generateParamsForReshapeShuffle<element::Type_t::u8>(),
};
std::vector<ReshapeShuffleParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_Reshape_With_Hardcoded_Refs,
ReferenceReshapeLayerTest,
::testing::ValuesIn(generateCombinedParamsForReshape()),
ReferenceReshapeLayerTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(
smoke_Reshape_Shuffle_With_Hardcoded_Refs,
ReferenceReshapeShuffleLayerTest,
::testing::ValuesIn(generateCombinedParamsForReshapeShuffle()),
ReferenceReshapeShuffleLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,201 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/scatter_nd_update.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct ScatterNDUpdateParams {
ScatterNDUpdateParams(const Tensor& dataTensor, const Tensor& indexTensor, const Tensor& updateTensor,
const Tensor& expectedTensor, const std::string& testcaseName = "") :
dataTensor(dataTensor), indexTensor(indexTensor), updateTensor(updateTensor),
expectedTensor(expectedTensor), testcaseName(testcaseName) {}
Tensor dataTensor;
Tensor indexTensor;
Tensor updateTensor;
Tensor expectedTensor;
std::string testcaseName;
};
class ReferenceScatterNDUpdateLayerTest : public testing::TestWithParam<ScatterNDUpdateParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params);
inputData = {params.dataTensor.data};
refOutData = {params.expectedTensor.data};
}
static std::string getTestCaseName(const testing::TestParamInfo<ScatterNDUpdateParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "dType=" << param.dataTensor.type;
result << "_dShape=" << param.dataTensor.shape;
result << "_iType=" << param.indexTensor.type;
result << "_iShape=" << param.indexTensor.shape;
result << "_uType=" << param.updateTensor.type;
result << "_uShape=" << param.updateTensor.shape;
result << "_eType=" << param.expectedTensor.type;
if (param.testcaseName != "") {
result << "_eShape=" << param.expectedTensor.shape;
result << "_" << param.testcaseName;
} else {
result << "_eShape=" << param.expectedTensor.shape;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const ScatterNDUpdateParams& params) {
const auto data = std::make_shared<op::v0::Parameter>(params.dataTensor.type, params.dataTensor.shape);
const auto indices = std::make_shared<op::v0::Constant>(params.indexTensor.type,
params.indexTensor.shape,
params.indexTensor.data.data());
const auto updates = std::make_shared<op::v0::Constant>(params.updateTensor.type,
params.updateTensor.shape,
params.updateTensor.data.data());
const auto scatter = std::make_shared<op::v3::ScatterNDUpdate>(data, indices, updates);
return std::make_shared<ov::Function>(NodeVector{scatter}, ParameterVector{data});
}
};
TEST_P(ReferenceScatterNDUpdateLayerTest, CompareWithRefs) {
Exec();
}
template <element::Type_t IN_ET, element::Type_t IU_ET>
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateParams() {
using T = typename element_type_traits<IN_ET>::value_type;
using U = typename element_type_traits<IU_ET>::value_type;
std::vector<ScatterNDUpdateParams> scatterParams {
// scatter_nd_update_1x1
ScatterNDUpdateParams(Tensor({1}, IN_ET, std::vector<T>{1}),
Tensor({1}, IU_ET, std::vector<U>{0}),
Tensor({1}, IN_ET, std::vector<T>{20}),
Tensor({1}, IN_ET, std::vector<T>{20}),
"scatter_nd_update_1x1"),
// scatter_nd_update_2x2_by_1
ScatterNDUpdateParams(Tensor({2, 2}, IN_ET, std::vector<T>{1, 2, 3, 4}),
Tensor({2, 1}, IU_ET, std::vector<U>{1, 0}),
Tensor({2, 2}, IN_ET, std::vector<T>{10, 20, 30, 40}),
Tensor({2, 2}, IN_ET, std::vector<T>{30, 40, 10, 20}),
"scatter_nd_update_2x2_by_1"),
// scatter_nd_update_2x2_by_2
ScatterNDUpdateParams(Tensor({2, 2}, IN_ET, std::vector<T>{1, 2, 3, 4}),
Tensor({2, 2}, IU_ET, std::vector<U>{0, 0, 1, 1}),
Tensor({2}, IN_ET, std::vector<T>{10, 40}),
Tensor({2, 2}, IN_ET, std::vector<T>{10, 2, 3, 40}),
"scatter_nd_update_2x2_by_2"),
// scatter_nd_update_3x3_by_1
ScatterNDUpdateParams(Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 37, 38, 39}),
Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
Tensor({2, 3, 3}, IN_ET, std::vector<T>{91, 92, 93, 94, 95, 96, 97, 98, 99,
81, 82, 83, 84, 85, 86, 87, 88, 89}),
Tensor({3, 3, 3}, IN_ET, std::vector<T>{91, 92, 93, 94, 95, 96, 97, 98, 99,
21, 22, 23, 24, 25, 26, 27, 28, 29,
81, 82, 83, 84, 85, 86, 87, 88, 89}),
"scatter_nd_update_3x3_by_1"),
// scatter_nd_update_3x3_by_2v2
ScatterNDUpdateParams(Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 37, 38, 39}),
Tensor({2, 2, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, 2, 2, 1, 0, 0, 1, 2, 2}),
Tensor({2, 2}, IN_ET, std::vector<T>{91, 92, 81, 82}),
Tensor({3, 3, 3}, IN_ET, std::vector<T>{91, 12, 13, 14, 15, 16, 17, 18, 19,
81, 22, 23, 24, 25, 26, 27, 28, 82,
31, 32, 33, 34, 35, 36, 37, 38, 92}),
"scatter_nd_update_3x3_by_2v2"),
// scatter_nd_update_3x3_by_2
ScatterNDUpdateParams(Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 37, 38, 39}),
Tensor({2, 2}, IU_ET, std::vector<U>{0, 0, 2, 2}),
Tensor({2, 3}, IN_ET, std::vector<T>{91, 92, 93, 87, 88, 89}),
Tensor({3, 3, 3}, IN_ET, std::vector<T>{91, 92, 93, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 87, 88, 89}),
"scatter_nd_update_3x3_by_2"),
// scatter_nd_update_3x3_by_3
ScatterNDUpdateParams(Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 37, 38, 39}),
Tensor({2, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, 2, 2}),
Tensor({2}, IN_ET, std::vector<T>{91, 99}),
Tensor({3, 3, 3}, IN_ET, std::vector<T>{91, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 23, 24, 25, 26, 27, 28, 29,
31, 32, 33, 34, 35, 36, 37, 38, 99}),
"scatter_nd_update_3x3_by_3"),
// scatter_nd_update_1d_from_examples
ScatterNDUpdateParams(Tensor({8}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8}),
Tensor({4, 1}, IU_ET, std::vector<U>{4, 3, 1, 7}),
Tensor({4}, IN_ET, std::vector<T>{9, 10, 11, 12}),
Tensor({8}, IN_ET, std::vector<T>{1, 11, 3, 10, 9, 6, 7, 12}),
"scatter_nd_update_1d_from_examples"),
// scatter_nd_update_4x4_shape_from_examples
ScatterNDUpdateParams(Tensor({4, 4, 4}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
Tensor({2, 4, 4}, IN_ET, std::vector<T>{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}),
Tensor({4, 4, 4}, IN_ET, std::vector<T>{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
"scatter_nd_update_4x4_shape_from_examples"),
// scatter_nd_update_4x4_v2
ScatterNDUpdateParams(Tensor({4, 4, 4}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
Tensor({2, 2, 2}, IU_ET, std::vector<U>{0, 0, 2, 2, 1, 1, 3, 3}),
Tensor({2, 2, 4}, IN_ET, std::vector<T>{15, 16, 17, 18, 25, 26, 27, 28,
35, 36, 37, 38, 45, 46, 47, 58}),
Tensor({4, 4, 4}, IN_ET, std::vector<T>{15, 16, 17, 18, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
1, 2, 3, 4, 35, 36, 37, 38, 8, 7, 6, 5, 4, 3, 2, 1,
8, 7, 6, 5, 4, 3, 2, 1, 25, 26, 27, 28, 5, 6, 7, 8,
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 45, 46, 47, 58}),
"scatter_nd_update_4x4_v2"),
};
return scatterParams;
}
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateCombinedParams() {
const std::vector<std::vector<ScatterNDUpdateParams>> scatterTypeParams {
generateScatterNDUpdateParams<element::Type_t::i32, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::i64, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::u32, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::u64, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::f16, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::f32, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::boolean, element::Type_t::i32>(),
generateScatterNDUpdateParams<element::Type_t::i32, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::i64, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::u32, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::u64, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::f16, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::f32, element::Type_t::i64>(),
generateScatterNDUpdateParams<element::Type_t::boolean, element::Type_t::i64>(),
};
std::vector<ScatterNDUpdateParams> combinedParams;
for (const auto& params : scatterTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(smoke_ScatterNDUpdate_With_Hardcoded_Refs, ReferenceScatterNDUpdateLayerTest,
testing::ValuesIn(generateScatterNDUpdateCombinedParams()), ReferenceScatterNDUpdateLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,311 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/shape_of.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct ShapeOfParamsV1 {
template <class IT, class OT>
ShapeOfParamsV1(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const std::vector<IT>& input_value,
const std::vector<OT>& expected_value)
: m_input_shape(input_shape),
m_expected_shape(expected_shape),
m_input_type(input_type),
m_expected_type(expected_type),
m_input_value(CreateTensor(input_shape, input_type, input_value)),
m_expected_value(CreateTensor(expected_shape, expected_type, expected_value)) {}
Shape m_input_shape;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value;
};
struct ShapeOfParamsV3 {
template <class IT, class OT1, class OT2>
ShapeOfParamsV3(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type1,
const element::Type& expected_type2,
const std::vector<IT>& input_value,
const std::vector<OT1>& expected_value1,
const std::vector<OT2>& expected_value2)
: m_input_shape(input_shape),
m_expected_shape(expected_shape),
m_input_type(input_type),
m_expected_type1(expected_type1),
m_expected_type2(expected_type2),
m_input_value(CreateTensor(input_shape, input_type, input_value)),
m_expected_value1(CreateTensor(expected_shape, expected_type1, expected_value1)),
m_expected_value2(CreateTensor(expected_shape, expected_type2, expected_value2)) {}
Shape m_input_shape;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type1;
element::Type m_expected_type2;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value1;
runtime::Tensor m_expected_value2;
};
class ReferenceShapeOfV1LayerTest : public testing::TestWithParam<ShapeOfParamsV1>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params.m_input_type, params.m_input_shape);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value};
}
static std::string getTestCaseName(const testing::TestParamInfo<ShapeOfParamsV1>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "output_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "output_type=" << param.m_expected_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type& input_type, const Shape& input_shape) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto shapeof = std::make_shared<op::v0::ShapeOf>(in);
return std::make_shared<Function>(NodeVector{shapeof}, ParameterVector{in});
}
};
class ReferenceShapeOfV3LayerTest : public testing::TestWithParam<ShapeOfParamsV3>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params.m_input_type, params.m_input_shape);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value1, params.m_expected_value2};
}
static std::string getTestCaseName(const testing::TestParamInfo<ShapeOfParamsV3>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "output_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "output_type1=" << param.m_expected_type1 << "; ";
result << "output_type2=" << param.m_expected_type2 << "; ";
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type& input_type, const Shape& input_shape) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto shapeof1 = std::make_shared<op::v3::ShapeOf>(in);
const auto shapeof2 = std::make_shared<op::v3::ShapeOf>(in, element::Type_t::i32);
return std::make_shared<Function>(OutputVector{shapeof1, shapeof2}, ParameterVector{in});
}
};
TEST_P(ReferenceShapeOfV1LayerTest, CompareWithHardcodedRefs) {
Exec();
}
TEST_P(ReferenceShapeOfV3LayerTest, CompareWithHardcodedRefs) {
Exec();
}
template <element::Type_t IT, element::Type_t OT>
std::vector<ShapeOfParamsV1> generateParamsForShapeOfSmall_V1() {
using T1 = typename element_type_traits<IT>::value_type;
using T2 = typename element_type_traits<OT>::value_type;
std::vector<ShapeOfParamsV1> params{
ShapeOfParamsV1(Shape{2},
Shape{1},
IT,
OT,
std::vector<T1>{2, 0},
std::vector<T2>{2}),
ShapeOfParamsV1(Shape{2, 4},
Shape{2},
IT,
OT,
std::vector<T1>{2 * 4, 0},
std::vector<T2>{2, 4})
};
return params;
}
template <element::Type_t IT, element::Type_t OT>
std::vector<ShapeOfParamsV1> generateParamsForShapeOfBig_V1() {
using T1 = typename element_type_traits<IT>::value_type;
using T2 = typename element_type_traits<OT>::value_type;
std::vector<ShapeOfParamsV1> params{
ShapeOfParamsV1(Shape{2},
Shape{1},
IT,
OT,
std::vector<T1>{2, 0},
std::vector<T2>{2}),
ShapeOfParamsV1(Shape{2, 4},
Shape{2},
IT,
OT,
std::vector<T1>{2 * 4, 0},
std::vector<T2>{2, 4}),
ShapeOfParamsV1(Shape{2, 4, 8, 16, 32},
Shape{5},
IT,
OT,
std::vector<T1>{2 * 4 * 8 * 16 * 32, 0},
std::vector<T2>{2, 4, 8, 16, 32})};
return params;
}
template <element::Type_t IT, element::Type_t OT1, element::Type_t OT2>
std::vector<ShapeOfParamsV3> generateParamsForShapeOfSmall_V3() {
using T1 = typename element_type_traits<IT>::value_type;
using T2 = typename element_type_traits<OT1>::value_type;
using T3 = typename element_type_traits<OT2>::value_type;
std::vector<ShapeOfParamsV3> params{
ShapeOfParamsV3(Shape{2},
Shape{1},
IT,
OT1,
OT2,
std::vector<T1>{2, 0},
std::vector<T2>{2},
std::vector<T3>{2}),
ShapeOfParamsV3(Shape{2, 4},
Shape{2},
IT,
OT1,
OT2,
std::vector<T1>{2 * 4, 0},
std::vector<T2>{2, 4},
std::vector<T3>{2, 4})
};
return params;
}
template <element::Type_t IT, element::Type_t OT1, element::Type_t OT2>
std::vector<ShapeOfParamsV3> generateParamsForShapeOfBig_V3() {
using T1 = typename element_type_traits<IT>::value_type;
using T2 = typename element_type_traits<OT1>::value_type;
using T3 = typename element_type_traits<OT2>::value_type;
std::vector<ShapeOfParamsV3> params{
ShapeOfParamsV3(Shape{2},
Shape{1},
IT,
OT1,
OT2,
std::vector<T1>{2, 0},
std::vector<T2>{2},
std::vector<T3>{2}),
ShapeOfParamsV3(Shape{2, 4},
Shape{2},
IT,
OT1,
OT2,
std::vector<T1>{2 * 4, 0},
std::vector<T2>{2, 4},
std::vector<T3>{2, 4}),
ShapeOfParamsV3(Shape{2, 4, 8, 16, 32},
Shape{5},
IT,
OT1,
OT2,
std::vector<T1>{2 * 4 * 8 * 16 * 32, 0},
std::vector<T2>{2, 4, 8, 16, 32},
std::vector<T3>{2, 4, 8, 16, 32})
};
return params;
}
std::vector<ShapeOfParamsV1> generateCombinedParamsForShapeOfV1() {
const std::vector<std::vector<ShapeOfParamsV1>> allTypeParams{
generateParamsForShapeOfBig_V1<element::Type_t::f32, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::f16, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::bf16, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::i64, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::i32, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::u64, element::Type_t::i64>(),
generateParamsForShapeOfBig_V1<element::Type_t::u32, element::Type_t::i64>(),
generateParamsForShapeOfSmall_V1<element::Type_t::i16, element::Type_t::i64>(),
generateParamsForShapeOfSmall_V1<element::Type_t::i8, element::Type_t::i64>(),
generateParamsForShapeOfSmall_V1<element::Type_t::u16, element::Type_t::i64>(),
generateParamsForShapeOfSmall_V1<element::Type_t::u8, element::Type_t::i64>()
};
std::vector<ShapeOfParamsV1> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
std::vector<ShapeOfParamsV3> generateCombinedParamsForShapeOfV3() {
const std::vector<std::vector<ShapeOfParamsV3>> allTypeParams{
generateParamsForShapeOfBig_V3<element::Type_t::f32, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::f16, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::bf16, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::i64, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::i32, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::u64, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfBig_V3<element::Type_t::u32, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfSmall_V3<element::Type_t::i16, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfSmall_V3<element::Type_t::i8, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfSmall_V3<element::Type_t::u16, element::Type_t::i64, element::Type_t::i32>(),
generateParamsForShapeOfSmall_V3<element::Type_t::u8, element::Type_t::i64, element::Type_t::i32>()
};
std::vector<ShapeOfParamsV3> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_ShapeOf_With_Hardcoded_Refs,
ReferenceShapeOfV1LayerTest,
::testing::ValuesIn(generateCombinedParamsForShapeOfV1()),
ReferenceShapeOfV1LayerTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(
smoke_ShapeOf_With_Hardcoded_Refs,
ReferenceShapeOfV3LayerTest,
::testing::ValuesIn(generateCombinedParamsForShapeOfV3()),
ReferenceShapeOfV3LayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,174 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/squeeze.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct SqueezeParams {
template <class IO_T, class Axes_T>
SqueezeParams(const Shape& input_shape,
const Shape& output_shape,
const element::Type& input_type,
const element::Type& output_type,
const std::vector<IO_T>& input_value,
const std::vector<IO_T>& expected_value,
const Shape& axes_shape,
const element::Type& axes_type,
const std::vector<Axes_T>& axes_value)
: m_input_shape(input_shape),
m_output_shape(output_shape),
m_input_type(input_type),
m_output_type(output_type),
m_input_value(CreateTensor(input_type, input_value)),
m_expected_value(CreateTensor(output_type, expected_value)),
m_axes_shape(axes_shape),
m_axes_type(axes_type),
m_axes_value(CreateTensor(axes_type, axes_value)),
m_axes_node(true) {}
template <class IO_T>
SqueezeParams(const Shape& input_shape,
const Shape& output_shape,
const element::Type& input_type,
const element::Type& output_type,
const std::vector<IO_T>& input_value,
const std::vector<IO_T>& expected_value)
: m_input_shape(input_shape),
m_output_shape(output_shape),
m_input_type(input_type),
m_output_type(output_type),
m_input_value(CreateTensor(input_type, input_value)),
m_expected_value(CreateTensor(input_type, expected_value)),
m_axes_node(false) {}
Shape m_input_shape;
Shape m_output_shape;
element::Type m_input_type;
element::Type m_output_type;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value;
Shape m_axes_shape;
element::Type m_axes_type;
runtime::Tensor m_axes_value;
bool m_axes_node;
};
class ReferenceSqueezeLayerTest : public testing::TestWithParam<SqueezeParams>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value};
}
static std::string getTestCaseName(const testing::TestParamInfo<SqueezeParams>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "output_shape=" << param.m_output_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "output_type=" << param.m_output_type << "; ";
if (param.m_axes_node) {
result << "axes_shape=" << param.m_axes_shape << "; ";
result << "axes_type=" << param.m_axes_type;
}
result << "axes_node=" << param.m_axes_node;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const SqueezeParams& params) {
const auto in = std::make_shared<op::v0::Parameter>(params.m_input_type, params.m_input_shape);
std::shared_ptr<op::v0::Constant> axes_node = NULL;
std::shared_ptr<op::v0::Squeeze> squeeze = NULL;
if (params.m_axes_node) {
axes_node = std::make_shared<op::v0::Constant>(params.m_axes_type, params.m_axes_shape, params.m_axes_value.data());
squeeze = std::make_shared<op::v0::Squeeze>(in, axes_node);
} else {
squeeze = std::make_shared<op::v0::Squeeze>(in);
}
return std::make_shared<ov::Function>(squeeze, ParameterVector{in});
}
};
TEST_P(ReferenceSqueezeLayerTest, CompareWithHardcodedRefs) {
Exec();
}
template <element::Type_t IO_T, element::Type_t Axes_T>
std::vector<SqueezeParams> generateParamsForSqueeze() {
using T1 = typename element_type_traits<IO_T>::value_type;
using T2 = typename element_type_traits<Axes_T>::value_type;
std::vector<SqueezeParams> params{
SqueezeParams(Shape{1, 4, 1, 1, 2},
Shape{4, 1, 2},
IO_T,
IO_T,
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
Shape {2},
Axes_T,
std::vector<T2>{0, 2}),
SqueezeParams(Shape{1, 4, 1, 1, 2},
Shape{4, 2},
IO_T,
IO_T,
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
Shape{0},
Axes_T,
std::vector<T2>{}),
SqueezeParams(Shape{1, 4, 1, 1, 2},
Shape{4, 2},
IO_T,
IO_T,
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8}),
};
return params;
}
std::vector<SqueezeParams> generateCombinedParamsForSqueeze() {
const std::vector<std::vector<SqueezeParams>> allTypeParams{
generateParamsForSqueeze<element::Type_t::f32, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::i64, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::i32, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::i16, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::i8, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::u64, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::u32, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::u16, element::Type_t::i64>(),
generateParamsForSqueeze<element::Type_t::u8, element::Type_t::i64>()
};
std::vector<SqueezeParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_Squeeze_With_Hardcoded_Refs,
ReferenceSqueezeLayerTest,
::testing::ValuesIn(generateCombinedParamsForSqueeze()),
ReferenceSqueezeLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,171 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/unsqueeze.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct UnsqueezeParams {
template <class IO_T, class Axes_T>
UnsqueezeParams(const Shape& input_shape,
const Shape& expected_shape,
const element::Type& input_type,
const element::Type& expected_type,
const std::vector<IO_T>& input_value,
const std::vector<IO_T>& expected_value,
const Shape& axes_shape,
const element::Type& axes_type,
const std::vector<Axes_T>& axes_value)
: m_input_shape(input_shape),
m_expected_shape(expected_shape),
m_input_type(input_type),
m_expected_type(expected_type),
m_input_value(CreateTensor(input_type, input_value)),
m_expected_value(CreateTensor(expected_type, expected_value)),
m_axes_shape(axes_shape),
m_axes_type(axes_type),
m_axes_value(CreateTensor(axes_type, axes_value)) {}
Shape m_input_shape;
Shape m_expected_shape;
element::Type m_input_type;
element::Type m_expected_type;
runtime::Tensor m_input_value;
runtime::Tensor m_expected_value;
Shape m_axes_shape;
element::Type m_axes_type;
runtime::Tensor m_axes_value;
};
class ReferenceUnsqueezeLayerTest : public testing::TestWithParam<UnsqueezeParams>, public CommonReferenceTest {
public:
void SetUp() override {
const auto params = GetParam();
function = CreateFunction(params.m_input_type,
params.m_input_shape,
params.m_axes_type,
params.m_axes_shape,
params.m_axes_value);
inputData = {params.m_input_value};
refOutData = {params.m_expected_value};
}
static std::string getTestCaseName(const testing::TestParamInfo<UnsqueezeParams>& obj) {
const auto param = obj.param;
std::ostringstream result;
result << "input_shape=" << param.m_input_shape << "; ";
result << "expected_shape=" << param.m_expected_shape << "; ";
result << "input_type=" << param.m_input_type << "; ";
result << "expected_type=" << param.m_expected_type << "; ";
result << "axes_shape=" << param.m_axes_shape << "; ";
result << "axes_type=" << param.m_axes_type << "; ";
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type_t& input_type,
const Shape& input_shape,
const element::Type& axes_type,
const Shape& axes_shape,
const runtime::Tensor& axes_value) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto axes = std::make_shared<op::v0::Constant>(axes_type, axes_shape, axes_value.data());
const auto unsqueeze = std::make_shared<op::v0::Unsqueeze>(in, axes);
return std::make_shared<ov::Function>(unsqueeze, ParameterVector{in});
}
};
TEST_P(ReferenceUnsqueezeLayerTest, CompareWithHardcodedRefs) {
Exec();
}
template <element::Type_t IO_T, element::Type_t Axes_T>
std::vector<UnsqueezeParams> generateParamsForUnsqueeze() {
using T1 = typename element_type_traits<IO_T>::value_type;
using T2 = typename element_type_traits<Axes_T>::value_type;
std::vector<UnsqueezeParams> params{
UnsqueezeParams(Shape{4, 2},
Shape{4, 1, 1, 2},
IO_T,
IO_T,
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
Shape {2},
Axes_T,
std::vector<T2>{1, 2})
};
return params;
}
template <element::Type_t IO_T, element::Type_t Axes_T>
std::vector<UnsqueezeParams> generateParamsForUnsqueezeNegative() {
using T1 = typename element_type_traits<IO_T>::value_type;
using T2 = typename element_type_traits<Axes_T>::value_type;
std::vector<UnsqueezeParams> params{
UnsqueezeParams(Shape{4, 2},
Shape{4, 1, 2, 1},
IO_T,
IO_T,
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
std::vector<T1>{1, 2, 3, 4, 5, 6, 7, 8},
Shape {2},
Axes_T,
std::vector<T2>{1, -1})
};
return params;
}
std::vector<UnsqueezeParams> generateCombinedParamsForUnsqueeze() {
const std::vector<std::vector<UnsqueezeParams>> allTypeParams{
generateParamsForUnsqueeze<element::Type_t::f32, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::f16, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::i64, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::i32, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::u64, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::u32, element::Type_t::i64>(),
generateParamsForUnsqueeze<element::Type_t::f32, element::Type_t::i32>(),
generateParamsForUnsqueeze<element::Type_t::f16, element::Type_t::i32>(),
generateParamsForUnsqueeze<element::Type_t::i64, element::Type_t::i32>(),
generateParamsForUnsqueeze<element::Type_t::i32, element::Type_t::i32>(),
generateParamsForUnsqueeze<element::Type_t::u64, element::Type_t::i32>(),
generateParamsForUnsqueeze<element::Type_t::u32, element::Type_t::i32>(),
generateParamsForUnsqueezeNegative<element::Type_t::f32, element::Type_t::i64>(),
generateParamsForUnsqueezeNegative<element::Type_t::f16, element::Type_t::i64>(),
generateParamsForUnsqueezeNegative<element::Type_t::i64, element::Type_t::i64>(),
generateParamsForUnsqueezeNegative<element::Type_t::i32, element::Type_t::i64>(),
generateParamsForUnsqueezeNegative<element::Type_t::f32, element::Type_t::i32>(),
generateParamsForUnsqueezeNegative<element::Type_t::f16, element::Type_t::i32>(),
generateParamsForUnsqueezeNegative<element::Type_t::i64, element::Type_t::i32>(),
generateParamsForUnsqueezeNegative<element::Type_t::i32, element::Type_t::i32>(),
};
std::vector<UnsqueezeParams> combinedParams;
for (const auto& params : allTypeParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(
smoke_Unsqueeze_With_Hardcoded_Refs,
ReferenceUnsqueezeLayerTest,
::testing::ValuesIn(generateCombinedParamsForUnsqueeze()),
ReferenceUnsqueezeLayerTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,21 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "behavior/ov_infer_request/callback.hpp"
using namespace ov::test::behavior;
namespace {
const std::vector<std::map<std::string, std::string>> configs = {
{}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestCallbackTests,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
OVInferRequestCallbackTests::getTestCaseName);
} // namespace

View File

@ -0,0 +1,19 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/ov_infer_request/cancellation.hpp"
using namespace ov::test::behavior;
namespace {
const std::vector<std::map<std::string, std::string>> configs = {
{},
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestCancellationTests,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
OVInferRequestCancellationTests::getTestCaseName);
} // namespace

View File

@ -4,9 +4,9 @@
#include <vector>
#include "behavior/infer_request/infer_request_dynamic.hpp"
#include "behavior/ov_infer_request/infer_request_dynamic.hpp"
using namespace BehaviorTestsDefinitions;
using namespace ov::test::behavior;
namespace {
@ -17,22 +17,22 @@ const std::vector<std::map<std::string, std::string>> configs = {
const std::vector<std::map<std::string, std::string>> HeteroConfigs = {
{{"TARGET_FALLBACK", CommonTestUtils::DEVICE_TEMPLATE}}};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestDynamicTests,
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestDynamicTests,
::testing::Combine(
::testing::Values(ngraph::builder::subgraph::makeSplitConvConcat()),
::testing::Values(std::vector<std::pair<std::vector<size_t>, std::vector<size_t>>>{{{1, 4, 20, 20}, {1, 10, 18, 18}},
{{2, 4, 20, 20}, {2, 10, 18, 18}}}),
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
InferRequestDynamicTests::getTestCaseName);
OVInferRequestDynamicTests::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, InferRequestDynamicTests,
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, OVInferRequestDynamicTests,
::testing::Combine(
::testing::Values(ngraph::builder::subgraph::makeSplitConvConcat()),
::testing::Values(std::vector<std::pair<std::vector<size_t>, std::vector<size_t>>>{{{1, 4, 20, 20}, {1, 10, 18, 18}},
{{2, 4, 20, 20}, {2, 10, 18, 18}}}),
::testing::Values(CommonTestUtils::DEVICE_HETERO),
::testing::ValuesIn(HeteroConfigs)),
InferRequestDynamicTests::getTestCaseName);
OVInferRequestDynamicTests::getTestCaseName);
} // namespace

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/infer_request/inference_chaining.hpp"
#include "behavior/ov_infer_request/inference_chaining.hpp"
#include "common_test_utils/test_constants.hpp"
using namespace ov::test::behavior;

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "behavior/ov_infer_request/io_tensor.hpp"
using namespace ov::test::behavior;
namespace {
const std::vector<std::map<std::string, std::string>> configs = {
{}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestIOTensorTest,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
OVInferRequestIOTensorTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,23 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "behavior/ov_infer_request/multithreading.hpp"
using namespace ov::test::behavior;
namespace {
const std::vector<std::map<std::string, std::string>> configs = {
{}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestMultithreadingTests,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
OVInferRequestMultithreadingTests::getTestCaseName);
} // namespace

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "behavior/ov_infer_request/wait.hpp"
using namespace ov::test::behavior;
namespace {
const std::vector<std::map<std::string, std::string>> configs = {
{}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferRequestWaitTests,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
OVInferRequestWaitTests::getTestCaseName);
} // namespace

View File

@ -22,4 +22,51 @@ INSTANTIATE_TEST_SUITE_P(nightly_RandomMajorNodes, HeteroSyntheticTest,
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::_randomMajorNodeFunctions)),
HeteroSyntheticTest::getTestCaseName);
static std::vector<std::function<std::shared_ptr<ngraph::Function>()>> dynamicBuilders = {
[] {return ngraph::builder::subgraph::makeConvPoolReluNonZero();},
};
INSTANTIATE_TEST_SUITE_P(smoke_NonZeroMajorNode_dynamic, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::withMajorNodesFunctions(
dynamicBuilders.front(), {"nonZero_1"}))),
HeteroSyntheticTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_NonZeroMajorNode_dynamic_batch, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::withMajorNodesFunctions(
dynamicBuilders.front(), {"nonZero_1"}, true))),
HeteroSyntheticTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_SingleMajorNode_dynamic, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::singleMajorNodeFunctions(
dynamicBuilders))),
HeteroSyntheticTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(nightly_RandomMajorNodes_dynamic, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::randomMajorNodeFunctions(
dynamicBuilders))),
HeteroSyntheticTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_SingleMajorNode_dynamic_batch, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::singleMajorNodeFunctions(
dynamicBuilders, true))),
HeteroSyntheticTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(nightly_RandomMajorNodes_dynamic_batch, HeteroSyntheticTest,
::testing::Combine(
::testing::Values(std::vector<PluginParameter>{{"TEMPLATE0", "templatePlugin"}, {"TEMPLATE1", "templatePlugin"}}),
::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::randomMajorNodeFunctions(
dynamicBuilders, true))),
HeteroSyntheticTest::getTestCaseName);
} // namespace

View File

@ -514,6 +514,72 @@ static RefPreprocessParams convert_layout_nhwc_to_net_no_tensor_shape() {
return res;
}
static RefPreprocessParams convert_layout_by_dims() {
RefPreprocessParams res("convert_layout_by_dims");
res.function = []() {
auto f = create_simple_function(element::u8, {1, 3, 2, 2});
f = PrePostProcessor()
.input(InputInfo()
.preprocess(PreProcessSteps().convert_layout({0, 3, 1, 2})))
.build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 3}, element::u8, std::vector<uint8_t>{1, 2, 3, // [H=0, W=0, RGB]
4, 5, 6, // [H=0, W=1]
7, 8, 9, // [H=1, W=0]
10, 11, 12}); // [H=1, W=1]
res.expected.emplace_back(Shape{1, 3, 2, 2}, element::u8, std::vector<uint8_t>{1, 4, 7, 10, // R
2, 5, 8, 11, // G
3, 6, 9, 12}); // B
return res;
}
static RefPreprocessParams convert_layout_by_dims_multi() {
RefPreprocessParams res("convert_layout_by_dims_multi");
res.function = []() {
auto f = create_simple_function(element::f32, {1, 3, 2, 2});
auto p = PreProcessSteps();
p.convert_layout({0, 1, 3, 2}); // NHWC->NHCW
p.convert_layout({0, 2, 1, 3}); // NHCW->NCHW
f = PrePostProcessor()
.input(InputInfo().preprocess(std::move(p)))
.build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 3}, element::f32, std::vector<float>{1, 2, 3, // [H=0, W=0]
4, 5, 6, // [H=0, W=1]
7, 8, 9, // [H=1, W=0]
10, 11, 12}); // [H=1, W=1]
res.expected.emplace_back(Shape{1, 3, 2, 2}, element::f32, std::vector<float>{1, 4, 7, 10, // R
2, 5, 8, 11, // G
3, 6, 9, 12}); // B
return res;
}
static RefPreprocessParams convert_layout_by_dims_multi_layout() {
RefPreprocessParams res("convert_layout_by_dims_multi_layout");
res.function = []() {
auto f = create_simple_function(element::f32, {1, 3, 2, 2});
auto p = PreProcessSteps();
p.convert_layout({0, 1, 3, 2}); // NHWC->NHCW
p.mean({1, 2, 2}); // Apply means to 'C' channel
p.convert_layout({0, 2, 1, 3}); // NHCW->NCHW
f = PrePostProcessor()
.input(InputInfo().tensor(InputTensorInfo().set_layout("N??C"))
.preprocess(std::move(p)))
.build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 3}, element::f32, std::vector<float>{1, 2, 3, // [H=0, W=0, RGB]
4, 5, 6, // [H=0, W=1]
7, 8, 9, // [H=1, W=0]
10, 11, 12}); // [H=1, W=1]
res.expected.emplace_back(Shape{1, 3, 2, 2}, element::f32, std::vector<float>{1-1, 4-1, 7-1, 10-1, // R
2-2, 5-2, 8-2, 11-2, // G
3-2, 6-2, 9-2, 12-2}); // B
return res;
}
static RefPreprocessParams resize_and_convert_layout() {
RefPreprocessParams res("resize_and_convert_layout");
res.function = []() {
@ -719,6 +785,48 @@ static RefPreprocessParams postprocess_2_inputs_basic() {
return res;
}
static RefPreprocessParams post_convert_layout_by_dims() {
RefPreprocessParams res("post_convert_layout_by_dims");
res.function = []() {
auto f = create_simple_function(element::u8, {1, 2, 2, 3});
f = PrePostProcessor()
.output(OutputInfo()
.postprocess(PostProcessSteps().convert_layout({0, 3, 1, 2})))
.build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 3}, element::u8, std::vector<uint8_t>{1, 2, 3, // [H=0, W=0, RGB]
4, 5, 6, // [H=0, W=1]
7, 8, 9, // [H=1, W=0]
10, 11, 12}); // [H=1, W=1]
res.expected.emplace_back(Shape{1, 3, 2, 2}, element::u8, std::vector<uint8_t>{1, 4, 7, 10, // R
2, 5, 8, 11, // G
3, 6, 9, 12}); // B
return res;
}
static RefPreprocessParams post_convert_layout_by_dims_multi() {
RefPreprocessParams res("post_convert_layout_by_dims_multi");
res.function = []() {
auto f = create_simple_function(element::f32, {1, 2, 2, 3});
auto p = PostProcessSteps();
p.convert_layout({0, 1, 3, 2}); // NHWC->NHCW
p.convert_layout({0, 2, 1, 3}); // NHCW->NCHW
f = PrePostProcessor()
.output(OutputInfo().postprocess(std::move(p)))
.build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 3}, element::f32, std::vector<float>{1, 2, 3, // [H=0, W=0]
4, 5, 6, // [H=0, W=1]
7, 8, 9, // [H=1, W=0]
10, 11, 12}); // [H=1, W=1]
res.expected.emplace_back(Shape{1, 3, 2, 2}, element::f32, std::vector<float>{1, 4, 7, 10, // R
2, 5, 8, 11, // G
3, 6, 9, 12}); // B
return res;
}
static RefPreprocessParams pre_and_post_processing() {
RefPreprocessParams res("pre_and_post_processing");
res.function = []() {
@ -746,6 +854,101 @@ static RefPreprocessParams pre_and_post_processing() {
return res;
}
static RefPreprocessParams rgb_to_bgr() {
RefPreprocessParams res("rgb_to_bgr");
res.function = []() {
auto f = create_simple_function(element::f32, Shape{2, 1, 1, 3});
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_color_format(ColorFormat::RGB))
.preprocess(PreProcessSteps().convert_color(ColorFormat::BGR))).build(f);
return f;
};
res.inputs.emplace_back(Shape{2, 3, 1, 1}, element::f32, std::vector<float>{1, 2, 3, 4, 5, 6});
res.expected.emplace_back(Shape{2, 3, 1, 1}, element::f32, std::vector<float>{3, 2, 1, 6, 5, 4});
return res;
}
static RefPreprocessParams bgr_to_rgb() {
RefPreprocessParams res("bgr_to_rgb");
res.function = []() {
auto f = create_simple_function(element::f32, Shape{2, 1, 1, 3});
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_color_format(ColorFormat::BGR))
.preprocess(PreProcessSteps().convert_color(ColorFormat::RGB))).build(f);
return f;
};
res.inputs.emplace_back(Shape{2, 3, 1, 1}, element::f32, std::vector<float>{1, 2, 3, 4, 5, 6});
res.expected.emplace_back(Shape{2, 3, 1, 1}, element::f32, std::vector<float>{3, 2, 1, 6, 5, 4});
return res;
}
static RefPreprocessParams reverse_channels_nchw() {
RefPreprocessParams res("reverse_channels_nchw");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{1, 2, 2, 2});
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_layout("NCHW"))
.preprocess(PreProcessSteps().reverse_channels())).build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 2, 2, 2}, element::f32, std::vector<float>{1, 2, 3, 4, 5, 6, 7, 8});
res.expected.emplace_back(Shape{1, 2, 2, 2}, element::f32, std::vector<float>{5, 6, 7, 8, 1, 2, 3, 4});
return res;
}
static RefPreprocessParams reverse_channels_dyn_layout() {
RefPreprocessParams res("reverse_channels_dyn_layout");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{1, 1, 3, 2});
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_color_format(ColorFormat::BGR).set_layout("...CN"))
.preprocess(PreProcessSteps().convert_color(ColorFormat::RGB))).build(f);
return f;
};
res.inputs.emplace_back(Shape{1, 1, 3, 2}, element::f32, std::vector<float>{1, 2, 3, 4, 5, 6});
res.expected.emplace_back(Shape{1, 1, 3, 2}, element::f32, std::vector<float>{5, 6, 3, 4, 1, 2});
return res;
}
static RefPreprocessParams reverse_dyn_shape() {
RefPreprocessParams res("reverse_dyn_shape");
res.function = []() {
auto f = create_simple_function(element::u8, PartialShape{Dimension::dynamic(),
Dimension::dynamic(),
Dimension::dynamic(),
Dimension::dynamic()});
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_layout("NCHW"))
.preprocess(PreProcessSteps().reverse_channels())).build(f);
return f;
};
res.inputs.emplace_back(element::u8, Shape{2, 2, 1, 3}, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
res.expected.emplace_back(Shape{2, 2, 1, 3}, element::u8, std::vector<uint8_t>{4, 5, 6, 1, 2, 3, 10, 11, 12, 7, 8, 9});
return res;
}
static RefPreprocessParams reverse_fully_dyn_shape() {
RefPreprocessParams res("reverse_fully_dyn_shape");
res.function = []() {
auto f = create_simple_function(element::u8, PartialShape::dynamic());
auto p = PreProcessSteps();
p.reverse_channels();
f = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_layout("...C??"))
.preprocess(std::move(p))).build(f);
return f;
};
res.inputs.emplace_back(element::u8, Shape{2, 2, 1, 3}, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
res.expected.emplace_back(Shape{2, 2, 1, 3}, element::u8, std::vector<uint8_t>{4, 5, 6, 1, 2, 3, 10, 11, 12, 7, 8, 9});
return res;
}
std::vector<RefPreprocessParams> allPreprocessTests() {
return std::vector<RefPreprocessParams> {
simple_mean_scale(),
@ -767,13 +970,24 @@ std::vector<RefPreprocessParams> allPreprocessTests() {
resize_lvalues(),
convert_layout_nhwc_to_nchw_lvalue(),
convert_layout_nhwc_to_net_no_tensor_shape(),
convert_layout_by_dims(),
convert_layout_by_dims_multi(),
convert_layout_by_dims_multi_layout(),
resize_and_convert_layout(),
convert_color_nv12_to_bgr_two_planes(),
convert_color_nv12_single_plane(),
convert_color_nv12_layout_resize(),
element_type_before_convert_color_nv12(),
postprocess_2_inputs_basic(),
pre_and_post_processing()
post_convert_layout_by_dims(),
post_convert_layout_by_dims_multi(),
pre_and_post_processing(),
rgb_to_bgr(),
bgr_to_rgb(),
reverse_channels_nchw(),
reverse_channels_dyn_layout(),
reverse_dyn_shape(),
reverse_fully_dyn_shape()
};
}

View File

@ -26,6 +26,10 @@ public:
void SetUp() override {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
}
};
class PreprocessOpenCVReferenceTest_NV12 : public PreprocessOpenCVReferenceTest {
public:
void Validate() override {
threshold = 1.f;
abs_threshold = 1.f;
@ -40,7 +44,7 @@ public:
} // namespace
static std::shared_ptr<Function> create_simple_function_nv12(element::Type type, const PartialShape& shape) {
static std::shared_ptr<Function> create_simple_function(element::Type type, const PartialShape& shape) {
auto data1 = std::make_shared<op::v0::Parameter>(type, shape);
data1->set_friendly_name("input1");
data1->get_output_tensor(0).set_names({"tensor_input1", "input1"});
@ -49,11 +53,11 @@ static std::shared_ptr<Function> create_simple_function_nv12(element::Type type,
op->set_friendly_name("Add0");
auto res = std::make_shared<op::v0::Result>(op);
res->set_friendly_name("Result1");
res->get_output_tensor(0).set_names({"tensor_output1", "Result1", "Convert1"});
res->get_output_tensor(0).set_names({"tensor_output1", "Result1"});
return std::make_shared<ov::Function>(ResultVector{res}, ParameterVector{data1});
}
TEST_F(PreprocessOpenCVReferenceTest, convert_nv12_full_color_range) {
TEST_F(PreprocessOpenCVReferenceTest_NV12, convert_nv12_full_color_range) {
size_t height = 64; // 64/2 = 32 values for R
size_t width = 64; // 64/2 = 32 values for G
int b_step = 5;
@ -64,7 +68,7 @@ TEST_F(PreprocessOpenCVReferenceTest, convert_nv12_full_color_range) {
auto full_height = height * b_dim;
auto func_shape = Shape{1, full_height, width, 3};
function = create_simple_function_nv12(element::u8, func_shape);
function = create_simple_function(element::u8, func_shape);
inputData.clear();
@ -90,10 +94,10 @@ TEST_F(PreprocessOpenCVReferenceTest, convert_nv12_full_color_range) {
Exec();
}
TEST_F(PreprocessOpenCVReferenceTest, convert_nv12_colored) {
TEST_F(PreprocessOpenCVReferenceTest_NV12, convert_nv12_colored) {
auto input_yuv = std::vector<uint8_t> {235, 81, 235, 81, 109, 184};
auto func_shape = Shape{1, 2, 2, 3};
function = create_simple_function_nv12(element::u8, func_shape);
function = create_simple_function(element::u8, func_shape);
inputData.clear();
@ -116,4 +120,136 @@ TEST_F(PreprocessOpenCVReferenceTest, convert_nv12_colored) {
Exec();
}
TEST_F(PreprocessOpenCVReferenceTest, resize_u8_simple_linear) {
auto input_shape = Shape{1, 1, 2, 2};
auto func_shape = Shape{1, 1, 1, 1};
auto input_img = std::vector<uint8_t> {5, 5, 5, 4};
function = create_simple_function(element::u8, func_shape);
inputData.clear();
function = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_spatial_static_shape(2, 2))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_LINEAR))
.network(InputNetworkInfo().set_layout("NCHW"))
)
.build(function);
const auto &param = function->get_parameters()[0];
inputData.emplace_back(param->get_element_type(), param->get_shape(), input_img.data());
// Calculate reference expected values from OpenCV
cv::Mat cvPic = cv::Mat(2, 2, CV_8UC1, input_img.data());
cv::Mat cvPicResized;
cv::resize(cvPic, cvPicResized, cv::Size(1, 1), cv::INTER_NEAREST);
refOutData.emplace_back(param->get_element_type(), func_shape, cvPicResized.data);
// Exec now
Exec();
}
TEST_F(PreprocessOpenCVReferenceTest, resize_u8_large_picture_linear) {
threshold = 1.f;
abs_threshold = 1.f; // Some pixels still have deviations of 1 step
const size_t input_height = 50;
const size_t input_width = 50;
const size_t func_height = 37;
const size_t func_width = 31;
auto input_shape = Shape{1, 1, input_height, input_width};
auto func_shape = Shape{1, 1, func_height, func_width};
auto input_img = std::vector<uint8_t> (shape_size(input_shape));
std::default_random_engine random(0); // hard-coded seed to make test results predictable
std::uniform_int_distribution<int> distrib(0, 255);
for (std::size_t i = 0; i < shape_size(input_shape); i++) {
auto v = distrib(random);
input_img[i] = static_cast<uint8_t>(v);
}
function = create_simple_function(element::u8, func_shape);
inputData.clear();
function = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_spatial_static_shape(input_height, input_width))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_LINEAR))
.network(InputNetworkInfo().set_layout("NCHW"))
)
.build(function);
const auto &param = function->get_parameters()[0];
inputData.emplace_back(param->get_element_type(), param->get_shape(), input_img.data());
// Calculate reference expected values from OpenCV
cv::Mat cvPic = cv::Mat(input_height, input_width, CV_8UC1, input_img.data());
cv::Mat cvPicResized;
cv::resize(cvPic, cvPicResized, cv::Size(func_width, func_height), cv::INTER_LINEAR_EXACT);
refOutData.emplace_back(param->get_element_type(), func_shape, cvPicResized.data);
// Exec now
Exec();
}
TEST_F(PreprocessOpenCVReferenceTest, resize_f32_large_picture_linear) {
threshold = 0.01f;
abs_threshold = 0.01f;
const size_t input_height = 50;
const size_t input_width = 50;
const size_t func_height = 37;
const size_t func_width = 31;
auto input_shape = Shape{1, 1, input_height, input_width};
auto func_shape = Shape{1, 1, func_height, func_width};
auto input_img = std::vector<float> (shape_size(input_shape));
std::default_random_engine random(0); // hard-coded seed to make test results predictable
std::uniform_int_distribution<int> distrib(0, 255);
for (std::size_t i = 0; i < shape_size(input_shape); i++) {
input_img[i] = static_cast<float>(distrib(random));
}
function = create_simple_function(element::f32, func_shape);
inputData.clear();
function = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_spatial_static_shape(input_height, input_width))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_LINEAR))
.network(InputNetworkInfo().set_layout("NCHW"))
)
.build(function);
const auto &param = function->get_parameters()[0];
inputData.emplace_back(param->get_element_type(), param->get_shape(), input_img.data());
// Calculate reference expected values from OpenCV
cv::Mat cvPic = cv::Mat(input_height, input_width, CV_32FC1, input_img.data());
cv::Mat cvPicResized;
cv::resize(cvPic, cvPicResized, cv::Size(func_width, func_height), cv::INTER_LINEAR_EXACT);
refOutData.emplace_back(param->get_element_type(), func_shape, cvPicResized.data);
// Exec now
Exec();
}
TEST_F(PreprocessOpenCVReferenceTest, DISABLED_resize_f32_large_picture_cubic_small) {
const size_t input_height = 4;
const size_t input_width = 4;
const size_t func_height = 3;
const size_t func_width = 3;
auto input_shape = Shape{1, 1, input_height, input_width};
auto func_shape = Shape{1, 1, func_height, func_width};
auto element_type = element::f32;
auto input_img = std::vector<float> {1.f, 2.f, 3.f, 4.f, 4.f, 3.f, 2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 4.f, 3.f, 2.f, 1.f};
function = create_simple_function(element_type, func_shape);
function = PrePostProcessor().input(InputInfo()
.tensor(InputTensorInfo().set_spatial_static_shape(input_height, input_width))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_CUBIC))
.network(InputNetworkInfo().set_layout("NCHW"))
)
.build(function);
inputData.emplace_back(element_type, input_shape, input_img.data());
// Calculate reference expected values from OpenCV
cv::Mat cvPic = cv::Mat(input_height, input_width, CV_32FC1, input_img.data());
cv::Mat cvPicResized;
cv::resize(cvPic, cvPicResized, cv::Size(func_width, func_height), cv::INTER_CUBIC);
refOutData.emplace_back(element_type, func_shape, cvPicResized.data);
// Exec now
Exec();
}
#endif // OPENCV_TEMPLATE_TESTS

View File

@ -26,7 +26,7 @@
#define INFERENCE_ENGINE_C_API_EXTERN
#endif
#if defined(__GNUC__) && (__GNUC__ < 4)
#if defined(OPENVINO_STATIC_LIBRARY) || defined(__GNUC__) && (__GNUC__ < 4)
#define INFERENCE_ENGINE_C_API(...) INFERENCE_ENGINE_C_API_EXTERN __VA_ARGS__
#define IE_NODISCARD
#else

View File

@ -9,7 +9,7 @@ file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
# create library
add_library(${TARGET_NAME} SHARED ${HEADERS} ${SOURCES})
add_library(${TARGET_NAME} ${HEADERS} ${SOURCES})
# Find OpenCV components if exist
find_package(OpenCV COMPONENTS core imgproc imgcodecs QUIET)

View File

@ -9,7 +9,7 @@ file(GLOB HEADERS ${InferenceEngine_C_API_SOURCE_DIR}/include/*.h)
# create library
add_library(${TARGET_NAME} SHARED ${HEADERS} ${SOURCES})
add_library(${TARGET_NAME} ${HEADERS} ${SOURCES})
add_library(openvino::runtime::c ALIAS ${TARGET_NAME})
target_link_libraries(${TARGET_NAME} PRIVATE inference_engine)

View File

@ -88,7 +88,7 @@ install(FILES requirements.txt
DESTINATION ${PYTHON_BRIDGE_CPACK_PATH}/${PYTHON_VERSION}
COMPONENT ${PYTHON_COMPONENT})
install(PROGRAMS src/openvino/__init__.py
install(PROGRAMS ${PYTHON_BRIDGE_OUTPUT_DIRECTORY}/__init__.py
DESTINATION ${PYTHON_BRIDGE_CPACK_PATH}/${PYTHON_VERSION}/openvino
COMPONENT ${PYTHON_COMPONENT})

View File

@ -206,10 +206,9 @@ cdef class Blob:
elif tensor_desc is not None and self._array_data is not None:
c_tensor_desc = tensor_desc.impl
precision = tensor_desc.precision
size_arr = np.prod(array.shape)
size_td = np.prod(tensor_desc.dims)
if size_arr != size_td:
raise AttributeError(f"Number of elements in provided numpy array {size_arr} and "
size_td = C.product(c_tensor_desc.getDims())
if array.size != size_td:
raise AttributeError(f"Number of elements in provided numpy array {array.size} and "
f"required by TensorDesc {size_td} are not equal")
if self._array_data.dtype != format_map[precision]:
raise ValueError(f"Data type {self._array_data.dtype} of provided numpy array "
@ -545,9 +544,7 @@ cdef class IECore:
# If there are more than one device of a specific type, they all are listed followed by a dot and a number.
@property
def available_devices(self):
cdef vector[string] c_devices
with nogil:
c_devices = self.impl.getAvailableDevices()
cdef vector[string] c_devices = self.impl.getAvailableDevices()
return [d.decode() for d in c_devices]
## This structure stores info about pre-processing of network inputs (scale, mean image, ...)
@ -926,14 +923,11 @@ cdef class ExecutableNetwork:
## A tuple of `InferRequest` instances
@property
def requests(self):
cdef size_t c_infer_requests_size
with nogil:
c_infer_requests_size = deref(self.impl).infer_requests.size()
cdef size_t c_infer_requests_size = deref(self.impl).infer_requests.size()
if len(self._infer_requests) == 0:
for i in range(c_infer_requests_size):
infer_request = InferRequest()
with nogil:
infer_request.impl = &(deref(self.impl).infer_requests[i])
infer_request.impl = &(deref(self.impl).infer_requests[i])
infer_request._inputs_list = list(self.input_info.keys())
infer_request._outputs_list = list(self.outputs.keys())
for input_name in infer_request._inputs_list:
@ -1053,10 +1047,7 @@ cdef class ExecutableNetwork:
## Get idle request ID
# @return Request index
cpdef get_idle_request_id(self):
cdef int request_id
with nogil:
request_id = deref(self.impl).getIdleRequestId()
return request_id
return deref(self.impl).getIdleRequestId()
ctypedef extern void (*cb_type)(void*, int) with gil
@ -1198,8 +1189,7 @@ cdef class InferRequest:
cpdef infer(self, inputs=None):
if inputs is not None:
self._fill_inputs(inputs)
with nogil:
deref(self.impl).infer()
deref(self.impl).infer()
## Starts asynchronous inference of the infer request and fill outputs array
#
@ -1216,8 +1206,7 @@ cdef class InferRequest:
cpdef async_infer(self, inputs=None):
if inputs is not None:
self._fill_inputs(inputs)
with nogil:
deref(self.impl).infer_async()
deref(self.impl).infer_async()
## Waits for the result to become available. Blocks until specified timeout elapses or the result
# becomes available, whichever comes first.
@ -1338,8 +1327,7 @@ cdef class IENetwork:
def __cinit__(self, model = None):
# Try to create Inference Engine network from capsule
if model is not None:
with nogil:
self.impl = C.IENetwork(model)
self.impl = C.IENetwork(model)
else:
with nogil:
self.impl = C.IENetwork()
@ -1353,9 +1341,7 @@ cdef class IENetwork:
## A dictionary that maps input layer names to InputInfoPtr objects.
@property
def input_info(self):
cdef map[string, C.InputInfo.Ptr] c_inputs
with nogil:
c_inputs = self.impl.getInputsInfo()
cdef map[string, C.InputInfo.Ptr] c_inputs = self.impl.getInputsInfo()
inputs = {}
cdef InputInfoPtr input_info_ptr
for input in c_inputs:
@ -1368,9 +1354,7 @@ cdef class IENetwork:
## A dictionary that maps output layer names to DataPtr objects
@property
def outputs(self):
cdef map[string, C.DataPtr] c_outputs
with nogil:
c_outputs = self.impl.getOutputs()
cdef map[string, C.DataPtr] c_outputs = self.impl.getOutputs()
outputs = {}
cdef DataPtr data_ptr
for output in c_outputs:

View File

@ -682,3 +682,7 @@ InferenceEngine::Blob::Ptr InferenceEnginePython::CVariableState::getState() {
void InferenceEnginePython::CVariableState::setState(InferenceEngine::Blob::Ptr state) {
variableState.SetState(state);
}
const size_t InferenceEnginePython::product(const InferenceEngine::SizeVector& dims) {
return std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<size_t>{});
}

View File

@ -7,11 +7,13 @@
#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <mutex>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
@ -203,4 +205,6 @@ InferenceEnginePython::IENetwork read_network(std::string path_to_xml, std::stri
PyObject* getPartialShape_capsule(InferenceEngine::CDataPtr data);
const size_t product(const InferenceEngine::SizeVector& dims);
}; // namespace InferenceEnginePython

View File

@ -162,18 +162,18 @@ cdef extern from "ie_api_impl.hpp" namespace "InferenceEnginePython":
object getMetric(const string & metric_name) except +
object getConfig(const string & metric_name) except +
int wait(int num_requests, int64_t timeout) nogil
int getIdleRequestId() nogil
int getIdleRequestId()
shared_ptr[CExecutableNetwork] getPluginLink() except +
cdef cppclass IENetwork:
IENetwork() nogil except +
IENetwork(object) nogil except +
IENetwork(object) except +
string name
size_t batch_size
string precision
map[string, vector[size_t]] inputs
const map[string, InputInfo.Ptr] getInputsInfo() nogil except +
map[string, DataPtr] getOutputs() nogil except +
const map[string, InputInfo.Ptr] getInputsInfo() except +
map[string, DataPtr] getOutputs() except +
void addOutput(string &, size_t) except +
void setAffinity(map[string, string] & types_affinity_map, map[string, string] & layers_affinity_map) except +
void setBatch(size_t size) except +
@ -193,8 +193,8 @@ cdef extern from "ie_api_impl.hpp" namespace "InferenceEnginePython":
void setBlob(const string &blob_name, const CBlob.Ptr &blob_ptr, CPreProcessInfo& info) except +
const CPreProcessInfo& getPreProcess(const string& blob_name) except +
map[string, ProfileInfo] getPerformanceCounts() except +
void infer() nogil except +
void infer_async() nogil except +
void infer() except +
void infer_async() except +
int wait(int64_t timeout) nogil except +
void setBatch(int size) except +
void setCyCallback(void (*)(void*, int), void *) except +
@ -219,7 +219,7 @@ cdef extern from "ie_api_impl.hpp" namespace "InferenceEnginePython":
void unregisterPlugin(const string & deviceName) except +
void registerPlugins(const string & xmlConfigFile) except +
void addExtension(const string & ext_lib_path, const string & deviceName) except +
vector[string] getAvailableDevices() nogil except +
vector[string] getAvailableDevices() except +
object getMetric(const string & deviceName, const string & name) except +
object getConfig(const string & deviceName, const string & name) except +
@ -230,3 +230,5 @@ cdef extern from "ie_api_impl.hpp" namespace "InferenceEnginePython":
cdef IENetwork read_network(string path_to_xml, string path_to_bin)
cdef object getPartialShape_capsule(DataPtr)
cdef const size_t product(const SizeVector& dims)

View File

@ -39,5 +39,9 @@ def GenerateMappingFile(IENetwork network, string path, bool extract_names):
C.GenerateMappingFile(network.impl, path, extract_names)
def Serialize(IENetwork network, string path_to_xml, string path_to_bin):
C.Serialize(network.impl, path_to_xml, path_to_bin)
def CheckAPI():
C.CheckAPI()

View File

@ -14,6 +14,7 @@
#include <pruning.hpp>
#include <transformations/common_optimizations/moc_transformations.hpp>
#include <transformations/control_flow/unroll_tensor_iterator.hpp>
#include <transformations/serialize.hpp>
void InferenceEnginePython::ApplyMOCTransformations(InferenceEnginePython::IENetwork network, bool cf) {
ngraph::pass::Manager manager;
@ -55,6 +56,14 @@ void InferenceEnginePython::GenerateMappingFile(InferenceEnginePython::IENetwork
manager.run_passes(network.actual->getFunction());
}
void InferenceEnginePython::Serialize(InferenceEnginePython::IENetwork network,
std::string path_to_xml,
std::string path_to_bin) {
ngraph::pass::Manager manager;
manager.register_pass<ngraph::pass::Serialize>(path_to_xml, path_to_bin);
manager.run_passes(network.actual->getFunction());
}
void InferenceEnginePython::CheckAPI() {
std::shared_ptr<ngraph::Function> f;
{

View File

@ -25,6 +25,8 @@ void ApplyPruningTransformation(InferenceEnginePython::IENetwork network);
void GenerateMappingFile(InferenceEnginePython::IENetwork network, std::string path, bool extract_names);
void Serialize(InferenceEnginePython::IENetwork network, std::string path_to_xml, std::string path_to_bin);
void CheckAPI();
}; // namespace InferenceEnginePython

View File

@ -20,4 +20,6 @@ cdef extern from "offline_transformations_api_impl.hpp" namespace "InferenceEngi
cdef void GenerateMappingFile(IENetwork network, string path, bool extract_names)
cdef void Serialize(IENetwork network, string path_to_xml, string path_to_bin)
cdef void CheckAPI()

View File

@ -21,11 +21,16 @@ def test_init_with_tensor_desc():
assert blob.tensor_desc == tensor_desc
def test_init_with_numpy():
tensor_desc = TensorDesc("FP32", [1, 3, 127, 127], "NCHW")
array = np.ones(shape=(1, 3, 127, 127), dtype=np.float32)
@pytest.mark.parametrize("shape, layout", [
([1, 3, 127, 127], "NCHW"),
([], "SCALAR"),
])
def test_init_with_numpy(shape, layout):
tensor_desc = TensorDesc("FP32", shape, layout)
array = np.ones(shape=shape, dtype=np.float32)
blob = Blob(tensor_desc, array)
assert isinstance(blob.buffer, np.ndarray)
assert np.shares_memory(blob.buffer, array)
assert blob.tensor_desc == tensor_desc

View File

@ -5,7 +5,7 @@ import os
import pytest
from sys import platform
from pathlib import Path
from threading import Thread
from threading import Event, Thread
from time import sleep, time
from queue import Queue
@ -274,3 +274,52 @@ def test_load_network_release_gil(device):
# Assert there were never any long gil locks
assert message_queue.qsize() == 0, \
f"More than 0 GIL locks occured! Latency: {message_queue.get()})"
def test_nogil_safe(device):
call_thread_func = Event()
core = IECore()
net = core.read_network(model=test_net_xml, weights=test_net_bin)
def thread_target(thread_func, thread_args):
call_thread_func.wait()
call_thread_func.clear()
thread_func(*thread_args)
def main_thread_target(gil_release_func, args):
call_thread_func.set()
gil_release_func(*args)
assert not call_thread_func.is_set()
def test_run_parallel(gil_release_func, args, thread_func, thread_args):
thread = Thread(target=thread_target, args=[thread_func, thread_args])
thread.start()
main_thread_target(gil_release_func, args)
thread.join()
main_targets = [{
core.read_network: [test_net_xml, test_net_bin],
core.load_network: [net, device],
},
{
core.load_network: [net, device],
}]
thread_targets = [{
core.get_versions: [device,],
core.read_network: [test_net_xml, test_net_bin],
core.load_network: [net, device],
core.query_network: [net, device],
getattr: [core, "available_devices"],
},
{
getattr: [net, "name"],
getattr: [net, "input_info"],
getattr: [net, "outputs"],
getattr: [net, "batch_size"],
}]
for main_target, custom_target in zip(main_targets, thread_targets):
for nogil_func, args in main_target.items():
for thread_func, thread_args in custom_target.items():
test_run_parallel(nogil_func, args, thread_func, thread_args)

View File

@ -3,7 +3,7 @@
//
/**
* @brief The entry point the Inference Engine sample application
* @brief The entry point the OpenVINO Runtime sample application
* @file classification_sample_async/main.cpp
* @example classification_sample_async/main.cpp
*/
@ -25,8 +25,9 @@
#include <vector>
#include "classification_sample_async.h"
#include "openvino/openvino.hpp"
using namespace InferenceEngine;
using namespace ov::preprocess;
/**
* @brief Checks input args
@ -62,170 +63,136 @@ bool ParseAndCheckCommandLine(int argc, char* argv[]) {
int main(int argc, char* argv[]) {
try {
// ------------------------------ Get Inference Engine version
// ------------------------------------------------------
slog::info << "InferenceEngine: " << GetInferenceEngineVersion() << slog::endl;
// -------- Get OpenVINO Runtime version --------
slog::info << "OpenVINO runtime: " << ov::get_openvino_version() << slog::endl;
// ------------------------------ Parsing and validation of input arguments
// ---------------------------------
// -------- Parsing and validation of input arguments --------
if (!ParseAndCheckCommandLine(argc, argv)) {
return 0;
return EXIT_SUCCESS;
}
// ------------------------------ Read input
// -----------------------------------------------------------
/** This vector stores paths to the processed images **/
std::vector<std::string> imageNames;
parseInputFilesArguments(imageNames);
if (imageNames.empty())
throw std::logic_error("No suitable images were found");
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 1. Initialize inference engine core
// -------------------------------------
slog::info << "Loading Inference Engine" << slog::endl;
Core ie;
// ------------------------------ Get Available Devices
// ------------------------------------------------------
slog::info << "Device info: " << slog::endl;
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
// -------- Read input --------
// This vector stores paths to the processed images
std::vector<std::string> image_names;
parseInputFilesArguments(image_names);
if (image_names.empty())
throw std::logic_error("No suitable images were found");
// -------- Step 1. Initialize OpenVINO Runtime Core --------
ov::runtime::Core core;
if (!FLAGS_l.empty()) {
// Custom CPU extension is loaded as a shared library and passed as a
// pointer to base extension
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
ie.AddExtension(extension_ptr);
slog::info << "CPU Extension loaded: " << FLAGS_l << slog::endl;
auto extension_ptr = std::make_shared<InferenceEngine::Extension>(FLAGS_l);
core.add_extension(extension_ptr);
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
}
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
// Config for device plugin custom extension is loaded from an .xml
// description
ie.SetConfig({{PluginConfigParams::KEY_CONFIG_FILE, FLAGS_c}}, FLAGS_d);
core.set_config({{InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, FLAGS_c}}, FLAGS_d);
slog::info << "Config for " << FLAGS_d << " device plugin custom extension loaded: " << FLAGS_c
<< slog::endl;
}
// -----------------------------------------------------------------------------------------------------
// Step 2. Read a model in OpenVINO Intermediate Representation (.xml and
// .bin files) or ONNX (.onnx file) format
slog::info << "Loading network files:" << slog::endl << FLAGS_m << slog::endl;
// -------- Step 2. Read a model --------
slog::info << "Loading model files:" << slog::endl << FLAGS_m << slog::endl;
std::shared_ptr<ov::Function> model = core.read_model(FLAGS_m);
/** Read network model **/
CNNNetwork network = ie.ReadNetwork(FLAGS_m);
// -----------------------------------------------------------------------------------------------------
OPENVINO_ASSERT(model->get_parameters().size() == 1, "Sample supports models with 1 input only");
OPENVINO_ASSERT(model->get_results().size() == 1, "Sample supports models with 1 output only");
// --------------------------- Step 3. Configure input & output
// ---------------------------------------------
if (network.getOutputsInfo().size() != 1)
throw std::logic_error("Sample supports topologies with 1 output only");
// -------- Step 3. Apply preprocessing --------
const ov::Layout tensor_layout{"NHWC"};
// --------------------------- Prepare input blobs
// -----------------------------------------------------
slog::info << "Preparing input blobs" << slog::endl;
// clang-format off
model = PrePostProcessor().
// 1) InputInfo() with no args assumes a model has a single input
input(InputInfo().
// 2) Set input tensor information:
// - precision of tensor is supposed to be 'u8'
// - layout of data is 'NHWC'
tensor(InputTensorInfo().
set_element_type(ov::element::u8).
set_layout(tensor_layout)).
// 3) Here we suppose model has 'NCHW' layout for input
network(InputNetworkInfo().
set_layout("NCHW"))).
output(OutputInfo().
// 4) Set output tensor information:
// - precision of tensor is supposed to be 'f32'
tensor(OutputTensorInfo().
set_element_type(ov::element::f32))).
// 5) Once the build() method is called, the preprocessing steps
// for layout and precision conversions are inserted automatically
build(model);
// clang-format on
/** Taking information about all topology inputs **/
InputsDataMap inputInfo(network.getInputsInfo());
if (inputInfo.size() != 1)
throw std::logic_error("Sample supports topologies with 1 input only");
// -------- Step 4. read input images --------
slog::info << "Read input images" << slog::endl;
auto inputInfoItem = *inputInfo.begin();
ov::Shape input_shape = model->input().get_shape();
const size_t width = input_shape[ov::layout::width(tensor_layout)];
const size_t height = input_shape[ov::layout::height(tensor_layout)];
/** Specifying the precision and layout of input data provided by the user.
* This should be called before load of the network to the device **/
inputInfoItem.second->setPrecision(Precision::U8);
inputInfoItem.second->setLayout(Layout::NCHW);
std::vector<std::shared_ptr<unsigned char>> imagesData = {};
std::vector<std::string> validImageNames = {};
for (const auto& i : imageNames) {
std::vector<std::shared_ptr<unsigned char>> images_data;
std::vector<std::string> valid_image_names;
for (const auto& i : image_names) {
FormatReader::ReaderPtr reader(i.c_str());
if (reader.get() == nullptr) {
slog::warn << "Image " + i + " cannot be read!" << slog::endl;
continue;
}
/** Store image data **/
std::shared_ptr<unsigned char> data(reader->getData(inputInfoItem.second->getTensorDesc().getDims()[3],
inputInfoItem.second->getTensorDesc().getDims()[2]));
// Store image data
std::shared_ptr<unsigned char> data(reader->getData(width, height));
if (data != nullptr) {
imagesData.push_back(data);
validImageNames.push_back(i);
images_data.push_back(data);
valid_image_names.push_back(i);
}
}
if (imagesData.empty() || validImageNames.empty())
if (images_data.empty() || valid_image_names.empty())
throw std::logic_error("Valid input images were not found!");
/** Setting batch size using image count **/
network.setBatchSize(imagesData.size());
size_t batchSize = network.getBatchSize();
// -------- Step 5. Loading model to the device --------
// Setting batch size using image count
const size_t batchSize = images_data.size();
input_shape[ov::layout::batch(tensor_layout)] = batchSize;
model->reshape({{model->input().get_any_name(), input_shape}});
slog::info << "Batch size is " << std::to_string(batchSize) << slog::endl;
// -----------------------------------------------------------------------------------------------------
// -------- Step 6. Loading model to the device --------
slog::info << "Loading model to the device " << FLAGS_d << slog::endl;
ov::runtime::ExecutableNetwork executable_network = core.compile_model(model, FLAGS_d);
// --------------------------- Step 4. Loading model to the device
// ------------------------------------------
slog::info << "Loading model to the device" << slog::endl;
ExecutableNetwork executable_network = ie.LoadNetwork(network, FLAGS_d);
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 5. Create infer request
// -------------------------------------------------
// -------- Step 6. Create infer request --------
slog::info << "Create infer request" << slog::endl;
InferRequest inferRequest = executable_network.CreateInferRequest();
// -----------------------------------------------------------------------------------------------------
ov::runtime::InferRequest infer_request = executable_network.create_infer_request();
// --------------------------- Step 6. Prepare input
// --------------------------------------------------------
for (auto& item : inputInfo) {
Blob::Ptr inputBlob = inferRequest.GetBlob(item.first);
SizeVector dims = inputBlob->getTensorDesc().getDims();
/** Fill input tensor with images. First b channel, then g and r channels
* **/
size_t num_channels = dims[1];
size_t image_size = dims[3] * dims[2];
// -------- Step 7. Combine multiple input images as batch --------
ov::runtime::Tensor input_tensor = infer_request.get_input_tensor();
MemoryBlob::Ptr minput = as<MemoryBlob>(inputBlob);
if (!minput) {
slog::err << "We expect MemoryBlob from inferRequest, but by fact we "
"were not able to cast inputBlob to MemoryBlob"
<< slog::endl;
return 1;
}
// locked memory holder should be alive all time while access to its
// buffer happens
auto minputHolder = minput->wmap();
auto data = minputHolder.as<PrecisionTrait<Precision::U8>::value_type*>();
if (data == nullptr)
throw std::runtime_error("Input blob has not allocated buffer");
/** Iterate over all input images **/
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
/** Iterate over all pixel in image (b,g,r) **/
for (size_t pid = 0; pid < image_size; pid++) {
/** Iterate over all channels **/
for (size_t ch = 0; ch < num_channels; ++ch) {
/** [images stride + channels stride + pixel id ] all in
* bytes **/
data[image_id * image_size * num_channels + ch * image_size + pid] =
imagesData.at(image_id).get()[pid * num_channels + ch];
}
}
}
for (size_t image_id = 0; image_id < images_data.size(); ++image_id) {
const size_t image_size = shape_size(input_shape) / batchSize;
std::memcpy(input_tensor.data<std::uint8_t>() + image_id * image_size,
images_data[image_id].get(),
image_size);
}
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 7. Do inference
// ---------------------------------------------------------
size_t numIterations = 10;
size_t curIteration = 0;
// -------- Step 8. Do asynchronous inference --------
size_t num_iterations = 10;
size_t cur_iteration = 0;
std::condition_variable condVar;
std::mutex mutex;
inferRequest.SetCompletionCallback([&] {
curIteration++;
slog::info << "Completed " << curIteration << " async request execution" << slog::endl;
if (curIteration < numIterations) {
infer_request.set_callback([&](std::exception_ptr ex) {
if (ex)
throw ex;
std::lock_guard<std::mutex> l(mutex);
cur_iteration++;
slog::info << "Completed " << cur_iteration << " async request execution" << slog::endl;
if (cur_iteration < num_iterations) {
/* here a user can read output containing inference results and put new
input to repeat async request again */
inferRequest.StartAsync();
infer_request.start_async();
} else {
/* continue sample execution after last Asynchronous inference request
* execution */
@ -234,30 +201,22 @@ int main(int argc, char* argv[]) {
});
/* Start async request for the first time */
slog::info << "Start inference (" << numIterations << " asynchronous executions)" << slog::endl;
inferRequest.StartAsync();
slog::info << "Start inference (" << num_iterations << " asynchronous executions)" << slog::endl;
infer_request.start_async();
/* Wait all repetitions of the async request */
std::mutex mutex;
/* Wait all iterations of the async request */
std::unique_lock<std::mutex> lock(mutex);
condVar.wait(lock, [&] {
return curIteration == numIterations;
return cur_iteration == num_iterations;
});
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 8. Process output
// -------------------------------------------------------
slog::info << "Processing output blobs" << slog::endl;
OutputsDataMap outputInfo(network.getOutputsInfo());
if (outputInfo.empty())
throw std::runtime_error("Can't get output blobs");
Blob::Ptr outputBlob = inferRequest.GetBlob(outputInfo.begin()->first);
// -------- Step 9. Process output --------
ov::runtime::Tensor output = infer_request.get_output_tensor();
/** Validating -nt value **/
const size_t resultsCnt = outputBlob->size() / batchSize;
const size_t resultsCnt = output.get_size() / batchSize;
if (FLAGS_nt > resultsCnt || FLAGS_nt < 1) {
slog::warn << "-nt " << FLAGS_nt << " is not available for this network (-nt should be less than "
slog::warn << "-nt " << FLAGS_nt << " is not available for this model (-nt should be less than "
<< resultsCnt + 1 << " and more than 0)\n Maximal value " << resultsCnt
<< " will be used." << slog::endl;
FLAGS_nt = resultsCnt;
@ -276,16 +235,16 @@ int main(int argc, char* argv[]) {
labels.push_back(strLine);
}
}
// Prints formatted classification results
ClassificationResult classificationResult(outputBlob, validImageNames, batchSize, FLAGS_nt, labels);
classificationResult.print();
// -----------------------------------------------------------------------------------------------------
ClassificationResult classificationResult(output, valid_image_names, batchSize, FLAGS_nt, labels);
classificationResult.show();
} catch (const std::exception& error) {
slog::err << error.what() << slog::endl;
return 1;
return EXIT_FAILURE;
} catch (...) {
slog::err << "Unknown/internal exception happened." << slog::endl;
return 1;
return EXIT_FAILURE;
}
slog::info << "Execution successful" << slog::endl;
@ -293,5 +252,5 @@ int main(int argc, char* argv[]) {
<< "This sample is an API example, for any performance measurements "
"please use the dedicated benchmark_app tool"
<< slog::endl;
return 0;
return EXIT_SUCCESS;
}

View File

@ -9,13 +9,15 @@
#pragma once
#include <algorithm>
#include <inference_engine.hpp>
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "inference_engine.hpp"
#include "openvino/openvino.hpp"
/**
* @class ClassificationResult
* @brief A ClassificationResult creates an output table with results
@ -27,6 +29,7 @@ private:
const std::string _probabilityStr = "probability";
const std::string _labelStr = "label";
size_t _nTop;
ov::runtime::Tensor _outTensor;
InferenceEngine::Blob::Ptr _outBlob;
const std::vector<std::string> _labels;
const std::vector<strType> _imageNames;
@ -47,12 +50,41 @@ private:
}
/**
* @brief Gets the top n results from a tblob
* @brief Gets the top n results from a tensor
*
* @param n Top n count
* @param input 1D tblob that contains probabilities
* @param input 1D tensor that contains probabilities
* @param output Vector of indexes for the top n places
*/
template <class T>
void topResults(unsigned int n, const ov::runtime::Tensor& input, std::vector<unsigned>& output) {
ov::Shape shape = input.get_shape();
size_t input_rank = shape.size();
OPENVINO_ASSERT(input_rank != 0 && shape[0] != 0, "Input tensor has incorrect dimensions!");
size_t batchSize = shape[0];
std::vector<unsigned> indexes(input.get_size() / batchSize);
n = static_cast<unsigned>(std::min<size_t>((size_t)n, input.get_size()));
output.resize(n * batchSize);
for (size_t i = 0; i < batchSize; i++) {
const size_t offset = i * (input.get_size() / batchSize);
const T* batchData = input.data<const T>();
batchData += offset;
std::iota(std::begin(indexes), std::end(indexes), 0);
std::partial_sort(std::begin(indexes),
std::begin(indexes) + n,
std::end(indexes),
[&batchData](unsigned l, unsigned r) {
return batchData[l] > batchData[r];
});
for (unsigned j = 0; j < n; j++) {
output.at(i * n + j) = indexes.at(j);
}
}
}
template <class T>
void topResults(unsigned int n, InferenceEngine::Blob::Ptr& input, std::vector<unsigned>& output) {
InferenceEngine::SizeVector dims = input->getTensorDesc().getDims();
@ -97,6 +129,33 @@ private:
* @param input 1D blob that contains probabilities
* @param output Vector of indexes for the top n places
*/
void topResults(unsigned int n, const ov::runtime::Tensor& input, std::vector<unsigned>& output) {
#define TENSOR_TOP_RESULT(elem_type) \
case ov::element::Type_t::elem_type: { \
using tensor_type = ov::fundamental_type_for<ov::element::Type_t::elem_type>; \
topResults<tensor_type>(n, input, output); \
break; \
}
switch (input.get_element_type()) {
TENSOR_TOP_RESULT(f32);
TENSOR_TOP_RESULT(f64);
TENSOR_TOP_RESULT(f16);
TENSOR_TOP_RESULT(i16);
TENSOR_TOP_RESULT(u8);
TENSOR_TOP_RESULT(i8);
TENSOR_TOP_RESULT(u16);
TENSOR_TOP_RESULT(i32);
TENSOR_TOP_RESULT(u32);
TENSOR_TOP_RESULT(i64);
TENSOR_TOP_RESULT(u64);
default:
OPENVINO_ASSERT(false, "cannot locate tensor with element type: ", input.get_element_type());
}
#undef TENSOR_TOP_RESULT
}
void topResults(unsigned int n, InferenceEngine::Blob::Ptr& input, std::vector<unsigned>& output) {
#define TBLOB_TOP_RESULT(precision) \
case InferenceEngine::Precision::precision: { \
@ -143,9 +202,54 @@ public:
topResults(_nTop, _outBlob, _results);
}
explicit ClassificationResultT(const ov::runtime::Tensor& output_tensor,
const std::vector<strType>& image_names = {},
size_t batch_size = 1,
size_t num_of_top = 10,
const std::vector<std::string>& labels = {})
: _nTop(num_of_top),
_outTensor(output_tensor),
_labels(labels),
_imageNames(image_names),
_batchSize(batch_size),
_results() {
OPENVINO_ASSERT(_imageNames.size() == _batchSize, "Batch size should be equal to the number of images.");
topResults(_nTop, _outTensor, _results);
}
/**
* @brief prints formatted classification results
*/
void show() {
/** Print the result iterating over each batch **/
std::cout << std::endl << "Top " << _nTop << " results:" << std::endl << std::endl;
for (unsigned int image_id = 0; image_id < _batchSize; ++image_id) {
std::wstring out(_imageNames[image_id].begin(), _imageNames[image_id].end());
std::wcout << L"Image " << out;
std::wcout.flush();
std::wcout.clear();
std::wcout << std::endl << std::endl;
printHeader();
for (size_t id = image_id * _nTop, cnt = 0; id < (image_id + 1) * _nTop; ++cnt, ++id) {
std::cout.precision(7);
/** Getting probability for resulting class **/
const auto index = _results.at(id) + image_id * (_outTensor.get_size() / _batchSize);
const auto result = _outTensor.data<const float>()[index];
std::cout << std::setw(static_cast<int>(_classidStr.length())) << std::left << _results.at(id) << " ";
std::cout << std::left << std::setw(static_cast<int>(_probabilityStr.length())) << std::fixed << result;
if (!_labels.empty()) {
std::cout << " " + _labels[_results.at(id)];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
}
void print() {
/** Print the result iterating over each batch **/
std::cout << std::endl << "Top " << _nTop << " results:" << std::endl << std::endl;

View File

@ -23,6 +23,8 @@
#include <utility>
#include <vector>
#include "openvino/openvino.hpp"
#ifndef UNUSED
# if defined(_MSC_VER) && !defined(__clang__)
# define UNUSED
@ -98,6 +100,16 @@ inline std::ostream& operator<<(std::ostream& os, const InferenceEngine::Version
return os;
}
inline std::ostream& operator<<(std::ostream& os, const ov::Version& version) {
os << "\t" << version.description << " version ......... ";
os << OPENVINO_VERSION_MAJOR << "." << OPENVINO_VERSION_MINOR << "." << OPENVINO_VERSION_PATCH;
os << "\n\tBuild ........... ";
os << version.buildNumber;
return os;
}
inline std::ostream& operator<<(std::ostream& os, const InferenceEngine::Version* version) {
if (nullptr != version) {
os << std::endl << *version;
@ -114,6 +126,15 @@ inline std::ostream& operator<<(std::ostream& os, const std::map<std::string, In
return os;
}
inline std::ostream& operator<<(std::ostream& os, const std::map<std::string, ov::Version>& versions) {
for (auto&& version : versions) {
os << "\t" << version.first << std::endl;
os << version.second << std::endl;
}
return os;
}
/**
* @class Color
* @brief A Color class stores channels of a given color

View File

@ -12,6 +12,8 @@
#include <opencv2/opencv.hpp>
#include <samples/common.hpp>
#include "openvino/openvino.hpp"
/**
* @brief Sets image data stored in cv::Mat object to a given Blob object.
* @param orig_image - given cv::Mat object with an image data.
@ -76,3 +78,17 @@ static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob(const cv::Mat& mat) {
return InferenceEngine::make_shared_blob<uint8_t>(tDesc, mat.data);
}
static UNUSED ov::runtime::Tensor wrapMat2Tensor(const cv::Mat& mat) {
const size_t channels = mat.channels();
const size_t height = mat.size().height;
const size_t width = mat.size().width;
const size_t strideH = mat.step.buf[0];
const size_t strideW = mat.step.buf[1];
const bool is_dense = strideW == channels && strideH == channels * width;
OPENVINO_ASSERT(is_dense, "Doesn't support conversion from not dense cv::Mat");
return ov::runtime::Tensor(ov::element::u8, ov::Shape{1, height, width, channels}, mat.data);
}

View File

@ -2,17 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <samples/classification_results.h>
#include <inference_engine.hpp>
#include <iterator>
#include <memory>
#include <samples/common.hpp>
#include <samples/ocv_common.hpp>
#include <samples/slog.hpp>
#include <string>
#include <vector>
using namespace InferenceEngine;
#include "openvino/core/layout.hpp"
#include "openvino/openvino.hpp"
#include "samples/classification_results.h"
#include "samples/common.hpp"
#include "samples/ocv_common.hpp"
using namespace ov::preprocess;
/**
* @brief Define names based depends on Unicode path support
@ -78,8 +80,10 @@ int wmain(int argc, wchar_t* argv[]) {
int main(int argc, char* argv[]) {
#endif
try {
// ------------------------------ Parsing and validation of input arguments
// ---------------------------------
// -------- Get OpenVINO Runtime version --------
slog::info << "OpenVINO runtime: " << ov::get_openvino_version() << slog::endl;
// -------- Parsing and validation of input arguments --------
if (argc != 4) {
tcout << "Usage : " << argv[0] << " <path_to_model> <path_to_image> <device_name>" << std::endl;
return EXIT_FAILURE;
@ -92,81 +96,80 @@ int main(int argc, char* argv[]) {
#else
const std::string device_name{argv[3]};
#endif
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 1. Initialize inference engine core
// -------------------------------------
Core ie;
// -----------------------------------------------------------------------------------------------------
// -------- Step 1. Initialize OpenVINO Runtime Core --------
ov::runtime::Core core;
// Step 2. Read a model in OpenVINO Intermediate Representation (.xml and
// .bin files) or ONNX (.onnx file) format
CNNNetwork network = ie.ReadNetwork(input_model);
if (network.getOutputsInfo().size() != 1)
throw std::logic_error("Sample supports topologies with 1 output only");
if (network.getInputsInfo().size() != 1)
throw std::logic_error("Sample supports topologies with 1 input only");
// -----------------------------------------------------------------------------------------------------
// -------- Step 2. Read a model --------
auto model = core.read_model(input_model);
// --------------------------- Step 3. Configure input & output
// ---------------------------------------------
// --------------------------- Prepare input blobs
// -----------------------------------------------------
InputInfo::Ptr input_info = network.getInputsInfo().begin()->second;
std::string input_name = network.getInputsInfo().begin()->first;
OPENVINO_ASSERT(model->get_parameters().size() == 1, "Sample supports models with 1 input only");
OPENVINO_ASSERT(model->get_results().size() == 1, "Sample supports models with 1 output only");
/* Mark input as resizable by setting of a resize algorithm.
* In this case we will be able to set an input blob of any shape to an
* infer request. Resize and layout conversions are executed automatically
* during inference */
input_info->getPreProcess().setResizeAlgorithm(RESIZE_BILINEAR);
input_info->setLayout(Layout::NHWC);
input_info->setPrecision(Precision::U8);
// -------- Step 3. Initialize inference engine core
// --------------------------- Prepare output blobs
// ----------------------------------------------------
if (network.getOutputsInfo().empty()) {
std::cerr << "Network outputs info is empty" << std::endl;
return EXIT_FAILURE;
}
DataPtr output_info = network.getOutputsInfo().begin()->second;
std::string output_name = network.getOutputsInfo().begin()->first;
output_info->setPrecision(Precision::FP32);
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 4. Loading a model to the device
// ------------------------------------------
ExecutableNetwork executable_network = ie.LoadNetwork(network, device_name);
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 5. Create an infer request
// -------------------------------------------------
InferRequest infer_request = executable_network.CreateInferRequest();
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 6. Prepare input
// --------------------------------------------------------
/* Read input image to a blob and set it to an infer request without resize
* and layout conversions. */
// Read input image to a tensor and set it to an infer request
// without resize and layout conversions
cv::Mat image = imread_t(input_image_path);
Blob::Ptr imgBlob = wrapMat2Blob(image); // just wrap Mat data by Blob::Ptr
// without allocating of new memory
infer_request.SetBlob(input_name, imgBlob); // infer_request accepts input blob of any size
// just wrap Mat data by ov::runtime::Tensor without allocating of new memory
ov::runtime::Tensor input_tensor = wrapMat2Tensor(image);
const ov::Shape tensor_shape = input_tensor.get_shape();
// -------- Step 4. Apply preprocessing --------
const ov::Layout tensor_layout{"NHWC"};
// clang-format off
model = PrePostProcessor().
// 1) InputInfo() with no args assumes a model has a single input
input(InputInfo().
// 2) Set input tensor information:
// - precision of tensor is supposed to be 'u8'
// - layout of data is 'NHWC'
// - set static spatial dimensions to input tensor to resize from
tensor(InputTensorInfo().
set_element_type(ov::element::u8).
set_spatial_static_shape(
tensor_shape[ov::layout::height(tensor_layout)],
tensor_shape[ov::layout::width(tensor_layout)]).
set_layout(tensor_layout)).
// 3) Adding explicit preprocessing steps:
// - convert layout to 'NCHW' (from 'NHWC' specified above at tensor layout)
// - apply linear resize from tensor spatial dims to model spatial dims
preprocess(PreProcessSteps().
convert_element_type(ov::element::f32). // WA for CPU plugin
convert_layout("NCHW"). // WA for CPU plugin
resize(ResizeAlgorithm::RESIZE_LINEAR)).
// 4) Here we suppose model has 'NCHW' layout for input
network(InputNetworkInfo().
set_layout("NCHW"))).
output(OutputInfo().
// 5) Set output tensor information:
// - precision of tensor is supposed to be 'f32'
tensor(OutputTensorInfo().
set_element_type(ov::element::f32))).
// 6) Apply preprocessing modifing the original 'model'
build(model);
// clang-format on
// -------- Step 5. Loading a model to the device --------
ov::runtime::ExecutableNetwork executable_network = core.compile_model(model, device_name);
// -------- Step 6. Create an infer request --------
ov::runtime::InferRequest infer_request = executable_network.create_infer_request();
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 7. Do inference
// --------------------------------------------------------
/* Running the request synchronously */
infer_request.Infer();
// -----------------------------------------------------------------------------------------------------
// -------- Step 7. Prepare input --------
infer_request.set_input_tensor(input_tensor);
// -------- Step 8. Do inference synchronously --------
infer_request.infer();
// -------- Step 9. Process output
ov::runtime::Tensor output_tensor = infer_request.get_output_tensor();
// --------------------------- Step 8. Process output
// ------------------------------------------------------
Blob::Ptr output = infer_request.GetBlob(output_name);
// Print classification results
ClassificationResult_t classificationResult(output, {input_image_path});
classificationResult.print();
ClassificationResult_t classification_result(output_tensor, {input_image_path});
classification_result.show();
// -----------------------------------------------------------------------------------------------------
} catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;

View File

@ -3,8 +3,6 @@
//
#include <cstdlib>
#include <ie_plugin_config.hpp>
#include <inference_engine.hpp>
#include <iomanip>
#include <memory>
#include <samples/common.hpp>
@ -13,7 +11,8 @@
#include <tuple>
#include <vector>
using namespace InferenceEngine;
#include "ie_plugin_config.hpp"
#include "openvino/openvino.hpp"
namespace {
/**
@ -33,7 +32,7 @@ std::ostream& operator<<(std::ostream& stream, const std::vector<T>& v) {
* @param reference on IE Parameter
* @return void
*/
void printParameterValue(const Parameter& value) {
void printParameterValue(const ov::runtime::Parameter& value) {
if (value.empty()) {
std::cout << "EMPTY VALUE" << std::endl;
} else if (value.is<bool>()) {
@ -65,8 +64,8 @@ void printParameterValue(const Parameter& value) {
std::cout << std::get<2>(values);
std::cout << " }";
std::cout << std::endl;
} else if (value.is<Metrics::DeviceType>()) {
auto v = value.as<Metrics::DeviceType>();
} else if (value.is<InferenceEngine::Metrics::DeviceType>()) {
auto v = value.as<InferenceEngine::Metrics::DeviceType>();
std::cout << v << std::endl;
} else if (value.is<std::map<InferenceEngine::Precision, float>>()) {
auto values = value.as<std::map<InferenceEngine::Precision, float>>();
@ -92,46 +91,45 @@ void printParameterValue(const Parameter& value) {
int main(int argc, char* argv[]) {
try {
// ------------------------------ Parsing and validation of input arguments
// ---------------------------------
// -------- Parsing and validation of input arguments --------
if (argc != 1) {
std::cout << "Usage : " << argv[0] << std::endl;
return EXIT_FAILURE;
}
// --------------------------- Step 1. Initialize inference engine core
// -------------------------------------
std::cout << "Loading Inference Engine" << std::endl;
Core ie;
// -------- Step 1. Initialize OpenVINO Runtime Core --------
std::cout << "Loading OpenVINO Runtime" << std::endl;
ov::runtime::Core core;
// --------------------------- Get list of available devices
// -------------------------------------
// -------- Step 2. Get list of available devices --------
std::vector<std::string> availableDevices = ie.GetAvailableDevices();
std::vector<std::string> availableDevices = core.get_available_devices();
// --------------------------- Query and print supported metrics and config
// keys--------------------
// -------- Step 3. Query and print supported metrics and config keys --------
std::cout << "Available devices: " << std::endl;
for (auto&& device : availableDevices) {
std::cout << device << std::endl;
// Query supported metrics and print all of them
std::cout << "\tSUPPORTED_METRICS: " << std::endl;
std::vector<std::string> supportedMetrics = ie.GetMetric(device, METRIC_KEY(SUPPORTED_METRICS));
std::vector<std::string> supportedMetrics = core.get_metric(device, METRIC_KEY(SUPPORTED_METRICS));
for (auto&& metricName : supportedMetrics) {
if (metricName != METRIC_KEY(SUPPORTED_METRICS) && metricName != METRIC_KEY(SUPPORTED_CONFIG_KEYS)) {
std::cout << "\t\t" << metricName << " : " << std::flush;
printParameterValue(ie.GetMetric(device, metricName));
printParameterValue(core.get_metric(device, metricName));
}
}
// Query supported config keys and print all of them
if (std::find(supportedMetrics.begin(), supportedMetrics.end(), METRIC_KEY(SUPPORTED_CONFIG_KEYS)) !=
supportedMetrics.end()) {
std::cout << "\tSUPPORTED_CONFIG_KEYS (default values): " << std::endl;
std::vector<std::string> supportedConfigKeys = ie.GetMetric(device, METRIC_KEY(SUPPORTED_CONFIG_KEYS));
std::vector<std::string> supportedConfigKeys =
core.get_metric(device, METRIC_KEY(SUPPORTED_CONFIG_KEYS));
for (auto&& configKey : supportedConfigKeys) {
std::cout << "\t\t" << configKey << " : " << std::flush;
printParameterValue(ie.GetConfig(device, configKey));
printParameterValue(core.get_config(device, configKey));
}
}
@ -141,5 +139,6 @@ int main(int argc, char* argv[]) {
std::cerr << std::endl << "Exception occurred: " << ex.what() << std::endl << std::flush;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -82,7 +82,7 @@ int main(int argc, char* argv[]) {
// that simplifies output filtering, try to find it.
if (auto ngraphFunction = network.getFunction()) {
for (const auto& op : ngraphFunction->get_ops()) {
if (op->get_type_info() == ngraph::op::DetectionOutput::type_info) {
if (op->get_type_info() == ngraph::op::DetectionOutput::get_type_info_static()) {
if (output_info->getName() != op->get_friendly_name()) {
throw std::logic_error("Detection output op does not produce a network output");
}

View File

@ -84,10 +84,7 @@ private:
class CustomReluOp : public ngraph::op::Op {
public:
static constexpr ngraph::NodeTypeInfo type_info{CUSTOM_RELU_TYPE, 0};
const ngraph::NodeTypeInfo& get_type_info() const override {
return type_info;
}
OPENVINO_OP("CustomReluOp", "experimental");
CustomReluOp() = default;
explicit CustomReluOp(const ngraph::Output<ngraph::Node>& arg) : Op({arg}) {
@ -118,8 +115,6 @@ public:
}
};
constexpr ngraph::NodeTypeInfo CustomReluOp::type_info;
class InPlaceExtension : public InferenceEngine::IExtension {
public:
InPlaceExtension() {

View File

@ -2,24 +2,26 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <format_reader_ptr.h>
#include <gflags/gflags.h>
#include <samples/classification_results.h>
#include <inference_engine.hpp>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <memory>
#include <samples/args_helper.hpp>
#include <samples/common.hpp>
#include <samples/slog.hpp>
#include <string>
#include <vector>
#include "ngraph/ngraph.hpp"
#include "format_reader_ptr.h"
#include "gflags/gflags.h"
#include "ngraph/util.hpp"
#include "ngraph_function_creation_sample.hpp"
#include "openvino/openvino.hpp"
#include "openvino/opsets/opset8.hpp"
#include "samples/args_helper.hpp"
#include "samples/classification_results.h"
#include "samples/common.hpp"
#include "samples/slog.hpp"
using namespace InferenceEngine;
using namespace ngraph;
using namespace ov;
/**
* @brief Checks input args
@ -64,19 +66,19 @@ bool ParseAndCheckCommandLine(int argc, char* argv[]) {
* @return none
*/
void readFile(const std::string& file_name, void* buffer, size_t maxSize) {
std::ifstream inputFile;
std::ifstream input_file;
inputFile.open(file_name, std::ios::binary | std::ios::in);
if (!inputFile.is_open()) {
input_file.open(file_name, std::ios::binary | std::ios::in);
if (!input_file.is_open()) {
throw std::logic_error("Cannot open weights file");
}
if (!inputFile.read(reinterpret_cast<char*>(buffer), maxSize)) {
inputFile.close();
if (!input_file.read(reinterpret_cast<char*>(buffer), maxSize)) {
input_file.close();
throw std::logic_error("Cannot read bytes from weights file");
}
inputFile.close();
input_file.close();
}
/**
@ -84,252 +86,222 @@ void readFile(const std::string& file_name, void* buffer, size_t maxSize) {
* @param filepath string
* @return weightsPtr tensor blob
*/
TBlob<uint8_t>::CPtr ReadWeights(std::string filepath) {
ov::runtime::Tensor ReadWeights(const std::string& filepath) {
std::ifstream weightFile(filepath, std::ifstream::ate | std::ifstream::binary);
int64_t fileSize = weightFile.tellg();
OPENVINO_ASSERT(fileSize == 1724336,
"Incorrect weights file. This sample works only with LeNet "
"classification model.");
if (fileSize < 0) {
throw std::logic_error("Incorrect weights file");
}
ov::runtime::Tensor weights(ov::element::u8, {static_cast<size_t>(fileSize)});
readFile(filepath, weights.data(), weights.get_byte_size());
size_t ulFileSize = static_cast<size_t>(fileSize);
TBlob<uint8_t>::Ptr weightsPtr(new TBlob<uint8_t>({Precision::FP32, {ulFileSize}, Layout::C}));
weightsPtr->allocate();
readFile(filepath, weightsPtr->buffer(), ulFileSize);
return weightsPtr;
return std::move(weights);
}
/**
* @brief Create ngraph function
* @return Ptr to ngraph function
*/
std::shared_ptr<Function> createNgraphFunction() {
TBlob<uint8_t>::CPtr weightsPtr = ReadWeights(FLAGS_m);
if (weightsPtr->byteSize() != 6897344)
IE_THROW() << "Incorrect weights file. This sample works only with LeNet "
"classification network.";
std::shared_ptr<ov::Function> createNgraphFunction() {
auto weights = ReadWeights(FLAGS_m);
const std::uint8_t* data = weights.data<std::uint8_t>();
// -------input------
std::vector<ptrdiff_t> padBegin{0, 0};
std::vector<ptrdiff_t> padEnd{0, 0};
auto paramNode = std::make_shared<op::Parameter>(element::Type_t::f32, Shape(std::vector<size_t>{{64, 1, 28, 28}}));
paramNode->set_friendly_name("Parameter");
auto paramNode = std::make_shared<ov::opset8::Parameter>(ov::element::Type_t::f32, ov::Shape({64, 1, 28, 28}));
// -------convolution 1----
auto convFirstShape = Shape{20, 1, 5, 5};
std::shared_ptr<Node> convolutionFirstConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32, convFirstShape, weightsPtr->cbuffer().as<uint8_t*>());
auto convolutionFirstConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, convFirstShape, data);
std::shared_ptr<Node> convolutionNodeFirst =
std::make_shared<op::v1::Convolution>(paramNode->output(0),
convolutionFirstConstantNode->output(0),
Strides(SizeVector{1, 1}),
CoordinateDiff(padBegin),
CoordinateDiff(padEnd),
Strides(SizeVector{1, 1}));
auto convolutionNodeFirst = std::make_shared<opset8::Convolution>(paramNode->output(0),
convolutionFirstConstantNode->output(0),
Strides({1, 1}),
CoordinateDiff(padBegin),
CoordinateDiff(padEnd),
Strides({1, 1}));
// -------Add--------------
auto addFirstShape = Shape{1, 20, 1, 1};
auto offset = shape_size(convFirstShape) * sizeof(float);
std::shared_ptr<Node> addFirstConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
addFirstShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto addFirstConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, addFirstShape, data + offset);
std::shared_ptr<Node> addNodeFirst =
std::make_shared<op::v1::Add>(convolutionNodeFirst->output(0), addFirstConstantNode->output(0));
auto addNodeFirst = std::make_shared<opset8::Add>(convolutionNodeFirst->output(0), addFirstConstantNode->output(0));
// -------MAXPOOL----------
Shape padBeginShape{0, 0};
Shape padEndShape{0, 0};
std::shared_ptr<Node> maxPoolingNodeFirst = std::make_shared<op::v1::MaxPool>(addNodeFirst->output(0),
std::vector<size_t>{2, 2},
padBeginShape,
padEndShape,
std::vector<size_t>{2, 2},
op::RoundingType::CEIL,
op::PadType::EXPLICIT);
auto maxPoolingNodeFirst = std::make_shared<op::v1::MaxPool>(addNodeFirst->output(0),
Strides{2, 2},
padBeginShape,
padEndShape,
Shape{2, 2},
op::RoundingType::CEIL);
// -------convolution 2----
auto convSecondShape = Shape{50, 20, 5, 5};
offset += shape_size(addFirstShape) * sizeof(float);
std::shared_ptr<Node> convolutionSecondConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
convSecondShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto convolutionSecondConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::f32, convSecondShape, data + offset);
std::shared_ptr<Node> convolutionNodeSecond =
std::make_shared<op::v1::Convolution>(maxPoolingNodeFirst->output(0),
convolutionSecondConstantNode->output(0),
Strides({1, 1}),
CoordinateDiff(padBegin),
CoordinateDiff(padEnd),
Strides({1, 1}));
auto convolutionNodeSecond = std::make_shared<opset8::Convolution>(maxPoolingNodeFirst->output(0),
convolutionSecondConstantNode->output(0),
Strides({1, 1}),
CoordinateDiff(padBegin),
CoordinateDiff(padEnd),
Strides({1, 1}));
// -------Add 2------------
auto addSecondShape = Shape{1, 50, 1, 1};
offset += shape_size(convSecondShape) * sizeof(float);
std::shared_ptr<Node> addSecondConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
addSecondShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto addSecondConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::f32, addSecondShape, data + offset);
std::shared_ptr<Node> addNodeSecond =
std::make_shared<op::v1::Add>(convolutionNodeSecond->output(0), addSecondConstantNode->output(0));
auto addNodeSecond =
std::make_shared<opset8::Add>(convolutionNodeSecond->output(0), addSecondConstantNode->output(0));
// -------MAXPOOL 2--------
std::shared_ptr<Node> maxPoolingNodeSecond = std::make_shared<op::v1::MaxPool>(addNodeSecond->output(0),
Strides{2, 2},
padBeginShape,
padEndShape,
Shape{2, 2},
op::RoundingType::CEIL,
op::PadType::EXPLICIT);
auto maxPoolingNodeSecond = std::make_shared<op::v1::MaxPool>(addNodeSecond->output(0),
Strides{2, 2},
padBeginShape,
padEndShape,
Shape{2, 2},
op::RoundingType::CEIL);
// -------Reshape----------
auto reshapeFirstShape = Shape{2};
auto reshapeOffset = shape_size(addSecondShape) * sizeof(float) + offset;
std::shared_ptr<Node> reshapeFirstConstantNode =
std::make_shared<op::Constant>(element::Type_t::i64,
reshapeFirstShape,
(weightsPtr->cbuffer().as<uint8_t*>() + reshapeOffset));
auto reshapeFirstConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::i64, reshapeFirstShape, data + reshapeOffset);
std::shared_ptr<Node> reshapeFirstNode =
auto reshapeFirstNode =
std::make_shared<op::v1::Reshape>(maxPoolingNodeSecond->output(0), reshapeFirstConstantNode->output(0), true);
// -------MatMul 1---------
auto matMulFirstShape = Shape{500, 800};
offset = shape_size(reshapeFirstShape) * sizeof(int64_t) + reshapeOffset;
std::shared_ptr<Node> matMulFirstConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
matMulFirstShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto matMulFirstConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::f32, matMulFirstShape, data + offset);
std::shared_ptr<Node> matMulFirstNode =
std::make_shared<op::MatMul>(reshapeFirstNode->output(0), matMulFirstConstantNode->output(0), false, true);
auto matMulFirstNode =
std::make_shared<opset8::MatMul>(reshapeFirstNode->output(0), matMulFirstConstantNode->output(0), false, true);
// -------Add 3------------
auto addThirdShape = Shape{1, 500};
offset += shape_size(matMulFirstShape) * sizeof(float);
std::shared_ptr<Node> addThirdConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
addThirdShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto addThirdConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, addThirdShape, data + offset);
std::shared_ptr<Node> addThirdNode =
std::make_shared<op::v1::Add>(matMulFirstNode->output(0), addThirdConstantNode->output(0));
auto addThirdNode = std::make_shared<opset8::Add>(matMulFirstNode->output(0), addThirdConstantNode->output(0));
// -------Relu-------------
std::shared_ptr<Node> reluNode = std::make_shared<op::Relu>(addThirdNode->output(0));
auto reluNode = std::make_shared<opset8::Relu>(addThirdNode->output(0));
// -------Reshape 2--------
auto reshapeSecondShape = Shape{2};
std::shared_ptr<Node> reshapeSecondConstantNode =
std::make_shared<op::Constant>(element::Type_t::i64,
reshapeSecondShape,
(weightsPtr->cbuffer().as<uint8_t*>() + reshapeOffset));
auto reshapeSecondConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::i64, reshapeSecondShape, data + reshapeOffset);
std::shared_ptr<Node> reshapeSecondNode =
auto reshapeSecondNode =
std::make_shared<op::v1::Reshape>(reluNode->output(0), reshapeSecondConstantNode->output(0), true);
// -------MatMul 2---------
auto matMulSecondShape = Shape{10, 500};
offset += shape_size(addThirdShape) * sizeof(float);
std::shared_ptr<Node> matMulSecondConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
matMulSecondShape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto matMulSecondConstantNode =
std::make_shared<opset8::Constant>(element::Type_t::f32, matMulSecondShape, data + offset);
std::shared_ptr<Node> matMulSecondNode =
std::make_shared<op::MatMul>(reshapeSecondNode->output(0), matMulSecondConstantNode->output(0), false, true);
auto matMulSecondNode = std::make_shared<opset8::MatMul>(reshapeSecondNode->output(0),
matMulSecondConstantNode->output(0),
false,
true);
// -------Add 4------------
auto add4Shape = Shape{1, 10};
offset += shape_size(matMulSecondShape) * sizeof(float);
std::shared_ptr<Node> add4ConstantNode =
std::make_shared<op::Constant>(element::Type_t::f32,
add4Shape,
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
auto add4ConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, add4Shape, data + offset);
std::shared_ptr<Node> add4Node =
std::make_shared<op::v1::Add>(matMulSecondNode->output(0), add4ConstantNode->output(0));
auto add4Node = std::make_shared<opset8::Add>(matMulSecondNode->output(0), add4ConstantNode->output(0));
// -------softMax----------
std::shared_ptr<Node> softMaxNode = std::make_shared<op::v1::Softmax>(add4Node->output(0), 1);
auto softMaxNode = std::make_shared<opset8::Softmax>(add4Node->output(0), 1);
softMaxNode->get_output_tensor(0).set_names({"output_tensor"});
// -------ngraph function--
auto result_full = std::make_shared<op::Result>(softMaxNode->output(0));
// ------- OpenVINO function--
auto result_full = std::make_shared<opset8::Result>(softMaxNode->output(0));
std::shared_ptr<ngraph::Function> fnPtr =
std::make_shared<ngraph::Function>(result_full, ngraph::ParameterVector{paramNode}, "lenet");
std::shared_ptr<ov::Function> fnPtr =
std::make_shared<ov::Function>(result_full, ov::ParameterVector{paramNode}, "lenet");
return fnPtr;
}
/**
* @brief The entry point for inference engine automatic ngraph function
* @brief The entry point for inference engine automatic ov::Function
* creation sample
* @file ngraph_function_creation_sample/main.cpp
* @example ngraph_function_creation_sample/main.cpp
*/
int main(int argc, char* argv[]) {
try {
// ------------------------------ Get Inference Engine version
// ------------------------------------------------------
slog::info << "InferenceEngine: " << GetInferenceEngineVersion() << slog::endl;
// ------------------------------ Parsing and validation of input arguments
// ---------------------------------
// -------- Get OpenVINO runtime version --------
slog::info << "OpenVINO Runtime: " << ov::get_openvino_version() << slog::endl;
// -------- Parsing and validation of input arguments --------
if (!ParseAndCheckCommandLine(argc, argv)) {
return 0;
return EXIT_SUCCESS;
}
// ------------------------------ Read input
// -----------------------------------------------------------
/** This vector stores paths to the processed images **/
// -------- Read input --------
std::vector<std::string> images;
parseInputFilesArguments(images);
if (images.empty()) {
throw std::logic_error("No suitable images were found");
}
// -----------------------------------------------------------------------------------------------------
OPENVINO_ASSERT(!images.empty(), "No suitable images were found");
// -------- Step 1. Initialize OpenVINO Runtime Core object --------
slog::info << "Loading OpenVINO runtime" << slog::endl;
runtime::Core core;
// --------------------------- Step 1. Initialize inference engine core
// -------------------------------------
slog::info << "Loading Inference Engine" << slog::endl;
Core ie;
// ------------------------------ Get Available Devices
// ------------------------------------------------------
slog::info << "Device info: " << slog::endl;
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
// -----------------------------------------------------------------------------------------------------
std::cout << core.get_versions(FLAGS_d) << std::endl;
//--------------------------- Step 2. Create network using ngraph function
//-----------------------------------
// -------- Step 2. Create network using ov::Function --------
CNNNetwork network(createNgraphFunction());
// -----------------------------------------------------------------------------------------------------
auto model = createNgraphFunction();
// --------------------------- Step 3. Configure input & output
// ---------------------------------------------
// --------------------------- Prepare input blobs
// -----------------------------------------------------
slog::info << "Preparing input blobs" << slog::endl;
// -------- Step 3. Apply preprocessing --------
const Layout tensor_layout{"NHWC"};
InputsDataMap inputInfo = network.getInputsInfo();
if (inputInfo.size() != 1) {
throw std::logic_error("Sample supports topologies only with 1 input");
}
// apply preprocessing
// clang-format off
using namespace ov::preprocess;
model = PrePostProcessor()
// 1) InputInfo() with no args assumes a model has a single input
.input(InputInfo()
// 2) Set input tensor information:
// - precision of tensor is supposed to be 'u8'
// - layout of data is 'NHWC'
.tensor(InputTensorInfo()
.set_layout(tensor_layout)
.set_element_type(element::u8))
// 3) Here we suppose model has 'NCHW' layout for input
.network(InputNetworkInfo()
.set_layout("NCHW")))
// 4) Once the build() method is called, the preprocessing steps
// for layout and precision conversions are inserted automatically
.build(model);
// clang-format on
auto inputInfoItem = *inputInfo.begin();
// -------- Step 4. Read input images --------
/** Specifying the precision and layout of input data provided by the user.
* Call this before loading the network to the device **/
inputInfoItem.second->setPrecision(Precision::FP32);
inputInfoItem.second->setLayout(Layout::NCHW);
const auto input = model->input();
auto input_shape = input.get_shape();
const size_t width = input_shape[layout::width(tensor_layout)];
const size_t height = input_shape[layout::height(tensor_layout)];
std::vector<std::shared_ptr<unsigned char>> imagesData;
for (auto& i : images) {
@ -339,156 +311,95 @@ int main(int argc, char* argv[]) {
continue;
}
if (reader->size() != inputInfoItem.second->getTensorDesc().getDims()[2] *
inputInfoItem.second->getTensorDesc().getDims()[3]) {
if (reader->size() != width * height) {
throw std::logic_error("Not supported format. Only MNist ubyte images supported.");
}
/** Store image data **/
std::shared_ptr<unsigned char> data(reader->getData(inputInfoItem.second->getTensorDesc().getDims()[3],
inputInfoItem.second->getTensorDesc().getDims()[2]));
// Store image data
std::shared_ptr<unsigned char> data(reader->getData(width, height));
if (data.get() != nullptr) {
imagesData.push_back(data);
}
}
if (imagesData.empty()) {
throw std::logic_error("Valid input images were not found");
}
OPENVINO_ASSERT(!imagesData.empty(), "Valid input images were not found");
/** Setting batch size using image count **/
network.setBatchSize(imagesData.size());
size_t batchSize = network.getBatchSize();
slog::info << "Batch size is " << std::to_string(batchSize) << slog::endl;
// -------- Step 4. Reshape a model --------
// Setting batch size using image count
const size_t batch_size = imagesData.size();
input_shape[layout::batch(tensor_layout)] = batch_size;
model->reshape({{input.get_any_name(), input_shape}});
slog::info << "Batch size is " << std::to_string(batch_size) << slog::endl;
// --------------------------- Prepare output blobs
// -----------------------------------------------------
slog::info << "Checking that the outputs are as the sample expects" << slog::endl;
OutputsDataMap outputInfo(network.getOutputsInfo());
std::string firstOutputName;
const auto outputShape = model->output().get_shape();
OPENVINO_ASSERT(outputShape.size() == 2, "Incorrect output dimensions for LeNet");
for (auto& item : outputInfo) {
if (firstOutputName.empty()) {
firstOutputName = item.first;
}
DataPtr outputData = item.second;
if (!outputData) {
throw std::logic_error("Output data pointer is not valid");
}
const auto classCount = outputShape[1];
OPENVINO_ASSERT(classCount <= 10, "Incorrect number of output classes for LeNet model");
item.second->setPrecision(Precision::FP32);
}
// -------- Step 4. Compiling model for the device --------
slog::info << "Compiling a model for the " << FLAGS_d << " device" << slog::endl;
runtime::ExecutableNetwork exeNetwork = core.compile_model(model, FLAGS_d);
if (outputInfo.size() != 1) {
throw std::logic_error("This demo accepts networks with a single output");
}
DataPtr& output = outputInfo.begin()->second;
auto outputName = outputInfo.begin()->first;
const SizeVector outputDims = output->getTensorDesc().getDims();
const int classCount = outputDims[1];
if (classCount > 10) {
throw std::logic_error("Incorrect number of output classes for LeNet network");
}
if (outputDims.size() != 2) {
throw std::logic_error("Incorrect output dimensions for LeNet");
}
output->setPrecision(Precision::FP32);
output->setLayout(Layout::NC);
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 4. Loading model to the device
// ------------------------------------------
slog::info << "Loading model to the device" << slog::endl;
ExecutableNetwork exeNetwork = ie.LoadNetwork(network, FLAGS_d);
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 5. Create infer request
// -------------------------------------------------
// -------- Step 5. Create infer request --------
slog::info << "Create infer request" << slog::endl;
InferRequest infer_request = exeNetwork.CreateInferRequest();
// -----------------------------------------------------------------------------------------------------
runtime::InferRequest infer_request = exeNetwork.create_infer_request();
// --------------------------- Step 6. Prepare input
// --------------------------------------------------------
/** Iterate over all the input blobs **/
for (const auto& item : inputInfo) {
/** Creating input blob **/
Blob::Ptr input = infer_request.GetBlob(item.first);
// -------- Step 6. Combine multiple input images as batch --------
slog::info << "Combining a batch and set input tensor" << slog::endl;
runtime::Tensor input_tensor = infer_request.get_input_tensor();
/** Filling input tensor with images. First b channel, then g and r
* channels **/
size_t num_channels = input->getTensorDesc().getDims()[1];
size_t image_size = input->getTensorDesc().getDims()[2] * input->getTensorDesc().getDims()[3];
auto data = input->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
/** Iterate over all input images **/
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
/** Iterate over all pixels in image (b,g,r) **/
for (size_t pid = 0; pid < image_size; pid++) {
/** Iterate over all channels **/
for (size_t ch = 0; ch < num_channels; ++ch) {
/** [images stride + channels stride + pixel id ] all in
* bytes **/
data[image_id * image_size * num_channels + ch * image_size + pid] =
imagesData.at(image_id).get()[pid * num_channels + ch];
}
}
}
// Iterate over all input images
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
const size_t image_size = shape_size(input_shape) / batch_size;
std::memcpy(input_tensor.data<std::uint8_t>() + image_id * image_size,
imagesData[image_id].get(),
image_size);
}
inputInfo = {};
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 7. Do inference
// ---------------------------------------------------------
slog::info << "Start inference" << slog::endl;
infer_request.Infer();
// -----------------------------------------------------------------------------------------------------
// -------- Step 7. Do sync inference --------
slog::info << "Start sync inference" << slog::endl;
infer_request.infer();
// --------------------------- Step 8. Process output
// -------------------------------------------------------
slog::info << "Processing output blobs" << slog::endl;
// -------- Step 8. Process output --------
slog::info << "Processing output tensor" << slog::endl;
const runtime::Tensor output_tensor = infer_request.get_output_tensor();
const Blob::Ptr outputBlob = infer_request.GetBlob(firstOutputName);
/** Validating -nt value **/
const size_t resultsCnt = outputBlob->size() / batchSize;
if (FLAGS_nt > resultsCnt || FLAGS_nt < 1) {
slog::warn << "-nt " << FLAGS_nt << " is not available for this network (-nt should be less than "
<< resultsCnt + 1 << " and more than 0).\n Maximal value " << resultsCnt
// Validating -nt value
const size_t results_cnt = output_tensor.get_size() / batch_size;
if (FLAGS_nt > results_cnt || FLAGS_nt < 1) {
slog::warn << "-nt " << FLAGS_nt << " is not available for this model (-nt should be less than "
<< results_cnt + 1 << " and more than 0).\n Maximal value " << results_cnt
<< " will be used.";
FLAGS_nt = resultsCnt;
FLAGS_nt = results_cnt;
}
/** Read labels from file (e.x. LeNet.labels) **/
std::string labelFileName = fileNameNoExt(FLAGS_m) + ".labels";
// Read labels from file (e.x. LeNet.labels) **/
std::string label_file_name = fileNameNoExt(FLAGS_m) + ".labels";
std::vector<std::string> labels;
std::ifstream inputFile;
inputFile.open(labelFileName, std::ios::in);
if (inputFile.is_open()) {
std::ifstream input_file;
input_file.open(label_file_name, std::ios::in);
if (input_file.is_open()) {
std::string strLine;
while (std::getline(inputFile, strLine)) {
while (std::getline(input_file, strLine)) {
trim(strLine);
labels.push_back(strLine);
}
inputFile.close();
input_file.close();
}
// Prints formatted classification results
ClassificationResult classificationResult(outputBlob, images, batchSize, FLAGS_nt, labels);
classificationResult.print();
// -----------------------------------------------------------------------------------------------------
ClassificationResult classification_result(output_tensor, images, batch_size, FLAGS_nt, labels);
classification_result.show();
} catch (const std::exception& ex) {
slog::err << ex.what() << slog::endl;
return EXIT_FAILURE;
}
slog::info << "This sample is an API example, for performance measurements, "
"use the dedicated benchmark_app tool"
<< slog::endl;
return 0;
return EXIT_SUCCESS;
}

View File

@ -89,11 +89,9 @@ int main(int argc, char* argv[]) {
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
if (!FLAGS_l.empty()) {
// Custom CPU extension is loaded as a shared library and passed as a
// pointer to base extension
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
ie.AddExtension(extension_ptr);
slog::info << "Custom extension loaded: " << FLAGS_l << slog::endl;
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
}
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
@ -184,7 +182,7 @@ int main(int argc, char* argv[]) {
if (auto ngraphFunction = network.getFunction()) {
for (const auto& out : outputsInfo) {
for (const auto& op : ngraphFunction->get_ops()) {
if (op->get_type_info() == ngraph::op::DetectionOutput::type_info &&
if (op->get_type_info() == ngraph::op::DetectionOutput::get_type_info_static() &&
op->get_friendly_name() == out.second->getName()) {
outputName = out.first;
outputInfo = out.second;

View File

@ -79,11 +79,9 @@ int main(int argc, char* argv[]) {
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
if (!FLAGS_l.empty()) {
// Custom CPU extension is loaded as a shared library and passed as a
// pointer to base extension
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
ie.AddExtension(extension_ptr);
slog::info << "Custom Extension loaded: " << FLAGS_l << slog::endl;
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
}
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
// Config for device plugin custom extension is loaded from an .xml

View File

@ -2,8 +2,9 @@
# SPDX-License-Identifier: Apache-2.0
#
if(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_COMPILER_IS_GNUCXX)
ie_add_compiler_flags(-Wall)
ie_add_compiler_flags(-Wmissing-declarations)
endif()
add_subdirectory(preprocessing)

View File

@ -13,12 +13,14 @@ CLDNNPlugin::CLDNNAsyncInferRequest::CLDNNAsyncInferRequest(const CLDNNInferRequ
: AsyncInferRequestThreadSafeDefault(inferRequest, taskExecutor, callbackExecutor), _inferRequest(inferRequest), _waitExecutor(waitExecutor) {
_pipeline = {};
_pipeline.push_back({taskExecutor,
[this] {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNAsyncInferRequest::PreprocessingAndStartPipeline");
_inferRequest->preprocess();
_inferRequest->enqueue();
} });
if (!_inferRequest->use_external_queue()) {
_pipeline.push_back({taskExecutor,
[this] {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNAsyncInferRequest::PreprocessingAndStartPipeline");
_inferRequest->preprocess();
_inferRequest->enqueue();
} });
}
_pipeline.push_back({_waitExecutor,
[this] {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNAsyncInferRequest::WaitPipeline");
@ -26,6 +28,22 @@ CLDNNPlugin::CLDNNAsyncInferRequest::CLDNNAsyncInferRequest(const CLDNNInferRequ
}});
}
void CLDNNPlugin::CLDNNAsyncInferRequest::Infer_ThreadUnsafe() {
if (_inferRequest->use_external_queue()) {
_inferRequest->preprocess();
_inferRequest->enqueue();
}
Parent::Infer_ThreadUnsafe();
}
void CLDNNPlugin::CLDNNAsyncInferRequest::StartAsync_ThreadUnsafe() {
if (_inferRequest->use_external_queue()) {
_inferRequest->preprocess();
_inferRequest->enqueue();
}
Parent::StartAsync_ThreadUnsafe();
}
CLDNNPlugin::CLDNNAsyncInferRequest::~CLDNNAsyncInferRequest() {
StopAndWait();
}

View File

@ -21,6 +21,9 @@ public:
~CLDNNAsyncInferRequest();
void Infer_ThreadUnsafe() override;
void StartAsync_ThreadUnsafe() override;
private:
CLDNNInferRequest::Ptr _inferRequest;
InferenceEngine::ITaskExecutor::Ptr _waitExecutor;

View File

@ -94,12 +94,8 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc
if (clonedNetwork.getFunction()) {
auto nGraphFunc = clonedNetwork.getFunction();
auto transformation_config = CLDNNPlugin::Config(config);
#ifdef ENABLE_ONEDNN_FOR_GPU
if (GetDeviceInfo(config.key_config_map).supports_immad)
transformation_config.enable_fp16_for_quantized_models = false;
#endif
TransformationsPipeline transformations(transformation_config);
auto deviceInfo = GetDeviceInfo(config.key_config_map);
TransformationsPipeline transformations(config, deviceInfo);
transformations.apply(nGraphFunc);
}

View File

@ -74,6 +74,9 @@ IInferRequestInternal::Ptr CLDNNExecNetwork::CreateInferRequestImpl(InputsDataMa
}
if (m_config.useProfiling)
ptr->EnableProfiling();
if (m_graphs.front()->use_external_queue()) {
ptr->enable_external_queue();
}
ptr->SetGraph(m_graphs.front());
return ptr;
@ -89,6 +92,10 @@ IInferRequestInternal::Ptr CLDNNExecNetwork::CreateInferRequestImpl(const std::v
}
if (m_config.useProfiling)
ptr->EnableProfiling();
if (m_graphs.front()->use_external_queue()) {
ptr->enable_external_queue();
}
ptr->SetGraph(m_graphs.front());
return ptr;

View File

@ -117,9 +117,26 @@ void CLDNNGraph::Build() {
}
}
bool CLDNNGraph::use_external_queue() const {
auto impl = getContextImpl(m_context);
return impl->GetExternalQueue() != nullptr;
}
std::shared_ptr<cldnn::network> CLDNNGraph::BuildNetwork(std::shared_ptr<cldnn::program> program) {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNGraph::BuildNetwork");
auto network = std::make_shared<cldnn::network>(program, m_stream_id);
std::shared_ptr<cldnn::network> network = nullptr;
auto impl = getContextImpl(m_context);
auto externalQueue = impl->GetExternalQueue();
if (externalQueue) {
if (m_config.throughput_streams != 1)
IE_THROW(ParameterMismatch) << "Throughput streams can't be used with shared queue!\n";
auto &engine = m_program->GetEngine();
network = std::make_shared<cldnn::network>(program, engine.create_stream(externalQueue), m_stream_id);
} else {
network = std::make_shared<cldnn::network>(program, m_stream_id);
}
if (!m_config.graph_dumps_dir.empty() && m_stream_id == 0) {
static int net_id = 0;

View File

@ -72,6 +72,8 @@ public:
m_cv.notify_one();
}
bool use_external_queue() const;
protected:
uint32_t m_state;
std::condition_variable m_cv;

View File

@ -285,7 +285,7 @@ void CLDNNInferRequest::SetBlob(const std::string& name, const Blob::Ptr& data)
// Stores the given blob as ROI blob. It will be used to fill in network input
// during pre-processing
if (_inputs[name]->is<gpu::ClBlob>()) {
Blob::Ptr inputHostBlob = create_input_host_blob(desc);
Blob::Ptr inputHostBlob = create_host_blob(desc);
inputHostBlob->allocate();
_inputs[name] = inputHostBlob;
}
@ -452,7 +452,8 @@ CLDNNInferRequest::CLDNNInferRequest(InputsDataMap networkInputs, OutputsDataMap
const CLDNNExecNetwork::Ptr& execNetwork)
: IInferRequestInternal(networkInputs, networkOutputs)
, m_useProfiling(false)
, m_useStreams(false) {
, m_useStreams(false)
, m_useExternalQueue(false) {
IE_ASSERT(nullptr != execNetwork);
streamExecutor = dynamic_cast<InferenceEngine::IStreamsExecutor*>(execNetwork->m_taskExecutor.get());
}
@ -625,8 +626,8 @@ void CLDNNInferRequest::wait_dynamic() {
// ---------------------------- internal utils --------- ----------------------------------- //
// ----------------------------------------------------------------------------------------- //
Blob::Ptr CLDNNInferRequest::create_input_host_blob(const TensorDesc& desc, uint8_t* mem_ptr) {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNInferRequest::create_input_host_blob");
Blob::Ptr CLDNNInferRequest::create_host_blob(const TensorDesc& desc, uint8_t* mem_ptr) {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNInferRequest::create_host_blob");
const Precision& p = desc.getPrecision();
switch (p) {
@ -676,37 +677,7 @@ Blob::Ptr CLDNNInferRequest::create_input_host_blob(const TensorDesc& desc, uint
else
return make_shared_blob<uint8_t>(desc);
default:
IE_THROW(NotImplemented) << "The plugin does not support input " << p.name() << " precision";
}
}
Blob::Ptr CLDNNInferRequest::create_output_host_blob(const TensorDesc& desc, uint8_t* mem_ptr) {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "CLDNNInferRequest::create_output_host_blob");
const Precision& p = desc.getPrecision();
switch (p) {
case Precision::FP32:
if (mem_ptr != nullptr)
return make_shared_blob<float>(desc, reinterpret_cast<float*>(mem_ptr));
else
return make_shared_blob<float>(desc);
case Precision::FP16:
if (mem_ptr != nullptr)
return make_shared_blob<uint16_t>(desc, reinterpret_cast<uint16_t*>(mem_ptr));
else
return make_shared_blob<uint16_t>(desc);
case Precision::I32:
if (mem_ptr != nullptr)
return make_shared_blob<int32_t>(desc, reinterpret_cast<int32_t*>(mem_ptr));
else
return make_shared_blob<int32_t>(desc);
case Precision::I64:
if (mem_ptr != nullptr)
return make_shared_blob<int64_t>(desc, reinterpret_cast<int64_t*>(mem_ptr));
else
return make_shared_blob<int64_t>(desc);
default:
IE_THROW() << "The plugin does not support output " << p.name() << " precision";
IE_THROW(NotImplemented) << "The plugin does not support " << p.name() << " blob precision";
}
}
@ -718,6 +689,8 @@ void CLDNNInferRequest::copy_output_data(cldnn::memory::ptr src, Blob::Ptr dst,
case Precision::FP16: copyResultToOutputBlob<uint16_t>(src, dst, bi, stream); break;
case Precision::I32: copyResultToOutputBlob<int32_t>(src, dst, bi, stream); break;
case Precision::I64: copyResultToOutputBlob<int64_t>(src, dst, bi, stream); break;
case Precision::U8: copyResultToOutputBlob<uint8_t>(src, dst, bi, stream); break;
case Precision::I8: copyResultToOutputBlob<int8_t>(src, dst, bi, stream); break;
default: IE_THROW(NotImplemented) << "The plugin does not support output " << dst->getTensorDesc().getPrecision() << " precision";
}
}
@ -798,7 +771,7 @@ void CLDNNInferRequest::allocate_inputs() {
desc_fp32.setPrecision(Precision::FP32);
auto blobPtr = create_device_blob(desc_fp32, litr->second);
_deviceInputs[name] = blobPtr;
Blob::Ptr inputBlob = create_input_host_blob(desc);
Blob::Ptr inputBlob = create_host_blob(desc);
inputBlob->allocate();
_inputs[name] = inputBlob;
} else {
@ -824,7 +797,7 @@ void CLDNNInferRequest::allocate_inputs_dynamic() {
IE_THROW() << "Empty dimensions for input blob " << input.first;
}
Blob::Ptr inputBlob = create_input_host_blob(desc);
Blob::Ptr inputBlob = create_host_blob(desc);
if (desc.getPrecision() == Precision::I16 || desc.getPrecision() == Precision::U16) {
desc.setPrecision(Precision::FP32);
auto fp32inputBlob = InferenceEngine::make_shared_blob<float>(desc);
@ -870,7 +843,7 @@ void CLDNNInferRequest::allocate_outputs_dynamic() {
IE_THROW() << "Empty dimensions for output blob " << no.first;
}
Blob::Ptr outputBlob = create_output_host_blob(desc);
Blob::Ptr outputBlob = create_host_blob(desc);
outputBlob->allocate();
_outputs[no.first] = outputBlob;
outputsMap[no.first] = outputID;

View File

@ -57,6 +57,9 @@ public:
void enqueue_dynamic();
void wait_dynamic();
bool use_external_queue() const { return m_useExternalQueue; }
void enable_external_queue() { m_useExternalQueue = true; }
private:
InferenceEngine::BlobMap _deviceOutputs;
std::map<std::string, cldnn::primitive_id> inputsMap;
@ -64,6 +67,7 @@ private:
bool m_useProfiling;
bool m_useStreams;
bool m_useExternalQueue;
std::shared_ptr<CLDNNGraph> m_graph;
// dynamic batch stuff
@ -75,8 +79,7 @@ private:
std::vector<cldnn::event::ptr>& dependencies);
void prepare_output(const cldnn::primitive_id& outputName, InferenceEngine::Blob::Ptr& outputBlob);
InferenceEngine::Blob::Ptr create_input_host_blob(const InferenceEngine::TensorDesc& desc, uint8_t* mem_ptr = nullptr);
InferenceEngine::Blob::Ptr create_output_host_blob(const InferenceEngine::TensorDesc& desc, uint8_t* mem_ptr = nullptr);
InferenceEngine::Blob::Ptr create_host_blob(const InferenceEngine::TensorDesc& desc, uint8_t* mem_ptr = nullptr);
InferenceEngine::Blob::Ptr create_device_blob(const InferenceEngine::TensorDesc& desc, const cldnn::layout& layout);
void copy_output_data(cldnn::memory::ptr outputMemory, InferenceEngine::Blob::Ptr bptr, buf_info* bi = nullptr);

View File

@ -29,12 +29,13 @@ enum class eltwise_mode : int32_t;
} // namespace cldnn
#define REGISTER_FACTORY_IMPL(op_version, op_name) \
void __register ## _ ## op_name ## _ ## op_version(); \
void __register ## _ ## op_name ## _ ## op_version() { \
Program::RegisterFactory<ngraph::op::op_version::op_name>( \
[](Program& p, const std::shared_ptr<ngraph::Node>& op) { \
auto op_casted = std::dynamic_pointer_cast<ngraph::op::op_version::op_name>(op); \
if (!op_casted) \
IE_THROW() << "Invalid ngraph Node type passed into " << __PRETTY_FUNCTION__; \
IE_THROW() << "Invalid ngraph Node type passed into " << __PRETTY_FUNCTION__; \
Create##op_name##Op(p, op_casted); \
}); \
}
@ -122,19 +123,7 @@ public:
using factory_t = std::function<void(Program&, const std::shared_ptr<ngraph::Node>&)>;
using factories_map_t = std::map<ngraph::DiscreteTypeInfo, factory_t>;
template<typename OpType,
typename std::enable_if<std::is_base_of<ngraph::Node, OpType>::value && ngraph::HasTypeInfoMember<OpType>::value, int>::type = 0>
static void RegisterFactory(factory_t func) {
static std::mutex m;
std::lock_guard<std::mutex> lock(m);
OPENVINO_SUPPRESS_DEPRECATED_START
if (Program::factories_map.find(OpType::type_info) == Program::factories_map.end())
Program::factories_map.insert({OpType::type_info, func});
OPENVINO_SUPPRESS_DEPRECATED_END
}
template<typename OpType,
typename std::enable_if<std::is_base_of<ngraph::Node, OpType>::value && !ngraph::HasTypeInfoMember<OpType>::value, int>::type = 0>
template<typename OpType>
static void RegisterFactory(factory_t func) {
static std::mutex m;
std::lock_guard<std::mutex> lock(m);

View File

@ -199,6 +199,7 @@ CLDNNExecutionContextImpl::CLDNNExecutionContextImpl(const std::shared_ptr<IInfe
m_plugin(plugin),
m_type(ContextType::OCL),
m_config(config),
m_external_queue(nullptr),
m_va_display(nullptr) {
lock.clear(std::memory_order_relaxed);
gpu_handle_param _context_id = nullptr;
@ -221,6 +222,9 @@ CLDNNExecutionContextImpl::CLDNNExecutionContextImpl(const std::shared_ptr<IInfe
if (tile_id_itr != params.end()) {
target_tile_id = tile_id_itr->second.as<int>();
}
if (params.find(GPU_PARAM_KEY(OCL_QUEUE)) != params.end())
m_external_queue = _ObjFromParamSimple<gpu_handle_param>(params, GPU_PARAM_KEY(OCL_QUEUE));
}
// TODO: Parameterize this based on plugin config and compilation options
@ -239,10 +243,13 @@ CLDNNExecutionContextImpl::CLDNNExecutionContextImpl(const std::shared_ptr<IInfe
(m_config.tuningConfig.mode == cldnn::tuning_mode::tuning_tune_and_cache) ||
(m_config.tuningConfig.mode == cldnn::tuning_mode::tuning_retune_and_cache));
cldnn::queue_types queue_type;
if (dev->get_info().supports_immad)
if (m_external_queue) {
queue_type = cldnn::stream::detect_queue_type(engine_type, m_external_queue);
} else if (dev->get_info().supports_immad) {
queue_type = cldnn::queue_types::in_order;
else
} else {
queue_type = cldnn::queue_types::out_of_order;
}
bool use_unified_shared_memory = true;
m_engine = cldnn::engine::create(engine_type, runtime_type, dev, cldnn::engine_configuration(enable_profiling,

View File

@ -224,6 +224,7 @@ public:
std::shared_ptr<cldnn::engine> GetEngine() const { return m_engine; }
Config& GetConfig() { return m_config; }
ContextType GetType() const { return m_type; }
InferenceEngine::gpu_handle_param GetExternalQueue() const { return m_external_queue; }
const std::weak_ptr<InferenceEngine::IInferencePlugin> GetPlugin() const { return m_plugin; }
void acquire_lock() {
@ -238,6 +239,7 @@ protected:
// TODO: refactor to unique_ptr
std::shared_ptr<cldnn::engine> m_engine;
InferenceEngine::gpu_handle_param m_va_display;
InferenceEngine::gpu_handle_param m_external_queue;
Config m_config;
ContextType m_type;

View File

@ -101,6 +101,11 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Function> func) {
OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "TransformationsPipeline::apply");
using const_node_ptr = const std::shared_ptr<const ngraph::Node>;
bool use_onednn = false;
#ifdef ENABLE_ONEDNN_FOR_GPU
use_onednn = device_info.supports_immad;
#endif
bool enableInt8;
{
ngraph::pass::Manager manager;
@ -325,7 +330,7 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Function> func) {
// Conversion to FP32 might be needed for quantized models that face any fp16 related issues (e.g. overflow) for non-quantized layers
// With this key users can work-around such issues
if (!config.enable_fp16_for_quantized_models) {
if (!config.enable_fp16_for_quantized_models || use_onednn) {
ngraph::pass::Manager manager;
manager.register_pass<ngraph::pass::ConvertPrecision>(precisions_array {{ ngraph::element::f16, ngraph::element::f32 }});
manager.run_passes(func);
@ -396,9 +401,11 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Function> func) {
return LayerTransformation::isAsymmetricQuantization(node) || WeightableLayerTransformation::isAsymmetricOnWeights(node);
});
lptPassConfig->set_callback<MatMulTransformation>([](const_node_ptr& node) -> bool {
return MatMulTransformation::is3DTensorOnActivations(node);
});
if (!use_onednn) {
lptPassConfig->set_callback<MatMulTransformation>([](const_node_ptr& node) -> bool {
return MatMulTransformation::is3DTensorOnActivations(node);
});
}
lptManager.register_pass<LowPrecision>(supportedPrecisions, perTensorQuantization);
lptManager.run_passes(func);

View File

@ -14,11 +14,13 @@ namespace CLDNNPlugin {
class TransformationsPipeline {
public:
explicit TransformationsPipeline(const Config &conf) : config(conf) {}
explicit TransformationsPipeline(const Config &conf, const cldnn::device_info &device_info)
: config(conf), device_info(device_info) {}
void apply(std::shared_ptr<ov::Function> func);
private:
Config config;
cldnn::device_info device_info;
};
} // namespace CLDNNPlugin

View File

@ -12,7 +12,7 @@
namespace CLDNNPlugin {
void CreateBatchToSpaceOp(Program& p, const std::shared_ptr<ngraph::op::v1::BatchToSpace>& op) {
static void CreateBatchToSpaceOp(Program& p, const std::shared_ptr<ngraph::op::v1::BatchToSpace>& op) {
p.ValidateInputs(op, {4});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -88,7 +88,7 @@ static void CreateCommonBroadcastOp(Program& p, const std::shared_ptr<ngraph::No
p.AddPrimitiveToProfiler(op);
}
void CreateBroadcastOp(Program& p, const std::shared_ptr<ngraph::op::v1::Broadcast>& op) {
static void CreateBroadcastOp(Program& p, const std::shared_ptr<ngraph::op::v1::Broadcast>& op) {
p.ValidateInputs(op, {2, 3});
if (op->get_broadcast_spec().m_type == ngraph::op::AutoBroadcastType::NONE && op->get_input_size() == 3) {
auto axis_mapping_node = std::dynamic_pointer_cast<ngraph::op::v0::Constant>(op->get_input_node_shared_ptr(2));
@ -103,7 +103,7 @@ void CreateBroadcastOp(Program& p, const std::shared_ptr<ngraph::op::v1::Broadca
}
}
void CreateBroadcastOp(Program& p, const std::shared_ptr<ngraph::op::v3::Broadcast>& op) {
static void CreateBroadcastOp(Program& p, const std::shared_ptr<ngraph::op::v3::Broadcast>& op) {
p.ValidateInputs(op, {2, 3});
ngraph::AxisSet axis_mapping;
if (op->get_input_size() == 3) {

View File

@ -38,7 +38,7 @@ static cldnn::concatenation::concatenation_axis GetConcatAxis(int32_t axis, size
return cldnn::concatenation::concatenation_axis::along_f; // shouldn't get here
}
void CreateConcatOp(Program& p, const std::shared_ptr<ngraph::op::v0::Concat>& op) {
static void CreateConcatOp(Program& p, const std::shared_ptr<ngraph::op::v0::Concat>& op) {
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
auto concatPrim = cldnn::concatenation(

View File

@ -78,7 +78,7 @@ static cldnn::tensor getConstTensor(const ngraph::Shape constDims) {
return constTensor;
}
void CreateConstantOp(Program& p, const std::shared_ptr<ngraph::op::v0::Constant>& op) {
static void CreateConstantOp(Program& p, const std::shared_ptr<ngraph::op::v0::Constant>& op) {
auto constDims = op->get_shape();
cldnn::tensor constTensor = getConstTensor(constDims);

View File

@ -12,7 +12,7 @@
namespace CLDNNPlugin {
void CreateConvertLikeOp(Program& p, const std::shared_ptr<ngraph::op::v1::ConvertLike>& op) {
static void CreateConvertLikeOp(Program& p, const std::shared_ptr<ngraph::op::v1::ConvertLike>& op) {
p.ValidateInputs(op, {2});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -30,7 +30,7 @@ void CreateConvertLikeOp(Program& p, const std::shared_ptr<ngraph::op::v1::Conve
p.AddPrimitiveToProfiler(op);
}
void CreateConvertOp(Program& p, const std::shared_ptr<ngraph::op::v0::Convert>& op) {
static void CreateConvertOp(Program& p, const std::shared_ptr<ngraph::op::v0::Convert>& op) {
p.ValidateInputs(op, {1});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -61,7 +61,7 @@ static ConvoltuionParameters GetConvolutionParameters(const ngraph::CoordinateDi
return {stride, padding, dilation, groups};
}
void CreateGroupConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::GroupConvolution>& op) {
static void CreateGroupConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::GroupConvolution>& op) {
p.ValidateInputs(op, {2});
auto inputs = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -91,7 +91,7 @@ void CreateGroupConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::
p.AddPrimitiveToProfiler(op);
}
void CreateConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::Convolution>& op) {
static void CreateConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::Convolution>& op) {
p.ValidateInputs(op, {2});
auto inputs = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -120,7 +120,7 @@ void CreateConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::Convo
p.AddPrimitiveToProfiler(op);
}
void CreateConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngraph::op::v1::ConvolutionBackpropData>& op) {
static void CreateConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngraph::op::v1::ConvolutionBackpropData>& op) {
// 3rd input is an optional output shape
p.ValidateInputs(op, {2, 3});
auto inputs = p.GetInputPrimitiveIDs(op);
@ -176,7 +176,7 @@ void CreateConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngraph::o
p.AddPrimitiveToProfiler(op);
}
void CreateGroupConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngraph::op::v1::GroupConvolutionBackpropData>& op) {
static void CreateGroupConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngraph::op::v1::GroupConvolutionBackpropData>& op) {
p.ValidateInputs(op, {2});
auto inputs = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -233,7 +233,7 @@ void CreateGroupConvolutionBackpropDataOp(Program& p, const std::shared_ptr<ngra
p.AddPrimitiveToProfiler(op);
}
void CreateDeformableConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::DeformableConvolution>& op) {
static void CreateDeformableConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::DeformableConvolution>& op) {
p.ValidateInputs(op, {3});
auto inputs = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -303,7 +303,7 @@ void CreateDeformableConvolutionOp(Program& p, const std::shared_ptr<ngraph::op:
}
}
void CreateBinaryConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::BinaryConvolution>& op) {
static void CreateBinaryConvolutionOp(Program& p, const std::shared_ptr<ngraph::op::v1::BinaryConvolution>& op) {
p.ValidateInputs(op, {2});
auto inputs = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -17,7 +17,7 @@
namespace CLDNNPlugin {
void CreateCommonCTCGreedyDecoderOp(Program& p, const std::shared_ptr<ngraph::Node>& op, bool ctc_merge_repeated) {
static void CreateCommonCTCGreedyDecoderOp(Program& p, const std::shared_ptr<ngraph::Node>& op, bool ctc_merge_repeated) {
p.ValidateInputs(op, {2, 3});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
@ -120,11 +120,11 @@ void CreateCommonCTCGreedyDecoderOp(Program& p, const std::shared_ptr<ngraph::No
p.AddPrimitiveToProfiler(CTCGreedyDecoderLayerName, op);
}
void CreateCTCGreedyDecoderOp(Program& p, const std::shared_ptr<ngraph::op::v0::CTCGreedyDecoder>& op) {
static void CreateCTCGreedyDecoderOp(Program& p, const std::shared_ptr<ngraph::op::v0::CTCGreedyDecoder>& op) {
CreateCommonCTCGreedyDecoderOp(p, op, op->get_ctc_merge_repeated());
}
void CreateCTCGreedyDecoderSeqLenOp(Program& p, const std::shared_ptr<ngraph::op::v6::CTCGreedyDecoderSeqLen>& op) {
static void CreateCTCGreedyDecoderSeqLenOp(Program& p, const std::shared_ptr<ngraph::op::v6::CTCGreedyDecoderSeqLen>& op) {
CreateCommonCTCGreedyDecoderOp(p, op, op->get_merge_repeated());
}

View File

@ -41,7 +41,7 @@ static inline cldnn::cum_sum::cum_sum_axis GetCumSumAxis(int32_t axis, uint32_t
return cldnn::cum_sum::cum_sum_axis::along_f; // shouldn't get here
}
void CreateCumSumOp(Program& p, const std::shared_ptr<ngraph::op::v0::CumSum>& op) {
static void CreateCumSumOp(Program& p, const std::shared_ptr<ngraph::op::v0::CumSum>& op) {
p.ValidateInputs(op, {1, 2});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -22,7 +22,7 @@ static cldnn::depth_to_space_mode GetDepthMode(ngraph::op::v0::DepthToSpace::Dep
return cldnn::depth_to_space_mode::blocks_first;
}
void CreateDepthToSpaceOp(Program& p, const std::shared_ptr<ngraph::op::v0::DepthToSpace>& op) {
static void CreateDepthToSpaceOp(Program& p, const std::shared_ptr<ngraph::op::v0::DepthToSpace>& op) {
p.ValidateInputs(op, {1});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -26,7 +26,7 @@ static cldnn::prior_box_code_type PriorBoxCodeFromString(const std::string& str)
return cldnn::prior_box_code_type::corner;
}
void CreateDetectionOutputOp(Program& p, const std::shared_ptr<ngraph::op::v0::DetectionOutput>& op) {
static void CreateDetectionOutputOp(Program& p, const std::shared_ptr<ngraph::op::v0::DetectionOutput>& op) {
p.ValidateInputs(op, {3});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -87,71 +87,71 @@ void CreateElementwiseOp(Program& p, const std::shared_ptr<ngraph::Node>& op, cl
p.AddPrimitiveToProfiler(op);
}
void CreateAddOp(Program& p, const std::shared_ptr<ngraph::op::v1::Add>& op) {
static void CreateAddOp(Program& p, const std::shared_ptr<ngraph::op::v1::Add>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::sum);
}
void CreateMultiplyOp(Program& p, const std::shared_ptr<ngraph::op::v1::Multiply>& op) {
static void CreateMultiplyOp(Program& p, const std::shared_ptr<ngraph::op::v1::Multiply>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::prod);
}
void CreateMaximumOp(Program& p, const std::shared_ptr<ngraph::op::v1::Maximum>& op) {
static void CreateMaximumOp(Program& p, const std::shared_ptr<ngraph::op::v1::Maximum>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::max);
}
void CreateMinimumOp(Program& p, const std::shared_ptr<ngraph::op::v1::Minimum>& op) {
static void CreateMinimumOp(Program& p, const std::shared_ptr<ngraph::op::v1::Minimum>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::min);
}
void CreateSubtractOp(Program& p, const std::shared_ptr<ngraph::op::v1::Subtract>& op) {
static void CreateSubtractOp(Program& p, const std::shared_ptr<ngraph::op::v1::Subtract>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::sub);
}
void CreateDivideOp(Program& p, const std::shared_ptr<ngraph::op::v1::Divide>& op) {
static void CreateDivideOp(Program& p, const std::shared_ptr<ngraph::op::v1::Divide>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::div);
}
void CreateSquaredDifferenceOp(Program& p, const std::shared_ptr<ngraph::op::v0::SquaredDifference>& op) {
static void CreateSquaredDifferenceOp(Program& p, const std::shared_ptr<ngraph::op::v0::SquaredDifference>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::squared_diff);
}
void CreateEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::Equal>& op) {
static void CreateEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::Equal>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::eq);
}
void CreateNotEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::NotEqual>& op) {
static void CreateNotEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::NotEqual>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::ne);
}
void CreateLessOp(Program& p, const std::shared_ptr<ngraph::op::v1::Less>& op) {
static void CreateLessOp(Program& p, const std::shared_ptr<ngraph::op::v1::Less>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::lt);
}
void CreateLessEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::LessEqual>& op) {
static void CreateLessEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::LessEqual>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::le);
}
void CreateGreaterOp(Program& p, const std::shared_ptr<ngraph::op::v1::Greater>& op) {
static void CreateGreaterOp(Program& p, const std::shared_ptr<ngraph::op::v1::Greater>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::gt);
}
void CreateGreaterEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::GreaterEqual>& op) {
static void CreateGreaterEqualOp(Program& p, const std::shared_ptr<ngraph::op::v1::GreaterEqual>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::ge);
}
void CreateLogicalAndOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalAnd>& op) {
static void CreateLogicalAndOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalAnd>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::logic_and);
}
void CreateLogicalOrOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalOr>& op) {
static void CreateLogicalOrOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalOr>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::logic_or);
}
void CreateLogicalXorOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalXor>& op) {
static void CreateLogicalXorOp(Program& p, const std::shared_ptr<ngraph::op::v1::LogicalXor>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::logic_xor);
}
void CreatePowerOp(Program& p, const std::shared_ptr<ngraph::op::v1::Power>& op) {
static void CreatePowerOp(Program& p, const std::shared_ptr<ngraph::op::v1::Power>& op) {
p.ValidateInputs(op, {2});
auto power_node = std::dynamic_pointer_cast<ngraph::op::v0::Constant>(op->get_input_node_shared_ptr(1));
if (power_node) {
@ -166,11 +166,11 @@ void CreatePowerOp(Program& p, const std::shared_ptr<ngraph::op::v1::Power>& op)
CreateElementwiseOp(p, op, cldnn::eltwise_mode::pow);
}
void CreateFloorModOp(Program& p, const std::shared_ptr<ngraph::op::v1::FloorMod>& op) {
static void CreateFloorModOp(Program& p, const std::shared_ptr<ngraph::op::v1::FloorMod>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::floor_mod);
}
void CreateModOp(Program& p, const std::shared_ptr<ngraph::op::v1::Mod>& op) {
static void CreateModOp(Program& p, const std::shared_ptr<ngraph::op::v1::Mod>& op) {
CreateElementwiseOp(p, op, cldnn::eltwise_mode::mod);
}

View File

@ -16,7 +16,7 @@
namespace CLDNNPlugin {
void CreateEmbeddingBagOffsetsSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingBagOffsetsSum>& op) {
static void CreateEmbeddingBagOffsetsSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingBagOffsetsSum>& op) {
p.ValidateInputs(op, {3, 4, 5});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -72,7 +72,7 @@ void CreateEmbeddingBagOffsetsSumOp(Program& p, const std::shared_ptr<ngraph::op
p.AddPrimitiveToProfiler(op);
}
void CreateEmbeddingBagPackedSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingBagPackedSum>& op) {
static void CreateEmbeddingBagPackedSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingBagPackedSum>& op) {
p.ValidateInputs(op, {2, 3});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
@ -113,7 +113,7 @@ void CreateEmbeddingBagPackedSumOp(Program& p, const std::shared_ptr<ngraph::op:
p.AddPrimitiveToProfiler(op);
}
void CreateEmbeddingSegmentsSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingSegmentsSum>& op) {
static void CreateEmbeddingSegmentsSumOp(Program& p, const std::shared_ptr<ngraph::op::v3::EmbeddingSegmentsSum>& op) {
p.ValidateInputs(op, {4, 5, 6});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -22,7 +22,7 @@ static inline std::string PadToString(ngraph::op::PadType pad) {
return "";
}
void CreateExtractImagePatchesOp(Program& p, const std::shared_ptr<ngraph::op::v3::ExtractImagePatches>& op) {
static void CreateExtractImagePatchesOp(Program& p, const std::shared_ptr<ngraph::op::v3::ExtractImagePatches>& op) {
p.ValidateInputs(op, {1});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -11,7 +11,7 @@
namespace CLDNNPlugin {
void CreateFakeQuantizeOp(Program& p, const std::shared_ptr<ngraph::op::v0::FakeQuantize>& op) {
static void CreateFakeQuantizeOp(Program& p, const std::shared_ptr<ngraph::op::v0::FakeQuantize>& op) {
p.ValidateInputs(op, {5});
std::string layerName = layer_type_name_ID(op);
auto inputPrimitives = p.GetInputPrimitiveIDs(op);

View File

@ -12,7 +12,7 @@
namespace CLDNNPlugin {
void CreateGatherTreeOp(Program& p, const std::shared_ptr<ngraph::op::v1::GatherTree>& op) {
static void CreateGatherTreeOp(Program& p, const std::shared_ptr<ngraph::op::v1::GatherTree>& op) {
p.ValidateInputs(op, {4});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);

View File

@ -104,21 +104,21 @@ void CreateGatherOpBase(Program& p, const std::shared_ptr<T>& op, const int64_t
p.AddPrimitiveToProfiler(op);
}
void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v1::Gather>& op) {
static void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v1::Gather>& op) {
p.ValidateInputs(op, {2, 3});
CreateGatherOpBase<ngraph::op::v1::Gather>(p, op);
}
REGISTER_FACTORY_IMPL(v1, Gather);
void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v7::Gather>& op) {
static void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v7::Gather>& op) {
p.ValidateInputs(op, {2, 3, 4});
CreateGatherOpBase<ngraph::op::v7::Gather>(p, op, op->get_batch_dims());
}
REGISTER_FACTORY_IMPL(v7, Gather);
void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v8::Gather>& op) {
static void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v8::Gather>& op) {
p.ValidateInputs(op, {2, 3, 4});
CreateGatherOpBase<ngraph::op::v8::Gather>(p, op, op->get_batch_dims(), true);
}

Some files were not shown because too many files have changed in this diff Show More