diff --git a/.ci/azure/linux_ngraph_onnx.yml b/.ci/azure/linux_ngraph_onnx.yml index c6071fc127f..5521d224630 100644 --- a/.ci/azure/linux_ngraph_onnx.yml +++ b/.ci/azure/linux_ngraph_onnx.yml @@ -4,17 +4,13 @@ jobs: matrix: Release: BUILD_TYPE: 'Release' - PROTOBUF_LITE: 'OFF' + PROTOBUF_LITE: 'ON' TOX_COMMAND: 'tox && tox -e zoo_models' Debug: BUILD_TYPE: 'Debug' - PROTOBUF_LITE: 'OFF' - TOX_COMMAND: 'tox' - Protobuf_lite: - BUILD_TYPE: 'Release' PROTOBUF_LITE: 'ON' - TOX_COMMAND: 'tox && tox -e zoo_models' - maxParallel: 3 + TOX_COMMAND: 'tox' + maxParallel: 2 # About 300% of total time timeoutInMinutes: 90 @@ -56,10 +52,10 @@ jobs: - script: | rm -rf $(WORK_DIR) ; mkdir $(WORK_DIR) - sudo rm -rf $(TMP_DIR) ; sudo mkdir $(TMP_DIR) ; sudo chmod 777 -R $(TMP_DIR) sudo mkdir -p $(MODELS_DIR) sudo apt --assume-yes install nfs-common sudo mount -vvv -t nfs cinfsshare.file.core.windows.net:/cinfsshare/onnxtestdata $(MODELS_DIR) -o vers=4,minorversion=1,sec=sys + mkdir -p $(MODELS_DIR)/models_data displayName: 'Make dirs' - checkout: self @@ -76,15 +72,15 @@ jobs: workingDirectory: $(WORK_DIR) displayName: 'Install dependencies' + - script: ngraph/python/tests/test_onnx/model_zoo_preprocess.sh -d $(MODELS_DIR)/models_data -o -s "$(ONNX_MODEL_ZOO_SHA)" + displayName: 'Update models' + condition: ne(variables['BUILD_TYPE'], 'Debug') + - script: sudo docker build --tag=openvino-onnx-ci-image --file=.ci/openvino-onnx/Dockerfile --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg PROTOBUF_LITE=$(PROTOBUF_LITE) . displayName: 'Docker build $(BUILD_TYPE) protobuf-lite: $(PROTOBUF_LITE)' - - script: ngraph/python/tests/test_onnx/model_zoo_preprocess.sh -d $(TMP_DIR) -o -s "$(ONNX_MODEL_ZOO_SHA)" - displayName: 'Get models' - condition: ne(variables['BUILD_TYPE'], 'Debug') - - script: sudo fallocate -l 64G /swapfile ; sudo mkswap /swapfile ; sudo swapon /swapfile ; df ; free -h displayName: 'Create swap' - - script: sudo docker run --name openvino-onnx-ci-container --volume $(TMP_DIR)/model_zoo/onnx_model_zoo_$(ONNX_MODEL_ZOO_SHA):/root/.onnx/model_zoo/onnx_model_zoo --volume $(MODELS_DIR)/msft:/root/.onnx/model_zoo/MSFT openvino-onnx-ci-image /bin/bash -c "$(TOX_COMMAND)" + - script: sudo docker run --name openvino-onnx-ci-container --volume $(MODELS_DIR)/models_data/model_zoo/onnx_model_zoo_$(ONNX_MODEL_ZOO_SHA):/root/.onnx/model_zoo/onnx_model_zoo --volume $(MODELS_DIR)/msft:/root/.onnx/model_zoo/MSFT openvino-onnx-ci-image /bin/bash -c "$(TOX_COMMAND)" displayName: 'Docker run $(BUILD_TYPE) protobuf-lite: $(PROTOBUF_LITE)' diff --git a/.ci/azure/windows.yml b/.ci/azure/windows.yml index e5ec0486f9b..3d0936c5411 100644 --- a/.ci/azure/windows.yml +++ b/.ci/azure/windows.yml @@ -16,7 +16,7 @@ jobs: timeoutInMinutes: 120 pool: - name: WIN_VMSS_VENV_F8S_WU2 + name: WIN_VMSS_VENV_F16S_WU2 variables: system.debug: true @@ -34,8 +34,6 @@ jobs: INSTALL_DIR: $(WORK_DIR)\install_pkg INSTALL_TEST_DIR: $(INSTALL_DIR)\tests SETUPVARS: $(INSTALL_DIR)\bin\setupvars.bat - IB_DIR: C:\Program Files (x86)\IncrediBuild - IB_TESTCONSOLE: $(IB_DIR)\IBTestConsole.exe steps: - script: | @@ -59,12 +57,6 @@ jobs: rd /Q /S $(BUILD_SAMPLES_DIR) & mkdir $(BUILD_SAMPLES_DIR) displayName: 'Make dir' - - script: | - certutil -urlcache -split -f https://openvinoweb.z5.web.core.windows.net/incredibuild/install_ib_console.bat install_ib_console.bat - call install_ib_console.bat - workingDirectory: $(WORK_DIR) - displayName: 'Install IncrediBuild' - - checkout: self clean: true lfs: false @@ -109,9 +101,7 @@ jobs: - script: dir $(REPO_DIR)\inference-engine\temp\ /s displayName: 'List temp SDKs' - - script: | - set PATH=$(WORK_DIR)\ninja-win;%PATH% - call "$(MSVS_VARS_PATH)" && "C:\Program Files (x86)\IncrediBuild\BuildConsole.exe" /COMMAND="ninja" + - script: call "$(MSVS_VARS_PATH)" && $(WORK_DIR)\ninja-win\ninja workingDirectory: $(BUILD_DIR) displayName: 'Build Win' @@ -153,10 +143,8 @@ jobs: displayName: 'PaddlePaddle 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 - displayName: 'IE UT old - IB' + - script: call $(SETUPVARS) && $(INSTALL_TEST_DIR)\InferenceEngineUnitTests.exe --gtest_output=xml:TEST-InferenceEngineUnitTests.xml + displayName: 'IE UT old' continueOnError: false - script: call $(SETUPVARS) && $(INSTALL_TEST_DIR)\ieUnitTests --gtest_output=xml:TEST-ieUnitTests.xml @@ -187,11 +175,8 @@ jobs: displayName: 'TEMPLATE FuncTests' continueOnError: false - # call $(SETUPVARS) && $(INSTALL_TEST_DIR)\cpuFuncTests.exe --gtest_filter=*smoke* --gtest_output=xml:TEST-cpuFuncTests.xml - - script: | - set PATH=$(IB_DIR);%PATH% - call $(SETUPVARS) && "$(IB_TESTCONSOLE)" $(INSTALL_TEST_DIR)\cpuFuncTests.exe --gtest_filter=*smoke*:-*CompareWithRefs/base_size=16_pre_nms_topn=100_post_nms_topn=100_nms_thresh=0.7_feat_stride=1_min_size=1_ratio*:*smoke_GRUSequenceCommonZeroClip/GRUSequenceTest.CompareWithRefs/mode=CONVERT_TO_TI_MAX_SEQ_LEN_CONST_seq_lengths* --gtest_output=xml:TEST-cpuFuncTests-IB.xml /testlevel=24 - displayName: 'CPU FuncTests - IB' + - script: $(SETUPVARS) && $(INSTALL_TEST_DIR)\cpuFuncTests.exe --gtest_filter=*smoke* --gtest_output=xml:TEST-cpuFuncTests.xml + displayName: 'CPU FuncTests' continueOnError: false - script: | @@ -213,8 +198,3 @@ jobs: buildPlatform: 'x64' # Optional buildConfiguration: 'Windows' # Optional #publishRunAttachments: true # Optional - - - script: echo Stop IncrediBuild_Agent && net stop IncrediBuild_Agent - displayName: Stop IncrediBuild - continueOnError: true - enabled: false diff --git a/.ci/azure/windows_conditional_compilation.yml b/.ci/azure/windows_conditional_compilation.yml index 719e02d7574..9024ede46f6 100644 --- a/.ci/azure/windows_conditional_compilation.yml +++ b/.ci/azure/windows_conditional_compilation.yml @@ -1,7 +1,7 @@ jobs: - job: WinCC # About 150% of total time - timeoutInMinutes: 120 + timeoutInMinutes: 60 pool: name: WIN_VMSS_VENV_F8S_WU2 @@ -10,26 +10,22 @@ jobs: system.debug: true VSTS_HTTP_RETRY: 5 VSTS_HTTP_TIMEOUT: 200 - WORKERS_NUMBER: 8 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: D:\build - BIN_DIR: $(REPO_DIR)\bin\intel64 MSVS_VARS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat MSVC_COMPILER_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.24.28314\bin\Hostx64\x64\cl.exe INSTALL_DIR: $(WORK_DIR)\install_pkg SETUPVARS: $(INSTALL_DIR)\bin\setupvars.bat - IB_DIR: C:\Program Files (x86)\IncrediBuild - IB_TESTCONSOLE: $(IB_DIR)\IBTestConsole.exe - TEST_ENV_PATH: $(REPO_DIR)\inference-engine\temp\tbb\bin;$(REPO_DIR)\inference-engine\temp\opencv_4.5.2\opencv\bin;$(IB_DIR);%PATH% steps: - script: | powershell -command "Invoke-RestMethod -Headers @{\"Metadata\"=\"true\"} -Method GET -Uri http://169.254.169.254/metadata/instance/compute?api-version=2019-06-01 | format-custom" where python3 + python3 --version where python python --version where java @@ -46,12 +42,6 @@ jobs: rd /Q /S $(BUILD_DIR) & mkdir $(BUILD_DIR) displayName: 'Make dir' - - script: | - certutil -urlcache -split -f https://openvinoweb.z5.web.core.windows.net/incredibuild/install_ib_console.bat install_ib_console.bat - call install_ib_console.bat - workingDirectory: $(WORK_DIR) - displayName: 'Install IncrediBuild' - - checkout: self clean: true lfs: false @@ -59,7 +49,8 @@ jobs: path: openvino - script: | - certutil -urlcache -split -f https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-win.zip ninja-win.zip + rem Speed up build + certutil -urlcache -split -f https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip ninja-win.zip powershell -command "Expand-Archive -Force ninja-win.zip" workingDirectory: $(WORK_DIR) displayName: 'Install dependencies' @@ -70,20 +61,19 @@ jobs: workingDirectory: $(BUILD_DIR) displayName: 'CMake' - - script: | - set PATH=$(WORK_DIR)\ninja-win;%PATH% - call "$(MSVS_VARS_PATH)" && "C:\Program Files (x86)\IncrediBuild\BuildConsole.exe" /COMMAND="ninja" + - script: dir $(REPO_DIR)\inference-engine\temp\ /s + displayName: 'List temp SDKs' + + - script: call "$(MSVS_VARS_PATH)" && $(WORK_DIR)\ninja-win\ninja workingDirectory: $(BUILD_DIR) - displayName: 'Build Win' + displayName: 'Build Win CC' - script: dir $(REPO_DIR)\bin\ /s - displayName: 'List files' + displayName: 'List bin files' - script: cmake -DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) -P cmake_install.cmake workingDirectory: $(BUILD_DIR) displayName: 'Install' - - script: echo Stop IncrediBuild_Agent && net stop IncrediBuild_Agent - displayName: Stop IncrediBuild - continueOnError: true - enabled: false + - script: dir $(INSTALL_DIR) /s + displayName: 'List install files' diff --git a/.ci/openvino-onnx/Dockerfile b/.ci/openvino-onnx/Dockerfile index ca2cbd8afbe..314ab2c1037 100644 --- a/.ci/openvino-onnx/Dockerfile +++ b/.ci/openvino-onnx/Dockerfile @@ -4,7 +4,7 @@ LABEL version=2021.03.30.1 # Build configuration arguments ARG BUILD_TYPE=Release -ARG PROTOBUF_LITE=OFF +ARG PROTOBUF_LITE=ON ARG http_proxy ARG https_proxy diff --git a/CODEOWNERS b/CODEOWNERS index 2894fac8ff3..165bc745563 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -75,6 +75,6 @@ azure-pipelines.yml @openvinotoolkit/openvino-admins *.md @openvinotoolkit/openvino-docs-maintainers # Control 3d party dependencies -*requirements* @openvino-configuration-mgmt -*setup.py @openvino-configuration-mgmt +**/*requirements*.* @openvino-configuration-mgmt +**/setup.py @openvino-configuration-mgmt /scripts/install_dependencies/ @openvino-configuration-mgmt diff --git a/cmake/developer_package/ncc_naming_style/openvino.style b/cmake/developer_package/ncc_naming_style/openvino.style index 1dc53167129..6832847ae3a 100644 --- a/cmake/developer_package/ncc_naming_style/openvino.style +++ b/cmake/developer_package/ncc_naming_style/openvino.style @@ -18,9 +18,11 @@ FunctionTemplate: '^(operator.+|\w+)$' TypeAliasName: '^\w+$' VariableReference: '^\w+$' +EnumName: '^[A-Z][\w]+$' +# excepts element_type +# TODO: Fix interpolate +EnumConstantName: '^([A-Z\d_]+|undefined|dynamic|boolean|bf16|f16|f32|f64|i4|i8|i16|i32|i64|u1|u4|u8|u16|u32|u64|asymmetric|align_corners|round_prefer_floor|round_prefer_ceil|floor|ceil|simple|nearest|linear|linear_onnx|cubic|area|scales|sizes|half_pixel|tf_half_pixel_for_nn|pytorch_half_pixel|asymetric)$' # TODO: align -EnumConstantName: '^.*$' -EnumName: '^.*$' UsingDeclaration: '^.*$' TypedefName: '^.*$' diff --git a/docs/IE_DG/Paddle_Support.md b/docs/IE_DG/Paddle_Support.md new file mode 100644 index 00000000000..03dddc6cdcc --- /dev/null +++ b/docs/IE_DG/Paddle_Support.md @@ -0,0 +1,34 @@ +# Paddle Support in the 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. + +## 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: + +```cpp +InferenceEngine::Core core; +auto network = core.ReadNetwork("model.xml"); +``` + +## Read Paddle Models from Paddle Format (Paddle `inference model` model type) + +**Example:** + +```cpp +InferenceEngine::Core core; +auto network = core.ReadNetwork("model.pdmodel"); +``` + +**Reshape feature:** + +OpenVINO™ does not provide a mechanism to specify pre-processing, such as mean values subtraction and 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 + +* 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). +* 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. diff --git a/docs/IE_DG/supported_plugins/AUTO.md b/docs/IE_DG/supported_plugins/AUTO.md new file mode 100644 index 00000000000..55a5e01f212 --- /dev/null +++ b/docs/IE_DG/supported_plugins/AUTO.md @@ -0,0 +1,128 @@ +# Auto-Device Plugin {#openvino_docs_IE_DG_supported_plugins_AUTO} + +## Auto-Device Plugin Execution + +Auto-device is a new special "virtual" or "proxy" device in the OpenVINO™ toolkit. + +Use "AUTO" as the device name to delegate selection of an actual accelerator to OpenVINO. +With the 2021.4 release, Auto-device internally recognizes and selects devices from CPU, +integrated GPU and discrete Intel GPUs (when available) depending on the device capabilities and the characteristic of CNN models, +for example, precisions. Then Auto-device assigns inference requests to the selected device. + +From the application point of view, this is just another device that handles all accelerators in full system. + +With the 2021.4 release, Auto-device setup is done in three major steps: +* Step 1: Configure each device as usual (for example, via the conventional SetConfig method) +* Step 2: Load a network to the Auto-device plugin. This is the only change needed in your application +* Step 3: Just like with any other executable network (resulted from LoadNetwork), create as many requests as needed to saturate the devices. +These steps are covered below in details. + + +## Defining and Configuring the Auto-Device Plugin +Following the OpenVINO notions of “devices”, the Auto-device has “AUTO” name. The only configuration option for Auto-device is a limited device list: + +| Parameter name | Parameter values | Default | Description | +| :--- | :--- | :--- |:-----------------------------------------------------------------------------| +| "AUTO_DEVICE_LIST" | comma-separated device names with no spaces| N/A | Device candidate list to be selected | + +You can use the configuration name directly as a string or use IE::KEY_AUTO_DEVICE_LIST from ie_plugin_config.hpp, +which defines the same string. + +There are two ways to use Auto-device: +1. Directly indicate device by “AUTO” or empty string: + +@snippet snippets/AUTO0.cpp part0 + +2. Use Auto-device configuration to limit the device candidates list to be selected: + +@snippet snippets/AUTO1.cpp part1 + +Auto-device supports query device optimization capabilities in metric; + +| Parameter name | Parameter values | +| :--- | :--- | +| "OPTIMIZATION_CAPABILITIES" | Auto-Device capabilities | + +## Enumerating Available Devices and Auto-Device Selecting Logic + +### Enumerating Available Devices + +Inference Engine now features a dedicated API to enumerate devices and their capabilities. +See [Hello Query Device C++ Sample](../../../inference-engine/samples/hello_query_device/README.md). +This is the example output from the sample (truncated to the devices' names only): + +```sh +./hello_query_device +Available devices: + Device: CPU +... + Device: GPU.0 +... + Device: GPU.1 +``` + +### Default Auto-Device selecting logic + +With the 2021.4 release, Auto-Device selects the most suitable device with following default logic: +1. Check if dGPU, iGPU and CPU device are available +2. Get the precision of the input model, such as FP32 +3. According to the priority of dGPU, iGPU and CPU (in this order), if the device supports the precision of input network, select it as the most suitable device + +For example, CPU, dGPU and iGPU can support below precision and optimization capabilities: + +| Device | OPTIMIZATION_CAPABILITIES | +| :--- | :--- | +| CPU | WINOGRAD FP32 FP16 INT8 BIN | +| dGPU | FP32 BIN BATCHED_BLOB FP16 INT8 | +| iGPU | FP32 BIN BATCHED_BLOB FP16 INT8 | + +When application use Auto-device to run FP16 IR on system with CPU, dGPU and iGPU, Auto-device will offload this workload to dGPU. + +When application use Auto-device to run FP16 IR on system with CPU and iGPU, Auto-device will offload this workload to iGPU. + +When application use Auto-device to run WINOGRAD-enabled IR on system with CPU, dGPU and iGPU, Auto-device will offload this workload to CPU. + +In any case, when loading the network to dGPU or iGPU fails, the networks falls back to CPU as the last choice. + +### Limit Auto Target Devices Logic + +According to the Auto-device selection logic from the previous section, +the most suitable device from available devices to load mode as follows: + +@snippet snippets/AUTO2.cpp part2 + +Another way to load mode to device from limited choice of devices is with Auto-device: + +@snippet snippets/AUTO3.cpp part3 + +## Configuring the Individual Devices and Creating the Auto-Device on Top + +As described in the first section, configure each individual device as usual and then just create the "AUTO" device on top: + +@snippet snippets/AUTO4.cpp part4 + +Alternatively, you can combine all the individual device settings into single config and load it, +allowing the Auto-device plugin to parse and apply it to the right devices. See the code example here: + +@snippet snippets/AUTO5.cpp part5 + +## Using the Auto-Device with OpenVINO Samples and Benchmark App + +Note that every OpenVINO sample that supports "-d" (which stands for "device") command-line option transparently accepts the Auto-device. +The Benchmark Application is the best example of the optimal usage of the Auto-device. +You do not need to set the number of requests and CPU threads, as the application provides optimal out-of-the-box performance. +Below is the example command-line to evaluate AUTO performance with that: + +```sh +./benchmark_app –d AUTO –m -i -niter 1000 +``` +You can also use the auto-device with limit device choice: + +```sh +./benchmark_app –d AUTO:CPU,GPU –m -i -niter 1000 +``` +Note that the default CPU stream is 1 if using “-d AUTO”. + +Note that you can use the FP16 IR to work with auto-device. +Also note that no demos are (yet) fully optimized for the auto-device, by means of selecting the most suitable device, +using the GPU streams/throttling, and so on. diff --git a/docs/IE_DG/supported_plugins/MYRIAD.md b/docs/IE_DG/supported_plugins/MYRIAD.md index 8983f20a925..6425cc5ed4b 100644 --- a/docs/IE_DG/supported_plugins/MYRIAD.md +++ b/docs/IE_DG/supported_plugins/MYRIAD.md @@ -66,10 +66,8 @@ In addition to common parameters, the MYRIAD plugin accepts the following option | Parameter Name | Parameter Values | Default | Description | | :--- | :--- | :--- | :--- | -| `KEY_VPU_MYRIAD_PLATFORM` | empty string/`VPU_MYRIAD_2450`/`VPU_MYRIAD_2480` | empty string | If set, the plugin will use a device with specific platform to allocate a network. | | `KEY_VPU_MYRIAD_PROTOCOL` | empty string/`VPU_MYRIAD_USB`/`VPU_MYRIAD_PCIE` | empty string | If set, the plugin will use a device with specific protocol to allocate a network. | | `KEY_VPU_MYRIAD_FORCE_RESET` | `YES`/`NO` | `NO` | Enables force reset of all booted devices when new ExecutableNetwork is created.
This is a plugin scope option and must be used with the plugin's SetConfig method only.
See Device allocation section for details. | -| `KEY_VPU_PLATFORM` | empty string/`VPU_2450`/`VPU_2480` | empty string | **Deprecated** Use `KEY_VPU_MYRIAD_PLATFORM` instead.
If set, the plugin will use a device with specific platform to allocate a network. | | `KEY_VPU_FORCE_RESET` | `YES`/`NO` | `NO` | **Deprecated** Use `KEY_VPU_MYRIAD_FORCE_RESET` instead.
Enables force reset of all booted devices when new ExecutableNetwork is created.
This is a plugin scope option and must be used with the plugin's SetConfig method only.
See Device allocation section for details. | ## Device allocation   diff --git a/docs/IE_DG/supported_plugins/Supported_Devices.md b/docs/IE_DG/supported_plugins/Supported_Devices.md index e1140ae4b74..5c003fc86bb 100644 --- a/docs/IE_DG/supported_plugins/Supported_Devices.md +++ b/docs/IE_DG/supported_plugins/Supported_Devices.md @@ -13,7 +13,8 @@ The Inference Engine provides unique capabilities to infer deep learning models |[CPU plugin](CPU.md) |Intel® Xeon® with Intel® Advanced Vector Extensions 2 (Intel® AVX2), Intel® Advanced Vector Extensions 512 (Intel® AVX-512), and AVX512_BF16, Intel® Core™ Processors with Intel® AVX2, Intel® Atom® Processors with Intel® Streaming SIMD Extensions (Intel® SSE) | |[VPU plugins](VPU.md) (available in the Intel® Distribution of OpenVINO™ toolkit) |Intel® Neural Compute Stick 2 powered by the Intel® Movidius™ Myriad™ X, Intel® Vision Accelerator Design with Intel® Movidius™ VPUs | |[GNA plugin](GNA.md) (available in the Intel® Distribution of OpenVINO™ toolkit) |Intel® Speech Enabling Developer Kit, Amazon Alexa* Premium Far-Field Developer Kit, Intel® Pentium® Silver J5005 Processor, Intel® Pentium® Silver N5000 Processor, Intel® Celeron® J4005 Processor, Intel® Celeron® J4105 Processor, Intel® Celeron® Processor N4100, Intel® Celeron® Processor N4000, Intel® Core™ i3-8121U Processor, Intel® Core™ i7-1065G7 Processor, Intel® Core™ i7-1060G7 Processor, Intel® Core™ i5-1035G4 Processor, Intel® Core™ i5-1035G7 Processor, Intel® Core™ i5-1035G1 Processor, Intel® Core™ i5-1030G7 Processor, Intel® Core™ i5-1030G4 Processor, Intel® Core™ i3-1005G1 Processor, Intel® Core™ i3-1000G1 Processor, Intel® Core™ i3-1000G4 Processor| -|[Multi-Device plugin](MULTI.md) |Multi-Device plugin enables simultaneous inference of the same network on several Intel® devices in parallel | +|[Multi-Device plugin](MULTI.md) |Multi-Device plugin enables simultaneous inference of the same network on several Intel® devices in parallel | +|[Auto-Device plugin](AUTO.md) |Auto-Device plugin enables selecting Intel® device for inference automatically | |[Heterogeneous plugin](HETERO.md) |Heterogeneous plugin enables automatic inference splitting between several Intel® devices (for example if a device doesn't [support certain layers](#supported-layers)). | Devices similar to the ones we have used for benchmarking can be accessed using [Intel® DevCloud for the Edge](https://devcloud.intel.com/edge/), a remote development environment with access to Intel® hardware and the latest versions of the Intel® Distribution of the OpenVINO™ Toolkit. [Learn more](https://devcloud.intel.com/edge/get_started/devcloud/) or [Register here](https://inteliot.force.com/DevcloudForEdge/s/). diff --git a/docs/MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md b/docs/MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md new file mode 100644 index 00000000000..65f5c8fbbab --- /dev/null +++ b/docs/MO_DG/prepare_model/convert_model/Convert_Model_From_Paddle.md @@ -0,0 +1,62 @@ +# 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\*: + +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. +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. + +## Supported Topologies + +| Model Name| Model Type| Description| +| ------------- | ------------ | ------------- | +|ppocr-det| optical character recognition| Models are exported from [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1/). Refer to [READ.md](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1/#pp-ocr-20-series-model-listupdate-on-dec-15).| +|ppocr-rec| optical character recognition| Models are exported from [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1/). Refer to [READ.md](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1/#pp-ocr-20-series-model-listupdate-on-dec-15).| +|ResNet-50| classification| Models are exported from [PaddleClas](https://github.com/PaddlePaddle/PaddleClas/tree/release/2.1/). Refer to [getting_started_en.md](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.1/docs/en/tutorials/getting_started_en.md#4-use-the-inference-model-to-predict)| +|MobileNet v2| classification| Models are exported from [PaddleClas](https://github.com/PaddlePaddle/PaddleClas/tree/release/2.1/). Refer to [getting_started_en.md](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.1/docs/en/tutorials/getting_started_en.md#4-use-the-inference-model-to-predict)| +|MobileNet v3| classification| Models are exported from [PaddleClas](https://github.com/PaddlePaddle/PaddleClas/tree/release/2.1/). Refer to [getting_started_en.md](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.1/docs/en/tutorials/getting_started_en.md#4-use-the-inference-model-to-predict)| +|BiSeNet v2| semantic segmentation| Models are exported from [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.1). Refer to [model_export.md](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.1/docs/model_export.md#)| +|DeepLab v3 plus| semantic segmentation| Models are exported from [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.1). Refer to [model_export.md](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.1/docs/model_export.md#)| +|Faster-SCNN| semantic segmentation| Models are exported from [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.1). Refer to [model_export.md](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.1/docs/model_export.md#)| +|OCRNET| semantic segmentation| Models are exported from [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.1). Refer to [model_export.md](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.1/docs/model_export.md#)| +|Yolo v3| detection| Models are exported from [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.1). Refer to [EXPORT_MODEL.md](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md#).| +|ppyolo| detection| Models are exported from [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.1). Refer to [EXPORT_MODEL.md](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md#).| + +> **NOTE:** The verified models are exported from the repository of branch release/2.1. + +## Convert a Paddle* Model + +To convert a Paddle\* model: + +1. Go to the `$INTEL_OPENVINO_DIR/deployment_tools/model_optimizer` directory. +2. Use the `mo.py` script to simply convert a model, specifying the framework, the path to the input model `.pdmodel` file and the path to an output directory with write permissions: +```sh +python3 mo.py --input_model .pdmodel --output_dir --framework=paddle +``` + +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. + +### 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 --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 +``` + +## Supported Paddle\* Layers +Refer to [Supported Framework Layers](../Supported_Frameworks_Layers.md) for the list of supported standard layers. + +## 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 diff --git a/docs/MO_DG/prepare_model/convert_model/Converting_Model.md b/docs/MO_DG/prepare_model/convert_model/Converting_Model.md index ed6451a7632..26ce1289b8c 100644 --- a/docs/MO_DG/prepare_model/convert_model/Converting_Model.md +++ b/docs/MO_DG/prepare_model/convert_model/Converting_Model.md @@ -16,7 +16,7 @@ The mo.py script is the universal entry point that can deduce the f * `.onnx` - ONNX\* models * `.nnet` - Kaldi\* models. -If the model files do not have standard extensions, you can use the ``--framework {tf,caffe,kaldi,onnx,mxnet}`` option to specify the framework type explicitly. +If the model files do not have standard extensions, you can use the ``--framework {tf,caffe,kaldi,onnx,mxnet,paddle}`` option to specify the framework type explicitly. For example, the following commands are equivalent: ```sh @@ -33,6 +33,7 @@ Framework-specific parameters for: * [MXNet](Convert_Model_From_MxNet.md), * [ONNX](Convert_Model_From_ONNX.md), * [Kaldi](Convert_Model_From_Kaldi.md). +* [Paddle](Convert_Model_From_Paddle.md). ## See Also diff --git a/docs/doxygen/ie_docs.xml b/docs/doxygen/ie_docs.xml index f5ef147751f..ee07308a19a 100644 --- a/docs/doxygen/ie_docs.xml +++ b/docs/doxygen/ie_docs.xml @@ -326,6 +326,7 @@ limitations under the License. + diff --git a/docs/ops/comparison/Greater_1.md b/docs/ops/comparison/Greater_1.md index 928eca83878..a1fe52e0364 100644 --- a/docs/ops/comparison/Greater_1.md +++ b/docs/ops/comparison/Greater_1.md @@ -4,7 +4,16 @@ **Category**: Comparison binary operation -**Short description**: *Greater* performs element-wise comparison operation with two given tensors applying multi-directional broadcast rules. +**Short description**: *Greater* performs element-wise comparison operation with two given tensors applying broadcast rules specified in the `auto_broadcast` attribute. + +**Detailed description** +Before performing arithmetic operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attribute is not `none`. Broadcasting is performed according to `auto_broadcast` value. + +After broadcasting, *Greater* does the following with the input tensors *a* and *b*: + +\f[ +o_{i} = a_{i} > b_{i} +\f] **Attributes**: @@ -13,39 +22,33 @@ * **Description**: specifies rules used for auto-broadcasting of input tensors. * **Range of values**: * *none* - no auto-broadcasting is allowed, all input shapes should match - * *numpy* - numpy broadcasting rules, aligned with ONNX Broadcasting. Description is available in ONNX docs. + * *numpy* - numpy broadcasting rules, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md), + * *pdpd* - PaddlePaddle-style implicit broadcasting, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md). * **Type**: string * **Default value**: "numpy" * **Required**: *no* **Inputs** -* **1**: A tensor of type *T*. **Required.** -* **2**: A tensor of type *T*. **Required.** +* **1**: A tensor of type *T* and arbitrary shape. **Required.** +* **2**: A tensor of type *T* and arbitrary shape. **Required.** **Outputs** -* **1**: The result of element-wise comparison operation. A tensor of type boolean. +* **1**: The result of element-wise comparison operation applied to the input tensors. A tensor of type *T_BOOL* and shape equal to broadcasted shape of two inputs. **Types** * *T*: arbitrary supported type. - -**Detailed description** -Before performing arithmetic operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value. - -After broadcasting *Greater* does the following with the input tensors *a* and *b*: - -\f[ -o_{i} = a_{i} > b_{i} -\f] +* *T_BOOL*: `boolean`. **Examples** -*Example 1* +*Example 1: no broadcast* ```xml + 256 @@ -65,9 +68,10 @@ o_{i} = a_{i} > b_{i} ``` -*Example 2: broadcast* +*Example 2: numpy broadcast* ```xml + 8 diff --git a/docs/ops/comparison/NotEqual_1.md b/docs/ops/comparison/NotEqual_1.md index 448f4bcb66a..691da41c175 100644 --- a/docs/ops/comparison/NotEqual_1.md +++ b/docs/ops/comparison/NotEqual_1.md @@ -4,7 +4,18 @@ **Category**: Comparison binary operation -**Short description**: *NotEqual* performs element-wise comparison operation with two given tensors applying multi-directional broadcast rules. +**Short description**: *NotEqual* performs element-wise comparison operation with two given tensors applying +multi-directional broadcast rules specified in the `auto_broadcast` attribute. + +**Detailed description** +Before performing comparison operation, input tensors *a* and *b* are broadcasted if their shapes are different. +Broadcasting is performed according to `auto_broadcast` value. + +After broadcasting, *NotEqual* does the following with the input tensors *a* and *b*: + +\f[ +o_{i} = a_{i} != b_{i} +\f] **Attributes**: @@ -13,7 +24,8 @@ * **Description**: specifies rules used for auto-broadcasting of input tensors. * **Range of values**: * *none* - no auto-broadcasting is allowed, all input shapes should match - * *numpy* - numpy broadcasting rules, aligned with ONNX Broadcasting. Description is available in ONNX docs. + * *numpy* - numpy broadcasting rules, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md), + * *pdpd* - PaddlePaddle-style implicit broadcasting, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md). * **Type**: string * **Default value**: "numpy" * **Required**: *no* @@ -31,15 +43,6 @@ * *T*: arbitrary supported type. -**Detailed description** -Before performing arithmetic operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value. - -After broadcasting *NotEqual* does the following with the input tensors *a* and *b*: - -\f[ -o_{i} = a_{i} \neq b_{i} -\f] - **Examples** *Example 1* diff --git a/docs/ops/logical/LogicalXor_1.md b/docs/ops/logical/LogicalXor_1.md index 16072f01183..a6a832308ae 100644 --- a/docs/ops/logical/LogicalXor_1.md +++ b/docs/ops/logical/LogicalXor_1.md @@ -6,33 +6,7 @@ **Short description**: *LogicalXor* performs element-wise logical XOR operation with two given tensors applying multi-directional broadcast rules. -**Attributes**: - -* *auto_broadcast* - - * **Description**: specifies rules used for auto-broadcasting of input tensors. - * **Range of values**: - * *none* - no auto-broadcasting is allowed, all input shapes should match - * *numpy* - numpy broadcasting rules, aligned with ONNX Broadcasting. Description is available in ONNX docs. - * **Type**: string - * **Default value**: "numpy" - * **Required**: *no* - -**Inputs** - -* **1**: A tensor of type *T*. **Required.** -* **2**: A tensor of type *T*. **Required.** - -**Outputs** - -* **1**: The result of element-wise logical XOR operation. A tensor of type *T*. - -**Types** - -* *T*: boolean type. - -**Detailed description** -Before performing logical operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value. +**Detailed description**: Before performing logical operation, input tensors *a* and *b* are broadcasted if their shapes are different and `auto_broadcast` attributes is not `none`. Broadcasting is performed according to `auto_broadcast` value. After broadcasting *LogicalXor* does the following with the input tensors *a* and *b*: @@ -40,9 +14,35 @@ After broadcasting *LogicalXor* does the following with the input tensors *a* an o_{i} = a_{i} \oplus b_{i} \f] +**Attributes**: + +* *auto_broadcast* + + * **Description**: specifies rules used for auto-broadcasting of input tensors. + * **Range of values**: + * *none* - no auto-broadcasting is allowed, all input shapes must match + * *numpy* - numpy broadcasting rules, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md), + * *pdpd* - PaddlePaddle-style implicit broadcasting, description is available in [Broadcast Rules For Elementwise Operations](../broadcast_rules.md). + * **Type**: string + * **Default value**: "numpy" + * **Required**: *no* + +**Inputs** + +* **1**: A tensor of type *T_BOOL* and arbitrary shape. **Required.** +* **2**: A tensor of type *T_BOOL* and arbitrary shape. **Required.** + +**Outputs** + +* **1**: The result of element-wise *logicalXor* operation. A tensor of type *T_BOOL* and the same shape equal to broadcasted shape of two inputs. + +**Types** + +* *T_BOOL*: `boolean`. + **Examples** -*Example 1* +*Example 1: no broadcast* ```xml @@ -65,7 +65,7 @@ o_{i} = a_{i} \oplus b_{i} ``` -*Example 2: broadcast* +*Example 2: numpy broadcast* ```xml diff --git a/docs/ops/pooling/MaxPool_1.md b/docs/ops/pooling/MaxPool_1.md index 182df220b52..9ea1be7380f 100644 --- a/docs/ops/pooling/MaxPool_1.md +++ b/docs/ops/pooling/MaxPool_1.md @@ -163,7 +163,7 @@ strides = [1, 1] kernel = [2, 2] rounding_type = "floor" auto_pad = "same_upper" -output = [[[[5, 5, -6], +output = [[[[5, 5, 3], [8, 9, 9] [8, 9, 9]], [[6, 5, 5], diff --git a/docs/ops/pooling/MaxPool_8.md b/docs/ops/pooling/MaxPool_8.md new file mode 100644 index 00000000000..808b2e616fc --- /dev/null +++ b/docs/ops/pooling/MaxPool_8.md @@ -0,0 +1,360 @@ +## MaxPool {#openvino_docs_ops_pooling_MaxPool_8} + +**Versioned name**: *MaxPool-8* + +**Category**: *Pooling* + +**Short description**: Performs the max pooling operation on input. + +**Detailed description**: Input shape can be either 3D, 4D, or 5D. The max pooling operation is performed with respect to input shape from the third dimension to the last dimension. If paddings are used, during the pooling calculation their values are `-inf`. The max pooling operation involves sliding a filter over each channel of a feature map and downsampling by choosing the largest value within the region covered by the filter. + +**Attributes**: *Pooling* attributes are specified in the `data` node, which is a child of the layer node. + +* *strides* + + * **Description**: *strides* is a distance (in pixels) to slide the window on the feature map over the (z, y, x) axes for 3D poolings and (y, x) axes for 2D poolings. For example, *strides* equal to "4,2,1" means sliding the window 4 pixels at a time over depth dimension, 2 over height dimension, and 1 over width dimension. + * **Range of values**: integer values starting from 0 + * **Type**: int[] + * **Required**: *yes* + +* *dilations* + + * **Description**: *dilations* specify the index of the next pixel to select when pooling. If not present, the dilation defaults to 1, meaning the adjacent pixel is chosen. A value of 2 indicates that one pixel is skipped and every other pixel is considered. Dilations specify one value for each spatial axis of the kernel: `(z, y, x)` for 3D poolings and `(y, x)` for 2D poolings. + * **Range of values**: integer values starting from 0 + * **Type**: int[] + * **Default value**: `[1,1,...]` + * **Required**: *no* + +* *pads_begin* + + * **Description**: *pads_begin* is a number of pixels to add to the beginning along each axis. For example, *pads_begin* equal to "1,2" means adding 1 pixel to the top of the input and 2 to the left of the input. All added padding values are equal to negative infinity. + * **Range of values**: integer values starting from 0 + * **Type**: int[] + * **Required**: *yes* + * **Note**: the attribute is ignored when *auto_pad* attribute is specified. + +* *pads_end* + + * **Description**: *pads_end* is a number of pixels to add to the ending along each axis. For example, *pads_end* equal to "1,2" means adding 1 pixel to the bottom of the input and 2 to the right of the input. All added padding values are equal to negative infinity. + * **Range of values**: integer values starting from 0 + * **Type**: int[] + * **Required**: *yes* + * **Note**: the attribute is ignored when the *auto_pad* attribute is specified. + +* *kernel* + + * **Description**: *kernel* is a size of each filter. For example, *kernel* equal to (2, 3) means that each filter has height equal to 2 and width equal to 3. + * **Range of values**: integer values starting from 1 + * **Type**: int[] + * **Required**: *yes* + +* *rounding_type* + + * **Description**: *rounding_type* is a type of rounding to be used to compute output shape. + * **Range of values**: + * *ceil* + * *floor* + * **Type**: string + * **Default value**: *floor* + * **Required**: *no* + +* *auto_pad* + + * **Description**: *auto_pad* how the padding is calculated. Possible values: + * *explicit*: explicit padding values from `pads_begin` and `pads_end` are used. + * *same_upper (same_lower)* the input is padded to match the output size. In case of odd padding value, an extra padding is added at the end (at the beginning). + * *valid* padding is not used. + * **Type**: string + * **Default value**: *explicit* + * **Required**: *no* + * **Note**: *pads_begin* and *pads_end* attributes are ignored when *auto_pad* is not equal to explicit. + +* *index_element_type* + + * **Description**: the type of output tensor with indices + * **Range of values**: "i64" or "i32" + * **Type**: string + * **Default value**: "i64" + * **Required**: *No* + +* *axis* + + * **Description**: indicator of the first dimension in the input shape that should be used to calculate the upper bound of allowed index output values. The upper bound is the product of dimensions starting from the one pointed by the 'axis' attribute until the end of the input shape. + * **Range of values**: integer number. Negative value means counting dimension from the end. The range is `[-R, R - 1]`, where `R` is the rank of the input tensor. + * **Type**: int + * **Default value**: 0 + * **Required**: *No* + +**Inputs**: + +* **1**: 3D, 4D, or 5D input tensor of type T. Required. + +**Outputs**: + * **1**: Input shape can be either `[N, C, H]`, `[N, C, H, W]`, or `[N, C, H, W, D]`. The corresponding output shape is `[N, C, H_out]`, `[N, C, H_out, W_out]` or `[N, C, H_out, W_out, D_out]`. Output tensor has the same data type as the input tensor. + + * **2**: Output tensor of type *T_IND* with indices of values selected by the pooling operation. + Shape of this output matches the first output. The type of this output can be specified using the `index_element_type` attribute. + Values are computed as indices in a tensor flattened to 1D, not considering padding. Examples for a 5D input tensor: + * When `axis == 0`, the values are in the range `[0, N * C * H * W * D)`. + * When `axis == 2`, the values are in the range `[0, H * W * D)`. + + Note: the values of this output can only be calculated correctly if `pads_value` is set to `-infinity`. + + +**Types** + +* *T*: floating point or integer type. + +* *T_IND*: `int64` or `int32`. + + +**Mathematical Formulation** +Output shape calculation based on `auto_pad` and `rounding_type`: + * `auto_pad = explicit` and `rounding_type = floor` + `H_out = floor((H + pads_begin[0] + pads_end[0] - ((kernel[0] - 1) * dilations[0] + 1)) / strides[0] + 1)` + `W_out = floor((W + pads_begin[1] + pads_end[1] - ((kernel[1] - 1) * dilations[1] + 1)) / strides[1] + 1)` + `D_out = floor((D + pads_begin[2] + pads_end[2] - ((kernel[2] - 1) * dilations[2] + 1)) / strides[2] + 1)` + + * `auto_pad = explicit` and `rounding_type = ceil` + `H_out = ceil((H + pads_begin[0] + pads_end[0] - ((kernel[0] - 1) * dilations[0] + 1)) / strides[0] + 1)` + `W_out = ceil((W + pads_begin[1] + pads_end[1] - ((kernel[1] - 1) * dilations[1] + 1)) / strides[1] + 1)` + `D_out = ceil((D + pads_begin[2] + pads_end[2] - ((kernel[2] - 1) * dilations[2] + 1)) / strides[2] + 1)` + + * `auto_pad = valid` + `H_out = ceil((H - ((kernel[0] - 1) * dilations[0] + 1) + 1) / strides[0])` + `W_out = ceil((W - ((kernel[1] - 1) * dilations[1] + 1) + 1) / strides[1])` + `D_out = ceil((D - ((kernel[2] - 1) * dilations[2] + 1) + 1) / strides[2])` + + * `auto_pad = same_upper / same_lower` + `H_out = H` + `W_out = W` + `D_out = D` + + +If `H + pads_begin[i] + pads_end[i] - kernel[i]` is not divisible by `strides[i]` evenly, the result is rounded with respect to the `rounding_type` attribute. + +Example 1 shows how *MaxPool* operates with 4D input using 2D kernel and `auto_pad = explicit`. + +``` +input = [[[[-1, 2, 3], + [4, 5, -6], + [-7, 8, 9]]]] +strides = [1, 1] +pads_begin = [1, 1] +pads_end = [1, 1] +kernel = [2, 2] +rounding_type = "floor" +auto_pad = "explicit" +output0 = [[[[-1, 2, 3, 3], + [4, 5, 5, -6], + [4, 8, 9, 9], + [-7, 8, 9, 9]]]] +output1 = [[[[0, 1, 2, 2], + [3, 4, 4, 5], + [3, 7, 8, 8], + [6, 7, 8, 8]]]] +``` + +Example 2 shows how *MaxPool* operates with 3D input using 1D kernel and `auto_pad = valid`. + +``` +input = [[[-1, 2, 3, 5, -7, 9, 1]]] +strides = [1] +kernel = [3] +rounding_type = "floor" +auto_pad = "valid" +output0 = [[[3, 5, 5, 9, 9]]] +output1 = [[[2, 3, 3, 5, 5]]] +``` + +Example 3 shows how *MaxPool* operates with 4D input using 2D kernel and `auto_pad = same_lower`. + +``` +input = [[[[-1, 2, 3], + [4, 5, -6], + [-7, 8, 9]]]] +strides = [1, 1] +kernel = [2, 2] +rounding_type = "floor" +auto_pad = "same_lower" +output0 = [[[[-1, 2, 3], + [4, 5, 5] + [4, 8, 9]]]] +output1 = [[[[0, 1, 2], + [3, 4, 4] + [3, 7, 8]]]] +``` + +Example 4 shows how *MaxPool* operates with 4D input using 2D kernel and `auto_pad = same_upper`. + +``` +input = [[[[-1, 2, 3], + [4, 5, -6], + [-7, 8, 9]], + [[2, -1, 5], + [6, -7, 1], + [8, 2, -3]]]] +strides = [1, 1] +kernel = [2, 2] +rounding_type = "floor" +auto_pad = "same_upper" +output0 = [[[[5, 5, 3], + [8, 9, 9] + [8, 9, 9]], + [[6, 5, 5], + [8, 2, 1], + [8, 2, -3]]]] +output1 = [[[[4, 4, 2], + [7, 8, 8] + [7, 8, 8]], + [[12, 11, 11], + [15, 16, 14], + [15, 16, 17]]]] +``` + +Example 5 shows how *MaxPool* operates with 4D input using 2D kernel, `auto_pad = valid` and `rounding_type = ceil`. + +``` +input = [[[[-1, 2, 3], + [4, 5, -6], + [-7, 8, 9]]]] +strides = [2, 2] +kernel = [2, 2] +rounding_type = "ceil" +auto_pad = "valid" +output0 = [[[[5, 3], + [8, 9]]]] +output1 = [[[[4, 2], + [7, 8]]]] +``` + +Example 6 shows how *MaxPool* operates on 4D input using dilated 2D kernel, `auto_pad = explicit` and `rounding_type = floor`. + +``` +input = [[[[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]]] +strides = [1, 1] +kernel = [2, 2] +dilations = [2, 2] +rounding_type = "floor" +auto_pad = "explicit" +pads_begin = [1, 1] +pads_end = [1, 1] +output0 = [[[[5, 6, 5], + [8, 9, 8], + [5, 6, 5]]]] +output1 = [[[[4, 5, 4], + [7, 8, 7], + [4, 5, 4]]]] +``` + +Example 7 shows how *MaxPool* operates on 4D input using 2D kernel, with non-default `axis` value. + +``` +input = [[[[1, 2, 3], + [4, 5, 6], + [7, 8, 9]], + [[10, 11, 12], + [13, 14, 15], + [16, 17, 18]] + ]] +strides = [1, 1] +kernel = [2, 2] +dilations = [1, 1] +rounding_type = "floor" +auto_pad = "explicit" +pads_begin = [0, 0] +pads_end = [0, 0] +axis = 2 +output0 = [[[[5, 6], + [8, 9]], + [[14, 15], + [17, 18]]]] +output1 = [[[[4, 5], + [7, 8]], + [[4, 5], + [7, 8]]]] +``` + +**Examples** + +```xml + + + + + 1 + 3 + 32 + 32 + + + + + 1 + 3 + 32 + 32 + + + 1 + 3 + 32 + 32 + + + + + + + + + 1 + 3 + 32 + 32 + + + + + 1 + 3 + 17 + 17 + + + 1 + 3 + 17 + 17 + + + + + + + + + 1 + 3 + 32 + 32 + + + + + 1 + 3 + 16 + 16 + + + 1 + 3 + 16 + 16 + + + +``` diff --git a/docs/snippets/AUTO0.cpp b/docs/snippets/AUTO0.cpp new file mode 100644 index 00000000000..b546e61a1c6 --- /dev/null +++ b/docs/snippets/AUTO0.cpp @@ -0,0 +1,12 @@ +#include + +int main() { +//! [part0] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + // these 2 lines below are equivalent + InferenceEngine::ExecutableNetwork exec0 = ie.LoadNetwork(network, "AUTO"); + InferenceEngine::ExecutableNetwork exec1 = ie.LoadNetwork(network, ""); +//! [part0] +return 0; +} diff --git a/docs/snippets/AUTO1.cpp b/docs/snippets/AUTO1.cpp new file mode 100644 index 00000000000..22487b5aeb0 --- /dev/null +++ b/docs/snippets/AUTO1.cpp @@ -0,0 +1,15 @@ +#include + +int main() { +//! [part1] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + // "AUTO" plugin is (globally) pre-configured with the explicit option: + ie.SetConfig({{"AUTO_DEVICE_LIST", "CPU,GPU"}}, "AUTO"); + // the below 3 lines are equivalent (the first line leverages the pre-configured AUTO, while second and third explicitly pass the same settings) + InferenceEngine::ExecutableNetwork exec0 = ie.LoadNetwork(network, "AUTO", {}); + InferenceEngine::ExecutableNetwork exec1 = ie.LoadNetwork(network, "AUTO", {{"AUTO_DEVICE_LIST", "CPU,GPU"}}); + InferenceEngine::ExecutableNetwork exec2 = ie.LoadNetwork(network, "AUTO:CPU,GPU"); +//! [part1] +return 0; +} diff --git a/docs/snippets/AUTO2.cpp b/docs/snippets/AUTO2.cpp new file mode 100644 index 00000000000..c70e2923af7 --- /dev/null +++ b/docs/snippets/AUTO2.cpp @@ -0,0 +1,10 @@ +#include + +int main() { +//! [part2] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + InferenceEngine::ExecutableNetwork exeNetwork = ie.LoadNetwork(network, "AUTO"); +//! [part2] +return 0; +} diff --git a/docs/snippets/AUTO3.cpp b/docs/snippets/AUTO3.cpp new file mode 100644 index 00000000000..37e8e350768 --- /dev/null +++ b/docs/snippets/AUTO3.cpp @@ -0,0 +1,10 @@ +#include + +int main() { +//! [part3] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + InferenceEngine::ExecutableNetwork exeNetwork = ie.LoadNetwork(network, "AUTO:CPU,GPU"); +//! [part3] +return 0; +} diff --git a/docs/snippets/AUTO4.cpp b/docs/snippets/AUTO4.cpp new file mode 100644 index 00000000000..ee39e7103d7 --- /dev/null +++ b/docs/snippets/AUTO4.cpp @@ -0,0 +1,19 @@ +#include + +int main() { + const std::map cpu_config = { { InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, InferenceEngine::PluginConfigParams::YES } }; + const std::map gpu_config = { { InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, InferenceEngine::PluginConfigParams::YES } }; + //! [part4] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + // configure the CPU device first + ie.SetConfig(cpu_config, "CPU"); + // configure the GPU device + ie.SetConfig(gpu_config, "GPU"); + // load the network to the auto-device + InferenceEngine::ExecutableNetwork exeNetwork = ie.LoadNetwork(network, "AUTO"); + // new metric allows to query the optimization capabilities + std::vector device_cap = exeNetwork.GetMetric(METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + //! [part4] + return 0; +} diff --git a/docs/snippets/AUTO5.cpp b/docs/snippets/AUTO5.cpp new file mode 100644 index 00000000000..e0678b4e0de --- /dev/null +++ b/docs/snippets/AUTO5.cpp @@ -0,0 +1,15 @@ +#include + +int main() { + std::string device_name = "AUTO:CPU,GPU"; + const std::map< std::string, std::string > full_config = {}; + //! [part5] + InferenceEngine::Core ie; + InferenceEngine::CNNNetwork network = ie.ReadNetwork("sample.xml"); + // 'device_name' can be "AUTO:CPU,GPU" to configure the auto-device to use CPU and GPU + InferenceEngine::ExecutableNetwork exeNetwork = ie.LoadNetwork(network, device_name, full_config); + // new metric allows to query the optimization capabilities + std::vector device_cap = exeNetwork.GetMetric(METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + //! [part5] + return 0; +} diff --git a/docs/template_plugin/tests/functional/op_reference/greater.cpp b/docs/template_plugin/tests/functional/op_reference/greater.cpp new file mode 100644 index 00000000000..c08a46ccda8 --- /dev/null +++ b/docs/template_plugin/tests/functional/op_reference/greater.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include + +#include "comparison.hpp" + +using namespace ngraph; +using namespace InferenceEngine; +using ComparisonTypes = ngraph::helpers::ComparisonTypes; + +namespace reference_tests { +namespace ComparisonOpsRefTestDefinitions { +namespace { +TEST_P(ReferenceComparisonLayerTest, GreaterCompareWithHardcodedRefs) { + Exec(); +} + +template +std::vector generateComparisonParams(const element::Type& type) { + using T = typename element_type_traits::value_type; + std::vector compParams { + // 1D // 2D // 3D // 4D + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{2, 2}, type, std::vector {0, 12, 23, 0}}) + .input2({{2, 2}, type, std::vector {0, 12, 23, 0}}) + .expected({{2, 2}, element::boolean, std::vector {0, 0, 0, 0}}), + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{2, 3}, type, std::vector {0, 6, 45, 1, 21, 21}}) + .input2({{2, 3}, type, std::vector {1, 18, 23, 1, 19, 21}}) + .expected({{2, 3}, element::boolean, std::vector {0, 0, 1, 0, 1, 0}}), + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{1}, type, std::vector {53}}) + .input2({{1}, type, std::vector {53}}) + .expected({{1}, element::boolean, std::vector {0}}), + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{2, 4}, type, std::vector {0, 12, 23, 0, 1, 5, 12, 8}}) + .input2({{2, 4}, type, std::vector {0, 12, 23, 0, 10, 5, 11, 8}}) + .expected({{2, 4}, element::boolean, std::vector {0, 0, 0, 0, 0, 0, 1, 0}}), + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{3, 1, 2}, type, std::vector {2, 1, 4, 1, 3, 1}}) + .input2({{1, 2, 1}, type, std::vector {1, 1}}) + .expected({{3, 2, 2}, element::boolean, std::vector {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}}), + Builder {} + .compType(ComparisonTypes::GREATER) + .input1({{2, 1, 2, 1}, type, std::vector {2, 1, 4, 1}}) + .input2({{1, 2, 1}, type, std::vector {1, 1}}) + .expected({{2, 1, 2, 1}, element::boolean, std::vector {1, 0, 1, 0}})}; + return compParams; +} + +std::vector generateComparisonCombinedParams() { + const std::vector> compTypeParams { + generateComparisonParams(element::f32), + generateComparisonParams(element::f16), + generateComparisonParams(element::i32), + generateComparisonParams(element::i64), + generateComparisonParams(element::u32), + generateComparisonParams(element::u64), + generateComparisonParams(element::boolean)}; + std::vector combinedParams; + + for (const auto& params : compTypeParams) { + combinedParams.insert(combinedParams.end(), params.begin(), params.end()); + } + return combinedParams; +} + +} // namespace +INSTANTIATE_TEST_SUITE_P(smoke_Comparison_With_Hardcoded_Refs, ReferenceComparisonLayerTest, ::testing::ValuesIn(generateComparisonCombinedParams()), + ReferenceComparisonLayerTest::getTestCaseName); +} // namespace ComparisonOpsRefTestDefinitions +} // namespace reference_tests diff --git a/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp b/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp new file mode 100644 index 00000000000..ac30a4c8352 --- /dev/null +++ b/docs/template_plugin/tests/functional/op_reference/logical_xor.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include +#include + +#include "logical.hpp" + +using namespace ngraph; +using namespace InferenceEngine; +using LogicalTypes = ngraph::helpers::LogicalTypes; + +namespace reference_tests { +namespace LogicalOpsRefTestDefinitions { +namespace { + +std::vector generateLogicalParams() { + std::vector logicalParams { + Builder {} + .opType(LogicalTypes::LOGICAL_XOR) + .input1({{2, 2}, element::boolean, std::vector {true, false, true, false}}) + .input2({{2, 2}, element::boolean, std::vector {false, true, true, false}}) + .expected({{2, 2}, element::boolean, std::vector {true, true, false, false}}), + Builder {} + .opType(LogicalTypes::LOGICAL_XOR) + .input1({{2, 1, 2, 1}, element::boolean, std::vector {true, false, true, false}}) + .input2({{1, 1, 2, 1}, element::boolean, std::vector {true, false}}) + .expected({{2, 1, 2, 1}, element::boolean, std::vector {false, false, false, false}}), + Builder {} + .opType(LogicalTypes::LOGICAL_XOR) + .input1({{3, 4}, element::boolean, std::vector {true, true, true, true, true, false, true, false, false, true, true, true}}) + .input2({{3, 4}, element::boolean, std::vector {true, true, true, true, true, true, true, false, false, true, true, false}}) + .expected({{3, 4}, element::boolean, std::vector {false, false, false, false, false, true, false, false, false, false, false, true}})}; + return logicalParams; +} + +INSTANTIATE_TEST_SUITE_P(smoke_LogicalOr_With_Hardcoded_Refs, ReferenceLogicalLayerTest, ::testing::ValuesIn(generateLogicalParams()), + ReferenceLogicalLayerTest::getTestCaseName); + +} // namespace +} // namespace LogicalOpsRefTestDefinitions +} // namespace reference_tests diff --git a/inference-engine/ie_bridges/python/wheel/setup.py b/inference-engine/ie_bridges/python/wheel/setup.py index 5d9ca16238a..6b233ff4284 100644 --- a/inference-engine/ie_bridges/python/wheel/setup.py +++ b/inference-engine/ie_bridges/python/wheel/setup.py @@ -7,10 +7,10 @@ import sys import errno import subprocess # nosec import typing +import multiprocessing from fnmatch import fnmatchcase from pathlib import Path from shutil import copyfile, rmtree -from distutils.command.install import install from distutils.command.build import build from distutils.command.clean import clean from distutils.errors import DistutilsSetupError @@ -27,11 +27,11 @@ PYTHON_VERSION = f'python{sys.version_info.major}.{sys.version_info.minor}' # The following variables can be defined in environment or .env file CMAKE_BUILD_DIR = config('CMAKE_BUILD_DIR', '.') -CORE_LIBS_DIR = config('CORE_LIBS_DIR', '') -PLUGINS_LIBS_DIR = config('PLUGINS_LIBS_DIR', '') -NGRAPH_LIBS_DIR = config('NGRAPH_LIBS_DIR', '') -TBB_LIBS_DIR = config('TBB_LIBS_DIR', '') -PY_PACKAGES_DIR = config('PY_PACKAGES_DIR', '') +CORE_LIBS_DIR = config('CORE_LIBS_DIR', 'deployment_tools/inference_engine/lib/intel64') +PLUGINS_LIBS_DIR = config('PLUGINS_LIBS_DIR', 'deployment_tools/inference_engine/lib/intel64') +NGRAPH_LIBS_DIR = config('NGRAPH_LIBS_DIR', 'deployment_tools/ngraph/lib') +TBB_LIBS_DIR = config('TBB_LIBS_DIR', 'deployment_tools/inference_engine/external/tbb/lib') +PY_PACKAGES_DIR = config('PY_PACKAGES_DIR', f'python/{PYTHON_VERSION}') LIBS_RPATH = '$ORIGIN' if sys.platform == 'linux' else '@loader_path' LIB_INSTALL_CFG = { @@ -118,7 +118,66 @@ class PrebuiltExtension(Extension): class CustomBuild(build): """Custom implementation of build_clib""" + cmake_build_types = ['Release', 'Debug', 'RelWithDebInfo', 'MinSizeRel'] + user_options = [ + ('config=', None, 'Build configuration [{types}].'.format(types='|'.join(cmake_build_types))), + ('jobs=', None, 'Specifies the number of jobs to use with make.'), + ('cmake-args=', None, 'Additional options to be passed to CMake.'), + ] + + def initialize_options(self): + """Set default values for all the options that this command supports.""" + super().initialize_options() + self.build_base = 'build' + self.config = None + self.jobs = None + self.cmake_args = None + + def finalize_options(self): + """Set final values for all the options that this command supports.""" + super().finalize_options() + + if not self.config: + if self.debug: + self.config = 'Debug' + else: + self.announce('Set default value for CMAKE_BUILD_TYPE = Release.', level=4) + self.config = 'Release' + else: + build_types = [item.lower() for item in self.cmake_build_types] + try: + i = build_types.index(str(self.config).lower()) + self.config = self.cmake_build_types[i] + self.debug = True if 'Debug' == self.config else False + except ValueError: + self.announce('Unsupported CMAKE_BUILD_TYPE value: ' + self.config, level=4) + self.announce('Supported values: {types}'.format(types=', '.join(self.cmake_build_types)), level=4) + sys.exit(1) + if self.jobs is None and os.getenv('MAX_JOBS') is not None: + self.jobs = os.getenv('MAX_JOBS') + self.jobs = multiprocessing.cpu_count() if self.jobs is None else int(self.jobs) + def run(self): + global CMAKE_BUILD_DIR + self.jobs = multiprocessing.cpu_count() + plat_specifier = '.{0}-{1}.{2}'.format(self.plat_name, *sys.version_info[:2]) + self.build_temp = os.path.join(self.build_base, 'temp' + plat_specifier, self.config) + + # if setup.py is directly called use CMake to build product + if CMAKE_BUILD_DIR == '.': + openvino_root_dir = os.path.normpath(os.path.join(CMAKE_BUILD_DIR, '../../../../')) + self.announce('Configuring cmake project', level=3) + + self.spawn(['cmake', '-H' + openvino_root_dir, '-B' + self.build_temp, + '-DCMAKE_BUILD_TYPE={type}'.format(type=self.config), + '-DENABLE_PYTHON=ON', + '-DNGRAPH_ONNX_FRONTEND_ENABLE=ON']) + + self.announce('Building binaries', level=3) + self.spawn(['cmake', '--build', self.build_temp, + '--config', self.config, '-j', str(self.jobs)]) + CMAKE_BUILD_DIR = self.build_temp + self.run_command('build_clib') build.run(self) # Copy extra package_data content filtered by find_packages @@ -133,14 +192,6 @@ class CustomBuild(build): copyfile(path, dst / path_rel) -class CustomInstall(install): - """Enable build_clib during the installation""" - - def run(self): - self.run_command('build_clib') - install.run(self) - - class PrepareLibs(build_clib): """Prepare prebuilt libraries""" @@ -369,6 +420,7 @@ if os.path.exists(package_license): packages = find_namespace_packages(get_package_dir(PY_INSTALL_CFG)) package_data: typing.Dict[str, list] = {} + setup( version=config('WHEEL_VERSION', '0.0.0'), author_email=config('WHEEL_AUTHOR_EMAIL', 'openvino_pushbot@intel.com'), @@ -376,14 +428,13 @@ setup( license=config('WHEEL_LICENCE_TYPE', 'OSI Approved :: Apache Software License'), author=config('WHEEL_AUTHOR', 'Intel Corporation'), description=config('WHEEL_DESC', 'Inference Engine Python* API'), - install_requires=get_dependencies(config('WHEEL_REQUIREMENTS', 'requirements.txt')), - long_description=get_description(config('WHEEL_OVERVIEW', 'pypi_overview.md')), + install_requires=get_dependencies(config('WHEEL_REQUIREMENTS', 'meta/openvino.requirements.txt')), + long_description=get_description(config('WHEEL_OVERVIEW', 'meta/pypi_overview.md')), long_description_content_type='text/markdown', download_url=config('WHEEL_DOWNLOAD_URL', 'https://github.com/openvinotoolkit/openvino/tags'), url=config('WHEEL_URL', 'https://docs.openvinotoolkit.org/latest/index.html'), cmdclass={ 'build': CustomBuild, - 'install': CustomInstall, 'build_clib': PrepareLibs, 'build_ext': CopyExt, 'clean': CustomClean, diff --git a/inference-engine/samples/benchmark_app/main.cpp b/inference-engine/samples/benchmark_app/main.cpp index 18aa66e0a45..53aa0f1922d 100644 --- a/inference-engine/samples/benchmark_app/main.cpp +++ b/inference-engine/samples/benchmark_app/main.cpp @@ -212,6 +212,9 @@ int main(int argc, char* argv[]) { bool perf_counts = false; // Update config per device according to command line parameters for (auto& device : devices) { + if (device == "AUTO") { + continue; + } if (!config.count(device)) config[device] = {}; std::map& device_config = config.at(device); diff --git a/inference-engine/samples/speech_sample/main.cpp b/inference-engine/samples/speech_sample/main.cpp index f2366ae7ab9..d236fc84833 100644 --- a/inference-engine/samples/speech_sample/main.cpp +++ b/inference-engine/samples/speech_sample/main.cpp @@ -627,24 +627,21 @@ int main(int argc, char* argv[]) { if (FLAGS_q.compare("user") == 0) { if (!FLAGS_rg.empty()) { - slog::warn - << "Custom scale factor will be ignored - using scale factor from provided imported gna model: " - << FLAGS_rg << slog::endl; - } else { - auto scaleFactorInput = ParseScaleFactors(FLAGS_sf); - if (numInputFiles != scaleFactorInput.size()) { - std::string errMessage( - "Incorrect command line for multiple inputs: " + std::to_string(scaleFactorInput.size()) + - " scale factors provided for " + std::to_string(numInputFiles) + " input files."); - throw std::logic_error(errMessage); - } + slog::warn << "Custom scale factor will be used for imported gna model: " << FLAGS_rg << slog::endl; + } - for (size_t i = 0; i < scaleFactorInput.size(); ++i) { - slog::info << "For input " << i << " using scale factor of " << scaleFactorInput[i] << slog::endl; - std::string scaleFactorConfigKey = - GNA_CONFIG_KEY(SCALE_FACTOR) + std::string("_") + std::to_string(i); - gnaPluginConfig[scaleFactorConfigKey] = scaleFactorInput[i]; - } + auto scaleFactorInput = ParseScaleFactors(FLAGS_sf); + if (numInputFiles != scaleFactorInput.size()) { + std::string errMessage( + "Incorrect command line for multiple inputs: " + std::to_string(scaleFactorInput.size()) + + " scale factors provided for " + std::to_string(numInputFiles) + " input files."); + throw std::logic_error(errMessage); + } + + for (size_t i = 0; i < scaleFactorInput.size(); ++i) { + slog::info << "For input " << i << " using scale factor of " << scaleFactorInput[i] << slog::endl; + std::string scaleFactorConfigKey = GNA_CONFIG_KEY(SCALE_FACTOR) + std::string("_") + std::to_string(i); + gnaPluginConfig[scaleFactorConfigKey] = scaleFactorInput[i]; } } else { // "static" quantization with calculated scale factor diff --git a/inference-engine/src/auto_plugin/auto_exec_network.cpp b/inference-engine/src/auto_plugin/auto_exec_network.cpp deleted file mode 100644 index 6bb3fb9ddfa..00000000000 --- a/inference-engine/src/auto_plugin/auto_exec_network.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include -#include - -#include "ie_metric_helpers.hpp" -#include "auto_exec_network.hpp" -#include "auto_infer_request.hpp" - -namespace AutoPlugin { -using namespace InferenceEngine; - -AutoExecutableNetwork::AutoExecutableNetwork(NetworkFuture cpuFuture, - NetworkFuture acceleratorFuture, - bool enablePerfCount) - : _cpuFuture(std::move(cpuFuture)) - , _acceleratorFuture(std::move(acceleratorFuture)) - , _enablePerfCount(enablePerfCount) { - // both are valid, like AUTO:CPU,GPU - if (_cpuFuture.valid() && _acceleratorFuture.valid()) { - try { - _networkFirstReady = _cpuFuture.get(); - _alreadyActualNetwork = false; - } catch (const std::exception& e) { - printf("Warning: load network to CPU failed: %s\n", e.what()); - _networkActualNeeded = _acceleratorFuture.get(); - _alreadyActualNetwork = true; - } - } else if (_acceleratorFuture.valid()) { // only accelerator is valid, like AUTO:GPU - _networkActualNeeded = _acceleratorFuture.get(); - _alreadyActualNetwork = true; - } else if (_cpuFuture.valid()) { // only CPU is valid, like AUTO:CPU - _networkActualNeeded = _cpuFuture.get(); - _alreadyActualNetwork = true; - } else { - IE_THROW() << "No device task available"; - } -} - -AutoExecutableNetwork::~AutoExecutableNetwork() = default; - -InferenceEngine::IInferRequestInternal::Ptr AutoExecutableNetwork::CreateInferRequestImpl(InputsDataMap networkInputs, - OutputsDataMap networkOutputs) { - InferenceEngine::SoExecutableNetworkInternal network; - SoIInferRequestInternal inferRequest; - if (TryGetActualNetwork(network)) { - inferRequest = {_networkActualNeeded, _networkActualNeeded->CreateInferRequest()}; - } else { - inferRequest = {_networkFirstReady, _networkFirstReady->CreateInferRequest()}; - } - return std::make_shared(_networkInputs, _networkOutputs, inferRequest, - shared_from_this(), _alreadyActualNetwork, - _enablePerfCount); -} - -bool AutoExecutableNetwork::TryGetActualNetwork(InferenceEngine::SoExecutableNetworkInternal& soExecNetwork) { - // try to get actual network - if (_acceleratorFuture.valid() && _acceleratorFuture.wait_for(std::chrono::nanoseconds(0)) == std::future_status::ready) { - soExecNetwork = _acceleratorFuture.get(); - _alreadyActualNetwork = true; - _networkActualNeeded = soExecNetwork; - // reapply config to actual network - // fixme: GPU doesn't support SetConfig and throw exception - try { - _networkActualNeeded->SetConfig(_cacheConfig); - } catch (...) { - } - return true; - } - // if already get actual network - if (_alreadyActualNetwork) { - soExecNetwork = _networkActualNeeded; - return true; - } - return false; -} - -void AutoExecutableNetwork::WaitForActualDevice() const { - if (_alreadyActualNetwork) { - return; - } - - if (_acceleratorFuture.valid()) { - _networkActualNeeded = _acceleratorFuture.get(); - _alreadyActualNetwork = true; - } else { - IE_THROW() << "Export failed due to no valid executable network"; - } -} - -void AutoExecutableNetwork::Export(std::ostream& networkModel) { - //fixme: the Export should work with actual device, so we have to wait!!! - WaitForActualDevice(); - _networkActualNeeded->Export(networkModel); -} - -RemoteContext::Ptr AutoExecutableNetwork::GetContext() const { - // fixme: the GetContext should work with actual device, so we have to wait!!! - WaitForActualDevice(); - return _networkActualNeeded->GetContext(); -} - -InferenceEngine::CNNNetwork AutoExecutableNetwork::GetExecGraphInfo() { - WaitForActualDevice(); - return _networkActualNeeded->GetExecGraphInfo(); -} - -Parameter AutoExecutableNetwork::GetMetric(const std::string &name) const { - // fixme: should we wait actual device? meanwhile it will block inference, how to fix? -// WaitForActualDevice(); - if (_alreadyActualNetwork) { - return _networkActualNeeded->GetMetric(name); - } else { - return _networkFirstReady->GetMetric(name); - } -} - -void AutoExecutableNetwork::SetConfig(const std::map& config) { - //fixme: have to store the config and reapply when the networks swapped - _cacheConfig = config; - if (_alreadyActualNetwork) { - _networkActualNeeded->SetConfig(config); - } else { - _networkFirstReady->SetConfig(config); - } -} - -Parameter AutoExecutableNetwork::GetConfig(const std::string& name) const { - //fixme: carefuly select between FirstLoaded and ActuallyNeeded - return _cacheConfig; -} - -} // namespace AutoPlugin diff --git a/inference-engine/src/auto_plugin/auto_exec_network.hpp b/inference-engine/src/auto_plugin/auto_exec_network.hpp deleted file mode 100644 index f3b11095d94..00000000000 --- a/inference-engine/src/auto_plugin/auto_exec_network.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace AutoPlugin { - -using DeviceName = std::string; -using NetworkFuture = std::future; - -class AutoExecutableNetwork : public InferenceEngine::IExecutableNetworkInternal { -public: - using Ptr = std::shared_ptr; - - explicit AutoExecutableNetwork(NetworkFuture cpuTask, - NetworkFuture acceleratorTask, - bool enablePerfCount); - - void Export(std::ostream& networkModel) override; - InferenceEngine::RemoteContext::Ptr GetContext() const override; - InferenceEngine::CNNNetwork GetExecGraphInfo() override; - InferenceEngine::Parameter GetMetric(const std::string &name) const override; - void SetConfig(const std::map& config) override; - InferenceEngine::Parameter GetConfig(const std::string& name) const override; - InferenceEngine::IInferRequestInternal::Ptr CreateInferRequestImpl(InferenceEngine::InputsDataMap networkInputs, - InferenceEngine::OutputsDataMap networkOutputs) override; - bool TryGetActualNetwork(InferenceEngine::SoExecutableNetworkInternal& soExecNetwork); - - ~AutoExecutableNetwork(); - -private: - void WaitForActualDevice() const; - -private: - InferenceEngine::SoExecutableNetworkInternal _networkFirstReady; - mutable InferenceEngine::SoExecutableNetworkInternal _networkActualNeeded; - NetworkFuture _cpuFuture; - mutable NetworkFuture _acceleratorFuture; - bool _enablePerfCount; - mutable std::atomic _alreadyActualNetwork = {false}; - std::map _cacheConfig; -}; - -} // namespace AutoPlugin diff --git a/inference-engine/src/auto_plugin/auto_infer_request.cpp b/inference-engine/src/auto_plugin/auto_infer_request.cpp deleted file mode 100644 index 1497ee3557b..00000000000 --- a/inference-engine/src/auto_plugin/auto_infer_request.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include "auto_infer_request.hpp" -#include -#include - -namespace AutoPlugin { - using namespace InferenceEngine; - -AutoInferRequest::AutoInferRequest(const InputsDataMap& networkInputs, - const OutputsDataMap& networkOutputs, - const SoIInferRequestInternal& inferRequest, - const InferenceEngine::IExecutableNetworkInternal::Ptr autoExecutableNetwork, - bool alreadyActualNetwork, - bool enablePerfCount) - : IInferRequestInternal(networkInputs, networkOutputs) - , _inferRequest(inferRequest) - , _autoExecutableNetwork(std::dynamic_pointer_cast(autoExecutableNetwork)) - , _alreadyActualNetwork(alreadyActualNetwork) - , _enablePerfCount(enablePerfCount) { - IE_ASSERT(_autoExecutableNetwork != nullptr); - for (const auto &it : _networkInputs) - _inputs[it.first] = _inferRequest->GetBlob(it.first); - for (const auto &it : _networkOutputs) - _outputs[it.first] = _inferRequest->GetBlob(it.first); -} - -std::map AutoInferRequest::GetPerformanceCounts() const { - if (_enablePerfCount) { - try { - return _inferRequest->GetPerformanceCounts(); - } catch (...) { - return {}; - } - } else { - return {}; - } -} - -void AutoInferRequest::InferImpl() { - HotSwapRequests(); //safe to call here (before actual inference started) - SetBlobsToDeviceRequest(); - _inferRequest->Infer(); -} - -void AutoInferRequest::SetBlob(const std::string& name, const InferenceEngine::Blob::Ptr& data) { - IInferRequestInternal::SetBlob(name, data); -} - -Blob::Ptr AutoInferRequest::GetBlob(const std::string& name) { - return IInferRequestInternal::GetBlob(name); -} - -void AutoInferRequest::Cancel() { - _inferRequest->Cancel(); -} - -void AutoInferRequest::StartAsync() { - HotSwapRequests(); //safe to call here (before actual inference started) - SetBlobsToDeviceRequest(); - _inferRequest->StartAsync(); -} - -InferenceEngine::StatusCode AutoInferRequest::Wait(int64_t millis_timeout) { - return _inferRequest->Wait(millis_timeout); -} - -void AutoInferRequest::SetCallback(Callback callback) { - _callback = callback; - _inferRequest->SetCallback(callback); -} - -void AutoInferRequest::HotSwapRequests() { - if (!_alreadyActualNetwork) { - InferenceEngine::SoExecutableNetworkInternal tempSoExecNetwork; - if (_autoExecutableNetwork->TryGetActualNetwork(tempSoExecNetwork)) { - _alreadyActualNetwork = true; - _inferRequest = {tempSoExecNetwork, tempSoExecNetwork->CreateInferRequest()}; - _inferRequest->SetCallback(_callback); - } - } -} - -void AutoInferRequest::SetBlobsToDeviceRequest() { - for (const auto &it : _networkInputs) { - const auto &name = it.first; - // this assumes the request is already in BUSY state - auto blob = GetBlob(name); - if (_inferRequest->GetBlob(name) != blob) - _inferRequest->SetBlob(name, blob); - } - for (const auto &it : _networkOutputs) { - const auto &name = it.first; - // this assumes the request is already in BUSY state - auto blob = GetBlob(name); - if (_inferRequest->GetBlob(name) != blob) - _inferRequest->SetBlob(name, blob); - } - } -} // namespace AutoPlugin diff --git a/inference-engine/src/auto_plugin/auto_infer_request.hpp b/inference-engine/src/auto_plugin/auto_infer_request.hpp deleted file mode 100644 index c0044164b48..00000000000 --- a/inference-engine/src/auto_plugin/auto_infer_request.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "auto_exec_network.hpp" - -namespace AutoPlugin { - -class AutoInferRequest : public InferenceEngine::IInferRequestInternal { -public: - using Ptr = std::shared_ptr; - explicit AutoInferRequest(const InferenceEngine::InputsDataMap& networkInputs, - const InferenceEngine::OutputsDataMap& networkOutputs, - const InferenceEngine::SoIInferRequestInternal& inferRequest, - const InferenceEngine::IExecutableNetworkInternal::Ptr executeNetwork, - bool alreadyActualNetwork, - bool enablePerfCount); - std::map GetPerformanceCounts() const override; - void InferImpl() override; - void SetBlob(const std::string& name, const InferenceEngine::Blob::Ptr& data) override; - InferenceEngine::Blob::Ptr GetBlob(const std::string& name) override; - void Cancel() override; - //async impl - void StartAsync() override; - InferenceEngine::StatusCode Wait(int64_t millis_timeout) override; - void SetCallback(Callback callback) override; - -private: - void HotSwapRequests(); - void SetBlobsToDeviceRequest(); - -private: - InferenceEngine::SoIInferRequestInternal _inferRequest; - AutoPlugin::AutoExecutableNetwork::Ptr _autoExecutableNetwork; - Callback _callback; // need to save the callback for hot-swap of the requests - bool _alreadyActualNetwork{ false }; - bool _enablePerfCount { false }; -}; - -} // namespace AutoPlugin diff --git a/inference-engine/src/auto_plugin/auto_plugin.cpp b/inference-engine/src/auto_plugin/auto_plugin.cpp index 75e80faa2b4..5ad9d46984a 100644 --- a/inference-engine/src/auto_plugin/auto_plugin.cpp +++ b/inference-engine/src/auto_plugin/auto_plugin.cpp @@ -2,397 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - #include "auto_plugin.hpp" -#include "ngraph_ops/convolution_ie.hpp" -#include "ngraph_ops/deconvolution_ie.hpp" namespace AutoPlugin { -namespace { - std::string GetNetworkPrecision(const InferenceEngine::CNNNetwork &network) { - auto nGraphFunc = network.getFunction(); - bool isINTModel = ngraph::op::util::has_op_with_type(nGraphFunc); - if (isINTModel) { - return METRIC_VALUE(INT8); - } - for (auto & node : nGraphFunc->get_ordered_ops()) { - if (std::dynamic_pointer_cast(node) || - std::dynamic_pointer_cast(node) || - std::dynamic_pointer_cast(node) || - std::dynamic_pointer_cast(node) || - std::dynamic_pointer_cast(node) || - std::dynamic_pointer_cast(node)) { - auto layerType = node->input(1).get_element_type().get_type_name(); - if (layerType == "f32") - return METRIC_VALUE(FP32); - if (layerType == "f16") - return METRIC_VALUE(FP16); - } - } - return METRIC_VALUE(FP32); - } -} // namespace - -AutoInferencePlugin::AutoInferencePlugin() { - _pluginName = "AUTO"; -} - -IE::IExecutableNetworkInternal::Ptr AutoInferencePlugin::LoadNetwork(const std::string& fileName, - const ConfigType& config) { - return LoadNetworkImpl(fileName, {}, config); -} - -IE::IExecutableNetworkInternal::Ptr AutoInferencePlugin::LoadExeNetworkImpl(const IE::CNNNetwork& network, - const ConfigType& config) { - if (network.getFunction() == nullptr) { - IE_THROW() << "AUTO device supports just ngraph network representation"; - } - - auto networkPrecision = GetNetworkPrecision(network); - return LoadNetworkImpl({}, network, config, networkPrecision); -} - -std::shared_ptr AutoInferencePlugin::LoadNetworkImpl(const std::string& modelPath, - const InferenceEngine::CNNNetwork& network, - const ConfigType& config, - const std::string& networkPrecision) { - if (GetCore() == nullptr) { - IE_THROW() << "Please, work with AUTO device via InferencEngine::Core object"; - } - - if (modelPath.empty() && network.getFunction() == nullptr) { - IE_THROW() << "AUTO device supports just ngraph network representation"; - } - - auto fullConfig = mergeConfigs(_config, config); - CheckConfig(fullConfig); - auto metaDevices = GetDeviceList(fullConfig); - auto core = GetCore(); // shared_ptr that holds the Core while the lambda below (which captures that by val) works - auto LoadNetworkAsync = - [core, modelPath, network](const std::string& device) - -> IE::SoExecutableNetworkInternal { - IE::SoExecutableNetworkInternal executableNetwork; - if (!modelPath.empty()) { - executableNetwork = core->LoadNetwork(modelPath, device, {}); - } else { - executableNetwork = core->LoadNetwork(network, device, {}); - } - return executableNetwork; - }; - - NetworkFuture cpuFuture; - NetworkFuture acceleratorFuture; - - // start CPU task - const auto CPUIter = std::find_if(metaDevices.begin(), metaDevices.end(), - [=](const std::string& d)->bool{return d.find("CPU") != std::string::npos;}); - if (CPUIter != metaDevices.end()) { - cpuFuture = std::async(std::launch::async, LoadNetworkAsync, *CPUIter); - } - - // start accelerator task, like GPU - const auto accelerator = SelectDevice(metaDevices, networkPrecision); - bool isAccelerator = accelerator.find("CPU") == std::string::npos; - if (isAccelerator) { - acceleratorFuture = std::async(std::launch::async, LoadNetworkAsync, accelerator); - } - - bool enablePerfCount = fullConfig.find(IE::PluginConfigParams::KEY_PERF_COUNT) != fullConfig.end(); - - return std::make_shared(std::move(cpuFuture), std::move(acceleratorFuture), enablePerfCount); -} - -IE::QueryNetworkResult AutoInferencePlugin::QueryNetwork(const IE::CNNNetwork& network, const ConfigType& config) const { - IE::QueryNetworkResult queryResult = {}; - if (GetCore() == nullptr) { - IE_THROW() << "Please, work with AUTO device via InferencEngine::Core object"; - } - - if (network.getFunction() == nullptr) { - IE_THROW() << "AUTO device supports just ngraph network representation"; - } - - auto fullConfig = mergeConfigs(_config, config); - auto metaDevices = GetDeviceList(fullConfig); - std::unordered_set supportedLayers; - for (auto&& value : metaDevices) { - try { - auto deviceQr = GetCore()->QueryNetwork(network, value, {}); - std::unordered_set deviceSupportedLayers; - for (auto &&layerQr : deviceQr.supportedLayersMap) { - deviceSupportedLayers.emplace(layerQr.first); - } - supportedLayers = supportedLayers.empty() - ? deviceSupportedLayers : (deviceSupportedLayers.empty() - ? supportedLayers : IE::details::Intersection( - supportedLayers, deviceSupportedLayers)); - break; - } catch (...) { - } - } - - for (auto&& supportedLayer : supportedLayers) { - queryResult.supportedLayersMap[supportedLayer] = GetName(); - } - return queryResult; -} - -IE::Parameter AutoInferencePlugin::GetConfig(const std::string& name, - const std::map & options) const { - auto it = _config.find(name); - if (it == _config.end()) { - IE_THROW() << "Unsupported config key: " << name; - } else { - return { it->second }; - } -} - -void AutoInferencePlugin::SetConfig(const ConfigType& config) { - for (auto && kvp : config) { - if (kvp.first.find("AUTO_") == 0) { - _config[kvp.first] = kvp.second; - } else if (kvp.first == IE::PluginConfigParams::KEY_PERF_COUNT) { - if (kvp.second == IE::PluginConfigParams::YES || - kvp.second == IE::PluginConfigParams::NO) { - _config[kvp.first] = kvp.second; - } else { - IE_THROW() << "Unsupported config value: " << kvp.second - << " for key: " << kvp.first; - } - } else { - IE_THROW() << "Unsupported config key: " << kvp.first; - } - } -} - -IE::Parameter AutoInferencePlugin::GetMetric(const std::string& name, - const std::map & options) const { - if (name == METRIC_KEY(SUPPORTED_METRICS)) { - std::vector metrics; - metrics.emplace_back(METRIC_KEY(SUPPORTED_METRICS)); - metrics.emplace_back(METRIC_KEY(FULL_DEVICE_NAME)); - metrics.emplace_back(METRIC_KEY(SUPPORTED_CONFIG_KEYS)); - metrics.emplace_back(METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - IE_SET_METRIC_RETURN(SUPPORTED_METRICS, metrics); - } else if (name == METRIC_KEY(FULL_DEVICE_NAME)) { - std::string device_name = {"Inference Engine AUTO device"}; - IE_SET_METRIC_RETURN(FULL_DEVICE_NAME, device_name); - } else if (name == METRIC_KEY(SUPPORTED_CONFIG_KEYS)) { - std::vector configKeys = { - IE::KEY_AUTO_DEVICE_LIST, - IE::PluginConfigParams::KEY_PERF_COUNT - }; - IE_SET_METRIC_RETURN(SUPPORTED_CONFIG_KEYS, configKeys); - } else if (name == METRIC_KEY(OPTIMIZATION_CAPABILITIES)) { - std::vector capabilities = GetOptimizationCapabilities(options); - IE_SET_METRIC_RETURN(OPTIMIZATION_CAPABILITIES, capabilities); - } else { - IE_THROW() << "Unsupported metric key " << name; - } -} - -//////////////////////////////////// private & protected functions /////////////////// -std::vector AutoInferencePlugin::GetDeviceList(const ConfigType& config) const { - std::vector deviceList; - - auto deviceListConfig = config.find(IE::KEY_AUTO_DEVICE_LIST); - if (deviceListConfig == config.end()) { - deviceList = GetCore()->GetAvailableDevices(); - } else { - deviceList = IE::DeviceIDParser::getHeteroDevices(deviceListConfig->second); - } - - if (deviceList.empty()) { - IE_THROW() << "Please, check environment due to no supported devices can be used"; - } - - return deviceList; -} - -std::vector AutoInferencePlugin::GetOptimizationCapabilities(const std::map & options) const { - // FIXME: workaround to get devicelist. - std::unordered_set capabilities; - std::vector queryDeviceLists{"CPU", "GPU"}; - - if (options.find(IE::KEY_AUTO_DEVICE_LIST) != options.end()) { - auto deviceListConfig = options.at(IE::KEY_AUTO_DEVICE_LIST).as(); - queryDeviceLists = IE::DeviceIDParser::getHeteroDevices(deviceListConfig); - } else if (_config.find(IE::KEY_AUTO_DEVICE_LIST) != _config.end()) { - auto deviceListConfig = _config.at(IE::KEY_AUTO_DEVICE_LIST); - queryDeviceLists = IE::DeviceIDParser::getHeteroDevices(deviceListConfig); - } - for (auto &item : queryDeviceLists) { - try { - std::vector device_cap = - GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - for (auto &cap : device_cap) { - capabilities.insert(cap); - } - } catch (...) { - } - } - return {capabilities.begin(), capabilities.end()}; -} - -void AutoInferencePlugin::CheckConfig(const ConfigType& config) { - std::vector supportedConfigKeys = GetMetric(METRIC_KEY(SUPPORTED_CONFIG_KEYS), {}); - for (auto&& kvp : config) { - if (kvp.first.find("AUTO_") == 0) { - continue; - } else if (kvp.first == IE::PluginConfigParams::KEY_PERF_COUNT) { - if (kvp.second == IE::PluginConfigParams::YES || - kvp.second == IE::PluginConfigParams::NO) { - continue; - } else { - IE_THROW() << "Unsupported config value: " << kvp.second - << " for key: " << kvp.first; - } - } else { - IE_THROW() << "Unsupported config key: " << kvp.first; - } - } -} - -DeviceName AutoInferencePlugin::SelectDevice(const std::vector& metaDevices, const std::string& networkPrecision) { - if (metaDevices.empty()) { - IE_THROW(NotFound) << "No available device to select in AUTO plugin"; - } - if (metaDevices.size() == 1) { - return metaDevices.at(0); - } - - std::vector CPU; - std::vector dGPU; - std::vector iGPU; - std::vector MYRIAD; - std::vector VPUX; - - for (auto& item : metaDevices) { - if (item.find("CPU") == 0) { - CPU.push_back(item); - continue; - } - if (item.find("MYRIAD") == 0) { - MYRIAD.push_back(item); - continue; - } - if (item.find("VPUX") == 0) { - VPUX.push_back(item); - continue; - } - if (item.find("GPU") == 0) { - auto gpuFullDeviceName = GetCore()->GetMetric(item, METRIC_KEY(FULL_DEVICE_NAME)).as(); - if (gpuFullDeviceName.find("iGPU") != std::string::npos) { - iGPU.push_back(item); - } else if (gpuFullDeviceName.find("dGPU") != std::string::npos) { - dGPU.push_back(item); - } - continue; - } - } - - if (CPU.empty() && dGPU.empty() && iGPU.empty() && MYRIAD.empty() && VPUX.empty()) { - IE_THROW(NotFound) << "No available device found"; - } - - // Priority of selecting device: dGPU > VPUX > iGPU > MYRIAD > CPU - if (!dGPU.empty()) { - for (auto&& item : dGPU) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!VPUX.empty()) { - for (auto&& item : VPUX) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!iGPU.empty()) { - for (auto&& item : iGPU) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!MYRIAD.empty()) { - for (auto&& item : MYRIAD) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); - if (supportNetwork != capability.end()) { - return item; - } - } - } - - // If network is FP32 but there is no device support FP32, offload FP32 network to device support FP16. - if (networkPrecision == "FP32") { - if (!dGPU.empty()) { - for (auto&& item : dGPU) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!VPUX.empty()) { - for (auto&& item : VPUX) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!iGPU.empty()) { - for (auto&& item : iGPU) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); - if (supportNetwork != capability.end()) { - return item; - } - } - } else if (!MYRIAD.empty()) { - for (auto&& item : MYRIAD) { - std::vector capability = GetCore()->GetMetric(item, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); - auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); - if (supportNetwork != capability.end()) { - return item; - } - } - } - } - - if (CPU.empty()) { - IE_THROW() << "Cannot select any device"; - } - return CPU[0]; -} - -ConfigType AutoInferencePlugin::mergeConfigs(ConfigType config, const ConfigType& local) { - for (auto && kvp : local) { - config[kvp.first] = kvp.second; - } - return config; -} - // define CreatePluginEngine to create plugin instance -static const IE::Version version = {{2, 1}, CI_BUILD_NUMBER, "AutoPlugin"}; +static const InferenceEngine::Version version = {{2, 1}, CI_BUILD_NUMBER, "AutoPlugin"}; IE_DEFINE_PLUGIN_CREATE_FUNCTION(AutoInferencePlugin, version) } // namespace AutoPlugin diff --git a/inference-engine/src/auto_plugin/auto_plugin.hpp b/inference-engine/src/auto_plugin/auto_plugin.hpp index a9c56155246..77e22d1ab03 100644 --- a/inference-engine/src/auto_plugin/auto_plugin.hpp +++ b/inference-engine/src/auto_plugin/auto_plugin.hpp @@ -4,43 +4,14 @@ #pragma once -#include -#include -#include -#include -#include - #include #include -#include - -#include "auto_exec_network.hpp" namespace AutoPlugin { -namespace IE = InferenceEngine; -using ConfigType = std::map; - -class AutoInferencePlugin : public IE::IInferencePlugin { +class AutoInferencePlugin : public InferenceEngine::IInferencePlugin { public: - AutoInferencePlugin(); + AutoInferencePlugin() = default; ~AutoInferencePlugin() = default; - IE::IExecutableNetworkInternal::Ptr LoadExeNetworkImpl(const IE::CNNNetwork& network, const ConfigType& config) override; - IE::IExecutableNetworkInternal::Ptr LoadNetwork(const std::string& fileName, const ConfigType& config) override; - IE::QueryNetworkResult QueryNetwork(const IE::CNNNetwork& network, const ConfigType& config) const override; - IE::Parameter GetMetric(const std::string& name, const std::map& options) const override; - IE::Parameter GetConfig(const std::string& name, const std::map & options) const override; - void SetConfig(const ConfigType& config) override; - -private: - std::shared_ptr LoadNetworkImpl(const std::string& modelPath, - const InferenceEngine::CNNNetwork& network, - const ConfigType &config, - const std::string &networkPrecision = METRIC_VALUE(FP32)); - std::vector GetDeviceList(const ConfigType& config) const; - std::vector GetOptimizationCapabilities(const std::map& options) const; - DeviceName SelectDevice(const std::vector& metaDevices, const std::string& networkPrecision = METRIC_VALUE(FP32)); - void CheckConfig(const ConfigType& config); - static ConfigType mergeConfigs(ConfigType config, const ConfigType& local); }; } // namespace AutoPlugin diff --git a/inference-engine/src/cldnn_engine/cldnn_engine.cpp b/inference-engine/src/cldnn_engine/cldnn_engine.cpp index 206c50c93c8..e84f9d2d9cf 100644 --- a/inference-engine/src/cldnn_engine/cldnn_engine.cpp +++ b/inference-engine/src/cldnn_engine/cldnn_engine.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -362,6 +363,7 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc pass_config->disable(); pass_config->disable(); pass_config->disable(); + pass_config->enable(); if (!config.enable_loop_unrolling) { pass_config->disable(); @@ -388,11 +390,12 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc OV_ITT_SCOPED_TASK(itt::domains::CLDNNPlugin, "clDNNEngine::TransformNetwork::LPT"); using namespace ngraph::pass::low_precision; - ngraph::pass::Manager manager; // 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) { + ngraph::pass::Manager manager; manager.register_pass(precisions_array {{ ngraph::element::f16, ngraph::element::f32 }}); + manager.run_passes(nGraphFunc); } auto supportedPrecisions = std::vector({ diff --git a/inference-engine/src/cldnn_engine/ops/interpolate.cpp b/inference-engine/src/cldnn_engine/ops/interpolate.cpp index b77999289c6..df99e6972ee 100644 --- a/inference-engine/src/cldnn_engine/ops/interpolate.cpp +++ b/inference-engine/src/cldnn_engine/ops/interpolate.cpp @@ -15,15 +15,15 @@ namespace CLDNNPlugin { static cldnn::coordinate_transformation_mode GetCoordinateTransformationMode(ngraph::op::v4::Interpolate::CoordinateTransformMode mode) { switch (mode) { - case ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL: return cldnn::coordinate_transformation_mode::half_pixel; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL: return cldnn::coordinate_transformation_mode::pytorch_half_pixel; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC: return cldnn::coordinate_transformation_mode::asymmetric; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN: return cldnn::coordinate_transformation_mode::tf_half_pixel_for_nn; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS: return cldnn::coordinate_transformation_mode::align_corners; } @@ -32,15 +32,15 @@ static cldnn::coordinate_transformation_mode GetCoordinateTransformationMode(ngr static cldnn::nearest_mode GetNearestMode(ngraph::op::v4::Interpolate::NearestMode mode) { switch (mode) { - case ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor: + case ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR: return cldnn::nearest_mode::round_prefer_floor; - case ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil: + case ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL: return cldnn::nearest_mode::round_prefer_ceil; - case ngraph::op::v4::Interpolate::NearestMode::floor: + case ngraph::op::v4::Interpolate::NearestMode::FLOOR: return cldnn::nearest_mode::floor; - case ngraph::op::v4::Interpolate::NearestMode::ceil: + case ngraph::op::v4::Interpolate::NearestMode::CEIL: return cldnn::nearest_mode::ceil; - case ngraph::op::v4::Interpolate::NearestMode::simple: + case ngraph::op::v4::Interpolate::NearestMode::SIMPLE: return cldnn::nearest_mode::simple; } @@ -49,18 +49,18 @@ static cldnn::nearest_mode GetNearestMode(ngraph::op::v4::Interpolate::NearestMo static cldnn::shape_calculation_mode GetShapeCalculationMode(ngraph::op::v4::Interpolate::ShapeCalcMode mode) { switch (mode) { - case ngraph::op::v4::Interpolate::ShapeCalcMode::sizes: return cldnn::shape_calculation_mode::sizes; - case ngraph::op::v4::Interpolate::ShapeCalcMode::scales: return cldnn::shape_calculation_mode::scales; + case ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES: return cldnn::shape_calculation_mode::sizes; + case ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES: return cldnn::shape_calculation_mode::scales; } IE_THROW() << "Unknown shape calculation mode: " << static_cast(mode); } static cldnn::resample_type GetResampleType(ngraph::op::v4::Interpolate::InterpolateMode mode) { switch (mode) { - case ngraph::op::v4::Interpolate::InterpolateMode::nearest: return cldnn::resample_type::nearest; - case ngraph::op::v4::Interpolate::InterpolateMode::linear: return cldnn::resample_type::caffe_bilinear; - case ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx: return cldnn::resample_type::linear_onnx; - case ngraph::op::v4::Interpolate::InterpolateMode::cubic: return cldnn::resample_type::cubic; + case ngraph::op::v4::Interpolate::InterpolateMode::NEAREST: return cldnn::resample_type::nearest; + case ngraph::op::v4::Interpolate::InterpolateMode::LINEAR: return cldnn::resample_type::caffe_bilinear; + case ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX: return cldnn::resample_type::linear_onnx; + case ngraph::op::v4::Interpolate::InterpolateMode::CUBIC: return cldnn::resample_type::cubic; } IE_THROW() << "Unknown interpolation mode: " << static_cast(mode); } diff --git a/inference-engine/src/gna_plugin/backend/gna_limitations.hpp b/inference-engine/src/gna_plugin/backend/gna_limitations.hpp index 731155df31d..5aa036c1559 100644 --- a/inference-engine/src/gna_plugin/backend/gna_limitations.hpp +++ b/inference-engine/src/gna_plugin/backend/gna_limitations.hpp @@ -7,6 +7,7 @@ #include "dnn_types.h" #include #include +#include namespace GNAPluginNS { namespace GNALimitations { @@ -114,5 +115,10 @@ public: bool AreLayersSupported(InferenceEngine::CNNNetwork& network, std::string& errMessage); +inline size_t GetMinBatchToFitInBuffer(InferenceEngine::DataPtr input) { + auto total_size = InferenceEngine::details::product(std::begin(input->getDims()), std::end(input->getDims())); + return total_size / bufferMaxSize + 1; +} + } // namespace GNALimitations } // namespace GNAPluginNS diff --git a/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp b/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp index cec813aecfa..a986a4b60e2 100644 --- a/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp +++ b/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp @@ -19,6 +19,7 @@ #include "gna_slope_scale.h" #include "runtime/pwl.h" #include "gna_data_types.hpp" +#include "round_float_define.hpp" namespace GNAPluginNS { namespace frontend { @@ -41,8 +42,8 @@ struct ScaleFactorUpdateResult { * @param p2 Second float value * @return Returns true if two float values are equal */ -static bool fp32eq(float p1, float p2) { - return (std::abs(p1 - p2) <= 0.00001f * std::min(std::abs(p1), std::abs(p2))); +static bool fp32eq(float p1, float p2, float accuracy = 0.00001f) { + return (std::abs(p1 - p2) <= accuracy * std::min(std::abs(p1), std::abs(p2))); } /** @@ -73,14 +74,14 @@ static float selectBestOutputScaleFactors(float inScale, std::vector outS auto sd = 0.0; for (size_t j = 0; j < slopes.size(); ++j) { auto s = gna_slope(slopes[j], inScale, outScale); - auto slope = static_cast(s.slope * s.slope_scale); - if (slope < static_cast(std::numeric_limits::min()) && slope > static_cast(std::numeric_limits::max())) { + auto slope = FLOAT_TO_INT16(s.slope * s.slope_scale); + if (slope < std::numeric_limits::min() || slope > std::numeric_limits::max()) { sd += std::numeric_limits::max(); continue; } auto testSlope = static_cast(slope) / s.slope_scale * inScale / outScale; - if (fp32eq(testSlope, slopes[j])) { + if (fp32eq(testSlope, slopes[j], 1.0E-6)) { return outScale; } @@ -1025,7 +1026,7 @@ class ScaleFactorPerLayer { quantDataForConCatInput->_dst_quant.SetScale(newScaleFactor); } else if (restarLayerInfo.isConst() || restarLayerInfo.isMemory()) { - gnalog() << "... warning " << restartedLayer->type << " layer will be requantized\n"; + gnalog() << "... warning " << restartedLayer->type << " layer will be requantized\n"; quantDataForConCatInput->_src_quant.SetScale(sourceQuantParams->_dst_quant.GetScale()); quantDataForConCatInput->_dst_quant.SetScale(sourceQuantParams->_dst_quant.GetScale()); } else { diff --git a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp index 88110701499..01581337aec 100644 --- a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp +++ b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp @@ -683,7 +683,7 @@ void GNAGraphCompiler::PowerPrimitive(InferenceEngine::CNNLayerPtr layer) { auto input = layer->insData[0].lock(); auto outputs = *layer->outData.begin(); - auto reshaped_dims = Get2DReshapedData(input, 8)->getDims(); + auto reshaped_dims = Get2DReshapedData(input, GNALimitations::GetMinBatchToFitInBuffer(input), 8)->getDims(); const uint32_t noOfInputsDivisor = gnaFlags->input_low_precision ? GNALimitations::noOfInputsLowPrecDivisor : GNALimitations::noOfInputsDivisor; uint32_t num_rows_in = reshaped_dims[1]; @@ -908,7 +908,7 @@ void GNAGraphCompiler::CopyPrimitive(InferenceEngine::CNNLayerPtr layer) { auto inputs = layer->insData.begin()->lock(); auto outputs = *layer->outData.begin(); - auto reshaped_dims = Get2DReshapedData(inputs, 8)->getDims(); + auto reshaped_dims = Get2DReshapedData(inputs, GNALimitations::GetMinBatchToFitInBuffer(inputs), 8)->getDims(); uint32_t num_rows_in = reshaped_dims[1]; uint32_t num_columns_in = reshaped_dims[0]; uint32_t num_rows_out = num_rows_in; @@ -1410,7 +1410,8 @@ void GNAGraphCompiler::AffinePrimitive(InferenceEngine::CNNLayerPtr layer, bool noOfInputsDivisor = GNALimitations::noOfInputsLowPrecDivisor; } - auto input_data = HasTo2DReshapeData(layer) ? Get2DReshapedData(inputs, 8) : inputs; + auto input_data = HasTo2DReshapeData(layer) ? + Get2DReshapedData(inputs, GNALimitations::GetMinBatchToFitInBuffer(inputs), 8) : inputs; auto in_dims = input_data->getDims(); auto batch_size = (in_dims.size() == 1) ? 1 : in_dims.front(); uint32_t num_rows_in = InferenceEngine::details::product(in_dims) / batch_size; @@ -2212,8 +2213,8 @@ void GNAGraphCompiler::connectOutput(InferenceEngine::CNNLayerPtr layer, void *p nextMemoryLayer.reserved_size = ALIGN64(memorySize); } else { - IE_ASSERT(nextMemoryLayer.reserved_size >= ALIGN64(num_data_bytes_out)); - gnamem->bind_ptr(ptr, &nextMemoryLayer.gna_ptr, getOffsetForBinding(layer)); + // We may need to extend memory buffer if connected input size is bigger, for example for concat connection + gnamem->bind_ptr(ptr, &nextMemoryLayer.gna_ptr, getOffsetForBinding(layer), ALIGN64(num_data_bytes_out)); } return; } @@ -2498,8 +2499,8 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, memoryLayer.reserved_size = ALIGN64(memorySize); } else { - IE_ASSERT(memoryLayer.reserved_size >= ALIGN64(num_data_bytes_in)); - gnamem->bind_ptr(ptr, &memoryLayer.gna_ptr, offset); + // We may need to extend memory buffer if connected input size is bigger, for example for concat connection + gnamem->bind_ptr(ptr, &memoryLayer.gna_ptr, offset, ALIGN64(num_data_bytes_in)); } return prevLayer; diff --git a/inference-engine/src/gna_plugin/gna_groups.hpp b/inference-engine/src/gna_plugin/gna_groups.hpp index 704588a153d..9c4654e1adc 100644 --- a/inference-engine/src/gna_plugin/gna_groups.hpp +++ b/inference-engine/src/gna_plugin/gna_groups.hpp @@ -15,7 +15,9 @@ namespace GNAPluginNS { * @param input a pointer to data to be reshaped * @param maxZeroDimSize the maximum size of zero dimension */ -inline InferenceEngine::DataPtr Get2DReshapedData(InferenceEngine::DataPtr input, size_t maxZeroDimSize) { +inline InferenceEngine::DataPtr Get2DReshapedData(InferenceEngine::DataPtr input, size_t minZeroDimSize, + size_t maxZeroDimSize) { + IE_ASSERT(minZeroDimSize > 0); auto dims = input->getDims(); uint32_t numRowsIn = InferenceEngine::details::product(begin(dims), end(dims)); uint32_t numColumnsIn = 1; @@ -23,7 +25,7 @@ inline InferenceEngine::DataPtr Get2DReshapedData(InferenceEngine::DataPtr input if (numRowsIn % 8 == 0) { if (dims.size() >= 2 || dims[0] >= maxZeroDimSize) { size_t indexDivide = maxZeroDimSize; - while (indexDivide > 1) { + while (indexDivide > minZeroDimSize) { if ((numRowsIn / 8) % indexDivide == 0) break; --indexDivide; } @@ -55,4 +57,5 @@ inline bool HasTo2DReshapeData(InferenceEngine::CNNLayerPtr layer) { // Don't reshape diagonallayers with bias connection return !GNAPluginNS::LayerInfo(getCreatorLayer(layer->insData.front().lock()).lock()).has32BOutput(); } + } // namespace GNAPluginNS \ No newline at end of file diff --git a/inference-engine/src/gna_plugin/gna_plugin.cpp b/inference-engine/src/gna_plugin/gna_plugin.cpp index 55ebcc460dd..e51914c3cc6 100644 --- a/inference-engine/src/gna_plugin/gna_plugin.cpp +++ b/inference-engine/src/gna_plugin/gna_plugin.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "transformations/remove_extra_reshapes.hpp" @@ -703,9 +704,9 @@ void GNAPlugin::LoadNetwork(CNNNetwork & _network) { manager.register_pass(); manager.register_pass(); manager.register_pass(); - manager.register_pass(); - manager.register_pass(); manager.register_pass(); + manager.register_pass(); + manager.register_pass(); manager.register_pass(); manager.register_pass(); manager.register_pass(); @@ -727,6 +728,8 @@ void GNAPlugin::LoadNetwork(CNNNetwork & _network) { pass_config->disable(); // Consider to enable after per-channel quantization on FakeQuantize layer is supported in GNAPlugin, see issue 52034 pass_config->disable(); + // TransposeReduction can be enabled when Transpose-Conv-Transpose patterns will be handled in ngraph transformations + pass_config->disable(); manager.run_passes(graph); convertedNetwork = InferenceEngine::details::convertFunctionToICNNNetwork(graph, clonedNetwork); } @@ -1576,6 +1579,18 @@ InferenceEngine::IExecutableNetworkInternal::Ptr GNAPlugin::ImportNetwork(std::i transpose_inputs_info, transpose_outputs_info); + // If scale factors are defined in configuration we still need to use them instead of imported values, + // for example to change the scale factors for the old models. + if (!config.inputScaleFactors.empty()) { + IE_ASSERT(config.inputScaleFactors.size() == inputsDesc->inputScaleFactors.size()); + for (size_t i = 0; i < config.inputScaleFactors.size(); ++i) { + if (config.inputScaleFactors[i] != GNAPluginNS::kScaleFactorDefault) { + gnalog() << "[Import Network] Using input scale factor defined in configuration for input " << i << std::endl; + inputsDesc->inputScaleFactors[i] = config.inputScaleFactors[i]; + } + } + } + #if GNA_LIB_VER == 2 auto getOrientation = [](Gna2Operation & gnaOperation) { return gnaOperation.Type == Gna2OperationTypeConvolution ? diff --git a/inference-engine/src/gna_plugin/gna_plugin_config.cpp b/inference-engine/src/gna_plugin/gna_plugin_config.cpp index f5e28e10aed..64b374b49af 100644 --- a/inference-engine/src/gna_plugin/gna_plugin_config.cpp +++ b/inference-engine/src/gna_plugin/gna_plugin_config.cpp @@ -95,7 +95,7 @@ void Config::UpdateFromMap(const std::map& config) { } // missing scale factors are set to be 1.0f if (inputScaleFactors.size() <= input_index) { - inputScaleFactors.resize(input_index + 1, 1.f); + inputScaleFactors.resize(input_index + 1, GNAPluginNS::kScaleFactorDefault); } inputScaleFactors[input_index] = InferenceEngine::CNNLayer::ie_parse_float(value); } else if (key == GNA_CONFIG_KEY(FIRMWARE_MODEL_IMAGE)) { diff --git a/inference-engine/src/gna_plugin/gna_plugin_config.hpp b/inference-engine/src/gna_plugin/gna_plugin_config.hpp index 850c61c5a6e..309882dd126 100644 --- a/inference-engine/src/gna_plugin/gna_plugin_config.hpp +++ b/inference-engine/src/gna_plugin/gna_plugin_config.hpp @@ -18,6 +18,8 @@ namespace GNAPluginNS { +static const float kScaleFactorDefault = 1.f; + struct Config { Config() { AdjustKeyMapValues(); diff --git a/inference-engine/src/gna_plugin/layers/gna_split_layer.hpp b/inference-engine/src/gna_plugin/layers/gna_split_layer.hpp index c6c16ffe99a..161c3da66f4 100644 --- a/inference-engine/src/gna_plugin/layers/gna_split_layer.hpp +++ b/inference-engine/src/gna_plugin/layers/gna_split_layer.hpp @@ -45,4 +45,18 @@ public: }; std::vector splitOutputLayers; }; + +// @brief Returns sizes of split outputs to split the input tensor to aligned parts not greater than the specified size +static std::vector GetAlignedSplitSizes(uint32_t totalSize, uint32_t maxSplitSize, uint32_t alignment = 64) { + std::vector splitSizes; + uint32_t maxAlignedSplitSize = maxSplitSize - maxSplitSize % alignment; + uint32_t usedSize = 0; + while (usedSize < totalSize) { + uint32_t partSize = std::min(totalSize - usedSize, maxAlignedSplitSize); + splitSizes.push_back(partSize); + usedSize += partSize; + } + return splitSizes; +} + } // namespace GNAPluginNS diff --git a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp index b92bd153370..b7507e8fbf9 100644 --- a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp +++ b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp @@ -87,7 +87,7 @@ static void insertDiagonalLayerBetween(InferenceEngine::CNNLayerPtr prevLayer, }); IE_ASSERT(inputLayer != nullptr); size_t weightsSize = LayerInfo(prevLayer).has32BOutput() ? nextLayer->outData[0]->getDims().back() : - Get2DReshapedData(nextLayer->outData[0], 8)->getDims()[1]; + Get2DReshapedData(nextLayer->outData[0], GNALimitations::GetMinBatchToFitInBuffer(nextLayer->outData[0]), 8)->getDims()[1]; std::vector weightsValues(weightsSize, fillValue); IE_ASSERT(diagLayer != nullptr); diagLayer->_weights = make_shared_blob( @@ -1113,6 +1113,9 @@ void InsertConcatAligningFilterPass::run() { SizeVector({filterWeights.size()}), Layout::C)); concatAligningFilter->_weights->allocate(); + if (!concatAligningFilter->_weights->buffer().as()) { + THROW_GNA_EXCEPTION << "Failed to allocate weights of size " << filterWeights.size() << " for " << filterName; + } CopyVectorToBlob(concatAligningFilter->_weights, filterWeights); @@ -1395,15 +1398,20 @@ void EltwiseSplitOverChannelsPass::run() { THROW_GNA_LAYER_EXCEPTION(l) << "number of outputs expected to be 1"; } auto oData = l->outData.front(); - auto out_width = GetDataDimSize(oData, DataDimName::W); - auto totalElementsForOutput = details::product(oData->getDims().begin(), oData->getDims().end()); - // gna limit this to be OxFFFF - auto maxAffineElements = 65536 - 64; - if (totalElementsForOutput <= maxAffineElements) { + auto oDims = oData->getDims(); + auto totalElementsSize = details::product(std::begin(oDims), std::end(oDims)); + if (totalElementsSize <= GNALimitations::bufferMaxSize) { continue; } - auto totalSplits = 1 + totalElementsForOutput / maxAffineElements; + auto firstValuableDim = std::find_if(std::begin(oDims), std::end(oDims), [](size_t val) { return val > 1; }); + IE_ASSERT(firstValuableDim != std::end(oDims)); + auto splittedElementsSize = *firstValuableDim; + auto splittedDimIx = std::distance(std::begin(oDims), firstValuableDim); + + // Split output size should be multiple by 64 to avoid align filters insertion + auto splitSizes = GetAlignedSplitSizes(splittedElementsSize, + GNALimitations::bufferMaxSize * splittedElementsSize / totalElementsSize); pass_trace() << "transforming " << LAYER_NAME(l) << " by splitting it to multiple eltwise operations\n"; auto quantized = InferenceEngine::getInjectedData(l); @@ -1421,27 +1429,13 @@ void EltwiseSplitOverChannelsPass::run() { auto inputDesc = l->insData[kThEltwiseInput].lock()->getTensorDesc(); // create split layer outputs - size_t usedElements = 0; - for (size_t i = 0; i < totalSplits; i++) { - SizeVector newDims; - size_t elements_num = std::min(totalElementsForOutput - usedElements, - static_cast(maxAffineElements)); - if (inputDesc.getDims().size() == 2) { - newDims = SizeVector{1, elements_num}; - } else { - elements_num = elements_num - elements_num % out_width; - newDims = SizeVector{1, elements_num / out_width, out_width}; - } - + for (auto elementsNum : splitSizes) { + auto newDims = oDims; + newDims[splittedDimIx] = elementsNum; auto newDesc = TensorDesc(inputDesc.getPrecision(), newDims, inputDesc.getLayout()); auto data = std::make_shared(l->name + "/" + std::to_string(kThEltwiseInput) + "/1", newDesc); getCreatorLayer(data) = split; split->outData.push_back(data); - - usedElements += elements_num; - if (usedElements == totalElementsForOutput) { - break; - } } // replacing connection X->eltwise to X->split auto oData = CNNLayerFindOutData(l, kThEltwiseInput); @@ -1461,7 +1455,7 @@ void EltwiseSplitOverChannelsPass::run() { concat->outData.push_back(masterEltwise->outData.front()); getCreatorLayer(masterEltwise->outData.front()) = concat; - for (size_t k = 0; k != totalSplits; k++) { + for (size_t k = 0; k != splitSizes.size(); k++) { auto eltwiseRaw = std::make_shared( LayerParams{l->name + "/eltwise/" + std::to_string(k), "Eltwise", Precision::FP32}); IE_ASSERT(eltwiseRaw != nullptr); @@ -1521,7 +1515,9 @@ void SubstituteScaleShiftBroadCastPass::run() { if (was_reshaped) { dataDims = reshaped_data[insData->getName()]; } else { - dataDims = HasTo2DReshapeData(l) ? Get2DReshapedData(insData, 8)->getDims() : insData->getDims(); + dataDims = HasTo2DReshapeData(l) ? + Get2DReshapedData(insData, GNALimitations::GetMinBatchToFitInBuffer(insData), 8)->getDims() : + insData->getDims(); } if (dataDims.size() <= 2) { diff --git a/inference-engine/src/gna_plugin/transformations/split_convolution_with_large_buffer_size.cpp b/inference-engine/src/gna_plugin/transformations/split_convolution_with_large_buffer_size.cpp index 4043c4aa5f0..b29cc04dac0 100644 --- a/inference-engine/src/gna_plugin/transformations/split_convolution_with_large_buffer_size.cpp +++ b/inference-engine/src/gna_plugin/transformations/split_convolution_with_large_buffer_size.cpp @@ -12,6 +12,7 @@ #include #include #include "backend/gna_limitations.hpp" +#include "layers/gna_split_layer.hpp" using namespace GNAPluginNS; @@ -19,22 +20,6 @@ NGRAPH_RTTI_DEFINITION(SplitConvolution, "SplitConvolution", 0); NGRAPH_RTTI_DEFINITION(SplitConvolutionWithBias, "SplitConvolutionWithBias", 0); NGRAPH_RTTI_DEFINITION(SplitConvolutionWithFq, "SplitConvolutionWithFq", 0); -static std::vector GetConvSplitSizes(std::shared_ptr conv) { - uint32_t width = conv->get_input_shape(0).back(); - uint32_t in_channels = conv->get_input_shape(0).at(1); - uint32_t usedWidth = 0; - std::vector split_sizes; - uint32_t width_max_size = GNALimitations::bufferMaxSize / in_channels; - width_max_size = width_max_size - width_max_size % 64; - while (usedWidth < width) { - uint32_t width_part = std::min(width - usedWidth, width_max_size); - split_sizes.push_back(width_part); - usedWidth += width_part; - } - IE_ASSERT(usedWidth == width); - return split_sizes; -} - static bool Convert(std::shared_ptr conv, std::shared_ptr add, std::shared_ptr bias, @@ -45,15 +30,21 @@ static bool Convert(std::shared_ptr conv, return false; } - auto split_sizes = GetConvSplitSizes(conv); + uint32_t width = conv->get_input_shape(0).back(); + uint32_t in_channels = conv->get_input_shape(0).at(1); + auto split_sizes = GetAlignedSplitSizes(width, GNALimitations::bufferMaxSize / in_channels); IE_ASSERT(split_sizes.size() > 1); + std::vector split_sizes_casted(split_sizes.size()); + std::transform(std::begin(split_sizes), std::end(split_sizes), std::begin(split_sizes_casted), [](uint32_t size) { + return static_cast(size); + }); /* TODO check if it's NHWC convolution wrapped with transposes or all input dimensions except of width == 1, otherwise this split axis isn't supported */ const int64_t width_axis = conv->get_input_shape(0).size() - 1; auto split_node = std::make_shared(conv->input_value(0), ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape({1}), std::vector{width_axis}), - ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape({split_sizes.size()}), split_sizes)); + ngraph::opset7::Constant::create(ngraph::element::i64, ngraph::Shape({split_sizes_casted.size()}), split_sizes_casted)); ngraph::copy_runtime_info(conv, split_node); split_node->set_friendly_name(conv->get_friendly_name() + "/split"); ngraph::OutputVector convOutputs; diff --git a/inference-engine/src/inference_engine/include/ie/vpu/myriad_plugin_config.hpp b/inference-engine/src/inference_engine/include/ie/vpu/myriad_plugin_config.hpp index e777daabf0a..f6eed5ef405 100644 --- a/inference-engine/src/inference_engine/include/ie/vpu/myriad_plugin_config.hpp +++ b/inference-engine/src/inference_engine/include/ie/vpu/myriad_plugin_config.hpp @@ -41,23 +41,6 @@ namespace VPUConfigParams { INFERENCE_ENGINE_DEPRECATED("Use InferenceEngine::MYRIAD_ENABLE_FORCE_RESET instead") DECLARE_VPU_MYRIAD_CONFIG_KEY(FORCE_RESET); -/** - * @deprecated - * @brief This option allows to specify device. - * If specified device is not available then creating infer request will throw an exception. - */ -INFERENCE_ENGINE_DEPRECATED("") -DECLARE_VPU_MYRIAD_CONFIG_KEY(PLATFORM); - -/** - * @deprecated - * @brief Supported keys definition for VPU_MYRIAD_CONFIG_KEY(PLATFORM) option. - */ -INFERENCE_ENGINE_DEPRECATED("") -DECLARE_VPU_MYRIAD_CONFIG_VALUE(2450); -INFERENCE_ENGINE_DEPRECATED("") -DECLARE_VPU_MYRIAD_CONFIG_VALUE(2480); - /** * @deprecated Use InferenceEngine::MYRIAD_DDR_TYPE instead * @brief This option allows to specify device memory type. diff --git a/inference-engine/src/inference_engine/include/openvino/runtime/core.hpp b/inference-engine/src/inference_engine/include/openvino/runtime/core.hpp index 9bc3504b69a..0ececc87aa5 100644 --- a/inference-engine/src/inference_engine/include/openvino/runtime/core.hpp +++ b/inference-engine/src/inference_engine/include/openvino/runtime/core.hpp @@ -19,10 +19,6 @@ #include "ie_plugin_config.hpp" #include "ie_version.hpp" -namespace ngraph { -class Function; -} // namespace ngraph - namespace InferenceEngine { class IExtension; class Blob; @@ -30,6 +26,9 @@ class RemoteContext; } // namespace InferenceEngine namespace ov { + +class Function; + namespace runtime { /** @@ -72,7 +71,7 @@ public: * * binPath parameter is not used. * @return Function */ - std::shared_ptr read_model(const std::wstring& modelPath, const std::wstring& binPath = {}) const; + std::shared_ptr read_model(const std::wstring& modelPath, const std::wstring& binPath = {}) const; #endif /** @@ -86,7 +85,7 @@ public: * * binPath parameter is not used. * @return Function */ - std::shared_ptr read_model(const std::string& modelPath, const std::string& binPath = {}) const; + std::shared_ptr read_model(const std::string& modelPath, const std::string& binPath = {}) const; /** * @brief Reads models from IR and ONNX formats * @param model string with model in IR or ONNX format @@ -101,8 +100,8 @@ public: * constant data becomes to point to invalid memory. * @return Function */ - std::shared_ptr read_model(const std::string& model, - const std::shared_ptr& weights) const; + std::shared_ptr read_model(const std::string& model, + const std::shared_ptr& weights) const; /** * @brief Creates an executable network from a network object. @@ -116,7 +115,7 @@ public: * operation * @return An executable network reference */ - InferenceEngine::ExecutableNetwork compile_model(const std::shared_ptr& network, + InferenceEngine::ExecutableNetwork compile_model(const std::shared_ptr& network, const std::string& deviceName, const std::map& config = {}); @@ -145,7 +144,7 @@ public: * operation * @return An executable network object */ - InferenceEngine::ExecutableNetwork compile_model(const std::shared_ptr& network, + InferenceEngine::ExecutableNetwork compile_model(const std::shared_ptr& network, const std::shared_ptr& context, const std::map& config = {}); @@ -189,7 +188,7 @@ public: * @param config Optional map of pairs: (config parameter name, config parameter value) * @return An object containing a map of pairs a layer name -> a device name supporting this layer. */ - InferenceEngine::QueryNetworkResult query_model(const std::shared_ptr& network, + InferenceEngine::QueryNetworkResult query_model(const std::shared_ptr& network, const std::string& deviceName, const std::map& config = {}) const; diff --git a/inference-engine/src/inference_engine/src/ie_core.cpp b/inference-engine/src/inference_engine/src/ie_core.cpp index b636d519368..5792e6388e0 100644 --- a/inference-engine/src/inference_engine/src/ie_core.cpp +++ b/inference-engine/src/inference_engine/src/ie_core.cpp @@ -62,18 +62,17 @@ Parsed parseDeviceNameIntoConfig(const std::string& deviceName, const std::ma } else if (deviceName_.find("MULTI:") == 0) { deviceName_ = "MULTI"; config_[InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES] = deviceName.substr(6); - } else if (deviceName_.find("AUTO") == 0) { - deviceName_ = "AUTO"; - if (deviceName.size() > std::string("AUTO").size()) { - std::string deviceList = deviceName.substr(std::string("AUTO:").size()); - if (deviceList.find("AUTO") != std::string::npos) { - IE_THROW() << "Device list for AUTO should not be AUTO"; - } - config_[InferenceEngine::KEY_AUTO_DEVICE_LIST] = deviceName.substr(std::string("AUTO:").size()); + } else if (deviceName.find("AUTO") == 0) { + deviceName_ = "MULTI"; + if (deviceName.find("AUTO:") == 0) { + config_[InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES] = + deviceName.substr(std::string("AUTO:").size()); } + config_.insert({CONFIG_KEY_INTERNAL(WORK_MODE), ""}); } else { - if (deviceName_.empty()) { - deviceName_ = "AUTO"; + if (deviceName_ == "AUTO") { + deviceName_ = "MULTI"; + config_.insert({CONFIG_KEY_INTERNAL(WORK_MODE), ""}); } InferenceEngine::DeviceIDParser parser(deviceName_); deviceName_ = parser.getDeviceName(); @@ -579,7 +578,21 @@ public: } } - auto parsed = parseDeviceNameIntoConfig(deviceName); + // AUTO case + { + if (deviceName.find("AUTO:") == 0) { + IE_THROW() + << "You can get specific metrics with the GetMetric only for the MULTI itself (without devices). " + "To get individual devices's metrics call GetMetric for each device separately"; + } + } + + std::string pluginName = deviceName; + if (pluginName == "AUTO") { + pluginName = "MULTI"; + } + + auto parsed = parseDeviceNameIntoConfig(pluginName); // we need to return a copy of Parameter object which is created on Core side, // not in InferenceEngine plugin side, which can be unloaded from Core in a parallel thread @@ -629,11 +642,14 @@ public: * @param deviceName A name of device * @return Reference to a CPP plugin wrapper */ - InferenceEngine::InferencePlugin GetCPPPluginByName(const std::string& deviceName) const { + InferenceEngine::InferencePlugin GetCPPPluginByName(const std::string& pluginName) const { OV_ITT_SCOPE(FIRST_INFERENCE, InferenceEngine::itt::domains::IE_LT, "CoreImpl::GetCPPPluginByName"); std::lock_guard lock(pluginsMutex); - + auto deviceName = pluginName; + if (deviceName == "AUTO") { + deviceName = "MULTI"; + } auto it = pluginRegistry.find(deviceName); if (it == pluginRegistry.end()) { IE_THROW() << "Device with \"" << deviceName << "\" name is not registered in the InferenceEngine"; @@ -856,9 +872,9 @@ public: } else if (deviceName.find("AUTO") == 0) { auto pos = deviceName.find_first_of(":"); if (pos != std::string::npos) { - deviceNames = InferenceEngine::DeviceIDParser::getHeteroDevices(deviceName.substr(pos + 1)); + deviceNames = InferenceEngine::DeviceIDParser::getMultiDevices(deviceName.substr(pos + 1)); } - deviceNames.emplace_back("AUTO"); + deviceNames.emplace_back("MULTI"); } else { deviceNames.push_back(deviceName); } diff --git a/inference-engine/src/inference_engine/src/threading/ie_tbb_streams_executor.cpp b/inference-engine/src/inference_engine/src/threading/ie_tbb_streams_executor.cpp new file mode 100644 index 00000000000..ab424f959d5 --- /dev/null +++ b/inference-engine/src/inference_engine/src/threading/ie_tbb_streams_executor.cpp @@ -0,0 +1,301 @@ +// Copyright (C) 2018-2019 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "threading/ie_tbb_streams_executor.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "details/ie_exception.hpp" +#include "ie_parallel.hpp" +#include "ie_parallel_custom_arena.hpp" +#include "ie_system_conf.h" +#include "threading/ie_thread_affinity.hpp" + +#if ((IE_THREAD == IE_THREAD_TBB) || (IE_THREAD == IE_THREAD_TBB_AUTO)) +# include +# include +# include +# include +# include + +namespace InferenceEngine { +struct TBBStreamsExecutor::Impl { + struct Stream; + using TaskQueue = tbb::concurrent_queue; + using StreamQueue = tbb::concurrent_bounded_queue; + using LocalStreams = tbb::enumerable_thread_specific; + struct Shared : public std::enable_shared_from_this { + using Ptr = std::shared_ptr; + TaskQueue _taskQueue; + StreamQueue _streamQueue; + }; + struct Stream { + struct Observer : tbb::task_scheduler_observer { + Stream* _thisStream = nullptr; + LocalStreams* _localStream = nullptr; + CpuSet _mask; + int _ncpus = 0; + int _threadBindingStep = 0; + int _offset = 0; + + Observer(custom::task_arena& arena, + Stream* thisStream, + LocalStreams* localStream, + const bool pinToCores, + const int streamId, + const int threadsPerStream, + const int threadBindingStep, + const int threadBindingOffset) + : tbb::task_scheduler_observer{static_cast(arena)}, + _thisStream{thisStream}, + _localStream{localStream}, + _threadBindingStep{threadBindingStep}, + _offset{streamId * threadsPerStream + threadBindingOffset} { + if (pinToCores) { + std::tie(_mask, _ncpus) = GetProcessMask(); + } + } + void on_scheduler_entry(bool) override { + _localStream->local() = _thisStream; + if (nullptr != _mask) { + PinThreadToVacantCore(_offset + tbb::this_task_arena::current_thread_index(), + _threadBindingStep, + _ncpus, + _mask); + } + } + void on_scheduler_exit(bool) override { + _localStream->local() = nullptr; + if (nullptr != _mask) { + PinCurrentThreadByMask(_ncpus, _mask); + } + } + ~Observer() override = default; + }; + + explicit Stream(Impl* impl, const bool externStream = false) : _impl{impl} { + { + std::lock_guard lock{_impl->_streamIdMutex}; + if (_impl->_streamIdQueue.empty()) { + _streamId = _impl->_streamId++; + } else { + _streamId = _impl->_streamIdQueue.front(); + _impl->_streamIdQueue.pop(); + } + } + _numaNodeId = _impl->_config._streams + ? _impl->_usedNumaNodes.at((_streamId % _impl->_config._streams) / + ((_impl->_config._streams + _impl->_usedNumaNodes.size() - 1) / + _impl->_usedNumaNodes.size())) + : _impl->_usedNumaNodes.at(_streamId % _impl->_usedNumaNodes.size()); + auto concurrency = + (0 == _impl->_config._threadsPerStream) ? tbb::task_arena::automatic : _impl->_config._threadsPerStream; + auto masterThreads = externStream ? 1u : 0u; + if (ThreadBindingType::HYBRID_AWARE == _impl->_config._threadBindingType) { + if (Config::PreferredCoreType::ROUND_ROBIN != _impl->_config._threadPreferredCoreType) { + if (Config::PreferredCoreType::ANY == _impl->_config._threadPreferredCoreType) { + _arena.initialize(concurrency); + } else { + const auto selected_core_type = + Config::PreferredCoreType::BIG == _impl->_config._threadPreferredCoreType + ? custom::info::core_types().back() // running on Big cores only + : custom::info::core_types().front(); // running on Little cores only + _arena.initialize(custom::task_arena::constraints{} + .set_core_type(selected_core_type) + .set_max_concurrency(concurrency)); + } + } else { + // assigning the stream to the core type in the round-robin fashion + // wrapping around total_streams (i.e. how many streams all different core types can handle + // together) + const auto total_streams = _impl->_totalSreamsOnCoreTypes.back().second; + const auto streamId_wrapped = _streamId % total_streams; + const auto& selected_core_type = + std::find_if(_impl->_totalSreamsOnCoreTypes.cbegin(), + _impl->_totalSreamsOnCoreTypes.cend(), + [streamId_wrapped](const decltype(_impl->_totalSreamsOnCoreTypes)::value_type& p) { + return p.second > streamId_wrapped; + }) + ->first; + _arena.initialize(custom::task_arena::constraints{} + .set_core_type(selected_core_type) + .set_max_concurrency(concurrency)); + } + } else if (ThreadBindingType::NUMA == _impl->_config._threadBindingType) { + _arena.initialize(custom::task_arena::constraints{_numaNodeId, concurrency}); + } else { + _arena.initialize(concurrency, masterThreads); + } + _observer.reset(new Observer{_arena, + this, + &(_impl->_localStream), + (ThreadBindingType::CORES == _impl->_config._threadBindingType), + _streamId, + _impl->_config._threadsPerStream, + _impl->_config._threadBindingStep, + _impl->_config._threadBindingOffset}); + _observer->observe(true); + } + + ~Stream() { + static_cast(_arena).terminate(); + _observer->observe(false); + { + std::lock_guard lock{_impl->_streamIdMutex}; + _impl->_streamIdQueue.push(_streamId); + } + } + + Impl* _impl = nullptr; + int _streamId = 0; + int _numaNodeId = 0; + custom::task_arena _arena; + std::unique_ptr _observer; + }; + + using Streams = std::list; + using ExternStreams = tbb::enumerable_thread_specific; + + explicit Impl(const Config& config) + : _config{config}, + _shared{std::make_shared()}, + _localStream{nullptr}, + _externStreams{this, true} { + if (_config._streams * _config._threadsPerStream >= static_cast(std::thread::hardware_concurrency())) { + _maxTbbThreads.reset( + new tbb::global_control{tbb::global_control::max_allowed_parallelism, + static_cast(_config._streams * _config._threadsPerStream + 1)}); + } + auto numaNodes = getAvailableNUMANodes(); + if (_config._streams != 0) { + std::copy_n(std::begin(numaNodes), + std::min(static_cast(_config._streams), numaNodes.size()), + std::back_inserter(_usedNumaNodes)); + } else { + _usedNumaNodes = numaNodes; + } + if (ThreadBindingType::HYBRID_AWARE == config._threadBindingType) { + const auto core_types = custom::info::core_types(); + const int threadsPerStream = + (0 == config._threadsPerStream) ? std::thread::hardware_concurrency() : config._threadsPerStream; + int sum = 0; + // reversed order, so BIG cores are first + for (auto iter = core_types.rbegin(); iter < core_types.rend(); iter++) { + const auto& type = *iter; + // calculating the #streams per core type + const int num_streams_for_core_type = + std::max(1, + custom::info::default_concurrency(custom::task_arena::constraints{}.set_core_type(type)) / + threadsPerStream); + sum += num_streams_for_core_type; + // prefix sum, so the core type for a given stream id will be deduced just as a upper_bound + // (notice that the map keeps the elements in the descending order, so the big cores are populated + // first) + _totalSreamsOnCoreTypes.emplace_back(type, sum); + } + } + _shared->_streamQueue.set_capacity(_config._streams); + for (int streamId = 0; streamId < _config._streams; ++streamId) { + _streams.emplace_back(this); + _shared->_streamQueue.push(&(_streams.back())); + } + } + + ~Impl() { + for (int streamId = 0; streamId < _config._streams; ++streamId) { + Stream* stream = nullptr; + _shared->_streamQueue.pop(stream); + (void)stream; + } + } + + static void Schedule(Shared::Ptr& shared, Task task) { + Stream* stream = nullptr; + if (shared->_streamQueue.try_pop(stream)) { + struct TryPop { + void operator()() const { + try { + do { + Task task = std::move(_task); + task(); + } while (_shared->_taskQueue.try_pop(_task)); + } catch (...) { + } + if (_shared->_streamQueue.try_push(_stream)) { + if (_shared->_taskQueue.try_pop(_task)) { + Schedule(_shared, std::move(_task)); + } + } + } + Stream* _stream; + mutable Shared::Ptr _shared; + mutable Task _task; + }; + stream->_arena.enqueue(TryPop{stream, shared->shared_from_this(), std::move(task)}); + } else { + shared->_taskQueue.push(std::move(task)); + } + } + + Config _config; + std::unique_ptr _maxTbbThreads; + std::mutex _streamIdMutex; + int _streamId = 0; + std::queue _streamIdQueue; + std::vector _usedNumaNodes; + Shared::Ptr _shared; + LocalStreams _localStream; + ExternStreams _externStreams; + Streams _streams; + using StreamIdToCoreTypes = std::vector>; + StreamIdToCoreTypes _totalSreamsOnCoreTypes; +}; + +TBBStreamsExecutor::TBBStreamsExecutor(const Config& config) : _impl{new TBBStreamsExecutor::Impl{config}} {} + +TBBStreamsExecutor::~TBBStreamsExecutor() { + _impl.reset(); +} + +int TBBStreamsExecutor::GetStreamId() { + auto stream = _impl->_localStream.local(); + if (nullptr == stream) { + stream = &(_impl->_externStreams.local()); + } + return stream->_streamId; +} + +int TBBStreamsExecutor::GetNumaNodeId() { + auto stream = _impl->_localStream.local(); + if (nullptr == stream) { + stream = &(_impl->_externStreams.local()); + } + return stream->_numaNodeId; +} + +void TBBStreamsExecutor::run(Task task) { + if (_impl->_config._streams == 0) { + Execute(std::move(task)); + } else { + Impl::Schedule(_impl->_shared, std::move(task)); + } +} + +void TBBStreamsExecutor::Execute(Task task) { + auto stream = _impl->_localStream.local(); + if (nullptr == stream) { + _impl->_externStreams.local()._arena.execute(std::move(task)); + } else { + stream->_arena.execute(std::move(task)); + } +} + +} // namespace InferenceEngine +#endif // ((IE_THREAD == IE_THREAD_TBB) || (IE_THREAD == IE_THREAD_TBB_AUTO)) diff --git a/inference-engine/src/legacy_api/src/transformations/convert_opset1_to_legacy/fc_bias_fusion.cpp b/inference-engine/src/legacy_api/src/transformations/convert_opset1_to_legacy/fc_bias_fusion.cpp index 6431f3f6cc3..99d5c0c5726 100644 --- a/inference-engine/src/legacy_api/src/transformations/convert_opset1_to_legacy/fc_bias_fusion.cpp +++ b/inference-engine/src/legacy_api/src/transformations/convert_opset1_to_legacy/fc_bias_fusion.cpp @@ -43,7 +43,9 @@ ngraph::pass::FullyConnectedBiasFusion::FullyConnectedBiasFusion() { Shape bias_shape(bias->get_shape()); Shape output_shape(fc->get_shape()); size_t bias_size = std::accumulate(bias_shape.begin(), bias_shape.end(), size_t{1}, std::multiplies()); - if (bias_shape.empty() || bias_shape.back() != output_shape.back() || bias_shape.back() != bias_size) { + if (bias_shape.empty() || + (bias_shape.back() != output_shape.back() && bias_shape.back() != 1) || + bias_shape.back() != bias_size) { return false; } diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/network_helper.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/network_helper.hpp index 3229c9814f0..93c80161deb 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/network_helper.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/network_helper.hpp @@ -131,7 +131,7 @@ public: const float dequantizationMul, const float dequantizationSub, const ngraph::element::Type originalPrecision, - const ngraph::PartialShape dataNodeOutputShape, + const ngraph::PartialShape& dataNodeOutputShape, element::Type precision, const element::Type deqPrecision = element::f32, std::shared_ptr input = nullptr); diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/pad.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/pad.hpp new file mode 100644 index 00000000000..66691f3871a --- /dev/null +++ b/inference-engine/src/low_precision_transformations/include/low_precision/pad.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include "layer_transformation.hpp" + +namespace ngraph { +namespace pass { +namespace low_precision { + +class LP_TRANSFORMATIONS_API PadTransformation : public LayerTransformation { +public: + NGRAPH_RTTI_DECLARATION; + PadTransformation(const Params& params = Params()); + bool transform(TransformationContext& context, pattern::Matcher& m) override; + bool canBeTransformed(const TransformationContext& context, std::shared_ptr op) const override; + bool isPrecisionPreserved(std::shared_ptr layer) const noexcept override; +}; + +} // namespace low_precision +} // namespace pass +} // namespace ngraph diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/avg_pool_precision_preserved_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/avg_pool_precision_preserved_attribute.hpp index b8aabf3718d..1e8794c5d5b 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/avg_pool_precision_preserved_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/avg_pool_precision_preserved_attribute.hpp @@ -17,11 +17,13 @@ class LP_TRANSFORMATIONS_API AvgPoolPrecisionPreservedAttribute : public Precisi }; using AvgPoolPrecisionPreservedAttributePtr = std::shared_ptr; +} // namespace ngraph -extern template class LP_TRANSFORMATIONS_API VariantImpl; +namespace ov { +extern template class LP_TRANSFORMATIONS_API VariantImpl; template<> -class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{ "LowPrecision::AvgPoolPrecisionPreserved", 0 }; @@ -31,9 +33,9 @@ public: VariantWrapper(const value_type& value) : VariantImpl(value) {} - AvgPoolPrecisionPreservedAttributePtr get() { return this->m_value; } + ngraph::AvgPoolPrecisionPreservedAttributePtr get() { return this->m_value; } - void merge(std::vector>>>& attributes); + void merge(std::vector>>>& attributes); std::string to_string() override; }; -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/intervals_alignment_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/intervals_alignment_attribute.hpp index 3c723a44405..964989a04ec 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/intervals_alignment_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/intervals_alignment_attribute.hpp @@ -62,12 +62,15 @@ public: }; using IntervalsAlignmentAttributePtr = std::shared_ptr; +} // namespace ngraph -extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; +namespace ov { + +extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; template<> -class LP_TRANSFORMATIONS_API VariantWrapper> : - public VariantImpl> { +class LP_TRANSFORMATIONS_API VariantWrapper> : + public VariantImpl> { public: static constexpr VariantTypeInfo type_info{ "LowPrecision::IntervalsAlignment", 0 }; @@ -77,12 +80,13 @@ public: VariantWrapper(const value_type& value) : VariantImpl(value) {} - std::shared_ptr get() const { return this->m_value; } + std::shared_ptr get() const { return this->m_value; } - static std::shared_ptr>> create( + static std::shared_ptr>> create( const std::shared_ptr& node, const AttributeParameters& params); - void merge(std::vector>>>& attributes); + void merge(std::vector>>>& attributes); std::string to_string() override; }; -} // namespace ngraph + +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/per_tensor_quantization_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/per_tensor_quantization_attribute.hpp index 1001df8bffe..84f5216bda7 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/per_tensor_quantization_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/per_tensor_quantization_attribute.hpp @@ -16,11 +16,14 @@ namespace ngraph { class LP_TRANSFORMATIONS_API PerTensorQuantizationAttribute { }; +} // namespace ngraph -extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; +namespace ov { + +extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; template<> -class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info { "LowPrecision::PerTensorQuantization", 0 }; @@ -30,4 +33,5 @@ public: return type_info; } }; -} // namespace ngraph + +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precision_preserved_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precision_preserved_attribute.hpp index bf109407d00..08a4e213586 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precision_preserved_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precision_preserved_attribute.hpp @@ -31,10 +31,14 @@ public: using PrecisionPreservedAttributePtr = std::shared_ptr; -extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; +} // namespace ngraph + +namespace ov { + +extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; template<> -class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class LP_TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{ "LowPrecision::PrecisionPreserved", 0 }; @@ -44,8 +48,9 @@ public: VariantWrapper(const value_type& value) : VariantImpl(value) {} - PrecisionPreservedAttributePtr get() { return this->m_value; } + ngraph::PrecisionPreservedAttributePtr get() { return this->m_value; } std::string to_string() override; }; -} // namespace ngraph + +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precisions_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precisions_attribute.hpp index 5fc08c17926..329ee2cb22e 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precisions_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/precisions_attribute.hpp @@ -34,11 +34,14 @@ public: static const std::vector defaultPrecisions; PrecisionsAttribute(const std::vector& precisions = defaultPrecisions); }; +} // namespace ngraph -extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl>; +namespace ov { + +extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl>; template<> -class LP_TRANSFORMATIONS_API VariantWrapper> : public VariantImpl> { +class LP_TRANSFORMATIONS_API VariantWrapper> : public VariantImpl> { public: static constexpr VariantTypeInfo type_info{ "LowPrecision::Precisions", 0 }; @@ -50,15 +53,16 @@ public: std::shared_ptr init(const std::shared_ptr& node) override; - std::shared_ptr get() { return this->m_value; } + std::shared_ptr get() { return this->m_value; } // create attribute instance for node - static std::shared_ptr>> create( + static std::shared_ptr>> create( const std::shared_ptr& node, const AttributeParameters& params); // merge attribute instances which can be got from different sources: node, input port or output port - void merge(std::vector>>>& attributes); + void merge(std::vector>>>& attributes); // vizualize shared attributes details in VizualizeTree pass std::string to_string() override; }; -} // namespace ngraph + +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/quantization_alignment_attribute.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/quantization_alignment_attribute.hpp index 198301a9c4a..28503344f23 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/quantization_alignment_attribute.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/rt_info/quantization_alignment_attribute.hpp @@ -32,12 +32,15 @@ public: }; using QuantizationAlignmentAttributePtr = std::shared_ptr; +} // namespace ngraph -extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; +namespace ov { + +extern template class LP_TRANSFORMATIONS_API ngraph::VariantImpl; template<> -class LP_TRANSFORMATIONS_API VariantWrapper> : - public VariantImpl> { +class LP_TRANSFORMATIONS_API VariantWrapper> : + public VariantImpl> { public: static constexpr VariantTypeInfo type_info{ "LowPrecision::QuantizationAlignment", 0 }; @@ -49,12 +52,12 @@ public: std::shared_ptr init(const std::shared_ptr& node) override; - std::shared_ptr get() { return this->m_value; } + std::shared_ptr get() { return this->m_value; } - static std::shared_ptr>> create( + static std::shared_ptr>> create( const std::shared_ptr& node, const AttributeParameters& params); - void merge(std::vector>>>& attributes); + void merge(std::vector>>>& attributes); std::string to_string() override; }; -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/low_precision_transformations/src/convolution.cpp b/inference-engine/src/low_precision_transformations/src/convolution.cpp index 889315678e9..cb05b00d141 100644 --- a/inference-engine/src/low_precision_transformations/src/convolution.cpp +++ b/inference-engine/src/low_precision_transformations/src/convolution.cpp @@ -55,8 +55,8 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph auto convolution = m.get_match_root(); if (!canConvolutionBeTransformed(context, convolution)) { - auto weightInput = convolution->get_input_node_shared_ptr(1); - std::shared_ptr reshapeFromWeights = as_type_ptr(weightInput); + const auto weightInput = convolution->get_input_node_shared_ptr(1); + const auto reshapeFromWeights = as_type_ptr(weightInput); FakeQuantizeDequantization dequantization = reshapeFromWeights == nullptr ? NetworkHelper::getDequantization(convolution, 1ul) : NetworkHelper::getDequantization(reshapeFromWeights); @@ -69,7 +69,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph reshapeFromWeights->input_value(1), false); } - if (as_type_ptr(resultConstant)) { + if (is_type(resultConstant)) { replace_node(weightInput, resultConstant); } } else { @@ -84,10 +84,9 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph { std::shared_ptr subtract; if (dequantization.subtract != nullptr) { - std::shared_ptr layer = dequantization.subtract; - ngraph::pass::low_precision::NetworkHelper::cleanRunTimeInfo(layer); - + NetworkHelper::cleanRunTimeInfo(dequantization.subtract->shared_from_this()); auto optimizedSubtract = NetworkHelper::optimizeSubtract(dequantization.subtract); + if (optimizedSubtract == nullptr) { optimizedSubtract = dequantization.subtract; } @@ -99,7 +98,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph size_t length = subtract->get_output_partial_shape(0).rank().get_length(); // Insert explicit broadcast for channel dimension [1] and immediately fold it - Shape broadcastShape(subtract->get_output_partial_shape(0).rank().get_length(), 1); + Shape broadcastShape(length, 1); broadcastShape[1] = subtract->get_output_partial_shape(0)[1].get_length(); std::shared_ptr newShift = fold( @@ -122,11 +121,9 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph const size_t groupsCount = NetworkHelper::getGroupsCount(convolution); std::shared_ptr newMultiplyAfterConst; if (groupsCount > 1ul) { - std::shared_ptr multiplyConst = as_type_ptr(dequantization.multiply->get_input_node_shared_ptr(1)); - - const std::vector scales = multiplyConst->cast_vector(); + const std::vector scales = dequantization.multiplyConstant->cast_vector(); if (scales.size() == 1ul) { - newMultiplyAfterConst = dequantization.multiply->input_value(1).get_node_shared_ptr()->clone_with_new_inputs({}); + newMultiplyAfterConst = dequantization.multiplyConstant->clone_with_new_inputs({}); } else { const ngraph::PartialShape inputPShape = convolution->get_input_partial_shape(0); const size_t inputChannelsInGroup = inputPShape[1].get_length() / groupsCount; @@ -150,17 +147,15 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph } newMultiplyAfterConst = std::make_shared( - dequantization.multiply->get_input_element_type(1), + dequantization.multiplyConstant->get_element_type(), newMulShape, outputScales); } } else { - std::shared_ptr reducedConstant = as_type_ptr( - dequantization.multiply->input_value(1).get_node_shared_ptr()); newMultiplyAfterConst = std::make_shared( - reducedConstant->get_output_element_type(0), + dequantization.multiplyConstant->get_element_type(), Shape{ 1 }, - reducedConstant->cast_vector()[0]); + dequantization.multiplyConstant->cast_vector()[0]); } const auto copyNode = convolution->clone_with_new_inputs({ dequantization.multiply->input_value(0), convolution->input_value(1) }); @@ -190,7 +185,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph if (is_type(convolution->get_input_node_ptr(0))) { auto newConvolution = convolution->clone_with_new_inputs({ - convolution->get_input_node_ptr(0)->get_input_source_output(0), + convolution->get_input_node_ptr(0)->input_value(0), convolution->input_value(1)}); replace_node(convolution, newConvolution); NetworkHelper::copyInfo(convolution, newConvolution); @@ -206,7 +201,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph return false; } - std::shared_ptr reshapeFromWeights = as_type_ptr(convolution->input_value(1).get_node_shared_ptr()); + std::shared_ptr reshapeFromWeights = as_type_ptr(convolution->get_input_node_shared_ptr(1)); dequantization = reshapeFromWeights == nullptr ? NetworkHelper::getDequantization(convolution, 1ul) : @@ -221,12 +216,15 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph std::shared_ptr multiplyFromWeights = as_type_ptr( reshapeFromWeights == nullptr ? - convolution->input_value(1).get_node_shared_ptr() : + convolution->get_input_node_shared_ptr(1) : convolution->get_input_node_ptr(1)->get_input_node_shared_ptr(0)); std::shared_ptr subtractFromWeights = as_type_ptr(multiplyFromWeights->get_input_node_shared_ptr(0)); { - Shape newScaleShape = multiplyFromWeights->get_input_shape(1); + const auto newScalePShape = multiplyFromWeights->get_input_partial_shape(1); + assert(newScalePShape.is_static()); + Shape newScaleShape = newScalePShape.to_shape(); + if (!newScaleShape.empty()) { // that's all we need: [C, 1, 1, 1] => [C, 1, 1] newScaleShape.pop_back(); @@ -268,9 +266,12 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph } else { subtractFromWeights = as_type_ptr(optimizedSubtract); - const Shape weightsShape = subtractFromWeights->input(0).get_shape(); - Shape zeroPointShape(weightsShape.size(), 1ul); - zeroPointShape[0] = weightsShape[0]; + const auto weightsPShape = subtractFromWeights->get_input_partial_shape(0); + assert(weightsPShape.is_static()); + + const size_t weightsRankValue = weightsPShape.rank().get_length(); + Shape zeroPointShape(weightsRankValue, 1ul); + zeroPointShape[0] = static_cast(weightsPShape[0].get_length()); auto zeroPointConstant = fold( subtractFromWeights->input_value(1), @@ -288,7 +289,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph std::shared_ptr childNode = reshapeFromWeights == nullptr ? convolution : reshapeFromWeights; auto newConvolution = convolution->clone_with_new_inputs({ - convolution->get_input_source_output(0), + convolution->input_value(0), childNode.get() == convolution.get() ? convolution->get_input_node_ptr(1)->input_value(0) : childNode->copy_with_new_inputs({convertFromWeights->input_value(0), childNode->input_value(1)})}); @@ -311,7 +312,7 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph std::shared_ptr finalDequantization = NetworkHelper::optimizeMultipliesAfter( convolution->output(0).get_target_inputs().begin()->get_node()->shared_from_this()); - ngraph::copy_runtime_info({ convolution, finalDequantization }, finalDequantization); + copy_runtime_info({ convolution, finalDequantization }, finalDequantization); updateOutput(context, finalDequantization, convolution); // [C, 1, 1] -> [1, C, 1, 1] diff --git a/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp b/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp index 54e010d3a84..680ed16eb17 100644 --- a/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp +++ b/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp @@ -87,7 +87,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con reshapeFromWeights->input_value(1), false); } - if (as_type_ptr(resultConstant)) { + if (is_type(resultConstant)) { replace_node(weightsInput, resultConstant); } } else { @@ -100,16 +100,14 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(convolutionBackpropData); { if (dequantization.subtract != nullptr) { - std::shared_ptr layer = dequantization.subtract; - ngraph::pass::low_precision::NetworkHelper::cleanRunTimeInfo(layer); - + NetworkHelper::cleanRunTimeInfo(dequantization.subtract->shared_from_this()); NetworkHelper::optimizeSubtract(dequantization.subtract); } - std::shared_ptr reducedConstant = as_type_ptr(dequantization.multiplyConstant); + std::shared_ptr newMultiplyAfterConst = std::make_shared( - reducedConstant->get_output_element_type(0), - Shape{ 1 }, - reducedConstant->cast_vector()[0]); + dequantization.multiplyConstant->get_element_type(), + Shape{ 1 }, + dequantization.multiplyConstant->cast_vector()[0]); auto inputs = convolutionBackpropData->input_values(); inputs[0] = dequantization.multiply->input_value(0); const auto copyNode = convolutionBackpropData->copy_with_new_inputs(inputs); @@ -126,7 +124,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con ngraph::op::TemporaryReplaceOutputType(newMultiplyAfterConst, deqPrecision).get()); replace_node(convolutionBackpropData, newMultiplyAfter); - convolutionBackpropData = newMultiplyAfter->input_value(0).get_node_shared_ptr(); + convolutionBackpropData = newMultiplyAfter->get_input_node_shared_ptr(0); inputs[0] = convolutionBackpropData->get_input_node_ptr(0)->input_value(0); if (is_type(convolutionBackpropData->get_input_node_ptr(0))) { auto newConvolution = convolutionBackpropData->copy_with_new_inputs(inputs); @@ -137,7 +135,6 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con { decomposeFakeQuantizeForWeightsPath(convolutionBackpropData, 1ul); - dequantization = NetworkHelper::getDequantization(convolutionBackpropData, 1ul); if (is_type(dequantization.data.get_node())) { @@ -152,7 +149,10 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con std::shared_ptr subtractFromWeights = as_type_ptr(multiplyFromWeights->get_input_node_shared_ptr(0)); { - Shape newScaleShape = multiplyFromWeights->get_input_shape(1); + const auto newScalePShape = multiplyFromWeights->get_input_partial_shape(1); + assert(newScalePShape.is_static()); + Shape newScaleShape = newScalePShape.to_shape(); + auto inputs = convolutionBackpropData->input_values(); inputs[1] = multiplyFromWeights->input_value(0); auto newMultiplyAfter = std::make_shared( @@ -164,7 +164,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con false), convolutionBackpropData->get_output_element_type(0))); replace_node(convolutionBackpropData, newMultiplyAfter); - convolutionBackpropData = newMultiplyAfter->input_value(0).get_node_shared_ptr(); + convolutionBackpropData = newMultiplyAfter->get_input_node_shared_ptr(0); } if (subtractFromWeights != nullptr) { @@ -175,9 +175,12 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con } else { subtractFromWeights = as_type_ptr(optimizedSubtract); - const Shape weightsShape = subtractFromWeights->input(0).get_shape(); - Shape zeroPointShape(weightsShape.size(), 1ul); - zeroPointShape[1] = weightsShape[1]; + const auto weightsPShape = subtractFromWeights->get_input_partial_shape(0); + assert(weightsPShape.is_static()); + + const size_t weightsRankValue = weightsPShape.rank().get_length(); + Shape zeroPointShape(weightsRankValue, 1ul); + zeroPointShape[1] = static_cast(weightsPShape[1].get_length()); auto zeroPointConstant = fold( subtractFromWeights->get_input_node_shared_ptr(1), @@ -215,7 +218,6 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con rt["DISABLED_CONSTANT_FOLDING"] = std::make_shared>(""); } - return true; } diff --git a/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp index 93e6aa813c1..405e8fca87a 100644 --- a/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp @@ -56,8 +56,10 @@ bool FakeQuantizeTransformation::transform(TransformationContext& context, ngrap namespace fq { static std::shared_ptr updateShape(std::shared_ptr constantOp, const PartialShape& targetShape) { + assert(constantOp->get_output_partial_shape(0).is_static()); const Shape shape = constantOp->get_output_shape(0); - if ((shape.size() < static_cast(targetShape.rank().get_length())) && (shape.size() > 1ul)) { + + if ((shape.size() > 1ul) && (shape.size() < static_cast(targetShape.rank().get_length()))) { constantOp = fold( constantOp, std::make_shared(ngraph::element::i32, Shape{ 1 }, std::vector({ 0ul }))); @@ -93,19 +95,19 @@ static std::shared_ptr getConstant(const std::shared_ptr } // namespace fq bool FakeQuantizeTransformation::checkElementwise(const std::shared_ptr& eltwise) { - const auto eltwiseInputPShape = eltwise->get_input_partial_shape(0); - const auto eltwiseOutputPShape = eltwise->get_output_partial_shape(0); - if (eltwiseInputPShape != eltwiseOutputPShape || eltwiseInputPShape.rank().is_dynamic() || eltwiseOutputPShape.rank().is_dynamic()) { - return false; - } - - std::shared_ptr constant = fq::getConstant(eltwise); + const std::shared_ptr constant = fq::getConstant(eltwise); if (constant == nullptr) { return false; } - Shape shape = constant->get_output_shape(0); - if ((!shape.empty()) && (shape_size(shape) != 1ul)) { + Shape shape = constant->get_shape(); + if (shape_size(shape) != 1ul) { + const auto eltwiseInputPShape = eltwise->get_input_partial_shape(0); + const auto eltwiseOutputPShape = eltwise->get_output_partial_shape(0); + if (eltwiseInputPShape != eltwiseOutputPShape || eltwiseInputPShape.rank().is_dynamic() || eltwiseOutputPShape.rank().is_dynamic()) { + return false; + } + if ((eltwiseOutputPShape.rank().get_length() - shape.size()) > 1) { return false; } @@ -179,8 +181,8 @@ std::shared_ptr FakeQuantizeTransformation::fuseElementwis inputHighConst_f32 = fq::updateShape(fold(inputHighConst_f32, value), fakeQuantize->get_output_partial_shape(0)); } else if (is_type(eltwise)) { // issue #40611 - if ((eltwise->input(0).get_element_type() == element::i32) && - ((eltwise->output(0).get_element_type() == element::f16) || (eltwise->output(0).get_element_type() == element::f32))) { + if ((eltwise->get_input_element_type(0) == element::i32) && + ((eltwise->get_output_element_type(0) == element::f16) || (eltwise->get_output_element_type(0) == element::f32))) { return nullptr; } } else { @@ -190,7 +192,7 @@ std::shared_ptr FakeQuantizeTransformation::fuseElementwis const auto data = fq::getData(eltwise); const size_t outputIdx = NetworkHelper::getParentOutputIndex(data, eltwise); - std::shared_ptr newFakeQuantize = as_type_ptr(fakeQuantize->clone_with_new_inputs({ + const auto newFakeQuantize = as_type_ptr(fakeQuantize->clone_with_new_inputs({ data->output(outputIdx), inputLowConst_f32, inputHighConst_f32, diff --git a/inference-engine/src/low_precision_transformations/src/fake_quantize_dequantization.cpp b/inference-engine/src/low_precision_transformations/src/fake_quantize_dequantization.cpp index 041b0009899..da84ed329a7 100644 --- a/inference-engine/src/low_precision_transformations/src/fake_quantize_dequantization.cpp +++ b/inference-engine/src/low_precision_transformations/src/fake_quantize_dequantization.cpp @@ -90,7 +90,7 @@ bool FakeQuantizeDequantization::checkShape(const std::shared_ptr& if (!inPShape.rank().is_dynamic()) { for (int i = 0; i < inPShape.rank().get_length(); ++i) { - if (inPShape[i] != outPShape[i] && !inPShape.is_dynamic()) { + if (inPShape[i] != outPShape[i] && !inPShape[i].is_dynamic()) { return false; } } @@ -108,7 +108,7 @@ bool FakeQuantizeDequantization::checkElementwise(const std::shared_ptrget_output_shape(0); + const ngraph::Shape constShape = constant->get_shape(); if ((constShape.size() > 5ul)) { return false; } diff --git a/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp index b15b466b476..6ce7acfad3a 100644 --- a/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp @@ -40,8 +40,12 @@ bool FuseFakeQuantizeTransformation::transform(TransformationContext& context, n namespace fuse_fq { -std::shared_ptr updateShape(std::shared_ptr op, const Shape& targetShape) { +std::shared_ptr updateShape(std::shared_ptr op, const PartialShape& targetPShape) { + assert(targetPShape.is_static()); + assert(op->get_output_partial_shape(0).is_static()); + const Shape targetShape = targetPShape.to_shape(); const Shape shape = op->get_output_shape(0); + if ((shape.size() < targetShape.size()) && (shape.size() > 1ul)) { op = fold( op, @@ -81,14 +85,19 @@ bool eltwiseWithConstant(const std::shared_ptr& eltwise) { return false; } - Shape shape = constant->get_output_shape(0); + Shape shape = constant->get_shape(); if ((!shape.empty()) && (shape_size(shape) != 1ul)) { - const Shape eltwiseShape = eltwise->get_output_shape(0); - if ((eltwiseShape.size() - shape.size()) > 1) { + const auto eltwisePShape = eltwise->get_output_partial_shape(0); + if (eltwisePShape.rank().is_dynamic()) { return false; } - if ((eltwiseShape.size() - shape.size()) == 1ul) { + const size_t eltwiseOutRank = eltwisePShape.rank().get_length(); + if ((eltwiseOutRank - shape.size()) > 1) { + return false; + } + + if ((eltwiseOutRank - shape.size()) == 1ul) { shape.insert(shape.begin(), 1ul); } @@ -118,22 +127,22 @@ std::shared_ptr FuseFakeQuantizeTransformation::handle( constant : foldConvert(constant, eltwise->get_output_element_type(0)); - inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_shape(0)); - inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_shape(0)); + inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_partial_shape(0)); + inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (is_type(eltwise) && fuse_fq::eltwiseWithConstant(eltwise)) { const auto value = constant->get_output_element_type(0) == eltwise->get_output_element_type(0) ? constant : foldConvert(constant, eltwise->get_output_element_type(0)); - inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_shape(0)); - inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_shape(0)); + inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_partial_shape(0)); + inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (is_type(eltwise) && fuse_fq::eltwiseWithConstant(eltwise)) { const auto value = constant->get_output_element_type(0) == eltwise->get_output_element_type(0) ? constant : foldConvert(constant, eltwise->get_output_element_type(0)); - inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_shape(0)); - inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_shape(0)); + inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_partial_shape(0)); + inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (is_type(eltwise) && fuse_fq::eltwiseWithConstant(eltwise)) { if (is_type(fuse_fq::getData(eltwise)) || is_type(fuse_fq::getData(eltwise))) { @@ -144,8 +153,8 @@ std::shared_ptr FuseFakeQuantizeTransformation::handle( constant : foldConvert(constant, eltwise->get_output_element_type(0)); - inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_shape(0)); - inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_shape(0)); + inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_partial_shape(0)); + inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (is_type(eltwise)) { // issue #40611 if ((eltwise->input(0).get_element_type() == element::i32) && (eltwise->output(0).get_element_type() == element::f32)) { diff --git a/inference-engine/src/low_precision_transformations/src/interpolate.cpp b/inference-engine/src/low_precision_transformations/src/interpolate.cpp index b8538bfd14b..c167a6713b6 100644 --- a/inference-engine/src/low_precision_transformations/src/interpolate.cpp +++ b/inference-engine/src/low_precision_transformations/src/interpolate.cpp @@ -72,7 +72,7 @@ bool InterpolateTransformation::isPrecisionPreserved(std::shared_ptr layer std::shared_ptr interpolate4 = as_type_ptr(layer); if (interpolate4) { const auto attrs = interpolate4->get_attrs(); - return attrs.mode == op::v4::Interpolate::InterpolateMode::nearest; + return attrs.mode == op::v4::Interpolate::InterpolateMode::NEAREST; } return false; @@ -108,7 +108,7 @@ bool InterpolateTransformation::canBeTransformed(const TransformationContext& co if (interpolate4) { const auto interpAttrs = interpolate4->get_attrs(); - if (interpAttrs.mode != op::v4::Interpolate::InterpolateMode::nearest) { + if (interpAttrs.mode != op::v4::Interpolate::InterpolateMode::NEAREST) { return false; } @@ -126,7 +126,7 @@ bool InterpolateTransformation::canBeTransformed(const TransformationContext& co } } - if (interpAttrs.coordinate_transformation_mode == op::v4::Interpolate::CoordinateTransformMode::align_corners) { + if (interpAttrs.coordinate_transformation_mode == op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS) { return false; } } diff --git a/inference-engine/src/low_precision_transformations/src/low_precision.cpp b/inference-engine/src/low_precision_transformations/src/low_precision.cpp index a138b484d7f..f33df2e5c89 100644 --- a/inference-engine/src/low_precision_transformations/src/low_precision.cpp +++ b/inference-engine/src/low_precision_transformations/src/low_precision.cpp @@ -50,6 +50,7 @@ #include "low_precision/multiply.hpp" #include "low_precision/mvn.hpp" #include "low_precision/normalize_l2.hpp" +#include "low_precision/pad.hpp" #include "low_precision/prelu.hpp" #include "low_precision/reduce_max.hpp" #include "low_precision/reduce_mean.hpp" @@ -219,6 +220,7 @@ bool ngraph::pass::low_precision::LowPrecision::run_on_function(std::shared_ptr< common->add_matcher(params); common->add_matcher(params); common->add_matcher(params); + common->add_matcher(params); common->add_matcher(params); common->add_matcher(params); common->add_matcher(params); diff --git a/inference-engine/src/low_precision_transformations/src/markup_precisions.cpp b/inference-engine/src/low_precision_transformations/src/markup_precisions.cpp index 17747179345..7cf2c5b3236 100644 --- a/inference-engine/src/low_precision_transformations/src/markup_precisions.cpp +++ b/inference-engine/src/low_precision_transformations/src/markup_precisions.cpp @@ -141,6 +141,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::isPrecisionPreserved(const s { name() }, { name() }, // TODO: there are conditions + { name() }, { name() }, { name() }, { name() }, @@ -166,7 +167,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::isPrecisionPreserved(const s std::shared_ptr interpolate4 = as_type_ptr(node); if (interpolate4) { const auto attrs = interpolate4->get_attrs(); - return attrs.mode == op::v4::Interpolate::InterpolateMode::nearest; + return attrs.mode == op::v4::Interpolate::InterpolateMode::NEAREST; } } @@ -194,6 +195,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::isSupported(const std::share { name() }, { name() }, { name() }, + { name() }, { name() }, { name() }, { name() }, diff --git a/inference-engine/src/low_precision_transformations/src/mat_mul.cpp b/inference-engine/src/low_precision_transformations/src/mat_mul.cpp index 693d0e6490e..83f08fd4ed3 100644 --- a/inference-engine/src/low_precision_transformations/src/mat_mul.cpp +++ b/inference-engine/src/low_precision_transformations/src/mat_mul.cpp @@ -94,7 +94,10 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat Shape(dequantization1.subtract->get_output_partial_shape(0).rank().get_length(), 1) : dequantization1.subtractConstant->get_shape(); - const auto weightsShape = newMatMul->get_input_shape(1); + const auto weightsPShape = newMatMul->get_input_partial_shape(1); + assert(weightsPShape.is_static()); + const auto weightsShape = weightsPShape.to_shape(); + const size_t firstWeightsIdx = matMul->get_transpose_b() ? weightsShape.size() - 1ul : weightsShape.size() - 2ul; const size_t lastDataIdx = matMul->get_transpose_a() ? broadcastShape.size() - 2 : broadcastShape.size() - 1; broadcastShape[lastDataIdx] = weightsShape[firstWeightsIdx]; @@ -118,8 +121,8 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat parent = newSubtract; } - auto transpose = [](const std::shared_ptr& node) -> std::shared_ptr { - const Shape outputShape = node->get_output_shape(0); + auto transpose = [](const std::shared_ptr& node) -> std::shared_ptr { + const Shape outputShape = node->get_shape(); if (outputShape.size() < 2ul) { return node; } @@ -153,7 +156,7 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat } } - const auto newMulConst = NetworkHelper::toScalarIfPossible(fold( + const auto newMulConst = NetworkHelper::toScalarIfPossible(fold( mulConst1, foldConvert(mulConst2, element::f32))); diff --git a/inference-engine/src/low_precision_transformations/src/multiply_to_group_convolution.cpp b/inference-engine/src/low_precision_transformations/src/multiply_to_group_convolution.cpp index 9b4a6147b61..6851a159fee 100644 --- a/inference-engine/src/low_precision_transformations/src/multiply_to_group_convolution.cpp +++ b/inference-engine/src/low_precision_transformations/src/multiply_to_group_convolution.cpp @@ -164,17 +164,17 @@ bool MultiplyToGroupConvolutionTransformation::canBeTransformed(const Transforma Shape constShape; int inputIndex; - if (is_type(operation->get_input_node_shared_ptr(1))) { + if (const auto constant = as_type_ptr(operation->get_input_node_shared_ptr(1))) { inputIndex = 0; - constShape = operation->get_input_shape(1); + constShape = constant->get_shape(); if (is_type(operation->get_input_node_shared_ptr(0)) || - (is_type(operation->get_input_node_shared_ptr(0)) && + (is_type(operation->get_input_node_shared_ptr(0)) && is_type(operation->get_input_node_shared_ptr(0)->get_input_node_shared_ptr(0)))) { return false; } - } else if (is_type(operation->get_input_node_shared_ptr(0))) { + } else if (const auto constant = as_type_ptr(operation->get_input_node_shared_ptr(0))) { inputIndex = 1; - constShape = operation->get_input_shape(0); + constShape = constant->get_shape(); } else { return false; } diff --git a/inference-engine/src/low_precision_transformations/src/network_helper.cpp b/inference-engine/src/low_precision_transformations/src/network_helper.cpp index 47b624236b0..32c6a1ce523 100644 --- a/inference-engine/src/low_precision_transformations/src/network_helper.cpp +++ b/inference-engine/src/low_precision_transformations/src/network_helper.cpp @@ -191,12 +191,12 @@ size_t NetworkHelper::getInputChannelsCount(std::shared_ptr layer) { } size_t NetworkHelper::getGroupsCount(std::shared_ptr layer) { - if (as_type_ptr(layer)) { + if (is_type(layer)) { return 1; - } else if (auto group_convolution = as_type_ptr(layer)) { - return layer->get_input_shape(1)[0]; // input weights for opset1::GC is in format GOI..., see the specification + } else if (is_type(layer)) { + return layer->get_input_partial_shape(1)[0].get_length(); // input weights for opset1::GC is in format GOI..., see the specification } else { - THROW_TRANSFORMATION_EXCEPTION << "Invalid layer type of " << layer->get_friendly_name() << "; expected Convolutino or GroupConvolution"; + THROW_TRANSFORMATION_EXCEPTION << "Invalid layer type of " << layer->get_friendly_name() << "; expected Convolution or GroupConvolution"; } } @@ -239,9 +239,15 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptrget_input_node_shared_ptr(multiplyBranch == 0 ? 1 : 0); std::shared_ptr bDivA; - if (shape_size(b->get_output_shape(0)) == 1 || - shape_size(a->get_output_shape(0)) == 1 || - shape_size(b->get_output_shape(0)) == shape_size(a->get_output_shape(0))) { + const auto aPShape = a->get_output_partial_shape(0); + assert(aPShape.is_static()); + const auto aShape = aPShape.to_shape(); + + const auto bPShape = b->get_output_partial_shape(0); + assert(bPShape.is_static()); + const auto bShape = bPShape.to_shape(); + + if ((shape_size(bShape) == 1) || (shape_size(aShape) == 1) || (shape_size(bShape) == shape_size(aShape))) { // safely division to avoid NaN const std::vector bValues = as_type_ptr(b)->cast_vector(); const std::vector aValues = as_type_ptr(a)->cast_vector(); @@ -263,7 +269,7 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptrget_output_element_type(0); bDivA = std::make_shared( aPrecision, - aBroadcasted ? b->get_output_shape(0) : a->get_output_shape(0), + aBroadcasted ? bShape : aShape, bDivAValues); } else { b = foldConvert(b, element::f32); @@ -463,7 +469,14 @@ std::shared_ptr NetworkHelper::optimizeMultipliesAfter } auto newInput = multiply->input_value(1 - constant1->output(0).get_target_inputs().begin()->get_index()); - auto newConst = fold(constant1, constant2); + auto multiplyResult = fold(constant1, constant2); + { + // optimize constant shape: used in rfcn-resnet101-coco + const auto multiplyResultConstant = as_type_ptr(multiplyResult); + if ((multiplyResultConstant != nullptr) && NetworkHelper::isScalarLike(multiplyResultConstant)) { + multiplyResult = NetworkHelper::toScalar(multiplyResultConstant); + } + } auto inputPrecision0 = nextMultiply->get_origin_input_type(0); auto inputPrecision1 = nextMultiply->get_origin_input_type(1); auto outputPrecision = nextMultiply->get_overridden_output_type(0); @@ -472,7 +485,7 @@ std::shared_ptr NetworkHelper::optimizeMultipliesAfter std::vector{ inputPrecision0, inputPrecision1 }, std::vector{ outputPrecision }, ngraph::op::TemporaryReplaceOutputType(newInput, inputPrecision0).get(), - ngraph::op::TemporaryReplaceOutputType(newConst, inputPrecision1).get()); + ngraph::op::TemporaryReplaceOutputType(multiplyResult, inputPrecision1).get()); copy_runtime_info(multiply, newMultiply); replace_node(nextMultiply, newMultiply); return newMultiply; @@ -734,9 +747,12 @@ std::shared_ptr NetworkHelper::foldFakeQuantize( auto constant = as_type_ptr(fq->get_input_node_shared_ptr(0)); if (constant) { - const bool roundValues = roundValuesWasSet ? roundValuesArg : fq->output(0).get_element_type().is_integral(); + const bool roundValues = roundValuesWasSet ? roundValuesArg : fq->get_output_element_type(0).is_integral(); + + const auto constPShape = fq->get_output_partial_shape(0); + assert(constPShape.is_static()); + const Shape constShape = constPShape.to_shape(); - Shape constShape = fq->get_output_shape(0); if (constShape.empty() || constShape.size() > 5lu) { THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected dimensions count " << constShape.size(); } @@ -1117,7 +1133,7 @@ FakeQuantizeDequantization NetworkHelper::makeDequantization( const float dequantizationMul, const float dequantizationSub, const ngraph::element::Type originalPrecision, - const ngraph::PartialShape dataNodeOutputShape, + const ngraph::PartialShape& dataNodeOutputShape, element::Type precision, const ngraph::element::Type deqPrecision, std::shared_ptr input) { @@ -1767,7 +1783,9 @@ std::vector NetworkHelper::precisionIntersection( bool NetworkHelper::isFQByDynamicDimension(const std::shared_ptr& fq) { const auto pInputShape = fq->get_input_partial_shape(0); - auto olShape = fq->get_input_shape(3); + const auto olPShape = fq->get_input_partial_shape(3); + assert(olPShape.is_static()); + auto olShape = olPShape.to_shape(); if (shape_size(olShape) > 1ul) { if (pInputShape.rank().is_dynamic()) { diff --git a/inference-engine/src/low_precision_transformations/src/normalize_l2.cpp b/inference-engine/src/low_precision_transformations/src/normalize_l2.cpp index 0ec9876e309..1d269094762 100644 --- a/inference-engine/src/low_precision_transformations/src/normalize_l2.cpp +++ b/inference-engine/src/low_precision_transformations/src/normalize_l2.cpp @@ -78,12 +78,12 @@ bool NormalizeL2Transformation::canBeTransformed(const TransformationContext& co const std::vector axesByChannels = { 1, 2, 3 }; std::vector axesValues = axes->cast_vector(); - if (!(axesValues == axesAcrossSpatial || axesValues == axesByChannels)) { + if ((axesValues != axesAcrossSpatial) && (axesValues != axesByChannels)) { return false; } - const ngraph::Shape outputShape = scalesConst->get_output_shape(0); - const size_t size = ngraph::shape_size(outputShape); + const Shape outputShape = scalesConst->get_shape(); + const size_t size = shape_size(outputShape); if (size != 1ul) { const auto channelsInterval = operation->get_output_partial_shape(0)[1]; if (channelsInterval.is_dynamic() || static_cast(channelsInterval.get_length()) != size) { diff --git a/inference-engine/src/low_precision_transformations/src/pad.cpp b/inference-engine/src/low_precision_transformations/src/pad.cpp new file mode 100644 index 00000000000..88141e8b5fc --- /dev/null +++ b/inference-engine/src/low_precision_transformations/src/pad.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "low_precision/pad.hpp" + +#include +#include + +#include +#include "low_precision/network_helper.hpp" + +namespace ngraph { +namespace pass { +namespace low_precision { + +NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::PadTransformation, "PadTransformation", 0); + +PadTransformation::PadTransformation(const Params& params) : LayerTransformation(params) { + auto mul = pattern::wrap_type(); + auto padsBegin = pattern::wrap_type(); + auto padsEnd = pattern::wrap_type(); + auto padsValue = pattern::wrap_type(); + auto matcher = pattern::wrap_type({ mul, padsBegin, padsEnd, padsValue }); + + ngraph::graph_rewrite_callback callback = [this](pattern::Matcher& m) { + auto op = m.get_match_root(); + if (transformation_callback(op)) { + return false; + } + return transform(*context, m); + }; + + auto m = std::make_shared(matcher, "PadTransformation"); + this->register_matcher(m, callback); +} + +bool PadTransformation::transform(TransformationContext& context, ngraph::pattern::Matcher& m) { + if (!canBeTransformed(context, m.get_match_root())) { + return false; + } + + const auto pad = as_type_ptr(NetworkHelper::separateInStandaloneBranch(m.get_match_root())); + const auto padConstant = as_type_ptr(pad->get_input_node_shared_ptr(3)); + const auto padConstantValue = padConstant->cast_vector()[0]; + + const auto padsBegin = pad->get_pads_begin(); + const auto padsEnd = pad->get_pads_end(); + const auto padMode = pad->get_pad_mode(); + + auto dequantization = NetworkHelper::getDequantization(pad); + + if (padMode == op::PadMode::CONSTANT) { + auto bcastConstant = [&](const std::shared_ptr &constant) { + size_t padIdx = 0; + for (size_t i = 0; i < padsBegin.size(); ++i) { + if (padsBegin[i] != 0 || padsEnd[i] != 0) { + padIdx = i; + break; + } + } + + const auto inputPShape = pad->get_input_partial_shape(0); + assert(inputPShape[padIdx].is_static()); + assert(inputPShape.rank().is_static()); + auto bcastedShape = Shape(inputPShape.rank().get_length(), 1ul); + bcastedShape[padIdx] = inputPShape[padIdx].get_length(); + + const auto bCastConst = opset1::Constant::create(element::i32, Shape{bcastedShape.size()}, bcastedShape); + return as_type_ptr(fold(constant, bCastConst)); + }; + + if (dequantization.subtract && shape_size(dequantization.subtractConstant->get_shape()) == 1ul) { + const auto broadcastedConstant = bcastConstant(dequantization.subtractConstant); + replace_node(dequantization.subtractConstant, broadcastedConstant); + dequantization.subtractConstant = broadcastedConstant; + } + + if (padConstantValue != 0.f && shape_size(dequantization.multiplyConstant->get_shape()) == 1ul) { + const auto broadcastedConstant = bcastConstant(dequantization.multiplyConstant); + replace_node(dequantization.multiplyConstant, broadcastedConstant); + dequantization.multiplyConstant = broadcastedConstant; + } + } + + auto foldConstantIfNecessary = [&padMode, &padsBegin, &padsEnd]( + const std::shared_ptr& constant, + const std::shared_ptr& pad, + float padVal) { + const auto constantShape = constant->get_shape(); + if (shape_size(constantShape) == 1ul) { + return NetworkHelper::toScalar(constant); + } + + std::vector padsForConstantBegin(constantShape.size(), 0ul); + std::vector padsForConstantEnd(constantShape.size(), 0ul); + bool foldingIsNecessary = false; + + // folding is necessary when dequantization and padding by the same dimension + for (size_t i = 0; i < constantShape.size(); ++i) { + if (padsBegin[i] != 0ul && constantShape[i] != 1ul) { + foldingIsNecessary = true; + padsForConstantBegin[i] = padsBegin[i]; + } + + if (padsEnd[i] != 0ul && constantShape[i] != 1ul) { + foldingIsNecessary = true; + padsForConstantEnd[i] = padsEnd[i]; + } + } + + if (foldingIsNecessary) { + const auto beginConst = opset1::Constant::create(element::u32, { padsForConstantBegin.size() }, padsForConstantBegin); + const auto endConst = opset1::Constant::create(element::u32, { padsForConstantEnd.size() }, padsForConstantEnd); + const auto padValueConstant = opset1::Constant::create(constant->get_element_type(), Shape{}, { padVal }); + const auto foldedConstant = fold(constant, beginConst, endConst, padValueConstant, padMode); + return as_type_ptr(foldedConstant); + } else { + return constant; + } + }; + + if (dequantization.subtract) { + const auto normalizedSubConst = NetworkHelper::normalizeDequantizationShape(dequantization.subtract); + float padValueForSub = padConstantValue; + if (padMode == op::PadMode::CONSTANT) { + padValueForSub = 0.f; + } + + const auto newSubConstant = foldConstantIfNecessary(normalizedSubConst, pad, padValueForSub); + replace_node(normalizedSubConst, newSubConstant); + dequantization.subtractConstant = newSubConstant; + } + + { + const auto normalizedMulConst = NetworkHelper::normalizeDequantizationShape(dequantization.multiply); + float padValueForMul = padConstantValue; + if (padMode == op::PadMode::CONSTANT) { + padValueForMul = 1.f; + } + + const auto newMulConstant = foldConstantIfNecessary(normalizedMulConst, pad, padValueForMul); + replace_node(normalizedMulConst, newMulConstant); + dequantization.multiplyConstant = newMulConstant; + } + + // we must convert pad value in low precision + const auto convertedZero = opset1::Constant::create(dequantization.data.get_element_type(), Shape{}, { padConstantValue }); + pad->set_argument(3, convertedZero); + + moveDequantizationAfter(context, pad, dequantization, true); + return true; +} + +bool PadTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr op) const { + if (!LayerTransformation::canBeTransformedSpatialDimension(context, op)) { + return false; + } + + const auto pad = as_type_ptr(op); + if (!pad) { + return false; + } + + const auto dequantization = NetworkHelper::getDequantization(op); + if (dequantization.empty()) { + return false; + } + + const auto mode = pad->get_pad_mode(); + if (mode == op::PadMode::CONSTANT) { + auto padAndDqByTheSameDimension = [&](const std::shared_ptr& deqConst) { + const auto padsBegin = pad->get_pads_begin(); + const auto padsEnd = pad->get_pads_end(); + + int beginNonZeroIdx = -1; + for (size_t i = 0; i < padsBegin.size(); ++i) { + const bool padDimensionNotUnique = (beginNonZeroIdx != -1) && (padsBegin[i] != 0); + if (padDimensionNotUnique) { + return false; + } + + if (padsBegin[i] != 0) { + beginNonZeroIdx = i; + } + } + + int endNonZeroIdx = -1; + for (size_t i = 0; i < padsEnd.size(); ++i) { + const bool padDimensionNotUnique = (endNonZeroIdx != -1) && (padsEnd[i] != 0); + if (padDimensionNotUnique) { + return false; + } + + if (padsEnd[i] != 0) { + endNonZeroIdx = i; + } + } + + if ((beginNonZeroIdx != endNonZeroIdx) && (beginNonZeroIdx != -1) && (endNonZeroIdx != -1)) { + return false; + } + + const size_t paddingDimension = beginNonZeroIdx != -1 ? beginNonZeroIdx : endNonZeroIdx; + const auto padInputPShape = pad->get_input_partial_shape(0); + const auto padInputRank = padInputPShape.rank(); + if (padInputRank.is_dynamic() || padInputPShape[paddingDimension].is_dynamic()) { + return false; + } + + + const size_t inputRankValue = padInputRank.get_length(); + auto deqShape = deqConst->get_shape(); + if (shape_size(deqShape) > 1ul) { + while (deqShape.size() < inputRankValue) { + deqShape.insert(deqShape.begin(), 1ul); + } + + for (size_t i = 0; i < deqShape.size(); ++i) { + const bool deqAndPadDimensionsMismatched = (deqShape[i] > 1ul) && (i != paddingDimension); + if (deqAndPadDimensionsMismatched) { + return false; + } + } + } + + return true; + }; + + if (dequantization.subtract && !padAndDqByTheSameDimension(dequantization.subtractConstant)) { + return false; + } + + const auto constant = as_type_ptr(pad->get_input_node_shared_ptr(3)); + const auto constantValue = constant->cast_vector()[0]; + if (constantValue != 0.f && !padAndDqByTheSameDimension(dequantization.multiplyConstant)) { + return false; + } + } + + if (mode == op::PadMode::REFLECT) { + auto deqShape = dequantization.multiplyConstant->get_shape(); + if (shape_size(deqShape) == 1ul) { + return true; + } else { + const auto padInputRank = pad->get_input_partial_shape(0).rank(); + if (padInputRank.is_dynamic()) { + return false; + } + + const size_t inputRankValue = padInputRank.get_length(); + while (deqShape.size() < inputRankValue) { + deqShape.insert(deqShape.begin(), 1ul); + } + + const auto padsBegin = pad->get_pads_begin(); + const auto padsEnd = pad->get_pads_end(); + + // PadTransformation with "REFLECT" mode doesn't support dequantization and padding by the same dimension + for (size_t i = 0; i < deqShape.size(); ++i) { + if (deqShape[i] != 1ul && (padsBegin[i] != 0ul || padsEnd[i] != 0ul)) { + return false; + } + } + } + } + + return true; +} + +bool PadTransformation::isPrecisionPreserved(std::shared_ptr layer) const noexcept { + return true; +} + +} // namespace low_precision +} // namespace pass +} // namespace ngraph diff --git a/inference-engine/src/low_precision_transformations/src/reshape.cpp b/inference-engine/src/low_precision_transformations/src/reshape.cpp index b94e62320e4..e8263bd7528 100644 --- a/inference-engine/src/low_precision_transformations/src/reshape.cpp +++ b/inference-engine/src/low_precision_transformations/src/reshape.cpp @@ -47,7 +47,7 @@ void reshapeDequantizationConstant(const std::shared_ptr& resha auto replaceConstant = [](const std::shared_ptr& reshape, const std::shared_ptr& originalConstant) { // reshape for element-wise constant is not required auto constantShape = originalConstant->get_shape(); - if (shape_size(constantShape) == 1ul) { + if (NetworkHelper::isScalarLike(originalConstant)) { if (!constantShape.empty()) { const auto newConstant = NetworkHelper::toScalar(originalConstant); replace_node(originalConstant, newConstant); @@ -75,19 +75,28 @@ void reshapeDequantizationConstant(const std::shared_ptr& resha return; } - Shape newOperationConstantBroadcastedShape = originalConstant->output(0).get_shape(); - // add dimensions to broadcast values - if (newOperationConstantBroadcastedShape.size() == 2ul) { - newOperationConstantBroadcastedShape.push_back(dimensionsToBroadcast); - } else { - newOperationConstantBroadcastedShape[2] = dimensionsToBroadcast; - } - const std::shared_ptr broadcastedConstant = fold( - originalConstant, - std::make_shared( + auto getBCastedConst = [](const std::shared_ptr& constant, size_t dimensionsToBroadcast) -> std::shared_ptr { + if (dimensionsToBroadcast == 1ul) { + return constant; + } + + Shape newOperationConstantBroadcastedShape = constant->get_shape(); + // add dimensions to broadcast values + if (newOperationConstantBroadcastedShape.size() == 2ul) { + newOperationConstantBroadcastedShape.push_back(dimensionsToBroadcast); + } else { + newOperationConstantBroadcastedShape[2] = dimensionsToBroadcast; + } + + const auto targetShapeConstant = opset1::Constant::create( element::i32, - Shape({ newOperationConstantBroadcastedShape.size() }), - newOperationConstantBroadcastedShape)); + Shape{ newOperationConstantBroadcastedShape.size() }, + newOperationConstantBroadcastedShape); + + return fold(constant, targetShapeConstant); + }; + + const std::shared_ptr broadcastedConstant = getBCastedConst(originalConstant, dimensionsToBroadcast); std::vector newReshapeConstValues(reshapeOutputRank.get_length(), 1ul); newReshapeConstValues[1] = reshapeOutputPShape[1].get_length(); @@ -190,7 +199,7 @@ bool ReshapeTransformation::canBeTransformed(const TransformationContext& contex subtractShapeWithBatch.insert(subtractShapeWithBatch.begin(), 1ul); } - const Shape multiplyShape = dequantization.multiply == nullptr ? Shape{} : dequantization.multiply->input(1).get_shape(); + const Shape multiplyShape = dequantization.multiply == nullptr ? Shape{} : dequantization.multiplyConstant->get_shape(); Shape multiplyShapeWithBatch = multiplyShape; if ((dequantization.multiply != nullptr) && (multiplyShapeWithBatch.size() > 1ul) && diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/avg_pool_precision_preserved_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/avg_pool_precision_preserved_attribute.cpp index 3bafe518a91..aba2aa578e5 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/avg_pool_precision_preserved_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/avg_pool_precision_preserved_attribute.cpp @@ -9,6 +9,7 @@ #include using namespace ngraph; +using namespace ov; template class ngraph::VariantImpl; diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp index cb786a8af36..2425b3f1e12 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp @@ -12,6 +12,7 @@ #include "low_precision/network_helper.hpp" using namespace ngraph; +using namespace ov; using namespace ngraph::pass::low_precision; IntervalsAlignmentAttribute::IntervalsAlignmentAttribute( diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/per_tensor_quantization_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/per_tensor_quantization_attribute.cpp index fe418173f2c..0036e9e378a 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/per_tensor_quantization_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/per_tensor_quantization_attribute.cpp @@ -5,6 +5,7 @@ #include "low_precision/rt_info/per_tensor_quantization_attribute.hpp" using namespace ngraph; +using namespace ov; template class ngraph::VariantImpl; -constexpr VariantTypeInfo VariantWrapper::type_info; \ No newline at end of file +constexpr VariantTypeInfo VariantWrapper::type_info; diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/precision_preserved_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/precision_preserved_attribute.cpp index 8e8a9b0b62f..c2b94e425b0 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/precision_preserved_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/precision_preserved_attribute.cpp @@ -8,6 +8,7 @@ #include using namespace ngraph; +using namespace ov; PrecisionPreservedAttribute::PrecisionPreservedAttribute(const bool value) { sharedValue->value = value; diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/precisions_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/precisions_attribute.cpp index c69fc1d9b69..334f3a3eae3 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/precisions_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/precisions_attribute.cpp @@ -14,6 +14,7 @@ #include "low_precision/network_helper.hpp" using namespace ngraph; +using namespace ov; // order defines default precision const std::vector PrecisionsAttribute::defaultPrecisions = { ngraph::element::u8, ngraph::element::i8 }; diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/quantization_alignment_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/quantization_alignment_attribute.cpp index e02c8153b2c..b95a9567a3e 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/quantization_alignment_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/quantization_alignment_attribute.cpp @@ -12,6 +12,7 @@ #include #include "low_precision/network_helper.hpp" +using namespace ov; using namespace ngraph; using namespace ngraph::pass::low_precision; diff --git a/inference-engine/src/low_precision_transformations/src/transpose.cpp b/inference-engine/src/low_precision_transformations/src/transpose.cpp index 66f29a66ec8..a7be7c7f6f4 100644 --- a/inference-engine/src/low_precision_transformations/src/transpose.cpp +++ b/inference-engine/src/low_precision_transformations/src/transpose.cpp @@ -42,47 +42,40 @@ void transposeDequantizationConstant(std::shared_ptr& transpose) { return; } - if (dequantization.multiply->get_input_node_ptr(1)->get_output_shape(0).size() > 1ul) { - auto transposeDeqConstant = []( - std::shared_ptr dequantizationConstant, - const PartialShape& transposeOutputShape, - const std::shared_ptr& transposeConstant) -> std::shared_ptr { - const auto dequantizationShape = dequantizationConstant->get_output_shape(0); - if (dequantizationShape.empty() || (dequantizationShape.size() == 1ul)) { - return nullptr; + auto transposeDeqConstant = []( + const std::shared_ptr& dequantizationConstant, + const PartialShape& transposeOutputPShape, + const std::shared_ptr& transposeConstant) -> std::shared_ptr { + const auto constantShape = dequantizationConstant->get_shape(); + if (shape_size(constantShape) == 1ul) { + return NetworkHelper::toScalar(dequantizationConstant); } - if (dequantizationShape.size() != static_cast(transposeOutputShape.rank().get_length())) { - dequantizationConstant = fold( - dequantizationConstant, - std::make_shared(element::i32, Shape{ 1 }, std::vector{0})); + assert(transposeOutputPShape.rank().is_static()); + const size_t transposeOutRank = transposeOutputPShape.rank().get_length(); + if (constantShape.size() != transposeOutRank) { + const auto unsqueezeConst = opset1::Constant::create(element::i32, Shape{ 1 }, std::vector{ 0 }); + const auto deqConstantWithBatch = fold(dequantizationConstant, unsqueezeConst); + return fold(deqConstantWithBatch, transposeConstant); + } else { + return fold(dequantizationConstant, transposeConstant); } - return fold(dequantizationConstant, transposeConstant); - }; + }; - if (dequantization.subtract != nullptr) { - auto constant = transposeDeqConstant( - dequantization.subtractConstant, - transpose->get_output_partial_shape(0), - transpose->get_input_node_shared_ptr(1)); - if (constant != nullptr) { - replace_node( - dequantization.subtract->get_input_node_shared_ptr(1), - constant); - } - } + if (dequantization.subtract != nullptr) { + const auto constant = transposeDeqConstant( + dequantization.subtractConstant, + transpose->get_output_partial_shape(0), + transpose->get_input_node_shared_ptr(1)); + replace_node(dequantization.subtractConstant, constant); + } - if (dequantization.multiply != nullptr) { - auto constant = transposeDeqConstant( - dequantization.multiplyConstant, - transpose->get_output_partial_shape(0), - transpose->get_input_node_shared_ptr(1)); - if (constant != nullptr) { - replace_node( - dequantization.multiply->get_input_node_shared_ptr(1), - constant); - } - } + if (dequantization.multiply != nullptr) { + const auto constant = transposeDeqConstant( + dequantization.multiplyConstant, + transpose->get_output_partial_shape(0), + transpose->get_input_node_shared_ptr(1)); + replace_node(dequantization.multiplyConstant, constant); } } @@ -113,7 +106,7 @@ bool TransposeTransformation::canBeTransformed(const TransformationContext& cont } const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op); - const bool isPerTensor = [&] { + const bool isPerTensor = [&] { if (dequantization.subtractConstant != nullptr) { if (!NetworkHelper::isScalarLike(dequantization.subtractConstant)) { return false; diff --git a/inference-engine/src/low_precision_transformations/src/weightable_layer_transformation.cpp b/inference-engine/src/low_precision_transformations/src/weightable_layer_transformation.cpp index 402327f277a..6649492dd55 100644 --- a/inference-engine/src/low_precision_transformations/src/weightable_layer_transformation.cpp +++ b/inference-engine/src/low_precision_transformations/src/weightable_layer_transformation.cpp @@ -74,14 +74,13 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext return false; } - const std::shared_ptr multiplyConst = as_type_ptr(dequantization.multiply->get_input_node_shared_ptr(1)); - const Shape multiplyConstShape = multiplyConst->get_output_shape(0); + const Shape multiplyConstShape = dequantization.multiplyConstant->get_shape(); if (!multiplyConstShape.empty() && (shape_size(multiplyConstShape) != 1ul)) { const size_t groupsCount = NetworkHelper::getGroupsCount(layer); - const ngraph::PartialShape inputPShape = layer->get_input_partial_shape(0); + const PartialShape inputPShape = layer->get_input_partial_shape(0); const size_t inputChannelsInGroup = inputPShape[1].get_length() / groupsCount; - const std::vector scales = multiplyConst->cast_vector(); + const std::vector scales = dequantization.multiplyConstant->cast_vector(); for (size_t group = 0; group < groupsCount; ++group) { for (size_t i = 0; i < inputChannelsInGroup; ++i) { if (scales[group * inputChannelsInGroup] != scales[group * inputChannelsInGroup + i]) { @@ -90,30 +89,33 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext } } - const ngraph::PartialShape outputPShape = layer->get_output_partial_shape(0); - const auto rank = outputPShape.rank().get_length(); - if ((rank != 4) && (rank != 5)) { + const PartialShape outputPShape = layer->get_output_partial_shape(0); + const auto rank = outputPShape.rank(); + if (rank.is_dynamic()) { + return false; + } + + const auto rankVal = rank.get_length(); + if ((rankVal != 4) && (rankVal != 5)) { return false; } } } else { - const std::shared_ptr multiply = as_type_ptr(layer->input_value(0).get_node_shared_ptr()); - if (multiply == nullptr) { + const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer); + if (dequantization.multiply == nullptr) { return false; } - // SS takes inputs [0: data, 1: scales, 2: shifts], takes scales (index = 1) - const std::shared_ptr multiplyConst = as_type_ptr(multiply->input_value(1).get_node_shared_ptr()); - if (multiplyConst == nullptr) { + if (dequantization.multiplyConstant == nullptr) { return false; } // exactly cast vector as original code has a conversion; // optimize cast: // two branches depending on real type of the constant? - const auto scalesBuffer = multiplyConst->cast_vector(); - size_t scalesBufferSize = shape_size(multiplyConst->get_output_shape(0)); - for (size_t i = 1lu; i < scalesBufferSize; ++i) { + const auto scalesBuffer = dequantization.multiplyConstant->cast_vector(); + size_t scalesBufferSize = shape_size(dequantization.multiplyConstant->get_shape()); + for (size_t i = 1ul; i < scalesBufferSize; ++i) { if (scalesBuffer[i - 1] != scalesBuffer[i]) { return false; } @@ -132,11 +134,11 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext // TODO Implement similar checks in other weightable operaitons - const std::shared_ptr reshapeFromWeights = as_type_ptr(layer->input_value(1).get_node_shared_ptr()); + const std::shared_ptr reshapeFromWeights = as_type_ptr(layer->get_input_node_shared_ptr(1)); std::shared_ptr fqFromWeights; if (reshapeFromWeights == nullptr) { - fqFromWeights = as_type_ptr(layer->input_value(1).get_node_shared_ptr()); + fqFromWeights = as_type_ptr(layer->get_input_node_shared_ptr(1)); if (fqFromWeights == nullptr) { const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, 1ul); fqFromWeights = as_type_ptr(dequantization.data.get_node_shared_ptr()); @@ -154,23 +156,29 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext return false; } - const Shape constOutputShape = fqFromWeights->get_input_node_ptr(3)->get_output_shape(0); - if (fqFromWeights->get_input_node_ptr(4)->get_output_shape(0) != constOutputShape) { + const auto olPShape = fqFromWeights->get_input_partial_shape(3); + const auto ohPShape = fqFromWeights->get_input_partial_shape(4); + if (olPShape.is_dynamic() || ohPShape.is_dynamic() || olPShape != ohPShape) { return false; } - const size_t outChannelsShapeIndex = is_type(layer) ? 1ul : 0ul; - if ( - // expected, it's ok: return true - (shape_size(constOutputShape) != 1ul) && - // not expected, something wrong: return false - ((constOutputShape.size() <= outChannelsShapeIndex) || - // Check if all dimensions of scale except the output channels are all ones - (shape_size(constOutputShape) != constOutputShape[outChannelsShapeIndex]) || - ((constOutputShape[outChannelsShapeIndex] != 1ul) && - (fqFromWeights->get_output_shape(0)[outChannelsShapeIndex] != constOutputShape[outChannelsShapeIndex])))) { + + const auto fqOutPShape = fqFromWeights->get_output_partial_shape(0); + const size_t outChannelsIdx = is_type(layer) ? 1ul : 0ul; + if (fqOutPShape.rank().is_dynamic() || fqOutPShape[outChannelsIdx].is_dynamic()) { return false; } + + const Shape constShape = olPShape.to_shape(); + if (shape_size(constShape) != 1ul) { + const size_t constChannels = constShape[outChannelsIdx]; + const size_t fqOutChannels = fqOutPShape[outChannelsIdx].get_length(); + const bool constChannelsAndFqChannelsMismatched = (constChannels != 1ul) && (fqOutChannels != constChannels); + + if ((constShape.size() <= outChannelsIdx) || (shape_size(constShape) != constChannels) || constChannelsAndFqChannelsMismatched) { + return false; + } + } } else { // TODO: LPT: is it possible to share with isQuantized? const FakeQuantizeDequantization dequantizationOnWeights = reshapeFromWeights == nullptr ? @@ -180,33 +188,33 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext return false; } - const opset1::Constant* weightsData = as_type(dequantizationOnWeights.data.get_node()); + const auto weightsData = as_type_ptr(dequantizationOnWeights.data.get_node_shared_ptr()); if (weightsData == nullptr) { return false; } - const ngraph::element::Type weightsDataPrecision = weightsData->output(0).get_element_type(); + const auto weightsDataPrecision = weightsData->get_element_type(); if (!DataPrecision::isSupported(weightsDataPrecision)) { return false; } if ((dequantizationOnWeights.subtract != nullptr) && (dequantizationOnWeights.subtractConvert != nullptr)) { - const auto subtractConstantType = dequantizationOnWeights.subtractConstant->output(0).get_element_type(); + const auto subtractConstantType = dequantizationOnWeights.subtractConstant->get_element_type(); if (subtractConstantType != weightsDataPrecision) { return false; } } - const size_t outChannelsShapeIndex = is_type(layer) ? 1ul : 0ul; + const size_t outChannelsIdx = is_type(layer) ? 1ul : 0ul; if (dequantizationOnWeights.subtract) { const auto subConstShape = dequantizationOnWeights.subtractConstant->get_shape(); - if (shape_size(subConstShape) > 1ul && shape_size(subConstShape) != subConstShape[outChannelsShapeIndex]) { + if (shape_size(subConstShape) > 1ul && shape_size(subConstShape) != subConstShape[outChannelsIdx]) { return false; } } if (dequantizationOnWeights.multiply) { const auto mulConstShape = dequantizationOnWeights.multiplyConstant->get_shape(); - if (shape_size(mulConstShape) > 1ul && shape_size(mulConstShape) != mulConstShape[outChannelsShapeIndex]) { + if (shape_size(mulConstShape) > 1ul && shape_size(mulConstShape) != mulConstShape[outChannelsIdx]) { return false; } } @@ -321,7 +329,7 @@ bool WeightableLayerTransformation::decomposeFakeQuantizeForWeightsPath(const st } bool WeightableLayerTransformation::isGroup(const std::shared_ptr& layer) { - if (!as_type_ptr(layer) && !as_type_ptr(layer)) { + if (!is_type(layer) && !is_type(layer)) { return false; } @@ -341,7 +349,7 @@ bool WeightableLayerTransformation::isDepthwise(const std::shared_ptr& lay } std::shared_ptr WeightableLayerTransformation::getFakeQuantizeOnWeights(const std::shared_ptr& node) { - auto fq = as_type_ptr(node->input_value(1).get_node_shared_ptr()); + auto fq = as_type_ptr(node->get_input_node_shared_ptr(1)); // TODO: temporary workaround if (fq == nullptr) { fq = as_type_ptr(node->get_input_node_ptr(1)->get_input_node_shared_ptr(0)); diff --git a/inference-engine/src/mkldnn_plugin/config.cpp b/inference-engine/src/mkldnn_plugin/config.cpp index c30cf428574..37715610c58 100644 --- a/inference-engine/src/mkldnn_plugin/config.cpp +++ b/inference-engine/src/mkldnn_plugin/config.cpp @@ -26,8 +26,13 @@ Config::Config() { // for the TBB code-path, additional configuration depending on the OS and CPU types #if (IE_THREAD == IE_THREAD_TBB || IE_THREAD == IE_THREAD_TBB_AUTO) #if defined(__APPLE__) || defined(_WIN32) - // 'CORES' is not implemented for Win/MacOS; so the 'NUMA' is default - streamExecutorConfig._threadBindingType = InferenceEngine::IStreamsExecutor::NUMA; + // 'CORES' is not implemented for Win/MacOS; so the 'NONE' or 'NUMA' is default + auto numaNodes = getAvailableNUMANodes(); + if (numaNodes.size() > 1) { + streamExecutorConfig._threadBindingType = InferenceEngine::IStreamsExecutor::NUMA; + } else { + streamExecutorConfig._threadBindingType = InferenceEngine::IStreamsExecutor::NONE; + } #endif if (getAvailableCoresTypes().size() > 1 /*Hybrid CPU*/) { diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp index 315b61724d3..b21b39f104a 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp @@ -12,8 +12,11 @@ #include "mkldnn_itt.h" #include "nodes/mkldnn_memory_node.hpp" #include - +#if ((IE_THREAD == IE_THREAD_TBB) || (IE_THREAD == IE_THREAD_TBB_AUTO)) +#include +#else #include +#endif #include #include #include @@ -32,6 +35,14 @@ MKLDNNExecNetwork::CreateInferRequestImpl(InferenceEngine::InputsDataMap network return std::make_shared(networkInputs, networkOutputs, std::static_pointer_cast(shared_from_this())); } +struct ImmediateSerialExecutor : public ITaskExecutor { + void run(InferenceEngine::Task task) override { + std::lock_guard l{_mutex}; + task(); + } + std::mutex _mutex; +}; + MKLDNNExecNetwork::MKLDNNExecNetwork(const InferenceEngine::CNNNetwork &network, const Config &cfg, const MKLDNNExtensionManager::Ptr& extMgr, @@ -61,11 +72,20 @@ MKLDNNExecNetwork::MKLDNNExecNetwork(const InferenceEngine::CNNNetwork &network, } else { auto streamsExecutorConfig = InferenceEngine::IStreamsExecutor::Config::MakeDefaultMultiThreaded(_cfg.streamExecutorConfig, isFloatModel); streamsExecutorConfig._name = "CPUStreamsExecutor"; - _taskExecutor = InferenceEngine::ExecutorManager::getInstance()->getIdleCPUStreamsExecutor(streamsExecutorConfig); +#if (IE_THREAD == IE_THREAD_TBB || IE_THREAD == IE_THREAD_TBB_AUTO) + _taskExecutor = std::make_shared(streamsExecutorConfig); +#else + _taskExecutor = ExecutorManager::getInstance()->getIdleCPUStreamsExecutor(streamsExecutorConfig); +#endif } if (0 != cfg.streamExecutorConfig._streams) { - _callbackExecutor = InferenceEngine::ExecutorManager::getInstance()->getIdleCPUStreamsExecutor( - IStreamsExecutor::Config{"CPUCallbackExecutor", 1, 0, IStreamsExecutor::ThreadBindingType::NONE}); +#if (IE_THREAD == IE_THREAD_TBB || IE_THREAD == IE_THREAD_TBB_AUTO) + // There is no additional threads but we still need serialize callback execution to preserve legacy behaviour + _callbackExecutor = std::make_shared(); +#else + _callbackExecutor = ExecutorManager::getInstance()->getIdleCPUStreamsExecutor( + IStreamsExecutor::Config{"CPUCallbackExecutor", 1, 0, IStreamsExecutor::ThreadBindingType::NONE}); +#endif } else { _callbackExecutor = _taskExecutor; } @@ -146,6 +166,19 @@ MKLDNNExecNetwork::Graph::Lock MKLDNNExecNetwork::GetGraph() { return graphLock; } +MKLDNNExecNetwork::Graph::Lock MKLDNNExecNetwork::GetGraph() const { + int streamId = 0; + int numaNodeId = 0; + auto streamsExecutor = dynamic_cast(_taskExecutor.get()); + if (nullptr != streamsExecutor) { + streamId = streamsExecutor->GetStreamId(); + numaNodeId = streamsExecutor->GetNumaNodeId(); + } + auto graphLock = Graph::Lock(_graphs[streamId % _graphs.size()]); + IE_ASSERT(graphLock._graph.IsReady()); + return graphLock; +} + void MKLDNNExecNetwork::setProperty(const std::map &properties) { { std::lock_guard lock{_cfgMutex}; @@ -171,9 +204,8 @@ InferenceEngine::CNNNetwork MKLDNNExecNetwork::GetExecGraphInfo() { } Parameter MKLDNNExecNetwork::GetConfig(const std::string &name) const { - if (_graphs.size() == 0) - IE_THROW() << "No graph was found"; - Config engConfig = const_cast(this)->GetGraph()._graph.getProperty(); + if (_graphs.size() == 0) IE_THROW() << "No graph was found"; + Config engConfig = GetGraph()._graph.getProperty(); auto option = engConfig._config.find(name); if (option != engConfig._config.end()) { return option->second; @@ -187,8 +219,7 @@ InferenceEngine::Parameter MKLDNNExecNetwork::GetMetric(const std::string &name) IE_THROW() << "No graph was found"; if (name == METRIC_KEY(NETWORK_NAME)) { - IE_SET_METRIC_RETURN(NETWORK_NAME, - const_cast(this)->GetGraph()._graph.dump().getName()); + IE_SET_METRIC_RETURN(NETWORK_NAME, GetGraph()._graph.dump().getName()); } else if (name == METRIC_KEY(SUPPORTED_METRICS)) { std::vector metrics; metrics.push_back(METRIC_KEY(NETWORK_NAME)); @@ -198,12 +229,12 @@ InferenceEngine::Parameter MKLDNNExecNetwork::GetMetric(const std::string &name) IE_SET_METRIC_RETURN(SUPPORTED_METRICS, metrics); } else if (name == METRIC_KEY(SUPPORTED_CONFIG_KEYS)) { std::vector configKeys; - for (auto && key : const_cast(this)->GetGraph()._graph.getProperty()._config) { + for (auto && key : GetGraph()._graph.getProperty()._config) { configKeys.push_back(key.first); } IE_SET_METRIC_RETURN(SUPPORTED_CONFIG_KEYS, configKeys); } else if (name == METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS)) { - Config engConfig = const_cast(this)->GetGraph()._graph.getProperty(); + Config engConfig = GetGraph()._graph.getProperty(); auto option = engConfig._config.find(CONFIG_KEY(CPU_THROUGHPUT_STREAMS)); IE_ASSERT(option != engConfig._config.end()); auto streams = std::stoi(option->second); diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.h b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.h index 22ed83c9401..a96098b133d 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.h @@ -59,8 +59,9 @@ protected: Graph& _graph; }; }; + // WARNING: Do not use _graphs directly. - std::deque _graphs; + mutable std::deque _graphs; NumaNodesWeights& _numaNodesWeights; /* WARNING: Use GetGraph() function to get access to graph in current stream. @@ -68,6 +69,8 @@ protected: * even from main thread */ Graph::Lock GetGraph(); + Graph::Lock GetGraph() const; + bool CanProcessDynBatch(const InferenceEngine::CNNNetwork &network) const; }; diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp index c7907aa5569..29820837762 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp @@ -24,22 +24,20 @@ #include #include #include "transformations/common_optimizations/convert_quantize_dequantize.hpp" -#include #include -#include #include #include #include #include -#include -#include +#include +#include #include #include #include #include +#include #include #include -#include #include #include #include @@ -53,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -249,8 +246,9 @@ static void Transformation(CNNNetwork& clonedNetwork, const Config& conf) { return false; }; - pass_config->set_callback( + pass_config->set_callback( [isSequencePrimitiveSupported](const_node_ptr &node) -> bool { return isSequencePrimitiveSupported(node); }); @@ -280,18 +278,17 @@ static void Transformation(CNNNetwork& clonedNetwork, const Config& conf) { return MKLDNNMVNNode::isSupportedOperation(node, errorMessage); }); + pass_config->set_callback( + [](const_node_ptr &node) -> bool { + std::string errorMsg; + return MKLDNNNormalizeL2Node::isSupportedOperation(node, errorMsg); + }); + pass_config->set_callback( [](const_node_ptr &node) -> bool { return node->input_value(0).get_partial_shape().rank().get_length() > 5; }); - auto normalizeL2FusionCallback = [](const_node_ptr &node) -> bool { - std::string errorMsg; - return !MKLDNNNormalizeL2Node::isSupportedOperation(node, errorMsg); - }; - pass_config->set_callback(normalizeL2FusionCallback); - pass_config->set_callback(normalizeL2FusionCallback); - // List of enabled/disabled transformations pass_config->disable(); pass_config->disable(); @@ -307,10 +304,11 @@ static void Transformation(CNNNetwork& clonedNetwork, const Config& conf) { pass_config->disable(); pass_config->disable(); pass_config->disable(); - pass_config->disable(); + pass_config->enable(); pass_config->enable(); pass_config->enable(); + pass_config->enable(); if (useLpt) { pass_config->set_callback([](const_node_ptr &node) -> bool { diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp index 4d29550eda0..370524be475 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp @@ -741,9 +741,10 @@ private: bool MKLDNNDeformableConvolutionNode::isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept { try { - const auto defConvNode = ngraph::as_type_ptr(op); - if (!defConvNode) { - errorMessage = "Node is not an instance of DeformableConvolution form the operation set v1."; + if (!one_of(op->get_type_info(), + ngraph::op::v1::DeformableConvolution::type_info, + ngraph::op::v8::DeformableConvolution::type_info)) { + errorMessage = "Node is not an instance of DeformableConvolution form the operation set v1 or v8."; return false; } } catch (...) { @@ -759,28 +760,35 @@ MKLDNNDeformableConvolutionNode::MKLDNNDeformableConvolutionNode(const std::shar if (!isSupportedOperation(op, errorMessage)) { IE_THROW(NotImplemented) << errorMessage; } - auto defConvNode = ngraph::as_type_ptr(op); + auto defConvNodeBase = std::dynamic_pointer_cast(op); - group = defConvNode->get_group(); - deformable_group = defConvNode->get_deformable_group(); - - auto& strides = defConvNode->get_strides(); + group = defConvNodeBase->get_group(); + deformable_group = defConvNodeBase->get_deformable_group(); + auto& strides = defConvNodeBase->get_strides(); for (int i = 0; i < strides.size(); i++) { stride.push_back(strides[i]); } - auto& dilations = defConvNode->get_dilations(); + auto& dilations = defConvNodeBase->get_dilations(); for (int i = 1; i <= dilations.size(); i++) { dilation.push_back(dilations[dilations.size() - i] - 1); } - paddingL = defConvNode->get_pads_begin(); + paddingL = defConvNodeBase->get_pads_begin(); + + if (op->get_type_info() == ngraph::op::v8::DeformableConvolution::type_info) { + auto defConvNode = std::dynamic_pointer_cast(op); + with_bilinear_pad = defConvNode->get_bilinear_interpolation_pad(); + } else { + with_bilinear_pad = false; + } + enforceRef = (op->get_type_info() == ngraph::op::v8::DeformableConvolution::type_info); } void MKLDNNDeformableConvolutionNode::getSupportedDescriptors() { std::string errorPrefix = "DeformableConvolution layer with name '" + getName() + "' "; - if (getParentEdges().size() != 3) + if (getParentEdges().size() != 3 && getParentEdges().size() != 4) IE_THROW() << errorPrefix << "has incorrect number of input edges"; if (getChildEdges().empty()) IE_THROW() << errorPrefix << "has incorrect number of output edges"; @@ -806,22 +814,29 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { if (!supportedPrimitiveDescriptors.empty()) return; + size_t inputsNumber = getOriginalInputsNumber(); NodeConfig config; config.dynBatchSupport = false; - config.inConfs.resize(3); + config.inConfs.resize(inputsNumber); config.inConfs[0].constant = false; config.inConfs[0].inPlace = -1; config.inConfs[1].constant = false; config.inConfs[1].inPlace = -1; - config.inConfs[1].constant = false; - config.inConfs[1].inPlace = -1; + config.inConfs[2].constant = false; + config.inConfs[2].inPlace = -1; + if (inputsNumber > 3) { + config.inConfs[3].constant = false; + config.inConfs[3].inPlace = -1; + } config.outConfs.resize(1); config.outConfs[0].constant = false; config.outConfs[0].inPlace = -1; impl_desc_type impl_type; - if (mayiuse(cpu::x64::avx512_common)) { + if (enforceRef) { + impl_type = impl_desc_type::ref; + } else if (mayiuse(cpu::x64::avx512_common)) { impl_type = impl_desc_type::jit_avx512; } else if (mayiuse(cpu::x64::avx2)) { impl_type = impl_desc_type::jit_avx2; @@ -831,8 +846,8 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { impl_type = impl_desc_type::ref; } - if (mayiuse(cpu::x64::sse41)) { - // optimzed implementation + if (!enforceRef && mayiuse(cpu::x64::sse41)) { + // optimized implementation auto dataFormat = memory::format_tag::nhwc; auto offFormat = memory::format_tag::nchw; auto weiFormat = group > 1 ? mayiuse(avx512_common) ? memory::format_tag::gOIhw16i16o : memory::format_tag::gOIhw8i8o @@ -842,8 +857,25 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { memory::data_type::f32, dataFormat); config.inConfs[1].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(1)->getShape().getStaticDims(), memory::data_type::f32, offFormat); - config.inConfs[2].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(2)->getShape().getStaticDims(), - memory::data_type::f32, weiFormat); + + auto& wDims = getParentEdgeAt(2)->getShape().getStaticDims(); + if (group > 1 && wDims.size() != 5) { + auto new_dims = InferenceEngine::SizeVector({group, div_up(wDims[0], group)}); + for (int i = 1; i < wDims.size(); i++) { + new_dims.push_back(wDims[i]); + } + config.inConfs[2].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(2)->getShape().getStaticDims(), + memory::data_type::f32, weiFormat); + } else { + config.inConfs[2].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(2)->getShape().getStaticDims(), + memory::data_type::f32, weiFormat); + } + + + if (inputsNumber > 3) { + config.inConfs[3].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(3)->getShape().getStaticDims(), + memory::data_type::f32, memory::format_tag::nchw); + } config.outConfs[0].desc = MKLDNNPlugin::make_unique(getChildEdgeAt(0)->getShape().getStaticDims(), memory::data_type::f32, dataFormat); supportedPrimitiveDescriptors.push_back({config, impl_type}); @@ -855,6 +887,10 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { memory::format_tag::nchw); config.inConfs[2].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(2)->getShape().getStaticDims(), memory::data_type::f32, memory::format_tag::oihw); + if (inputsNumber > 3) { + config.inConfs[3].desc = MKLDNNPlugin::make_unique(getParentEdgeAt(3)->getShape().getStaticDims(), memory::data_type::f32, + memory::format_tag::nchw); + } config.outConfs[0].desc = MKLDNNPlugin::make_unique(getChildEdgeAt(0)->getShape().getStaticDims(), memory::data_type::f32, memory::format_tag::nchw); supportedPrimitiveDescriptors.push_back({config, impl_type}); @@ -874,6 +910,7 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.dg = deformable_group; jcp.ngroups = group; + jcp.mb = srcDims[0]; jcp.oc = dstDims[1] / jcp.ngroups; @@ -884,9 +921,8 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.oh = dstDims[2]; jcp.ow = dstDims[3]; - bool with_groups = group > 1; - jcp.kh = weiDims[with_groups + 2]; - jcp.kw = weiDims[with_groups + 3]; + jcp.kh = weiDims[2]; + jcp.kw = weiDims[3]; jcp.t_pad = paddingL[0]; jcp.l_pad = paddingL[1]; @@ -898,6 +934,8 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.dilate_w = dilation[1]; jcp.with_bias = false; + jcp.with_bi_pad = with_bilinear_pad; + jcp.with_modulation = getParentEdges().size() > 3; const int simd_w = mayiuse(cpu::x64::avx512_common) ? 16 : 8; jcp.ic_block = simd_w; @@ -910,13 +948,16 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.typesize_in = sizeof(float); jcp.typesize_off = sizeof(float); jcp.typesize_out = sizeof(float); + jcp.typesize_modulation = sizeof(float); jcp.ur_w = mayiuse(cpu::x64::avx512_common) ? 6 : 3; jcp.nb_oc_blocking = !mayiuse(cpu::x64::avx2) ? 2 : 4; jcp.nthr = dnnl_get_max_threads(); - if (mayiuse(cpu::x64::avx512_common)) { + if (enforceRef) { + return; + } else if (mayiuse(cpu::x64::avx512_common)) { def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32(jcp)); } else if (mayiuse(cpu::x64::avx2)) { def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32(jcp)); @@ -930,9 +971,9 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const float* offsets, const float* weights, float* dst, const std::vector& src_strides, const std::vector& off_strides, - const std::vector& wei_strides, const std::vector& dst_strides) { + const std::vector& wei_strides, const std::vector& dst_strides, + const float* modulation, const std::vector& modulation_strides) { const bool with_groups = jcp.ngroups > 1; - const int G = jcp.ngroups; const int MB = jcp.mb; const int OH = jcp.oh; @@ -956,65 +997,79 @@ void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const f const int DG = jcp.dg; - const int channel_per_deformable_group = IC * G / DG; + const int channel_per_deformable_group = (IC * G) / DG; + const bool with_bi_pad = jcp.with_bi_pad; auto ker = [=](int g, int mb, int oc, int oh, int ow) { float d = 0; const int h_in = oh * KSH - padT; const int w_in = ow * KSW - padL; for (int ic = 0; ic < IC; ic++) { - const float *data_im_ptr = src + mb * src_strides[0] + (g * IC + ic) * src_strides[1] + h_in * src_strides[2] + w_in * src_strides[3]; - const int deformable_group_index = ic / channel_per_deformable_group; + const float *data_im_ptr = src + mb * src_strides[0] + (g * IC + ic) * src_strides[1]; + const int deformable_group_index = (IC * g + ic) / channel_per_deformable_group; const float *data_offset_ptr = offsets + mb * off_strides[0] + (deformable_group_index * 2 * KH * KW) * off_strides[1]; + const float *modulation_offset_ptr = nullptr; + if (modulation != nullptr) { + modulation_offset_ptr = modulation + mb * modulation_strides[0] + (deformable_group_index * KH * KW) * modulation_strides[1]; + } + for (int kh = 0; kh < KH; kh++) { for (int kw = 0; kw < KW; kw++) { const size_t data_offset_h_index = 2 * (kh * KW + kw) * off_strides[1] + oh * off_strides[2] + ow * off_strides[3]; const size_t data_offset_w_index = (2 * (kh * KW + kw) + 1) * off_strides[1] + oh * off_strides[2] + ow * off_strides[3]; const float offset_h = data_offset_ptr[data_offset_h_index]; const float offset_w = data_offset_ptr[data_offset_w_index]; - float val = 0.0f; - const float h_im = h_in + kh * (KDH + 1) + offset_h; - const float w_im = w_in + kw * (KDW + 1) + offset_w; - - if (h_im >= 0 && w_im >= 0 && h_im < IH && w_im < IW) { - float map_h = kh * (KDH + 1) + offset_h; - float map_w = kw * (KDW + 1) + offset_w; - const int cur_height = IH - h_in; - const int cur_width = IW - w_in; - int h_low = static_cast(floorf(map_h)); - int w_low = static_cast(floorf(map_w)); - int h_high; - int w_high; - if (h_low >= cur_height - 1) { - h_high = h_low = cur_height - 1; - map_h = static_cast(h_low); - } else { - h_high = h_low + 1; - } - - if (w_low >= cur_width - 1) { - w_high = w_low = cur_width - 1; - map_w = static_cast(w_low); - } else { - w_high = w_low + 1; - } + float map_h = h_in + kh * (KDH + 1) + offset_h; + float map_w = w_in + kw * (KDW + 1) + offset_w; + bool skip_compute; + if (with_bilinear_pad) { + skip_compute = !(static_cast(map_w) > -1 && + static_cast(map_w) < IW && + static_cast(map_h) > -1 && + static_cast(map_h) < IH); + } else { + skip_compute = !(map_w >= 0 && + map_w < IW && + map_h >= 0 && + map_h < IH); + } + if (!skip_compute) { + const int cur_h_end = IH; + const int cur_w_end = IW; + int h_low = with_bi_pad ? static_cast(floorf(map_h)) : + std::max(static_cast(floorf(map_h)), 0); + int w_low = with_bi_pad ? static_cast(floorf(map_w)) : + std::max(static_cast(floorf(map_w)), 0); + const int cur_h_start = h_low; + const int cur_w_start = w_low; + int h_high = with_bi_pad ? h_low + 1 : std::min(static_cast(ceilf(map_h)), cur_h_end - 1); + int w_high = with_bi_pad ? w_low + 1 : std::min(static_cast(ceilf(map_w)), cur_w_end - 1); float lh = map_h - h_low; float lw = map_w - w_low; float hh = 1 - lh, hw = 1 - lw; - float v1 = data_im_ptr[h_low * src_strides[2] + w_low * src_strides[3]]; - float v2 = data_im_ptr[h_low * src_strides[2] + w_high * src_strides[3]]; - float v3 = data_im_ptr[h_high * src_strides[2] + w_low * src_strides[3]]; - float v4 = data_im_ptr[h_high * src_strides[2] + w_high * src_strides[3]]; + float v1 = (cur_w_start >= 0 && cur_h_start >= 0) ? data_im_ptr[h_low * src_strides[2] + w_low * src_strides[3]] : 0.0f; + float v2 = (w_high < cur_w_end && cur_h_start >= 0) ? data_im_ptr[h_low * src_strides[2] + w_high * src_strides[3]] : 0.0f; + float v3 = (cur_w_start >= 0 && h_high < cur_h_end) ? data_im_ptr[h_high * src_strides[2] + w_low * src_strides[3]] : 0.0f; + float v4 = (w_high < cur_w_end && h_high < cur_h_end) ? data_im_ptr[h_high * src_strides[2] + w_high * src_strides[3]] : 0.0f; float w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; - val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + float val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); + + float modulation_scalar = 1.0f; + + if (modulation_offset_ptr != nullptr) { + size_t modulation_index = (kh * KW + kw) * modulation_strides[1] + oh * modulation_strides[2] + ow * modulation_strides[3]; + modulation_scalar = modulation_offset_ptr[modulation_index]; + } + + const float weight = with_groups ? weights[(g + oc / G) * wei_strides[0] + ic * wei_strides[1] + kh * wei_strides[2] + + kw * wei_strides[3]] + : weights[oc * wei_strides[0] + ic * wei_strides[1] + kh * wei_strides[2] + kw * wei_strides[3]]; + d += val * weight * modulation_scalar; } - d += val * (with_groups ? weights[g * wei_strides[0] + oc * wei_strides[1] + ic * wei_strides[2] + kh * wei_strides[3] + - kw * wei_strides[4]] - : weights[oc * wei_strides[0] + ic * wei_strides[1] + kh * wei_strides[2] + kw * wei_strides[3]]); } } } @@ -1023,7 +1078,7 @@ void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const f }; parallel_nd(G, MB, OC, OH, OW, - [&](int g, int mb, int oc, int oh, int ow) { + [&](int g, int mb, int oc, int oh, int ow) { dst[mb * dst_strides[0] + (g * OC + oc) * dst_strides[1] + oh * dst_strides[2] + ow * dst_strides[3]] = ker(g, mb, oc, oh, ow); }); } @@ -1058,6 +1113,8 @@ void MKLDNNDeformableConvolutionNode::executeOptimized(const float* src, const f } void MKLDNNDeformableConvolutionNode::execute(mkldnn::stream strm) { + const size_t inputsNumber = getOriginalInputsNumber(); + auto &srcMemory0 = getParentEdgeAt(0)->getMemory(); auto &srcMemory1 = getParentEdgeAt(1)->getMemory(); auto &srcMemory2 = getParentEdgeAt(2)->getMemory(); @@ -1066,8 +1123,18 @@ void MKLDNNDeformableConvolutionNode::execute(mkldnn::stream strm) { const auto *src = reinterpret_cast(srcMemory0.GetPtr()); const auto *offsets = reinterpret_cast(srcMemory1.GetPtr()); const auto *weights = reinterpret_cast(srcMemory2.GetPtr()); + float* modulation = nullptr; + if (inputsNumber > 3) { + modulation = reinterpret_cast(getParentEdgeAt(3)->getMemory().GetPtr()); + } + float *dst = reinterpret_cast(dstMemory.GetPtr()); + auto selectedPrimitiveDescriptor = getSelectedPrimitiveDescriptor(); + if (!selectedPrimitiveDescriptor) + IE_THROW() << "CPU deformable convolution with name '" << getName() << "' doesn't have primitive descriptors."; + auto config = selectedPrimitiveDescriptor->getConfig(); + auto src_block_desc = getParentEdgeAt(0)->getMemory().GetDescWithType(); std::vector src_strides(src_block_desc.getStrides().size()); for (int i = 0; i < src_strides.size(); i++) { @@ -1080,13 +1147,19 @@ void MKLDNNDeformableConvolutionNode::execute(mkldnn::stream strm) { dst_strides[dst_block_desc.getOrder()[i]] = dst_block_desc.getStrides()[i]; } + auto off_strides = getParentEdgeAt(1)->getMemory().GetDescWithType().getStrides(); auto wei_strides = getParentEdgeAt(2)->getMemory().GetDescWithType().getStrides(); + InferenceEngine::SizeVector modulation_strides; + if (inputsNumber > 3) { + modulation_strides = getParentEdgeAt(3)->getMemory().GetDescWithType().getStrides(); + } + if (def_conv_kernel) { executeOptimized(src, offsets, weights, dst, src_strides, off_strides, dst_strides); } else { - executeReference(src, offsets, weights, dst, src_strides, off_strides, wei_strides, dst_strides); + executeReference(src, offsets, weights, dst, src_strides, off_strides, wei_strides, dst_strides, modulation, modulation_strides); } } diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h index e74e49788cc..29af41af4da 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h @@ -22,8 +22,6 @@ struct jit_def_conv_params { int kd, kh, kw; int stride_d, stride_h, stride_w; int dilate_d, dilate_h, dilate_w; - bool with_bias; - bool with_sum; int nthr; int nb_ic, ic_block; int nb_oc, oc_block; @@ -32,13 +30,19 @@ struct jit_def_conv_params { int ur_w_tail; int typesize_in; int typesize_off; + int typesize_modulation; int typesize_bia; int typesize_out; + bool with_bias; + bool with_sum; + bool with_modulation; + bool with_bi_pad; }; struct jit_def_conv_call_args { const void *src; const void *off; + const void *modulation; const void *filt; const void *bias; const void *dst; @@ -75,11 +79,13 @@ public: bool canBeInPlace() const override { return false; } + bool enforceRef = false; InferenceEngine::Precision getRuntimePrecision() const override; private: size_t group = 1; + bool with_bilinear_pad = false; std::vector stride = {}; std::vector dilation = {}; std::vector paddingL = {}; @@ -92,10 +98,10 @@ private: void executeReference(const float* src, const float* offsets, const float* weights, float* dst, const std::vector& src_strides, const std::vector& off_strides, - const std::vector& wei_strides, const std::vector& dst_strides); + const std::vector& wei_strides, const std::vector& dst_strides, + const float* modulation = nullptr, const std::vector& modulation_strides = {}); void executeOptimized(const float* src, const float* offsets, const float* weights, float* dst, - const std::vector& src_strides, const std::vector& off_strides, - const std::vector& dst_strides); + const std::vector& src_strides, const std::vector& off_strides, const std::vector& dst_strides); }; } // namespace MKLDNNPlugin diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp index 4f98fc1099f..8e87617d369 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp @@ -272,6 +272,8 @@ void MKLDNNStridedSliceNode::createPrimitive() { auto srcOrder = srcBlockingDesc.getOrder(); params.srcDims = srcBlockingDesc.getBlockDims(); params.dstDims = dstBlockingDesc.getBlockDims(); + params.srcMemPtr = srcMemPtr; + params.dstMemPtr = dstMemPtr; params.dataSize = getSelectedPrimitiveDescriptor()->getConfig().inConfs[DATA_ID].desc->getPrecision().size(); if (params.parametersAreConstant) { @@ -282,9 +284,7 @@ void MKLDNNStridedSliceNode::createPrimitive() { SizeVector newSrcDims, newDstDims; dimsNormalization(newSrcDims, newDstDims); dimsGluing(realNDims, newSrcDims, newDstDims); - - if (params.dstDims.size() == 1 || params.nDimsForWork != 1) - indicesCalculation(); + indicesCalculation(); } } @@ -510,14 +510,35 @@ void MKLDNNStridedSliceNode::dimsGluing(const size_t realNDims, const SizeVector if (params.dstDims.size() > 2) params.lastDstDim /= newDstDims[secondDim.first]; } + + // some parameter calculations for common execution + params.isOptimized = params.nDimsForWork == 1 && params.dstDims.size() > 1; + if (params.isOptimized) { + if (params.dstDims.size() == 2) + params.dstDims[1] = 1; + + params.workAmount = params.dstDims[0] * params.dstDims[1]; + params.srcShift = (begin[0] * params.srcStrides[0] + begin[1] * params.srcStrides[1]) * params.dataSize; + } else { + params.srcShift = stride.back() == 1 && stride.size() > 1 ? + begin[params.nDimsForWork] * params.srcStrides[params.nDimsForWork] * params.dataSize : 0; + } } void MKLDNNStridedSliceNode::indicesCalculation() { // indices calculation before execution for the best performance - params.nThreads = parallel_get_max_threads(); params.srcIndices.resize(params.workAmount, 0); params.dstIndices.resize(params.workAmount, 0); + // should choose more optimal thread count + const size_t nthr = parallel_get_max_threads(); + params.nThreads = nthr > params.workAmount ? params.workAmount : nthr; + + if (params.isOptimized) { + indicesCalculationForOptimized(); + return; + } + auto getSrcIdx = [this](const SizeVector& indexes){ size_t srcIdx = 0; for (int i = 0; i < params.nDimsForWork; ++i) @@ -542,10 +563,10 @@ void MKLDNNStridedSliceNode::indicesCalculation() { if (coords[k] < params.dstDims[k]) { srcIdx += stride[k] * params.srcStrides[k] * params.dataSize; break; - } else { - coords[k] = 0; - out = true; } + + coords[k] = 0; + out = true; } if (out) @@ -554,6 +575,25 @@ void MKLDNNStridedSliceNode::indicesCalculation() { }); } +void MKLDNNStridedSliceNode::indicesCalculationForOptimized() { + const size_t dstIdx0 = params.dstStrides[0] * params.dataSize; + const size_t dstIdx1 = params.dstStrides[1] * params.dataSize; + const size_t srcIdx0 = stride[0] * params.srcStrides[0] * params.dataSize; + const size_t srcIdx1 = stride[1] * params.srcStrides[1] * params.dataSize; + + for (size_t i0 = 0; i0 < params.dstDims[0]; i0++) { + const size_t idx = i0 * params.dstDims[1]; + + params.dstIndices[idx] = i0 * dstIdx0; + params.srcIndices[idx] = i0 * srcIdx0; + + for (size_t i1 = 1; i1 < params.dstDims[1]; i1++) { + params.dstIndices[idx + i1] = params.dstIndices[idx] + i1 * dstIdx1; + params.srcIndices[idx + i1] = params.srcIndices[idx] + i1 * srcIdx1; + } + } +} + void MKLDNNStridedSliceNode::execute(mkldnn::stream strm) { if (!params.parametersAreConstant) { auto srcDims = getParentEdgeAt(DATA_ID)->getShape().getStaticDims(); @@ -586,42 +626,15 @@ void MKLDNNStridedSliceNode::execute(mkldnn::stream strm) { SizeVector newSrcDims, newDstDims; dimsNormalization(newSrcDims, newDstDims); dimsGluing(dstDims.size(), newSrcDims, newDstDims); - - if (params.dstDims.size() == 1 || params.nDimsForWork != 1) - indicesCalculation(); + indicesCalculation(); } - if (params.dstDims.size() > 1 && params.nDimsForWork == 1) - stridedSliceV(); - else - stridedSlice(); + stridedSlice(); } -void MKLDNNStridedSliceNode::stridedSliceV() { - const uint8_t* srcData = reinterpret_cast(this->getParentEdgeAt(DATA_ID)->getMemoryPtr()->GetPtr()) + - (begin[0] * params.srcStrides[0] + begin[1] * params.srcStrides[1]) * params.dataSize; - uint8_t* dstData = reinterpret_cast(this->getChildEdgeAt(0)->getMemoryPtr()->GetPtr()); - - const size_t dstIdx = params.dstStrides[0] * params.dataSize; - const size_t srcIdx = stride[0] * params.srcStrides[0] * params.dataSize; - const size_t dstShift = params.dstStrides[1] * params.dataSize; - const size_t srcShift = stride[1] * params.srcStrides[1] * params.dataSize; - - if (params.dstDims.size() > 2) { - parallel_for2d(params.dstDims[0], params.dstDims[1], [&](const size_t i, const size_t j) { - cpu_memcpy(&dstData[i * dstIdx + j * dstShift], &srcData[i * srcIdx + j * srcShift], params.lastDstDim); - }); - } else { - parallel_for(params.dstDims[0], [&](const size_t i) { - cpu_memcpy(&dstData[i * dstIdx], &srcData[i * srcIdx], params.lastDstDim); - }); - } -} - -void MKLDNNStridedSliceNode::stridedSlice() { - const uint8_t* srcData = reinterpret_cast(this->getParentEdgeAt(DATA_ID)->getMemoryPtr()->GetPtr()) + - (stride.back() == 1 && stride.size() > 1 ? begin[params.nDimsForWork] * params.srcStrides[params.nDimsForWork] * params.dataSize : 0); - uint8_t* dstData = reinterpret_cast(this->getChildEdgeAt(0)->getMemoryPtr()->GetPtr()); +inline void MKLDNNStridedSliceNode::stridedSlice() { + const uint8_t* srcData = reinterpret_cast(params.srcMemPtr->GetPtr()) + params.srcShift; + uint8_t* dstData = reinterpret_cast(params.dstMemPtr->GetPtr()); parallel_nt(params.nThreads, [&](const int ithr, const int nthr) { size_t start = 0, end = 0; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h index 91bf6701877..672bc0b6ce9 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h @@ -27,14 +27,14 @@ public: static bool isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept; private: - void stridedSliceV(); - void stridedSlice(); + inline void stridedSlice(); void addHiddenDims(const size_t nSrcDims); void orderParametersByLayouts(); void dimsNormalization(InferenceEngine::SizeVector& newSrcDims, InferenceEngine::SizeVector& newDstDims); void dimsGluing(const size_t realNDims, const InferenceEngine::SizeVector& newSrcDims, const InferenceEngine::SizeVector& newDstDims); void indicesCalculation(); + void indicesCalculationForOptimized(); const size_t DATA_ID = 0; const size_t BEGIN_ID = 1; @@ -56,6 +56,8 @@ private: InferenceEngine::SizeVector strideDims; struct { + MKLDNNMemoryPtr srcMemPtr = nullptr; + MKLDNNMemoryPtr dstMemPtr = nullptr; InferenceEngine::SizeVector srcDims; InferenceEngine::SizeVector dstDims; InferenceEngine::SizeVector srcStrides; @@ -69,6 +71,8 @@ private: size_t workAmount = 0; size_t lastDstDim = 0; size_t dataSize = 0; + size_t srcShift = 0; + bool isOptimized = false; bool equalDims = false; bool parametersAreConstant = true; } params; diff --git a/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.cpp b/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.cpp index 859515fd75e..f61ae9d6d11 100644 --- a/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.cpp +++ b/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.cpp @@ -8,20 +8,20 @@ #include "memory_formats_attribute.hpp" -namespace ngraph { +using namespace ngraph; +using namespace ov; -template class ngraph::MLKDNNMemoryFormatsHelper; +template class ov::MLKDNNMemoryFormatsHelper; constexpr VariantTypeInfo VariantWrapper::type_info; -std::string getMLKDNNInputMemoryFormats(const std::shared_ptr & node) { +std::string ngraph::getMLKDNNInputMemoryFormats(const std::shared_ptr & node) { return MLKDNNMemoryFormatsHelper::getMemoryFormats(node); } -template class ngraph::MLKDNNMemoryFormatsHelper; +template class ov::MLKDNNMemoryFormatsHelper; constexpr VariantTypeInfo VariantWrapper::type_info; -std::string getMLKDNNOutputMemoryFormats(const std::shared_ptr & node) { +std::string ngraph::getMLKDNNOutputMemoryFormats(const std::shared_ptr & node) { return MLKDNNMemoryFormatsHelper::getMemoryFormats(node); } -} // namespace ngraph diff --git a/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.hpp b/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.hpp index 0e9edbe55c5..5962f6f196c 100644 --- a/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.hpp +++ b/inference-engine/src/mkldnn_plugin/utils/rt_info/memory_formats_attribute.hpp @@ -25,6 +25,25 @@ public: std::string getMemoryFormats() const { return memory_format; } }; + +class MLKDNNInputMemoryFormats : public MLKDNNMemoryFormats { +public: + MLKDNNInputMemoryFormats() = default; + explicit MLKDNNInputMemoryFormats(const std::string &_memory_format) : MLKDNNMemoryFormats(_memory_format) {} +}; + +std::string getMLKDNNInputMemoryFormats(const std::shared_ptr& node); + +class MLKDNNOutputMemoryFormats : public MLKDNNMemoryFormats { +public: + MLKDNNOutputMemoryFormats() = default; + explicit MLKDNNOutputMemoryFormats(const std::string &_memory_format) : MLKDNNMemoryFormats(_memory_format) {} +}; +std::string getMLKDNNOutputMemoryFormats(const std::shared_ptr& node); + +} // namespace ngraph + +namespace ov { template class MLKDNNMemoryFormatsHelper : public VariantImpl { public: @@ -35,7 +54,7 @@ public: using MemoryFormatsWrapper = VariantWrapper; if (!rtInfo.count(MemoryFormatsWrapper::type_info.name)) return ""; const auto &attr = rtInfo.at(MemoryFormatsWrapper::type_info.name); - MemoryFormatsType mem_format = as_type_ptr(attr)->get(); + MemoryFormatsType mem_format = ngraph::as_type_ptr(attr)->get(); return mem_format.getMemoryFormats(); } @@ -48,7 +67,7 @@ public: } if (unique_mem_format.size() > 1) { - throw ngraph_error(std::string(VariantWrapper::type_info.name) + " no rule defined for multiple values."); + throw ngraph::ngraph_error(std::string(VariantWrapper::type_info.name) + " no rule defined for multiple values."); } std::string final_mem_format; @@ -59,46 +78,29 @@ public: } std::shared_ptr init(const std::shared_ptr & node) override { - throw ngraph_error(std::string(VariantWrapper::type_info.name) + " has no default initialization."); + throw ngraph::ngraph_error(std::string(VariantWrapper::type_info.name) + " has no default initialization."); } }; - -class MLKDNNInputMemoryFormats : public MLKDNNMemoryFormats { -public: - MLKDNNInputMemoryFormats() = default; - explicit MLKDNNInputMemoryFormats(const std::string &_memory_format) : MLKDNNMemoryFormats(_memory_format) {} -}; - -extern template class MLKDNNMemoryFormatsHelper; +extern template class MLKDNNMemoryFormatsHelper; template<> -class VariantWrapper : public MLKDNNMemoryFormatsHelper { +class VariantWrapper : public MLKDNNMemoryFormatsHelper { public: - static constexpr VariantTypeInfo type_info{MLKDNNInputMemoryFormatsAttr, 0}; + static constexpr VariantTypeInfo type_info{ngraph::MLKDNNInputMemoryFormatsAttr, 0}; const VariantTypeInfo &get_type_info() const override { return type_info; } - VariantWrapper(const MLKDNNInputMemoryFormats &value) : MLKDNNMemoryFormatsHelper(value) {} + VariantWrapper(const ngraph::MLKDNNInputMemoryFormats &value) : MLKDNNMemoryFormatsHelper(value) {} }; -std::string getMLKDNNInputMemoryFormats(const std::shared_ptr& node); - -class MLKDNNOutputMemoryFormats : public MLKDNNMemoryFormats { -public: - MLKDNNOutputMemoryFormats() = default; - explicit MLKDNNOutputMemoryFormats(const std::string &_memory_format) : MLKDNNMemoryFormats(_memory_format) {} -}; - -extern template class MLKDNNMemoryFormatsHelper; +extern template class MLKDNNMemoryFormatsHelper; template<> -class VariantWrapper : public MLKDNNMemoryFormatsHelper { +class VariantWrapper : public MLKDNNMemoryFormatsHelper { public: - static constexpr VariantTypeInfo type_info{MLKDNNOutputMemoryFormatsAttr, 0}; + static constexpr VariantTypeInfo type_info{ngraph::MLKDNNOutputMemoryFormatsAttr, 0}; const VariantTypeInfo &get_type_info() const override { return type_info; } - VariantWrapper(const MLKDNNOutputMemoryFormats &value) : MLKDNNMemoryFormatsHelper(value) {} + VariantWrapper(const ngraph::MLKDNNOutputMemoryFormats &value) : MLKDNNMemoryFormatsHelper(value) {} }; -std::string getMLKDNNOutputMemoryFormats(const std::shared_ptr& node); - -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/multi_device/CMakeLists.txt b/inference-engine/src/multi_device/CMakeLists.txt index d028c5c7562..75c6d43b615 100644 --- a/inference-engine/src/multi_device/CMakeLists.txt +++ b/inference-engine/src/multi_device/CMakeLists.txt @@ -12,7 +12,7 @@ ie_add_plugin(NAME ${TARGET_NAME} SOURCES ${SOURCES} ${HEADERS} VERSION_DEFINES_FOR multi_device_plugin.cpp) -target_link_libraries(${TARGET_NAME} PRIVATE inference_engine) +target_link_libraries(${TARGET_NAME} PRIVATE inference_engine ngraph inference_engine_transformations) set_ie_threading_interface_for(${TARGET_NAME}) diff --git a/inference-engine/src/multi_device/multi_device_plugin.cpp b/inference-engine/src/multi_device/multi_device_plugin.cpp index 66c41380c58..263cfdf165e 100644 --- a/inference-engine/src/multi_device/multi_device_plugin.cpp +++ b/inference-engine/src/multi_device/multi_device_plugin.cpp @@ -10,6 +10,10 @@ #include #include +#include +#include +#include "ngraph_ops/convolution_ie.hpp" +#include "ngraph_ops/deconvolution_ie.hpp" #include #include @@ -21,6 +25,30 @@ namespace MultiDevicePlugin { using namespace InferenceEngine; namespace { + + std::string GetNetworkPrecision(const InferenceEngine::CNNNetwork &network) { + auto nGraphFunc = network.getFunction(); + bool isINTModel = ngraph::op::util::has_op_with_type(nGraphFunc); + if (isINTModel) { + return METRIC_VALUE(INT8); + } + for (auto & node : nGraphFunc->get_ordered_ops()) { + if (std::dynamic_pointer_cast(node) || + std::dynamic_pointer_cast(node) || + std::dynamic_pointer_cast(node) || + std::dynamic_pointer_cast(node) || + std::dynamic_pointer_cast(node) || + std::dynamic_pointer_cast(node)) { + auto layerType = node->input(1).get_element_type().get_type_name(); + if (layerType == "f32") + return METRIC_VALUE(FP32); + if (layerType == "f16") + return METRIC_VALUE(FP16); + } + } + return METRIC_VALUE(FP32); + } + std::map mergeConfigs(std::map config, const std::map & local) { for (auto && kvp : local) { @@ -28,7 +56,10 @@ namespace { } return config; } - std::vector supported_configKeys = {MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES}; + std::vector supported_configKeys = { + MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, + CONFIG_KEY_INTERNAL(WORK_MODE) + }; } // namespace std::map MultiDeviceInferencePlugin::GetSupportedConfig( @@ -98,8 +129,8 @@ std::vector MultiDeviceInferencePlugin::ParseMetaDevices(cons InferenceEngine::Parameter MultiDeviceInferencePlugin::GetConfig(const std::string& name, const std::map & options) const { - if (name == MULTI_CONFIG_KEY(DEVICE_PRIORITIES)) { - auto it = _config.find(MULTI_CONFIG_KEY(DEVICE_PRIORITIES)); + if (supported_configKeys.end() != std::find(supported_configKeys.begin(), supported_configKeys.end(), name)) { + auto it = _config.find(name); if (it == _config.end()) { IE_THROW() << "Value for KEY_MULTI_DEVICE_PRIORITIES is not set"; } else { @@ -148,17 +179,23 @@ InferenceEngine::Parameter MultiDeviceInferencePlugin::GetMetric(const std::stri // Is called only when caching is enabled IExecutableNetworkInternal::Ptr MultiDeviceInferencePlugin::LoadNetwork(const std::string& modelPath, const std::map& config) { - return LoadExeNetworkImpl(modelPath, {}, config); + return LoadNetworkImpl(modelPath, {}, config); } IExecutableNetworkInternal::Ptr MultiDeviceInferencePlugin::LoadExeNetworkImpl(const CNNNetwork &network, const std::map& config) { - return LoadExeNetworkImpl({}, network, config); + if (network.getFunction() == nullptr) { + IE_THROW() << "MULTI device supports just ngraph network representation"; + } + + auto networkPrecision = GetNetworkPrecision(network); + return LoadNetworkImpl({}, network, config, networkPrecision); } -IExecutableNetworkInternal::Ptr MultiDeviceInferencePlugin::LoadExeNetworkImpl(const std::string& modelPath, +IExecutableNetworkInternal::Ptr MultiDeviceInferencePlugin::LoadNetworkImpl(const std::string& modelPath, CNNNetwork network, - const std::map& config) { + const std::map& config, + const std::string &networkPrecision) { if (GetCore() == nullptr) { IE_THROW() << "Please, work with MULTI device via InferenceEngine::Core object"; } @@ -168,16 +205,39 @@ IExecutableNetworkInternal::Ptr MultiDeviceInferencePlugin::LoadExeNetworkImpl(c } auto fullConfig = mergeConfigs(_config, config); - auto priorities = fullConfig.find(MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES); - if (priorities == fullConfig.end()) { - IE_THROW() << "KEY_MULTI_DEVICE_PRIORITIES key is not set for MULTI device"; - } - - auto metaDevices = ParseMetaDevices(priorities->second, fullConfig); - // collect the settings that are applicable to the devices we are loading the network to std::unordered_map multiNetworkConfig; - multiNetworkConfig.insert(*priorities); + std::vector metaDevices; + auto workMode = fullConfig.find(CONFIG_KEY_INTERNAL(WORK_MODE)); + auto priorities = fullConfig.find(MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES); + + // not found device priorities for -d AUTO use case + if (priorities == fullConfig.end()) { + if (workMode != fullConfig.end()) { + std::string allDevices; + auto availableDevices = GetCore()->GetAvailableDevices(); + if (availableDevices.empty()) { + IE_THROW(NotFound) << "No available device found"; + } + for (auto&& device : availableDevices) { + allDevices += device; + allDevices += ((device == availableDevices[availableDevices.size()-1]) ? "" : ","); + } + metaDevices = ParseMetaDevices(allDevices, fullConfig); + multiNetworkConfig.insert({MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, allDevices}); + } else { + IE_THROW() << "KEY_MULTI_DEVICE_PRIORITIES key is not set for MULTI device"; + } + } else { // for use case -d MULTI:xPU or -d AUTO:xPU + metaDevices = ParseMetaDevices(priorities->second, fullConfig); + multiNetworkConfig.insert(*priorities); + } + // check if it is -d AUTO or -d AUTO:xPU use case + if (workMode != fullConfig.end()) { + auto targetDevice = SelectDevice(metaDevices, networkPrecision); + // std::cout << "!!! DEBUG: select device is " << targetDevice.deviceName << std::endl; + metaDevices = { targetDevice }; + } DeviceMap executableNetworkPerDevice; std::mutex load_mutex; @@ -275,4 +335,125 @@ QueryNetworkResult MultiDeviceInferencePlugin::QueryNetwork(const CNNNetwork& return queryResult; } + +DeviceInformation MultiDeviceInferencePlugin::SelectDevice(const std::vector& metaDevices, const std::string& networkPrecision) { + if (metaDevices.empty()) { + IE_THROW(NotFound) << "No available device to select in AUTO plugin"; + } + if (metaDevices.size() == 1) { + return metaDevices.at(0); + } + + std::vector CPU; + std::vector dGPU; + std::vector iGPU; + std::vector MYRIAD; + std::vector VPUX; + + for (auto& item : metaDevices) { + if (item.deviceName.find("CPU") == 0) { + CPU.push_back(item); + continue; + } + if (item.deviceName.find("MYRIAD") == 0) { + MYRIAD.push_back(item); + continue; + } + if (item.deviceName.find("VPUX") == 0) { + VPUX.push_back(item); + continue; + } + if (item.deviceName.find("GPU") == 0) { + auto gpuFullDeviceName = GetCore()->GetMetric(item.deviceName, METRIC_KEY(FULL_DEVICE_NAME)).as(); + if (gpuFullDeviceName.find("iGPU") != std::string::npos) { + iGPU.push_back(item); + } else if (gpuFullDeviceName.find("dGPU") != std::string::npos) { + dGPU.push_back(item); + } + continue; + } + } + + if (CPU.empty() && dGPU.empty() && iGPU.empty() && MYRIAD.empty() && VPUX.empty()) { + IE_THROW(NotFound) << "No available device found"; + } + + // Priority of selecting device: dGPU > VPUX > iGPU > MYRIAD > CPU + if (!dGPU.empty()) { + for (auto&& item : dGPU) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!VPUX.empty()) { + for (auto&& item : VPUX) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!iGPU.empty()) { + for (auto&& item : iGPU) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!MYRIAD.empty()) { + for (auto&& item : MYRIAD) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), networkPrecision); + if (supportNetwork != capability.end()) { + return item; + } + } + } + + // If network is FP32 but there is no device support FP32, offload FP32 network to device support FP16. + if (networkPrecision == "FP32") { + if (!dGPU.empty()) { + for (auto&& item : dGPU) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!VPUX.empty()) { + for (auto&& item : VPUX) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!iGPU.empty()) { + for (auto&& item : iGPU) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); + if (supportNetwork != capability.end()) { + return item; + } + } + } else if (!MYRIAD.empty()) { + for (auto&& item : MYRIAD) { + std::vector capability = GetCore()->GetMetric(item.deviceName, METRIC_KEY(OPTIMIZATION_CAPABILITIES)); + auto supportNetwork = std::find(capability.begin(), capability.end(), "FP16"); + if (supportNetwork != capability.end()) { + return item; + } + } + } + } + + if (CPU.empty()) { + IE_THROW() << "Cannot select any device"; + } + return CPU[0]; +} + } // namespace MultiDevicePlugin diff --git a/inference-engine/src/multi_device/multi_device_plugin.hpp b/inference-engine/src/multi_device/multi_device_plugin.hpp index c900c0d8565..4021c5ec9e1 100644 --- a/inference-engine/src/multi_device/multi_device_plugin.hpp +++ b/inference-engine/src/multi_device/multi_device_plugin.hpp @@ -41,9 +41,11 @@ protected: const MultiDevicePlugin::DeviceName & deviceName) const; private: - InferenceEngine::IExecutableNetworkInternal::Ptr LoadExeNetworkImpl(const std::string& modelPath, + InferenceEngine::IExecutableNetworkInternal::Ptr LoadNetworkImpl(const std::string& modelPath, InferenceEngine::CNNNetwork network, - const std::map& config); + const std::map& config, + const std::string &networkPrecision = METRIC_VALUE(FP32)); + DeviceInformation SelectDevice(const std::vector& metaDevices, const std::string& networkPrecision = METRIC_VALUE(FP32)); }; } // namespace MultiDevicePlugin diff --git a/inference-engine/src/offline_transformations/include/mask_attribute.hpp b/inference-engine/src/offline_transformations/include/mask_attribute.hpp index 282f81b054e..29d90bb341d 100644 --- a/inference-engine/src/offline_transformations/include/mask_attribute.hpp +++ b/inference-engine/src/offline_transformations/include/mask_attribute.hpp @@ -192,24 +192,6 @@ private: std::ostream & operator<< (std::ostream & out, const Mask & mask); -extern template class VariantImpl; - -template<> -class VariantWrapper : public VariantImpl { -public: - static constexpr VariantTypeInfo type_info{"Variant::RuntimeAttribute::Mask", 0}; - - const VariantTypeInfo &get_type_info() const override { - return type_info; - } - - static std::shared_ptr> create(const value_type & value) { - return std::make_shared>(value); - } - - explicit VariantWrapper(const value_type &value) : VariantImpl(value) {} -}; - Mask::Ptr getMask(const Output & output); Mask::Ptr getMask(const Output & output); @@ -217,3 +199,25 @@ Mask::Ptr getMask(const Output & output); void setMask(Output output, const Mask::Ptr & mask); } // namespace ngraph + +namespace ov { + +extern template class VariantImpl; + +template<> +class VariantWrapper : public VariantImpl { +public: + static constexpr VariantTypeInfo type_info{"Variant::RuntimeAttribute::Mask", 0}; + + const VariantTypeInfo &get_type_info() const override { + return type_info; + } + + static std::shared_ptr> create(const value_type & value) { + return std::make_shared>(value); + } + + explicit VariantWrapper(const value_type &value) : VariantImpl(value) {} +}; + +} // namespace ov diff --git a/inference-engine/src/offline_transformations/src/moc_transformations.cpp b/inference-engine/src/offline_transformations/src/moc_transformations.cpp index 1a23f72e607..9852c5e4b99 100644 --- a/inference-engine/src/offline_transformations/src/moc_transformations.cpp +++ b/inference-engine/src/offline_transformations/src/moc_transformations.cpp @@ -35,6 +35,8 @@ #include #include #include +#include +#include NGRAPH_RTTI_DEFINITION(ngraph::pass::MOCTransformations, "MOCTransformations", 0); @@ -79,11 +81,13 @@ bool ngraph::pass::MOCTransformations::run_on_function(std::shared_ptradd_matcher(); common_fusions->add_matcher(); common_fusions->add_matcher(); + common_fusions->add_matcher(); common_fusions->add_matcher(); common_fusions->add_matcher(); common_fusions->add_matcher(); common_fusions->add_matcher(); common_fusions->add_matcher(); + common_fusions->add_matcher(); common_fusions->set_name("ngraph::pass::CommonFusions"); manager.register_pass(); diff --git a/inference-engine/src/offline_transformations/src/pruning/mask_attribute.cpp b/inference-engine/src/offline_transformations/src/pruning/mask_attribute.cpp index 7e0de45a093..42fa47a3eb6 100644 --- a/inference-engine/src/offline_transformations/src/pruning/mask_attribute.cpp +++ b/inference-engine/src/offline_transformations/src/pruning/mask_attribute.cpp @@ -12,10 +12,6 @@ namespace ngraph { -template class ngraph::VariantImpl; - -constexpr VariantTypeInfo VariantWrapper::type_info; - Mask::Ptr getMask(const Output & output) { auto &rtInfo = output.get_rt_info(); using MaskWrapper = VariantWrapper; @@ -57,6 +53,12 @@ std::ostream & operator<< (std::ostream & out, const Mask & mask) { return out; } - - } // namespace ngraph + +namespace ov { + +template class ngraph::VariantImpl; + +constexpr VariantTypeInfo VariantWrapper::type_info; + +} // namespace ov diff --git a/inference-engine/src/plugin_api/cpp_interfaces/interface/ie_internal_plugin_config.hpp b/inference-engine/src/plugin_api/cpp_interfaces/interface/ie_internal_plugin_config.hpp index 10963a5c78c..913ea531305 100644 --- a/inference-engine/src/plugin_api/cpp_interfaces/interface/ie_internal_plugin_config.hpp +++ b/inference-engine/src/plugin_api/cpp_interfaces/interface/ie_internal_plugin_config.hpp @@ -45,6 +45,15 @@ DECLARE_CONFIG_KEY(CPU_THREADS_PER_STREAM); */ DECLARE_CONFIG_KEY(FORCE_DISABLE_CACHE); +/** + * @brief The name for setting work mode internal in MULTI device plugin option. + * + * This option should be used with value only: + * PluginConfigInternalParams::MULTI_MODE_AUTO or PluginConfigInternalParams::MULTI_MODE_LEGACY + */ +DECLARE_CONFIG_KEY(WORK_MODE); +DECLARE_CONFIG_VALUE(MULTI_MODE_AUTO); + } // namespace PluginConfigInternalParams } // namespace InferenceEngine diff --git a/inference-engine/src/plugin_api/threading/ie_tbb_streams_executor.hpp b/inference-engine/src/plugin_api/threading/ie_tbb_streams_executor.hpp new file mode 100644 index 00000000000..baf2b8b393d --- /dev/null +++ b/inference-engine/src/plugin_api/threading/ie_tbb_streams_executor.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2018-2019 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include "ie_api.h" +#include "ie_parallel.hpp" +#include "threading/ie_istreams_executor.hpp" + +namespace InferenceEngine { +/** + * @class TBBStreamsExecutor + * @brief CPU Streams executor implementation. Use TBB thread pool to run tasks + */ +class INFERENCE_ENGINE_API_CLASS(TBBStreamsExecutor) : public IStreamsExecutor { +public: + using Ptr = std::shared_ptr; + explicit TBBStreamsExecutor(const Config& config = {}); + ~TBBStreamsExecutor() override; + void run(Task task) override; + void Execute(Task task) override; + int GetStreamId() override; + int GetNumaNodeId() override; + +private: + struct Impl; + std::unique_ptr _impl; +}; +} // namespace InferenceEngine diff --git a/inference-engine/src/readers/ir_reader/ie_ir_reader.hpp b/inference-engine/src/readers/ir_reader/ie_ir_reader.hpp index 6e1c092bc79..ad72c1e52d3 100644 --- a/inference-engine/src/readers/ir_reader/ie_ir_reader.hpp +++ b/inference-engine/src/readers/ir_reader/ie_ir_reader.hpp @@ -20,10 +20,6 @@ class xml_node; class xml_document; } // namespace pugi -namespace ngraph { -class Function; -} // namespace ngraph - namespace InferenceEngine { /** diff --git a/inference-engine/src/snippets/include/snippets/register_info.hpp b/inference-engine/src/snippets/include/snippets/register_info.hpp index 23f5a14036c..4a37b6c27a4 100644 --- a/inference-engine/src/snippets/include/snippets/register_info.hpp +++ b/inference-engine/src/snippets/include/snippets/register_info.hpp @@ -4,21 +4,21 @@ #pragma once -#include -#include #include +#include +#include -namespace ngraph { +namespace ov { template <> class TRANSFORMATIONS_API VariantWrapper> : public VariantImpl> { public: static constexpr VariantTypeInfo type_info{"Variant::RegInfo|Variant::RuntimeAttribute::AxisVector", 0}; - const VariantTypeInfo& get_type_info() const override { return type_info; } - VariantWrapper(const value_type& value) - : VariantImpl(value) { + const VariantTypeInfo& get_type_info() const override { + return type_info; } + VariantWrapper(const value_type& value) : VariantImpl(value) {} }; -} // namespace ngraph \ No newline at end of file +} // namespace ov diff --git a/inference-engine/src/transformations/include/transformations/common_optimizations/normalize_l2_fusion.hpp b/inference-engine/src/transformations/include/transformations/common_optimizations/normalize_l2_fusion.hpp index 1f5106ebe0b..f3b435c9e14 100644 --- a/inference-engine/src/transformations/include/transformations/common_optimizations/normalize_l2_fusion.hpp +++ b/inference-engine/src/transformations/include/transformations/common_optimizations/normalize_l2_fusion.hpp @@ -15,43 +15,18 @@ namespace ngraph { namespace pass { class TRANSFORMATIONS_API NormalizeL2Fusion; -class TRANSFORMATIONS_API NormalizeL2FusionWithMax; -class TRANSFORMATIONS_API NormalizeL2FusionWithAdd; } // namespace pass } // namespace ngraph /** * @ingroup ie_transformation_common_api - * @brief NormalizeL2FusionWithMax transformation replaces a sub-graph + * @brief NormalizeL2Fusion transformation replaces various sub-graphs with a NormalizeL2 op: * x/(max(sqrt(sum(x[j0, ..., jN]**2), eps)) with a NormalizeL2 op. - */ -class ngraph::pass::NormalizeL2FusionWithMax: public ngraph::pass::MatcherPass { -public: - NGRAPH_RTTI_DECLARATION; - NormalizeL2FusionWithMax(); -}; - -/** - * @ingroup ie_transformation_common_api - * @brief NormalizeL2FusionWithAdd transformation replaces a sub-graph * x/(add(sqrt(sum(x[j0, ..., jN]**2), eps)) with a NormalizeL2 op. */ -class ngraph::pass::NormalizeL2FusionWithAdd: public ngraph::pass::MatcherPass { +class ngraph::pass::NormalizeL2Fusion: public ngraph::pass::MatcherPass { public: NGRAPH_RTTI_DECLARATION; - NormalizeL2FusionWithAdd(); -}; - -/** - * @ingroup ie_transformation_common_api - * @brief NormalizeL2Fusion transformation replaces various sub-graphs with a NormalizeL2 op. - */ -class ngraph::pass::NormalizeL2Fusion: public ngraph::pass::GraphRewrite { -public: - NGRAPH_RTTI_DECLARATION; - NormalizeL2Fusion() { - add_matcher(); - add_matcher(); - } + NormalizeL2Fusion(); }; \ No newline at end of file diff --git a/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v7_to_gather_v1.hpp b/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_downgrade.hpp similarity index 64% rename from inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v7_to_gather_v1.hpp rename to inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_downgrade.hpp index af8e29807ad..47d8ca52ac0 100644 --- a/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v7_to_gather_v1.hpp +++ b/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_downgrade.hpp @@ -12,6 +12,7 @@ namespace ngraph { namespace pass { class TRANSFORMATIONS_API ConvertGather7ToGather1; +class TRANSFORMATIONS_API ConvertGather8ToGather7; } // namespace pass } // namespace ngraph @@ -25,3 +26,13 @@ public: NGRAPH_RTTI_DECLARATION; ConvertGather7ToGather1(); }; + +/** + * @ingroup ie_transformation_common_api + * @brief ConvertGather8ToGather7 converts v8::Gather into v7::Gather. + */ +class ngraph::pass::ConvertGather8ToGather7 : public ngraph::pass::MatcherPass { +public: + NGRAPH_RTTI_DECLARATION; + ConvertGather8ToGather7(); +}; diff --git a/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v1_to_gather_v7.hpp b/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_upgrade.hpp similarity index 64% rename from inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v1_to_gather_v7.hpp rename to inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_upgrade.hpp index c7dd7c30b55..90d782681a9 100644 --- a/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_v1_to_gather_v7.hpp +++ b/inference-engine/src/transformations/include/transformations/op_conversions/convert_gather_upgrade.hpp @@ -13,6 +13,8 @@ namespace pass { class TRANSFORMATIONS_API ConvertGather1ToGather7; +class TRANSFORMATIONS_API ConvertGather7ToGather8; + } // namespace pass } // namespace ngraph @@ -25,3 +27,13 @@ public: NGRAPH_RTTI_DECLARATION; ConvertGather1ToGather7(); }; + +/** + * @ingroup ie_transformation_common_api + * @brief ConvertGather7ToGather8 converts v7::Gather into v8::Gather. + */ +class ngraph::pass::ConvertGather7ToGather8 : public ngraph::pass::MatcherPass { +public: + NGRAPH_RTTI_DECLARATION; + ConvertGather7ToGather8(); +}; diff --git a/inference-engine/src/transformations/include/transformations/op_conversions/normalize_l2_decomposition.hpp b/inference-engine/src/transformations/include/transformations/op_conversions/normalize_l2_decomposition.hpp new file mode 100644 index 00000000000..d6c6c8091b7 --- /dev/null +++ b/inference-engine/src/transformations/include/transformations/op_conversions/normalize_l2_decomposition.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include + +#include +#include +#include "ngraph/pattern/matcher.hpp" + +namespace ngraph { +namespace pass { + +class TRANSFORMATIONS_API NormalizeL2Decomposition; + +} // namespace pass +} // namespace ngraph + +/** + * @ingroup ie_transformation_common_api + * @brief Decomposes NormalizeL2 into subgraph + */ +class ngraph::pass::NormalizeL2Decomposition: public ngraph::pass::MatcherPass { +public: + NGRAPH_RTTI_DECLARATION; + NormalizeL2Decomposition(); +}; diff --git a/inference-engine/src/transformations/include/transformations/rt_info/dequantization_attribute.hpp b/inference-engine/src/transformations/include/transformations/rt_info/dequantization_attribute.hpp index 8b75663f7e3..9b9b0747bc9 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/dequantization_attribute.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/dequantization_attribute.hpp @@ -46,11 +46,21 @@ public: */ std::string getDequantizationAttr() const; }; +/** + * @ingroup ie_runtime_attr_api + * @brief getDequantization return string with dequantization value + * @param[in] node The node will be used to get Dequantization attribute + */ +TRANSFORMATIONS_API std::string getDequantization(const std::shared_ptr& node); -extern template class TRANSFORMATIONS_API VariantImpl; +} // namespace ngraph + +namespace ov { + +extern template class TRANSFORMATIONS_API VariantImpl; template<> -class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{"DEQUANTIZATION", 0}; @@ -65,11 +75,4 @@ public: std::shared_ptr init(const std::shared_ptr & node) override; }; -/** - * @ingroup ie_runtime_attr_api - * @brief getDequantization return string with dequantization value - * @param[in] node The node will be used to get Dequantization attribute - */ -TRANSFORMATIONS_API std::string getDequantization(const std::shared_ptr& node); - -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/transformations/include/transformations/rt_info/disable_constant_folding.hpp b/inference-engine/src/transformations/include/transformations/rt_info/disable_constant_folding.hpp index 1e04ce22dcc..26bbe5e4010 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/disable_constant_folding.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/disable_constant_folding.hpp @@ -24,10 +24,14 @@ public: DisableConstantFolding() = default; }; -extern template class TRANSFORMATIONS_API VariantImpl; +TRANSFORMATIONS_API void disable_constant_folding(const std::shared_ptr& node); +} // namespace ngraph + +namespace ov { +extern template class TRANSFORMATIONS_API VariantImpl; template<> -class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{"DISABLED_CONSTANT_FOLDING", 0}; @@ -40,5 +44,4 @@ public: bool is_copyable() const override { return false; } }; -TRANSFORMATIONS_API void disable_constant_folding(const std::shared_ptr& node); -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/transformations/include/transformations/rt_info/fused_names_attribute.hpp b/inference-engine/src/transformations/include/transformations/rt_info/fused_names_attribute.hpp index 20a4946127f..95e6fae96a8 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/fused_names_attribute.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/fused_names_attribute.hpp @@ -61,24 +61,6 @@ public: std::vector getVectorNames() const; }; -extern template class TRANSFORMATIONS_API VariantImpl; - -template<> -class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { -public: - static constexpr VariantTypeInfo type_info{"Variant::RuntimeAttribute::FusedNames", 0}; - - const VariantTypeInfo &get_type_info() const override { - return type_info; - } - - VariantWrapper(const value_type &value) : VariantImpl(value) {} - - std::shared_ptr merge(const ngraph::NodeVector & nodes) override; - - std::shared_ptr init(const std::shared_ptr & node) override; -}; - /** * @ingroup ie_runtime_attr_api * @brief getFusedNames return string with operation names separated by coma in alphabetical order @@ -95,3 +77,24 @@ TRANSFORMATIONS_API std::string getFusedNames(const std::shared_ptr getFusedNamesVector(const std::shared_ptr & node); } // namespace ngraph + +namespace ov { + +extern template class TRANSFORMATIONS_API VariantImpl; + +template<> +class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +public: + static constexpr VariantTypeInfo type_info{"Variant::RuntimeAttribute::FusedNames", 0}; + + const VariantTypeInfo &get_type_info() const override { + return type_info; + } + + VariantWrapper(const value_type &value) : VariantImpl(value) {} + + std::shared_ptr merge(const ngraph::NodeVector & nodes) override; + + std::shared_ptr init(const std::shared_ptr & node) override; +}; +} // namespace ov diff --git a/inference-engine/src/transformations/include/transformations/rt_info/primitives_priority_attribute.hpp b/inference-engine/src/transformations/include/transformations/rt_info/primitives_priority_attribute.hpp index eeff9dab29c..d2af91b58e8 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/primitives_priority_attribute.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/primitives_priority_attribute.hpp @@ -47,11 +47,21 @@ public: */ std::string getPrimitivesPriority() const; }; +/** + * @ingroup ie_runtime_attr_api + * @brief getPrimitivesPriority return string with primitive priorities value + * @param[in] node The node will be used to get PrimitivesPriority attribute + */ +TRANSFORMATIONS_API std::string getPrimitivesPriority(const std::shared_ptr & node); -extern template class TRANSFORMATIONS_API VariantImpl; +} // namespace ngraph + +namespace ov { + +extern template class TRANSFORMATIONS_API VariantImpl; template<> -class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{"Variant::RuntimeAttribute::PrimitivesPriority", 0}; @@ -61,16 +71,9 @@ public: VariantWrapper(const value_type &value) : VariantImpl(value) {} - std::shared_ptr merge(const ngraph::NodeVector & nodes) override; + std::shared_ptr merge(const ngraph::NodeVector & nodes) override; - std::shared_ptr init(const std::shared_ptr & node) override; + std::shared_ptr init(const std::shared_ptr & node) override; }; -/** - * @ingroup ie_runtime_attr_api - * @brief getPrimitivesPriority return string with primitive priorities value - * @param[in] node The node will be used to get PrimitivesPriority attribute - */ -TRANSFORMATIONS_API std::string getPrimitivesPriority(const std::shared_ptr & node); - -} // namespace ngraph +} // namespace ov diff --git a/inference-engine/src/transformations/include/transformations/rt_info/strides_property.hpp b/inference-engine/src/transformations/include/transformations/rt_info/strides_property.hpp index 2ec78ce6892..41ac9b6f0ae 100644 --- a/inference-engine/src/transformations/include/transformations/rt_info/strides_property.hpp +++ b/inference-engine/src/transformations/include/transformations/rt_info/strides_property.hpp @@ -10,9 +10,9 @@ #include -namespace ngraph { +namespace ov { template <> -class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { +class TRANSFORMATIONS_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{"Variant::Strides", 0}; const VariantTypeInfo& get_type_info() const override { return type_info; } @@ -21,7 +21,7 @@ public: } }; -} // namespace ngraph +} // namespace ov TRANSFORMATIONS_API bool has_strides_prop(const ngraph::Input& node); TRANSFORMATIONS_API ngraph::Strides get_strides_prop(const ngraph::Input& node); diff --git a/inference-engine/src/transformations/include/transformations/utils/utils.hpp b/inference-engine/src/transformations/include/transformations/utils/utils.hpp index 0fd1b5542a8..001d2f4ecaf 100644 --- a/inference-engine/src/transformations/include/transformations/utils/utils.hpp +++ b/inference-engine/src/transformations/include/transformations/utils/utils.hpp @@ -16,6 +16,10 @@ #include #include +#include +#include +#include + namespace ngraph { namespace op { namespace util { @@ -130,7 +134,6 @@ Output eltwise_fold(const Output & input0, const Output & inpu } TRANSFORMATIONS_API std::vector> get_node_target_inputs(const std::shared_ptr& node); - } // namespace util } // namespace op } // namespace ngraph diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp index e0089d644da..373e34f9a01 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/common_optimizations.cpp @@ -47,8 +47,8 @@ #include "transformations/op_conversions/bidirectional_sequences_decomposition.hpp" #include "transformations/op_conversions/convert_pad_to_group_conv.hpp" #include "transformations/op_conversions/convert_divide.hpp" -#include "transformations/op_conversions/convert_gather_v7_to_gather_v1.hpp" -#include "transformations/op_conversions/convert_gather_v1_to_gather_v7.hpp" +#include "transformations/op_conversions/convert_gather_downgrade.hpp" +#include "transformations/op_conversions/convert_gather_upgrade.hpp" #include "transformations/op_conversions/convert_mod.hpp" #include "transformations/op_conversions/convert_minimum_to_power_and_max.hpp" #include "transformations/op_conversions/convert_negative.hpp" @@ -78,6 +78,7 @@ #include #include #include +#include NGRAPH_RTTI_DEFINITION(ngraph::pass::CommonOptimizations, "CommonOptimizations", 0); @@ -160,6 +161,7 @@ bool ngraph::pass::CommonOptimizations::run_on_function(std::shared_ptradd_matcher(); decomp->add_matcher(); decomp->add_matcher(); + decomp->add_matcher(); decomp->add_matcher(); decomp->add_matcher(); decomp->add_matcher(); @@ -179,8 +181,10 @@ bool ngraph::pass::CommonOptimizations::run_on_function(std::shared_ptrset_name("ngraph::pass::ConvFusions"); manager.register_pass(); - manager.register_pass(); + manager.register_pass(); // not plugins implemented gather8 + manager.register_pass(); // not plugins implemented gather7 manager.register_pass(); + manager.register_pass(); manager.register_pass(); auto fq_fusions = manager.register_pass(); diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/leaky_relu_fusion.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/leaky_relu_fusion.cpp index 388d2f17104..45ee376fe23 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/leaky_relu_fusion.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/leaky_relu_fusion.cpp @@ -24,14 +24,13 @@ ngraph::pass::LeakyReluFusion::LeakyReluFusion() { auto max_pattern = ngraph::pattern::wrap_type({data_pattern, multiply_pattern}); ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) { - auto pattern_map = m.get_pattern_value_map(); - auto data = pattern_map.at(data_pattern); + const auto & pattern_map = m.get_pattern_value_map(); const auto & original_alpha_pattern = pattern_map.at(alpha_pattern); if (shape_size(original_alpha_pattern.get_shape()) != 1) return false; - auto leaky_relu = register_new_node(data, original_alpha_pattern); + auto leaky_relu = register_new_node(pattern_map.at(data_pattern), original_alpha_pattern); auto maximum = pattern_map.at(max_pattern); leaky_relu->set_friendly_name(maximum.get_node()->get_friendly_name()); diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/normalize_l2_fusion.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/normalize_l2_fusion.cpp index 22aac2e1c71..11147d815cd 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/normalize_l2_fusion.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/normalize_l2_fusion.cpp @@ -9,34 +9,37 @@ #include #include -#include +#include #include #include +#include NGRAPH_RTTI_DEFINITION(ngraph::pass::NormalizeL2Fusion, "NormalizeL2Fusion", 0); -NGRAPH_RTTI_DEFINITION(ngraph::pass::NormalizeL2FusionWithMax, "NormalizeL2FusionWithMax", 0); - -ngraph::pass::NormalizeL2FusionWithMax::NormalizeL2FusionWithMax() { - MATCHER_SCOPE(NormalizeL2FusionWithMax); +ngraph::pass::NormalizeL2Fusion::NormalizeL2Fusion() { + MATCHER_SCOPE(NormalizeL2Fusion); auto input = ngraph::pattern::any_input(); - auto exp = ngraph::pattern::wrap_type(); - auto pow = std::make_shared(input, exp); - auto axes = ngraph::pattern::wrap_type(); - auto reduce_sum = std::make_shared(pow, axes); - auto eps_const = ngraph::pattern::wrap_type(); - auto max = std::make_shared(reduce_sum, eps_const); - auto sqrt = std::make_shared(max); - auto divide = std::make_shared(input, sqrt); + auto exp = ngraph::pattern::wrap_type(); + auto pow = std::make_shared(input, exp); + auto axes = ngraph::pattern::wrap_type(); + auto reduce_sum = std::make_shared(pow, axes); + auto eps_const = ngraph::pattern::wrap_type(); - ngraph::matcher_pass_callback matcher_pass_callback = [=](ngraph::pattern::Matcher& m) { - auto& pattern_to_output = m.get_pattern_value_map(); + auto max = std::make_shared(reduce_sum, eps_const); + auto add = std::make_shared(reduce_sum, eps_const); + auto max_or_add = std::make_shared(OutputVector{max, add}); + + auto sqrt = std::make_shared(max_or_add); + auto divide = std::make_shared(input, sqrt); + + ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) { + const auto& pattern_to_output = m.get_pattern_value_map(); const auto data_input = pattern_to_output.at(input); - const auto exp_input = std::dynamic_pointer_cast(pattern_to_output.at(exp).get_node_shared_ptr()); - const auto axes_input = std::dynamic_pointer_cast(pattern_to_output.at(axes).get_node_shared_ptr()); - const auto eps_attr = std::dynamic_pointer_cast(pattern_to_output.at(eps_const).get_node_shared_ptr()); + const auto exp_input = std::dynamic_pointer_cast(pattern_to_output.at(exp).get_node_shared_ptr()); + const auto axes_input = std::dynamic_pointer_cast(pattern_to_output.at(axes).get_node_shared_ptr()); + const auto eps_attr = std::dynamic_pointer_cast(pattern_to_output.at(eps_const).get_node_shared_ptr()); if (!exp_input || !axes_input || !eps_attr) { return false; @@ -51,7 +54,19 @@ ngraph::pass::NormalizeL2FusionWithMax::NormalizeL2FusionWithMax() { } const auto eps_attr_value = eps_attr->cast_vector()[0]; - auto normalize_l2 = std::make_shared(data_input, axes_input, eps_attr_value, op::EpsMode::MAX); + op::EpsMode mode; + Output eps_node; + if (pattern_to_output.count(max)) { + mode = op::EpsMode::MAX; + eps_node = pattern_to_output.at(max); + } else if (pattern_to_output.count(add)) { + mode = op::EpsMode::ADD; + eps_node = pattern_to_output.at(add); + } else { + return false; + } + + auto normalize_l2 = std::make_shared(data_input, axes_input, eps_attr_value, mode); if (transformation_callback(normalize_l2)) return false; @@ -59,64 +74,8 @@ ngraph::pass::NormalizeL2FusionWithMax::NormalizeL2FusionWithMax() { ngraph::copy_runtime_info({pattern_to_output.at(pow).get_node_shared_ptr(), pattern_to_output.at(reduce_sum).get_node_shared_ptr(), pattern_to_output.at(sqrt).get_node_shared_ptr(), - pattern_to_output.at(max).get_node_shared_ptr(), - pattern_to_output.at(divide).get_node_shared_ptr() - }, - normalize_l2); - ngraph::replace_node(m.get_match_root(), normalize_l2); - return true; - }; - - auto m = std::make_shared(divide, matcher_name); - register_matcher(m, matcher_pass_callback); -} - -NGRAPH_RTTI_DEFINITION(ngraph::pass::NormalizeL2FusionWithAdd, "NormalizeL2FusionWithAdd", 0); - -ngraph::pass::NormalizeL2FusionWithAdd::NormalizeL2FusionWithAdd() { - MATCHER_SCOPE(NormalizeL2FusionWithAdd); - auto input = ngraph::pattern::any_input(); - - auto exp = ngraph::pattern::wrap_type(); - auto pow = std::make_shared(input, exp); - auto axes = ngraph::pattern::wrap_type(); - auto reduce_sum = std::make_shared(pow, axes); - auto eps_const = ngraph::pattern::wrap_type(); - auto add = std::make_shared(reduce_sum, eps_const); - auto sqrt = std::make_shared(add); - auto divide = std::make_shared(input, sqrt); - - ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) { - auto& pattern_to_output = m.get_pattern_value_map(); - - const auto data_input = pattern_to_output.at(input); - const auto exp_input = std::dynamic_pointer_cast(pattern_to_output.at(exp).get_node_shared_ptr()); - const auto axes_input = std::dynamic_pointer_cast(pattern_to_output.at(axes).get_node_shared_ptr()); - const auto eps_attr = std::dynamic_pointer_cast(pattern_to_output.at(eps_const).get_node_shared_ptr()); - - if (!exp_input || !axes_input || !eps_attr) { - return false; - } - - const bool is_square_pow = shape_size(exp_input->get_shape()) <= 1 && exp_input->cast_vector()[0] == 2; - if (!is_square_pow) { - return false; - } - if (shape_size(eps_attr->get_shape()) > 1) { - return false; - } - const auto eps_attr_value = op::util::has_constant_value(exp_input, 2.0f); - - auto normalize_l2 = std::make_shared(data_input, axes_input, eps_attr_value, op::EpsMode::ADD); - if (transformation_callback(normalize_l2)) - return false; - - normalize_l2->set_friendly_name(m.get_match_root()->get_friendly_name()); - ngraph::copy_runtime_info({pattern_to_output.at(pow).get_node_shared_ptr(), - pattern_to_output.at(reduce_sum).get_node_shared_ptr(), - pattern_to_output.at(sqrt).get_node_shared_ptr(), - pattern_to_output.at(add).get_node_shared_ptr(), - pattern_to_output.at(divide).get_node_shared_ptr() + pattern_to_output.at(divide).get_node_shared_ptr(), + eps_node.get_node_shared_ptr() }, normalize_l2); ngraph::replace_node(m.get_match_root(), normalize_l2); diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_downgrade.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_downgrade.cpp new file mode 100644 index 00000000000..80ad6847d9b --- /dev/null +++ b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_downgrade.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/op_conversions/convert_gather_downgrade.hpp" +#include +#include +#include +#include +#include +#include "itt.hpp" + +using namespace std; +using namespace ngraph; + +NGRAPH_RTTI_DEFINITION(pass::ConvertGather7ToGather1, "ConvertGather7ToGather1", 0); +NGRAPH_RTTI_DEFINITION(pass::ConvertGather8ToGather7, "ConvertGather8ToGather7", 0); + + +pass::ConvertGather7ToGather1::ConvertGather7ToGather1() { + MATCHER_SCOPE(ConvertGather7ToGather1); + + auto gather_v7_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto gather_v7_node = std::dynamic_pointer_cast(m.get_match_root()); + if (!gather_v7_node) + return false; + if (gather_v7_node->get_batch_dims() != 0) + return false; + + auto gather_v1_node = make_shared(gather_v7_node->input_value(0), + gather_v7_node->input_value(1), + gather_v7_node->input_value(2)); + + gather_v1_node->set_friendly_name(gather_v7_node->get_friendly_name()); + ngraph::copy_runtime_info(gather_v7_node, gather_v1_node); + ngraph::replace_node(gather_v7_node, gather_v1_node); + return true; + }; + + auto m = make_shared(gather_v7_pattern, matcher_name); + register_matcher(m, callback); +} + +pass::ConvertGather8ToGather7::ConvertGather8ToGather7() { + MATCHER_SCOPE(ConvertGather8ToGather7); + + auto gather_v8_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto gather_v8_node = std::dynamic_pointer_cast(m.get_match_root()); + if (!gather_v8_node) + return false; + + auto gather_v7_node = make_shared(gather_v8_node->input_value(0), + gather_v8_node->input_value(1), + gather_v8_node->input_value(2), + gather_v8_node->get_batch_dims()); + + gather_v7_node->set_friendly_name(gather_v8_node->get_friendly_name()); + ngraph::copy_runtime_info(gather_v8_node, gather_v7_node); + ngraph::replace_node(gather_v8_node, gather_v7_node); + return true; + }; + + auto m = make_shared(gather_v8_pattern, matcher_name); + register_matcher(m, callback); +} diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_upgrade.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_upgrade.cpp new file mode 100644 index 00000000000..5fff142d883 --- /dev/null +++ b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_upgrade.cpp @@ -0,0 +1,68 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/op_conversions/convert_gather_upgrade.hpp" +#include +#include +#include +#include +#include +#include "itt.hpp" + +using namespace std; +using namespace ngraph; + +NGRAPH_RTTI_DEFINITION(pass::ConvertGather1ToGather7, "ConvertGather1ToGather7", 0); +NGRAPH_RTTI_DEFINITION(pass::ConvertGather7ToGather8, "ConvertGather7ToGather8", 0); + + +pass::ConvertGather1ToGather7::ConvertGather1ToGather7() { + MATCHER_SCOPE(ConvertGather1ToGather7); + + auto gather_v1_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto gather_v1_node = std::dynamic_pointer_cast(m.get_match_root()); + if (!gather_v1_node) + return false; + + auto gather_v7_node = make_shared(gather_v1_node->input_value(0), + gather_v1_node->input_value(1), + gather_v1_node->input_value(2), + 0); + + gather_v7_node->set_friendly_name(gather_v1_node->get_friendly_name()); + ngraph::copy_runtime_info(gather_v1_node, gather_v7_node); + ngraph::replace_node(gather_v1_node, gather_v7_node); + return true; + }; + + auto m = make_shared(gather_v1_pattern, matcher_name); + register_matcher(m, callback); +} + +pass::ConvertGather7ToGather8::ConvertGather7ToGather8() { + MATCHER_SCOPE(ConvertGather7ToGather8); + + auto gather_v7_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto gather_v7_node = std::dynamic_pointer_cast(m.get_match_root()); + if (!gather_v7_node) + return false; + + auto gather_v8_node = make_shared(gather_v7_node->input_value(0), + gather_v7_node->input_value(1), + gather_v7_node->input_value(2), + gather_v7_node->get_batch_dims()); + + gather_v8_node->set_friendly_name(gather_v7_node->get_friendly_name()); + ngraph::copy_runtime_info(gather_v7_node, gather_v8_node); + ngraph::replace_node(gather_v7_node, gather_v8_node); + return true; + }; + + auto m = make_shared(gather_v7_pattern, matcher_name); + register_matcher(m, callback); +} diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v1_to_gather_v7.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v1_to_gather_v7.cpp deleted file mode 100644 index 7037c880eb5..00000000000 --- a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v1_to_gather_v7.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "transformations/op_conversions/convert_gather_v1_to_gather_v7.hpp" -#include -#include -#include -#include -#include "itt.hpp" - -NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertGather1ToGather7, "ConvertGather1ToGather7", 0); - -ngraph::pass::ConvertGather1ToGather7::ConvertGather1ToGather7() { - MATCHER_SCOPE(ConvertGather1ToGather7); - - auto gather_v1 = pattern::wrap_type(); - - ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) { - auto gather_v1_node = m.get_match_root(); - if (!gather_v1_node) - return false; - - auto data_input = gather_v1_node->input_value(0); - auto indices_input = gather_v1_node->input_value(1); - auto axis_input = gather_v1_node->input_value(2); - - auto gather_v7 = std::make_shared(data_input, indices_input, axis_input, 0); - gather_v7->set_friendly_name(gather_v1_node->get_friendly_name()); - ngraph::copy_runtime_info(gather_v1_node, gather_v7); - ngraph::replace_node(gather_v1_node, gather_v7); - return true; - }; - - auto m = std::make_shared(gather_v1, matcher_name); - register_matcher(m, callback); -} diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v7_to_gather_v1.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v7_to_gather_v1.cpp deleted file mode 100644 index 5e39be3feed..00000000000 --- a/inference-engine/src/transformations/src/transformations/op_conversions/convert_gather_v7_to_gather_v1.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "transformations/op_conversions/convert_gather_v7_to_gather_v1.hpp" -#include -#include -#include -#include - -#include "itt.hpp" - -NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertGather7ToGather1, "ConvertGather7ToGather1", 0); - -ngraph::pass::ConvertGather7ToGather1::ConvertGather7ToGather1() { - MATCHER_SCOPE(ConvertGather7ToGather1); - - auto gather_v7 = pattern::wrap_type(); - - ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) { - auto gather_v7_node = std::dynamic_pointer_cast(m.get_match_root()); - if (!gather_v7_node) - return false; - - if (gather_v7_node->get_batch_dims() != 0) - return false; - - auto data_input = gather_v7_node->input_value(0); - auto indices_input = gather_v7_node->input_value(1); - auto axis_input = gather_v7_node->input_value(2); - - auto gather_v1 = std::make_shared(data_input, indices_input, axis_input); - gather_v1->set_friendly_name(gather_v7_node->get_friendly_name()); - ngraph::copy_runtime_info(gather_v7_node, gather_v1); - ngraph::replace_node(gather_v7_node, gather_v1); - return true; - }; - - auto m = std::make_shared(gather_v7, matcher_name); - register_matcher(m, callback); -} diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/convert_interpolate1_to_interpolate4.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/convert_interpolate1_to_interpolate4.cpp index 36a58551a68..a8b45668461 100644 --- a/inference-engine/src/transformations/src/transformations/op_conversions/convert_interpolate1_to_interpolate4.cpp +++ b/inference-engine/src/transformations/src/transformations/op_conversions/convert_interpolate1_to_interpolate4.cpp @@ -44,7 +44,7 @@ ngraph::pass::ConvertInterpolate1ToInterpolate4::ConvertInterpolate1ToInterpolat ngraph::opset4::Interpolate::InterpolateAttrs attrsV4; if (attrsV0.mode == "nearest") { - attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::nearest; + attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::NEAREST; } else if (attrsV0.mode == "linear") { // If we write only // attrsV4.mode = ngraph::op::v4::Interpolate::InterpolateMode::linear; @@ -54,34 +54,34 @@ ngraph::pass::ConvertInterpolate1ToInterpolate4::ConvertInterpolate1ToInterpolat // TODO: delete this conditional statement, when CPU will have // optimized version of the 'linear' mode. if (input_shape_rank < 5) { - attrsV4.mode = ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx; + attrsV4.mode = ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX; } else if (input_shape_rank == 5) { - attrsV4.mode = ngraph::op::v4::Interpolate::InterpolateMode::linear; + attrsV4.mode = ngraph::op::v4::Interpolate::InterpolateMode::LINEAR; } else { return false; } } else if (attrsV0.mode == "cubic") { - attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::cubic; + attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::CUBIC; } else if (attrsV0.mode == "linear_onnx") { - attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::linear_onnx; + attrsV4.mode = ngraph::opset4::Interpolate::InterpolateMode::LINEAR_ONNX; } else { return false; } - attrsV4.shape_calculation_mode = ngraph::opset4::Interpolate::ShapeCalcMode::sizes; - attrsV4.nearest_mode = ngraph::opset4::Interpolate::NearestMode::simple; + attrsV4.shape_calculation_mode = ngraph::opset4::Interpolate::ShapeCalcMode::SIZES; + attrsV4.nearest_mode = ngraph::opset4::Interpolate::NearestMode::SIMPLE; attrsV4.pads_begin = attrsV0.pads_begin; attrsV4.pads_end = attrsV0.pads_end; attrsV4.antialias = attrsV0.antialias; - attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::asymmetric; + attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::ASYMMETRIC; attrsV4.cube_coeff = -0.75f; if (attrsV0.align_corners) { - attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::align_corners; - } else if ((attrsV4.mode == ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx || - attrsV4.mode == ngraph::op::v4::Interpolate::InterpolateMode::linear) && + attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS; + } else if ((attrsV4.mode == ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX || + attrsV4.mode == ngraph::op::v4::Interpolate::InterpolateMode::LINEAR) && std::all_of(attrsV4.pads_begin.begin(), attrsV4.pads_begin.end(), [](size_t i){return i == 0;}) && std::all_of(attrsV4.pads_end.begin(), attrsV4.pads_end.end(), [](size_t i){return i == 0;}) && !(input_shape_rank - 2 == 2 && attrsV0.axes == AxisSet{2, 3})) { - attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::half_pixel; + attrsV4.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::HALF_PIXEL; } auto interpolateV4 = std::make_shared(interpolationV0->input_value(0), interpolationV0->input_value(1), diff --git a/inference-engine/src/transformations/src/transformations/op_conversions/normalize_l2_decomposition.cpp b/inference-engine/src/transformations/src/transformations/op_conversions/normalize_l2_decomposition.cpp new file mode 100644 index 00000000000..cfbb6e1d0e1 --- /dev/null +++ b/inference-engine/src/transformations/src/transformations/op_conversions/normalize_l2_decomposition.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "itt.hpp" +#include "transformations/op_conversions/normalize_l2_decomposition.hpp" + +#include + +#include +#include +#include + +NGRAPH_RTTI_DEFINITION(ngraph::pass::NormalizeL2Decomposition, "NormalizeL2Decomposition", 0); + +ngraph::pass::NormalizeL2Decomposition::NormalizeL2Decomposition() { + MATCHER_SCOPE(NormalizeL2Decomposition); + auto normalize_l2_pattern = ngraph::pattern::wrap_type(); + + ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher &m) { + auto normalize_l2 = std::dynamic_pointer_cast(m.get_match_root()); + + if (!normalize_l2 || transformation_callback(normalize_l2)) { + return false; + } + + auto power = std::make_shared(normalize_l2->input_value(0), + opset8::Constant::create(normalize_l2->get_input_element_type(0), Shape{}, {2.0})); + auto reduce_sum = std::make_shared(power, normalize_l2->input_value(1), true); + + std::shared_ptr eps_node; + auto eps_const_node = opset8::Constant::create(normalize_l2->get_input_element_type(0), Shape{}, {normalize_l2->get_eps()}); + switch (normalize_l2->get_eps_mode()) { + case op::EpsMode::ADD: + eps_node = std::make_shared(reduce_sum, eps_const_node); + break; + case op::EpsMode::MAX: + eps_node = std::make_shared(reduce_sum, eps_const_node); + break; + default: + return false; + } + + auto sqrt = std::make_shared(eps_node); + auto div = std::make_shared(normalize_l2->input_value(0), sqrt); + + div->set_friendly_name(normalize_l2->get_friendly_name()); + ngraph::copy_runtime_info(normalize_l2, {power, reduce_sum, eps_node, sqrt, div}); + ngraph::replace_node(normalize_l2, div); + return true; + }; + + auto m = std::make_shared(normalize_l2_pattern, matcher_name); + register_matcher(m, callback); +} + diff --git a/inference-engine/src/transformations/src/transformations/rt_info/dequantization_attribute.cpp b/inference-engine/src/transformations/src/transformations/rt_info/dequantization_attribute.cpp index 67bfc8de3f6..829f5a0d85b 100644 --- a/inference-engine/src/transformations/src/transformations/rt_info/dequantization_attribute.cpp +++ b/inference-engine/src/transformations/src/transformations/rt_info/dequantization_attribute.cpp @@ -13,16 +13,28 @@ #include "transformations/rt_info/dequantization_attribute.hpp" -namespace ngraph { - -template class ngraph::VariantImpl; - -constexpr VariantTypeInfo VariantWrapper::type_info; +using namespace ov; +using namespace ngraph; std::string DequantizationAttr::getDequantizationAttr() const { return dequantization_attribute; } +std::string ngraph::getDequantization(const std::shared_ptr& node) { + const auto& rtInfo = node->get_rt_info(); + using getDequantizationWrapper = VariantWrapper; + + if (!rtInfo.count(getDequantizationWrapper::type_info.name)) return ""; + + const auto& attr = rtInfo.at(getDequantizationWrapper::type_info.name); + DequantizationAttr pp = as_type_ptr(attr)->get(); + return pp.getDequantizationAttr(); +} + +template class ov::VariantImpl; + +constexpr VariantTypeInfo VariantWrapper::type_info; + std::shared_ptr VariantWrapper::merge(const ngraph::NodeVector & nodes) { std::set dequantizations; @@ -43,17 +55,3 @@ std::shared_ptr VariantWrapper::merge(const std::shared_ptr VariantWrapper::init(const std::shared_ptr & node) { return std::make_shared>(DequantizationAttr(node->get_friendly_name())); } - -std::string getDequantization(const std::shared_ptr& node) { - const auto& rtInfo = node->get_rt_info(); - using getDequantizationWrapper = VariantWrapper; - - if (!rtInfo.count(getDequantizationWrapper::type_info.name)) return ""; - - const auto& attr = rtInfo.at(getDequantizationWrapper::type_info.name); - DequantizationAttr pp = as_type_ptr(attr)->get(); - return pp.getDequantizationAttr(); -} - - -} // namespace ngraph diff --git a/inference-engine/src/transformations/src/transformations/rt_info/disable_constant_folding.cpp b/inference-engine/src/transformations/src/transformations/rt_info/disable_constant_folding.cpp index 791102ed1f4..696f02bf521 100644 --- a/inference-engine/src/transformations/src/transformations/rt_info/disable_constant_folding.cpp +++ b/inference-engine/src/transformations/src/transformations/rt_info/disable_constant_folding.cpp @@ -4,11 +4,11 @@ #include "transformations/rt_info/disable_constant_folding.hpp" -template class ngraph::VariantImpl; +template class ov::VariantImpl; -constexpr ngraph::VariantTypeInfo ngraph::VariantWrapper::type_info; +constexpr ov::VariantTypeInfo ov::VariantWrapper::type_info; void ngraph::disable_constant_folding(const std::shared_ptr& node) { auto & rt_info = node->get_rt_info(); rt_info[VariantWrapper::type_info.name] = make_variant({}); -} \ No newline at end of file +} diff --git a/inference-engine/src/transformations/src/transformations/rt_info/fused_names_attribute.cpp b/inference-engine/src/transformations/src/transformations/rt_info/fused_names_attribute.cpp index cf60bc39573..01af6fc50d4 100644 --- a/inference-engine/src/transformations/src/transformations/rt_info/fused_names_attribute.cpp +++ b/inference-engine/src/transformations/src/transformations/rt_info/fused_names_attribute.cpp @@ -13,11 +13,8 @@ #include "transformations/rt_info/fused_names_attribute.hpp" -namespace ngraph { - -template class ngraph::VariantImpl; - -constexpr VariantTypeInfo VariantWrapper::type_info; +using namespace ngraph; +using namespace ov; std::string FusedNames::getNames() const { std::string res; @@ -37,6 +34,34 @@ void FusedNames::fuseWith(const FusedNames &names) { } } +std::string ngraph::getFusedNames(const std::shared_ptr &node) { + const auto &rtInfo = node->get_rt_info(); + using FusedNamesWrapper = VariantWrapper; + + if (!rtInfo.count(FusedNamesWrapper::type_info.name)) return {}; + + const auto &attr = rtInfo.at(FusedNamesWrapper::type_info.name); + FusedNames fusedNames = as_type_ptr(attr)->get(); + return fusedNames.getNames(); +} + +std::vector ngraph::getFusedNamesVector(const std::shared_ptr &node) { + if (!node) return {}; + + const auto &rtInfo = node->get_rt_info(); + using FusedNamesWrapper = VariantWrapper; + + if (!rtInfo.count(FusedNamesWrapper::type_info.name)) return {}; + + const auto &attr = rtInfo.at(FusedNamesWrapper::type_info.name); + FusedNames fusedNames = as_type_ptr(attr)->get(); + return fusedNames.getVectorNames(); +} + +template class ov::VariantImpl; + +constexpr VariantTypeInfo VariantWrapper::type_info; + std::shared_ptr VariantWrapper::merge(const ngraph::NodeVector & nodes) { FusedNames mergedNames; for (auto &node : nodes) { @@ -54,30 +79,3 @@ std::shared_ptr VariantWrapper::merge(const ngraph: std::shared_ptr VariantWrapper::init(const std::shared_ptr & node) { return std::make_shared > (FusedNames(node->get_friendly_name())); } - -std::string getFusedNames(const std::shared_ptr &node) { - const auto &rtInfo = node->get_rt_info(); - using FusedNamesWrapper = VariantWrapper; - - if (!rtInfo.count(FusedNamesWrapper::type_info.name)) return {}; - - const auto &attr = rtInfo.at(FusedNamesWrapper::type_info.name); - FusedNames fusedNames = as_type_ptr(attr)->get(); - return fusedNames.getNames(); -} - -std::vector getFusedNamesVector(const std::shared_ptr &node) { - if (!node) return {}; - - const auto &rtInfo = node->get_rt_info(); - using FusedNamesWrapper = VariantWrapper; - - if (!rtInfo.count(FusedNamesWrapper::type_info.name)) return {}; - - const auto &attr = rtInfo.at(FusedNamesWrapper::type_info.name); - FusedNames fusedNames = as_type_ptr(attr)->get(); - return fusedNames.getVectorNames(); -} - - -} // namespace ngraph diff --git a/inference-engine/src/transformations/src/transformations/rt_info/primitives_priority_attribute.cpp b/inference-engine/src/transformations/src/transformations/rt_info/primitives_priority_attribute.cpp index 82aa5892230..86244edd94d 100644 --- a/inference-engine/src/transformations/src/transformations/rt_info/primitives_priority_attribute.cpp +++ b/inference-engine/src/transformations/src/transformations/rt_info/primitives_priority_attribute.cpp @@ -16,16 +16,28 @@ #include "ngraph_ops/convolution_ie.hpp" #include "ngraph_ops/deconvolution_ie.hpp" -namespace ngraph { - -template class ngraph::VariantImpl; - -constexpr VariantTypeInfo VariantWrapper::type_info; +using namespace ov; +using namespace ngraph; std::string PrimitivesPriority::getPrimitivesPriority() const { return primitives_priority; } +std::string ngraph::getPrimitivesPriority(const std::shared_ptr &node) { + const auto &rtInfo = node->get_rt_info(); + using PrimitivesPriorityWrapper = VariantWrapper; + + if (!rtInfo.count(PrimitivesPriorityWrapper::type_info.name)) return ""; + + const auto &attr = rtInfo.at(PrimitivesPriorityWrapper::type_info.name); + PrimitivesPriority pp = as_type_ptr(attr)->get(); + return pp.getPrimitivesPriority(); +} + +template class ov::VariantImpl; + +constexpr VariantTypeInfo VariantWrapper::type_info; + std::shared_ptr VariantWrapper::merge(const ngraph::NodeVector & nodes) { auto isConvolutionBased = [](const std::shared_ptr & node) -> bool { if (std::dynamic_pointer_cast(node) || @@ -62,16 +74,3 @@ std::shared_ptr VariantWrapper::merge(const std::shared_ptr VariantWrapper::init(const std::shared_ptr & node) { throw ngraph_error(std::string(type_info.name) + " has no default initialization."); } - -std::string getPrimitivesPriority(const std::shared_ptr &node) { - const auto &rtInfo = node->get_rt_info(); - using PrimitivesPriorityWrapper = VariantWrapper; - - if (!rtInfo.count(PrimitivesPriorityWrapper::type_info.name)) return ""; - - const auto &attr = rtInfo.at(PrimitivesPriorityWrapper::type_info.name); - PrimitivesPriority pp = as_type_ptr(attr)->get(); - return pp.getPrimitivesPriority(); -} - -} // namespace ngraph diff --git a/inference-engine/src/transformations/src/transformations/smart_reshape/strided_slice_squeeze.cpp b/inference-engine/src/transformations/src/transformations/smart_reshape/strided_slice_squeeze.cpp index 24e0cf207d3..cb03cd9b88e 100644 --- a/inference-engine/src/transformations/src/transformations/smart_reshape/strided_slice_squeeze.cpp +++ b/inference-engine/src/transformations/src/transformations/smart_reshape/strided_slice_squeeze.cpp @@ -158,8 +158,8 @@ bool squeezes_perform_the_same(std::shared_ptr lhs, std const auto l_axes = std::dynamic_pointer_cast(lhs->get_input_node_shared_ptr(1)); const auto r_axes = std::dynamic_pointer_cast(rhs->get_input_node_shared_ptr(1)); if (l_axes && r_axes) - return normalize_axes(lhs->description(), l_axes->cast_vector(), rank) == - normalize_axes(rhs->description(), r_axes->cast_vector(), rank); + return ngraph::normalize_axes(lhs->description(), l_axes->cast_vector(), rank) == + ngraph::normalize_axes(rhs->description(), r_axes->cast_vector(), rank); return false; } diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/compile_env.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/compile_env.hpp index 3228c7e1a4c..7cff0ee8dba 100644 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/compile_env.hpp +++ b/inference-engine/src/vpu/graph_transformer/include/vpu/compile_env.hpp @@ -13,21 +13,20 @@ namespace vpu { struct DeviceResources { - static int numShaves(const ncDevicePlatform_t& platform); - static int numSlices(const ncDevicePlatform_t& platform); + static int numShaves(); + static int numSlices(); static int numStreams(); }; struct DefaultAllocation { - static int numStreams(const ncDevicePlatform_t& platform, const PluginConfiguration& configuration); - static int numSlices(const ncDevicePlatform_t& platform, int numStreams); - static int numShaves(const ncDevicePlatform_t& platform, int numStreams, int numSlices); + static int numStreams(const PluginConfiguration& configuration); + static int numSlices(int numStreams); + static int numShaves(int numStreams, int numSlices); static int tilingCMXLimit(int numSlices); }; struct CompileEnv final { public: - ncDevicePlatform_t platform; Resources resources; PluginConfiguration config; @@ -50,14 +49,13 @@ public: static const CompileEnv* getOrNull(); static void init( - ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log); static void updateConfig(const PluginConfiguration& config); static void free(); private: - explicit CompileEnv(ncDevicePlatform_t platform); + CompileEnv(); }; } // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/configuration/options/platform.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/configuration/options/platform.hpp deleted file mode 100644 index bcf527ac37b..00000000000 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/configuration/options/platform.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -#include "vpu/configuration/as_parameter_enabler.hpp" - -#include - -namespace vpu { - -namespace details { - -enum class Access; -enum class Category; - -} // namespace details - -class PluginConfiguration; - -struct PlatformOption : public AsParameterEnabler { - using value_type = ncDevicePlatform_t; - - static std::string key(); - static void validate(const std::string&); - static void validate(const PluginConfiguration&); - static std::string defaultValue(); - static value_type parse(const std::string&); - static details::Access access(); - static details::Category category(); -}; - -} // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer.hpp index 218a69989ef..6566e5d5265 100644 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer.hpp +++ b/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer.hpp @@ -71,7 +71,7 @@ struct CompiledGraph final { // compileNetwork // -CompiledGraph::Ptr compileNetwork(const ie::CNNNetwork& network, ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log, +CompiledGraph::Ptr compileNetwork(const ie::CNNNetwork& network, const PluginConfiguration& config, const Logger::Ptr& log, const std::shared_ptr core); CompiledGraph::Ptr compileSubNetwork(const ie::CNNNetwork& network, const PluginConfiguration& subConfig, const std::shared_ptr core); @@ -80,7 +80,7 @@ CompiledGraph::Ptr compileSubNetwork(const ie::CNNNetwork& network, const Plugin // getSupportedLayers // -std::set getSupportedLayers(const ie::CNNNetwork& network, ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log, +std::set getSupportedLayers(const ie::CNNNetwork& network, const PluginConfiguration& config, const Logger::Ptr& log, const std::shared_ptr core); // diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer_internal.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer_internal.hpp index 99cddb1be79..b6c02c0f8e4 100644 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer_internal.hpp +++ b/inference-engine/src/vpu/graph_transformer/include/vpu/graph_transformer_internal.hpp @@ -12,7 +12,6 @@ namespace vpu { CompiledGraph::Ptr compileModel( const Model& model, - ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log); diff --git a/inference-engine/src/vpu/graph_transformer/src/configuration/options/platform.cpp b/inference-engine/src/vpu/graph_transformer/src/configuration/options/platform.cpp deleted file mode 100644 index 210414dd1e8..00000000000 --- a/inference-engine/src/vpu/graph_transformer/src/configuration/options/platform.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "vpu/configuration/options/platform.hpp" -#include "vpu/utils/containers.hpp" -#include "vpu/configuration/plugin_configuration.hpp" - -#include -#include - -#include - -namespace vpu { - -namespace { - -const std::unordered_map& string2platform() { -IE_SUPPRESS_DEPRECATED_START - static const std::unordered_map converters = { - {VPU_MYRIAD_CONFIG_VALUE(2450), ncDevicePlatform_t::NC_MYRIAD_2}, - {VPU_MYRIAD_CONFIG_VALUE(2480), ncDevicePlatform_t::NC_MYRIAD_X}, - {std::string(), ncDevicePlatform_t::NC_ANY_PLATFORM}, - }; -IE_SUPPRESS_DEPRECATED_END - return converters; -} - -} // namespace - -void PlatformOption::validate(const std::string& value) { - const auto& converters = string2platform(); - VPU_THROW_UNLESS(converters.count(value) != 0, R"(unexpected {} option value "{}", only {} are supported)", - key(), value, getKeys(converters)); -} - -void PlatformOption::validate(const PluginConfiguration& configuration) { - validate(configuration[key()]); -} - -std::string PlatformOption::key() { -IE_SUPPRESS_DEPRECATED_START - return VPU_MYRIAD_CONFIG_KEY(PLATFORM); -IE_SUPPRESS_DEPRECATED_END -} - -details::Access PlatformOption::access() { - return details::Access::Public; -} - -details::Category PlatformOption::category() { - return details::Category::RunTime; -} - -std::string PlatformOption::defaultValue() { - return std::string(); -} - -PlatformOption::value_type PlatformOption::parse(const std::string& value) { - const auto& converters = string2platform(); - VPU_THROW_UNSUPPORTED_OPTION_UNLESS(converters.count(value) != 0, R"(unexpected {} option value "{}", only {} are supported)", - key(), value, getKeys(converters)); - return converters.at(value); -} - -} // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp b/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp index ba3888dea28..c2e5c054de4 100644 --- a/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp @@ -479,10 +479,6 @@ ModelPtr FrontEnd::runCommonPasses(ie::CNNNetwork network, env.log->trace("Parse custom layers : %s", customLayers); VPU_LOGGER_SECTION(env.log); - if (env.platform != ncDevicePlatform_t::NC_MYRIAD_X) { - VPU_THROW_FORMAT("Custom layers are not supported for %v platforms", env.platform); - } - _customLayers = CustomLayer::loadFromFile(customLayers); } diff --git a/inference-engine/src/vpu/graph_transformer/src/graph_transformer.cpp b/inference-engine/src/vpu/graph_transformer/src/graph_transformer.cpp index 463e0fdcada..c82a75515d0 100644 --- a/inference-engine/src/vpu/graph_transformer/src/graph_transformer.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/graph_transformer.cpp @@ -64,7 +64,7 @@ thread_local CompileEnv* g_compileEnv = nullptr; } // namespace -CompileEnv::CompileEnv(ncDevicePlatform_t platform) : platform(platform) {} +CompileEnv::CompileEnv() {} const CompileEnv& CompileEnv::get() { IE_ASSERT(g_compileEnv != nullptr); @@ -79,8 +79,8 @@ const CompileEnv* CompileEnv::getOrNull() { return g_compileEnv; } -void CompileEnv::init(ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log) { - g_compileEnv = new CompileEnv(platform); +void CompileEnv::init(const PluginConfiguration& config, const Logger::Ptr& log) { + g_compileEnv = new CompileEnv(); g_compileEnv->config = config; g_compileEnv->log = log; @@ -88,22 +88,18 @@ void CompileEnv::init(ncDevicePlatform_t platform, const PluginConfiguration& co g_compileEnv->profile.setLogger(log); #endif - if (platform == ncDevicePlatform_t::NC_MYRIAD_2) { - g_compileEnv->config.set(ie::MYRIAD_ENABLE_HW_ACCELERATION, ie::PluginConfigParams::NO); - } - const auto numExecutors = config.get().hasValue() - ? config.get().get() : DefaultAllocation::numStreams(platform, config); + ? config.get().get() : DefaultAllocation::numStreams(config); VPU_THROW_UNLESS(numExecutors >= 1 && numExecutors <= DeviceResources::numStreams(), R"(Value of configuration option ("{}") must be in the range [{}, {}], actual is "{}")", ThroughputStreamsOption::key(), 1, DeviceResources::numStreams(), numExecutors); const auto numSlices = config.get().hasValue() ? config.get().get() - : DefaultAllocation::numSlices(platform, numExecutors); - VPU_THROW_UNLESS(numSlices >= 1 && numSlices <= DeviceResources::numSlices(platform), + : DefaultAllocation::numSlices(numExecutors); + VPU_THROW_UNLESS(numSlices >= 1 && numSlices <= DeviceResources::numSlices(), R"(Value of configuration option ("{}") must be in the range [{}, {}], actual is "{}")", - NumberOfCMXSlicesOption::key(), 1, DeviceResources::numSlices(platform), numSlices); + NumberOfCMXSlicesOption::key(), 1, DeviceResources::numSlices(), numSlices); int defaultCmxLimit = DefaultAllocation::tilingCMXLimit(numSlices); const auto tilingCMXLimit = config.get().hasValue() @@ -115,18 +111,18 @@ void CompileEnv::init(ncDevicePlatform_t platform, const PluginConfiguration& co const auto numShaves = config.get().hasValue() ? config.get().get() - : DefaultAllocation::numShaves(platform, numExecutors, numSlices); - VPU_THROW_UNLESS(numShaves >= 1 && numShaves <= DeviceResources::numShaves(platform), + : DefaultAllocation::numShaves(numExecutors, numSlices); + VPU_THROW_UNLESS(numShaves >= 1 && numShaves <= DeviceResources::numShaves(), R"(Value of configuration option ("{}") must be in the range [{}, {}], actual is "{}")", - NumberOfSHAVEsOption::key(), 1, DeviceResources::numShaves(platform), numShaves); + NumberOfSHAVEsOption::key(), 1, DeviceResources::numShaves(), numShaves); const auto numAllocatedShaves = numShaves * numExecutors; - VPU_THROW_UNLESS(numAllocatedShaves >= 1 && numAllocatedShaves <= DeviceResources::numShaves(platform), - R"(Cannot allocate "{}" shaves: only {} is available)", numAllocatedShaves, DeviceResources::numShaves(platform)); + VPU_THROW_UNLESS(numAllocatedShaves >= 1 && numAllocatedShaves <= DeviceResources::numShaves(), + R"(Cannot allocate "{}" shaves: only {} is available)", numAllocatedShaves, DeviceResources::numShaves()); const auto numAllocatedSlices = numSlices * numExecutors; - VPU_THROW_UNLESS(numAllocatedSlices >= 1 && numAllocatedSlices <= DeviceResources::numSlices(platform), - R"(Cannot allocate "{}" slices: only {} is available)", numAllocatedSlices, DeviceResources::numSlices(platform)); + VPU_THROW_UNLESS(numAllocatedSlices >= 1 && numAllocatedSlices <= DeviceResources::numSlices(), + R"(Cannot allocate "{}" slices: only {} is available)", numAllocatedSlices, DeviceResources::numSlices()); g_compileEnv->resources.numSHAVEs = numShaves; g_compileEnv->resources.numCMXSlices = numSlices; @@ -203,9 +199,9 @@ CompiledGraph::Ptr compileImpl(const Model& model) { } // namespace -CompiledGraph::Ptr compileNetwork(const ie::CNNNetwork& network, ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log, +CompiledGraph::Ptr compileNetwork(const ie::CNNNetwork& network, const PluginConfiguration& config, const Logger::Ptr& log, const std::shared_ptr core) { - CompileEnv::init(platform, config, log); + CompileEnv::init(config, log); AutoScope autoDeinit([] { CompileEnv::free(); }); @@ -217,10 +213,9 @@ CompiledGraph::Ptr compileNetwork(const ie::CNNNetwork& network, ncDevicePlatfor CompiledGraph::Ptr compileModel( const Model& model, - ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log) { - CompileEnv::init(platform, config, log); + CompileEnv::init(config, log); AutoScope autoDeinit([] { CompileEnv::free(); }); @@ -251,11 +246,10 @@ CompiledGraph::Ptr compileSubNetwork(const ie::CNNNetwork& network, const Plugin std::set getSupportedLayers( const ie::CNNNetwork& network, - ncDevicePlatform_t platform, const PluginConfiguration& config, const Logger::Ptr& log, const std::shared_ptr core) { - CompileEnv::init(platform, config, log); + CompileEnv::init(config, log); AutoScope autoDeinit([] { CompileEnv::free(); }); @@ -267,29 +261,29 @@ std::set getSupportedLayers( return frontEnd->checkSupportedLayers(network); } -int DeviceResources::numShaves(const ncDevicePlatform_t& platform) { - return platform == ncDevicePlatform_t::NC_MYRIAD_2 ? 12 : 16; +int DeviceResources::numShaves() { + return 16; } -int DeviceResources::numSlices(const ncDevicePlatform_t& platform) { - return platform == ncDevicePlatform_t::NC_MYRIAD_2 ? 12 : 19; +int DeviceResources::numSlices() { + return 19; } int DeviceResources::numStreams() { return 3; } -int DefaultAllocation::numStreams(const ncDevicePlatform_t& platform, const PluginConfiguration& configuration) { - return platform == ncDevicePlatform_t::NC_MYRIAD_X && configuration.get() ? 2 : 1; +int DefaultAllocation::numStreams(const PluginConfiguration& configuration) { + return configuration.get() ? 2 : 1; } -int DefaultAllocation::numSlices(const ncDevicePlatform_t& platform, int numStreams) { - const auto capabilities = DeviceResources::numSlices(platform); +int DefaultAllocation::numSlices(int numStreams) { + const auto capabilities = DeviceResources::numSlices(); return capabilities / numStreams; } -int DefaultAllocation::numShaves(const ncDevicePlatform_t& platform, int numStreams, int numSlices) { - const auto numAvailableShaves = DeviceResources::numShaves(platform); +int DefaultAllocation::numShaves(int numStreams, int numSlices) { + const auto numAvailableShaves = DeviceResources::numShaves(); if (numStreams == 1) { return numAvailableShaves; } diff --git a/inference-engine/src/vpu/graph_transformer/src/model/stage.cpp b/inference-engine/src/vpu/graph_transformer/src/model/stage.cpp index cad7da95ca8..8733742a0ad 100644 --- a/inference-engine/src/vpu/graph_transformer/src/model/stage.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/model/stage.cpp @@ -197,12 +197,6 @@ StageSHAVEsRequirements StageNode::getSHAVEsRequirements() const { // Get result from Stage implementation. // - // return max for Myriad2 - const auto& compileEnv = CompileEnv::get(); - if (compileEnv.platform == ncDevicePlatform_t::NC_MYRIAD_2) { - return StageSHAVEsRequirements::NeedMax; - } - auto reqs = getSHAVEsRequirementsImpl(); // diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.cpp b/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.cpp index 679fb25d1cd..f9bd974a0ff 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.cpp +++ b/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.cpp @@ -54,9 +54,8 @@ ExecutableNetwork::ExecutableNetwork( void ExecutableNetwork::openDevice(std::vector& devicePool) { _device = _executor->openDevice(devicePool, _config); - const auto& revision = _device->revision(); _actualNumExecutors = _config.get().hasValue() - ? _config.get().get() : DefaultAllocation::numStreams(revision, _config); + ? _config.get().get() : DefaultAllocation::numStreams(_config); } ExecutableNetwork::ExecutableNetwork( @@ -75,7 +74,6 @@ ExecutableNetwork::ExecutableNetwork( auto compiledGraph = compileNetwork( network, - NC_MYRIAD_X, _config, compilerLog, _core); diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.h b/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.h index c64a9f6aaf0..d093597cd49 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.h +++ b/inference-engine/src/vpu/myriad_plugin/myriad_executable_network.h @@ -54,8 +54,7 @@ public: ie::IInferRequestInternal::Ptr CreateInferRequestImpl(ie::InputsDataMap networkInputs, ie::OutputsDataMap networkOutputs) override { if (!_isNetworkConstant && (_device == nullptr || !_device->isBooted())) { - IE_THROW() << "Can not create infer request: there is no available devices with platform " - << _device->_platform; + IE_THROW() << "Can not create infer request: there is no available devices with platform "; } return std::make_shared(_graphDesc, networkInputs, networkOutputs, @@ -66,8 +65,7 @@ public: ie::IInferRequestInternal::Ptr CreateInferRequest() override { if (!_isNetworkConstant && (_device == nullptr || !_device->isBooted())) { - IE_THROW() << "Can not create infer request: there is no available devices with platform " - << _device->_platform; + IE_THROW() << "Can not create infer request: there is no available devices with platform "; } auto syncRequestImpl = std::make_shared(_graphDesc, _networkInputs, _networkOutputs, diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_executor.cpp b/inference-engine/src/vpu/myriad_plugin/myriad_executor.cpp index f0f3628049c..1cc67e639e0 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_executor.cpp +++ b/inference-engine/src/vpu/myriad_plugin/myriad_executor.cpp @@ -90,7 +90,6 @@ ncStatus_t MyriadExecutor::bootNextDevice(std::vector &devicePool, co } #endif - const ncDevicePlatform_t& configPlatform = ncDevicePlatform_t::NC_ANY_PLATFORM; const ncDeviceProtocol_t& configProtocol = config.get(); const std::string& configDevName = config.get(); PowerConfig powerConfig = config.get(); @@ -114,7 +113,6 @@ ncStatus_t MyriadExecutor::bootNextDevice(std::vector &devicePool, co #endif ncDeviceDescr_t in_deviceDesc = {}; - in_deviceDesc.platform = configPlatform; in_deviceDesc.protocol = configProtocol; if (!configDevName.empty()) { @@ -126,13 +124,6 @@ ncStatus_t MyriadExecutor::bootNextDevice(std::vector &devicePool, co if (it == availableDevicesDesc.end()) { IE_THROW() << "Myriad device: " << configDevName << " not found."; - } else { - ncDeviceDescr_t deviceDesc = *it; - if (configPlatform != NC_ANY_PLATFORM && - configPlatform != deviceDesc.platform) { - IE_THROW() << "Input value of device name and platform are contradict each other. Device name: " << configDevName - << "Platform: " << configPlatform; - } } configDevName.copy(in_deviceDesc.name, NC_MAX_NAME_SIZE - 1); @@ -164,8 +155,8 @@ ncStatus_t MyriadExecutor::bootNextDevice(std::vector &devicePool, co // Get device protocol status = ncDeviceGetOption(device._deviceHandle, NC_RO_DEVICE_PLATFORM, - reinterpret_cast(&device._platform), &dataLength); - if (status != NC_OK || dataLength != sizeof(device._platform)) { + reinterpret_cast(&device), &dataLength); + if (status != NC_OK) { _log->warning("Failed to get device platform"); ncDeviceClose(&device._deviceHandle, _mvnc->watchdogHndl()); return status != NC_OK ? status : NC_ERROR; // for dataLength error @@ -273,10 +264,11 @@ DevicePtr MyriadExecutor::openDevice(std::vector& devicePool, return device->isBooted() && device->isNotFull() && device->isSuitableForConfig(config); }); - // Return mock device. If try infer with it, exception will be thrown if (availableDevices.empty()) { - IE_THROW() << "Can not init Myriad device: " << ncStatusToStr(nullptr, booted); + DeviceDesc device; + device._protocol = config.get(); + return std::make_shared(device); } auto deviceWithMinExecutors = std::min_element(availableDevices.begin(), availableDevices.end(), @@ -288,7 +280,6 @@ DevicePtr MyriadExecutor::openDevice(std::vector& devicePool, } _log->info("Device #%d %s (%s protocol) allocated", devicePool.size() - 1, - devicePool.back()->_platform == NC_MYRIAD_X ? "MYRIAD-X" : "MYRIAD-2", devicePool.back()->_protocol == NC_USB? "USB" : "PCIe"); return devicePool.back(); @@ -378,7 +369,7 @@ void MyriadExecutor::allocateGraph(DevicePtr &device, GraphDesc &graphDesc, IE_THROW() << "Failed to get output description: " << ncStatusToStr(graphDesc._graphHandle, status); } - unsigned int fifo_elements = (device->_platform == NC_MYRIAD_2 && executors == 1) ? 4 : 2 * executors; + unsigned int fifo_elements = 2 * executors; status = ncFifoCreate("input", NC_FIFO_HOST_WO, &graphDesc._inputFifoHandle); if (status != NC_OK) { diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_executor.h b/inference-engine/src/vpu/myriad_plugin/myriad_executor.h index 997f7525d32..84a6269347b 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_executor.h +++ b/inference-engine/src/vpu/myriad_plugin/myriad_executor.h @@ -38,7 +38,6 @@ struct DeviceDesc { int _graphNum = 0; int _maxGraphNum = 0; std::string _name; - ncDevicePlatform_t _platform = NC_ANY_PLATFORM; ncDeviceProtocol_t _protocol = NC_ANY_PROTOCOL; int _deviceIdx = -1; @@ -63,11 +62,6 @@ struct DeviceDesc { return isSuitableByName && ((config.get() == NC_ANY_PROTOCOL) || (_protocol == config.get())); } - - ncDevicePlatform_t revision() const { - VPU_THROW_UNLESS(_platform != NC_ANY_PLATFORM, "Cannot get a revision from not booted device"); - return _platform; - } }; typedef std::shared_ptr DevicePtr; diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_metrics.cpp b/inference-engine/src/vpu/myriad_plugin/myriad_metrics.cpp index 83e16dbaff0..78b4b031b24 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_metrics.cpp +++ b/inference-engine/src/vpu/myriad_plugin/myriad_metrics.cpp @@ -40,7 +40,6 @@ IE_SUPPRESS_DEPRECATED_START // deprecated KEY_VPU_CUSTOM_LAYERS, KEY_VPU_MYRIAD_FORCE_RESET, - KEY_VPU_MYRIAD_PLATFORM, CONFIG_KEY(CONFIG_FILE), }; diff --git a/inference-engine/src/vpu/myriad_plugin/myriad_plugin.cpp b/inference-engine/src/vpu/myriad_plugin/myriad_plugin.cpp index e84877890a6..1136f71f345 100644 --- a/inference-engine/src/vpu/myriad_plugin/myriad_plugin.cpp +++ b/inference-engine/src/vpu/myriad_plugin/myriad_plugin.cpp @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -165,7 +164,6 @@ QueryNetworkResult Engine::QueryNetwork( const auto supportedLayers = getSupportedLayers( network, - ncDevicePlatform_t::NC_ANY_PLATFORM, parsedConfigCopy, log, GetCore()); @@ -247,7 +245,6 @@ IE_SUPPRESS_DEPRECATED_START _parsedConfig.registerDeprecatedOption(VPU_CONFIG_KEY(CUSTOM_LAYERS)); _parsedConfig.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE)); _parsedConfig.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(FORCE_RESET)); - _parsedConfig.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(PLATFORM)); IE_SUPPRESS_DEPRECATED_END } diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/add_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/add_transformation.cpp index 2b0ea5f013e..529cd008547 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/add_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/add_transformation.cpp @@ -77,19 +77,6 @@ typedef std::tuple < AddTransformationTestValues > AddTransformationParams; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class AddTransformation : public LayerTransformation, public testing::WithParamInterface { public: void SetUp() override { diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/align_concat_quantization_parameters_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/align_concat_quantization_parameters_transformation.cpp index 5264e458669..30a6d84eb68 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/align_concat_quantization_parameters_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/align_concat_quantization_parameters_transformation.cpp @@ -162,7 +162,7 @@ const std::vector tes ngraph::element::f32, {{}, {std::vector(6, 128.f), element::f32, {1, 6, 1, 1}}, {}}, ngraph::element::f32, - {{}, {}, {std::vector(9, 0.0001f), element::f32, {1, 9, 1, 1}}} + {{}, {}, {{0.0001f}, element::f32, {}}} } } }; diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/avg_pool_with_child_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/avg_pool_with_child_transformation.cpp index aa2c591eeb3..0de23c8081c 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/avg_pool_with_child_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/avg_pool_with_child_transformation.cpp @@ -137,7 +137,7 @@ const std::vector testValues = { {}, ngraph::element::u8, {}, - {{}, {}, {std::vector{0.0002f}, element::f32, {1, 6, 1, 1}}} + {{}, {}, {std::vector{0.0002f}, element::f32, {}}} } }, // U8 per tensor quantization diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_neighbors_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_neighbors_transformation.cpp index 1dacc2f7eb7..3ecbcd116bb 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_neighbors_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_neighbors_transformation.cpp @@ -343,11 +343,11 @@ const std::vector testValues = { { {}, {{ 128.f, 128.f, 128.f, 128.f, 128.f, 128.f }, ngraph::element::f32, { 1, 6, 1, 1 }, false}, - {{0.1f}, ngraph::element::f32, { 1, 1, 1, 1 } } }, + {{0.1f}, ngraph::element::f32, {} } }, { {}, {{128.f, 128.f, 128.f}, ngraph::element::f32, { 1, 3, 1, 1 }, false}, - {{0.1f}, ngraph::element::f32, { 1, 1, 1, 1 } } } + {{0.1f}, ngraph::element::f32, {} } } }, "convolution", "convolution" diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_backprop_data_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_backprop_data_transformation.cpp index 50802fbba21..dc81761eb5b 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_backprop_data_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_backprop_data_transformation.cpp @@ -223,7 +223,7 @@ const std::vector testValues = ngraph::element::u8, {{}, { { 128.f }, ngraph::element::f32, {}, false }, {}}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -243,7 +243,7 @@ const std::vector testValues = ngraph::element::u8, {{}, { { 128.f }, ngraph::element::f32, {}, false }, {}}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -263,7 +263,7 @@ const std::vector testValues = ngraph::element::u8, {{}, { { 128.f }, ngraph::element::f32, {}, false }, {}}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::f32, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -283,7 +283,7 @@ const std::vector testValues = ngraph::element::u8, {{}, { { 128.f }, ngraph::element::f32, {}, false }, {}}, {{}, { { 2.f }, ngraph::element::f32, {1, 2, 1, 1}, true, 1ul, element::i8, false, { "DISABLED_CONSTANT_FOLDING" } }, {}}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ 2.f }), true } @@ -303,7 +303,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -323,7 +323,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -343,7 +343,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, {1}}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ 2.f }), true } @@ -363,7 +363,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -403,7 +403,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 2, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), true } @@ -423,7 +423,7 @@ const std::vector testValues = ngraph::element::u8, {}, {}, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 2, 1, 1 }}}, + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}}, op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ 2.f }), true } diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_qdq_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_qdq_transformation.cpp index 32300353277..98ef612c595 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_qdq_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_qdq_transformation.cpp @@ -178,7 +178,7 @@ const std::vector testValues = { { std::vector{ 100.f }, ngraph::element::i8}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0006f }, ngraph::element::f32, {1, 1, 1, 1}}} + {{}, {}, {{ 0.0006f }, ngraph::element::f32, {}}} } }, @@ -230,7 +230,7 @@ const std::vector testValues = { { std::vector{ -125.f }, ngraph::element::i8}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, @@ -353,7 +353,7 @@ const std::vector testValues = { { std::vector{ 2.f }, ngraph::element::i8}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0006f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0006f }, ngraph::element::f32, {}}} } }, @@ -421,7 +421,7 @@ const std::vector testValues = { { std::vector{ 2.f }, ngraph::element::i8}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0006f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0006f }, ngraph::element::f32, {}}} } }, // incorrect zero point on activations [not transformed] diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_transformation.cpp index d8f35b7bca5..394ea243b3c 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_transformation.cpp @@ -153,7 +153,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // with zero point @@ -193,7 +193,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::f32, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // without zero point @@ -213,7 +213,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // without zero point @@ -233,7 +233,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // without zero point, not update precisions @@ -253,7 +253,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::f32, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // with zero point, per-channel quantization with the same values @@ -273,7 +273,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // with zero point, per-channel quantization with different values @@ -389,7 +389,7 @@ const std::vector testValues = { op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector{ -125.f }), {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 1, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // incorrect zero point on activations [not transformed] diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_with_incorrect_weights.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_with_incorrect_weights.cpp index 3a28bbe934e..dd13a0fe87a 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_with_incorrect_weights.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/convolution_with_incorrect_weights.cpp @@ -131,7 +131,7 @@ const std::vector testValues = { {}, ngraph::element::i8, {-126.f}, - {{}, {}, {{ 0.1f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 0.1f }, ngraph::element::f32, {}}}, }, }, }; diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/elementwise_with_multi_parent_dequantization_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/elementwise_with_multi_parent_dequantization_transformation.cpp index c850a471b47..014376e8ae8 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/elementwise_with_multi_parent_dequantization_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/elementwise_with_multi_parent_dequantization_transformation.cpp @@ -50,19 +50,6 @@ public: Expected expected; }; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class ElementwiseWithMultiParentDequantizationTransformation : public LayerTransformation, public testing::WithParamInterface { diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_and_two_output_branches_with_convolution.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_and_two_output_branches_with_convolution.cpp index 7ff62291259..0990ea02099 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_and_two_output_branches_with_convolution.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_and_two_output_branches_with_convolution.cpp @@ -130,9 +130,9 @@ const std::vector fak {{}, {}, {}}, ngraph::element::f32, { 255ul, {1, 1, 1, 1}, { 0.f }, { 254.f }, { -127.f }, { 127.f } }, - {{}, {}, {{ 1.f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 1.f }, ngraph::element::f32, {}}}, { 255ul, {1, 1, 1, 1}, { 0.f }, { 254.f }, { -127.f }, { 127.f } }, - {{}, {}, {{ 1.f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 1.f }, ngraph::element::f32, {}}}, } }, // TODO: LPT: issue #58685 @@ -169,9 +169,9 @@ const std::vector fak {{}, {}, {}}, ngraph::element::f32, { }, - {{}, {}, {{ 1.f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 1.f }, ngraph::element::f32, {}}}, { }, - {{}, {}, {{ 1.f }, ngraph::element::f32, { 1, 1, 1, 1 }}}, + {{}, {}, {{ 1.f }, ngraph::element::f32, {}}}, } } }; diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_with_dq_not_optimal_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_with_dq_not_optimal_transformation.cpp index 9266a6d8e62..34d55ee701d 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_with_dq_not_optimal_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fake_quantize_with_dq_not_optimal_transformation.cpp @@ -204,7 +204,7 @@ const std::vector fakeQuanti { { }, { }, - { {0.0003f}, ngraph::element::f32, {1, 1, 1, 1}} + { {0.0003f}, ngraph::element::f32, {}} } }, } diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_convert_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_convert_transformation.cpp index 85da2f104ee..b41a139fa55 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_convert_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_convert_transformation.cpp @@ -48,19 +48,6 @@ typedef std::tuple< ngraph::PartialShape, FuseConvertTransformationTestValues> FuseConvertTransformationParams; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class FuseConvertTransformation : public LayerTransformation, public testing::WithParamInterface { public: void SetUp() override { diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_fake_quantize_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_fake_quantize_transformation.cpp index 354e0dab7f6..223efa27859 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_fake_quantize_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_fake_quantize_transformation.cpp @@ -385,12 +385,12 @@ const std::vector testValues = { }, { element::f32, - { {127}, element::f32 }, + {}, element::f32, - { {element::f32}, { -128 }, { 0.01f } }, + { {}, {}, {} }, element::f32, element::f32, - { 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } } + { 256ul, {}, { -255.f }, { 0.f }, { 0.f }, { 2.55f } } } }, // negative multiply diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_multiply_to_fake_quantize_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_multiply_to_fake_quantize_transformation.cpp index 48d637370a0..715ab98c921 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_multiply_to_fake_quantize_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_multiply_to_fake_quantize_transformation.cpp @@ -176,7 +176,8 @@ INSTANTIATE_TEST_SUITE_P( namespace testValues2 { const std::vector inputShapesWithDynamicChannels = { - {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()} + {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}, + ngraph::PartialShape::dynamic() }; const std::vector testValues = { @@ -213,33 +214,4 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(testValues)), FuseMultiplyToFakeQuantizeTransformation::getTestCaseName); } // namespace testValues2 - -namespace testValues3 { -const std::vector inputShapesWithDynamicChannels = { - PartialShape::dynamic() -}; - -const std::vector testValues = { - { - LayerTransformation::createParamsU8I8(), - { - { 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 255.f }, element::u8 }, - { {}, {}, { 0.5f } }, - }, - { - { 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 255.f }, element::u8 }, - { {}, {}, { 0.5f } }, - } - }, -}; - -INSTANTIATE_TEST_SUITE_P( - smoke_LPT, - FuseMultiplyToFakeQuantizeTransformation, - ::testing::Combine( - ::testing::ValuesIn(quantizationLevels), - ::testing::ValuesIn(inputShapesWithDynamicChannels), - ::testing::ValuesIn(testValues)), - FuseMultiplyToFakeQuantizeTransformation::getTestCaseName); -} // namespace testValues3 } // namespace diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_subtract_to_fake_quantize_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_subtract_to_fake_quantize_transformation.cpp index 2af936da365..23b2c946e86 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_subtract_to_fake_quantize_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/fuse_subtract_to_fake_quantize_transformation.cpp @@ -256,6 +256,7 @@ INSTANTIATE_TEST_SUITE_P( namespace testValues2 { const std::vector inputShapesWithDynamicChannels = { {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}, + PartialShape::dynamic() }; const std::vector testValues = { @@ -300,37 +301,4 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(testValues)), FuseSubtractToFakeQuantizeTransformation::getTestCaseName); } // namespace testValues2 - -namespace testValues3 { -const std::vector inputShapesWithDynamicRank = { - PartialShape::dynamic() -}; - -const std::vector testValues = { - { - LayerTransformation::createParamsU8I8(), - { - { 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 255.f }, element::u8 }, - { {element::f32}, { 128.f }, {} }, - {}, - {} - }, - { - { 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 255.f }, element::u8 }, - { {element::f32}, { 128.f }, {} }, - {}, - {} - } - }, -}; - -INSTANTIATE_TEST_SUITE_P( - smoke_LPT, - FuseSubtractToFakeQuantizeTransformation, - ::testing::Combine( - ::testing::ValuesIn(quantizationLevels), - ::testing::ValuesIn(inputShapesWithDynamicRank), - ::testing::ValuesIn(testValues)), - FuseSubtractToFakeQuantizeTransformation::getTestCaseName); -} // namespace testValues3 } // namespace diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/group_convolution_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/group_convolution_transformation.cpp index 469a5b06d56..1426ed6fe63 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/group_convolution_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/group_convolution_transformation.cpp @@ -163,7 +163,7 @@ const std::vector testValuesGroupConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 24, 1, 1 }}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) } }, @@ -188,7 +188,7 @@ const std::vector testValuesGroupConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 24, 1, 1 }}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) } }, @@ -213,7 +213,7 @@ const std::vector testValuesGroupConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 24, 1, 1 }}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) } }, @@ -262,7 +262,7 @@ const std::vector testValuesGroupConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 24, 1, 1 }}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} // 0.0002 = 0.02 (on data) * 0.01 (on weights) } }, // group convolution, per-channel quantization with different values, without zero point @@ -335,7 +335,7 @@ const std::vector testValuesGroupConv = { { {}, {}, - {{ 0.0002f }, ngraph::element::f32, {1, 24, 1, 1}} + {{ 0.0002f }, ngraph::element::f32, {}} }, } }, @@ -384,7 +384,7 @@ const std::vector testValuesGroupConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 24, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // per-channel quantization with different values, without zero point @@ -535,7 +535,7 @@ const std::vector testValuesForDepthWiseConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 6, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // depth-wise convolution, tensor quantization, with zero point @@ -559,7 +559,7 @@ const std::vector testValuesForDepthWiseConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 6, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // depth-wise convolution, per-channel quantization with different values, without zero point @@ -629,7 +629,7 @@ const std::vector testValuesForDepthWiseConv = { { {}, {}, - {{ 0.0002f }, ngraph::element::f32, {1, 6, 1, 1}} + {{ 0.0002f }, ngraph::element::f32, {}} }, } }, @@ -678,7 +678,7 @@ const std::vector testValuesForDepthWiseConv = { {}, {}, ngraph::element::f32, - {{}, {}, {{ 0.0002f }, ngraph::element::f32, { 1, 6, 1, 1 }}} + {{}, {}, {{ 0.0002f }, ngraph::element::f32, {}}} } }, // without dequantization operations diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/interpolate_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/interpolate_transformation.cpp index 0dfece76d57..3751f719c5f 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/interpolate_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/interpolate_transformation.cpp @@ -89,19 +89,6 @@ public: Expected expected; }; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class InterpolateTransformation : public LayerTransformation, public testing::WithParamInterface { public: void SetUp() override { @@ -428,8 +415,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -453,8 +440,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -478,8 +465,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -503,8 +490,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -528,8 +515,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -553,8 +540,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS, {0, 0, 0, 0}, {0, 0, 0, 0}), 4, @@ -578,8 +565,8 @@ const std::vector testValues { LayerTransformation::createParamsU8I8(), interpAttributes(), interp4Attributes( - ngraph::op::v4::Interpolate::InterpolateMode::nearest, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, {0, 0, 0, 1}, {0, 0, 1, 0}), 4, diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/layer_transformation.hpp b/inference-engine/tests/functional/inference_engine/lp_transformations/layer_transformation.hpp index a6f316f9cbd..374eb6d265a 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/layer_transformation.hpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/layer_transformation.hpp @@ -249,3 +249,16 @@ protected: std::shared_ptr actualFunction; std::shared_ptr referenceFunction; }; + +template +inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { + os << "{ "; + for (size_t i = 0; i < values.size(); ++i) { + os << values[i]; + if (i != (values.size() - 1ul)) { + os << ", "; + } + } + os << " }"; + return os; +} diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/multiply_to_group_convolution_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/multiply_to_group_convolution_transformation.cpp index a15b63eaf48..aab9028a6c6 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/multiply_to_group_convolution_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/multiply_to_group_convolution_transformation.cpp @@ -48,19 +48,6 @@ public: Expected expected; }; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class MultiplyToGroupConvolutionTransformation : public LayerTransformation, public testing::WithParamInterface { diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/mvn_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/mvn_transformation.cpp index a36e78c8735..e01bb3f80ad 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/mvn_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/mvn_transformation.cpp @@ -55,19 +55,6 @@ typedef std::tuple< int > MVNTransformationParams; -template -inline std::ostream& operator<<(std::ostream& os, const std::vector& values) { - os << "{ "; - for (size_t i = 0; i < values.size(); ++i) { - os << values[i]; - if (i != (values.size() - 1ul)) { - os << ", "; - } - } - os << " }"; - return os; -} - class MVNTransformation : public LayerTransformation, public testing::WithParamInterface { public: void SetUp() override { diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/pad_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/pad_transformation.cpp new file mode 100644 index 00000000000..6001fe1db14 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/pad_transformation.cpp @@ -0,0 +1,793 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "layer_transformation.hpp" + +#include +#include +#include +#include + +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include "lpt_ngraph_functions/common/dequantization_operations.hpp" +#include "lpt_ngraph_functions/pad_function.hpp" +#include "simple_low_precision_transformer.hpp" + + +namespace { +using namespace testing; +using namespace ngraph; +using namespace ngraph::pass; + +class PadTransformationTestValues { +public: + class Actual { + public: + ngraph::element::Type precisionBeforeDequantization; + ngraph::builder::subgraph::DequantizationOperations dequantization; + }; + + class Expected { + public: + ngraph::element::Type precisionBeforeDequantization; + ngraph::builder::subgraph::DequantizationOperations dequantizationBefore; + ngraph::element::Type precisionAfterOperation; + ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; + }; + + TestTransformationParams params; + Actual actual; + Expected expected; +}; + +typedef std::tuple < + ngraph::PartialShape, // input Shape + std::pair, std::vector>, // pads begin, pads end + ngraph::op::PadMode, // pads mode + float, // pads value (used if mode == CONSTANT) + PadTransformationTestValues> PadTransformationParams; + +class PadTransformation : public LayerTransformation, public testing::WithParamInterface { +public: + void SetUp() override { + const ngraph::PartialShape inputShape = std::get<0>(GetParam()); + const auto pads = std::get<1>(GetParam()); + const ngraph::op::PadMode padsMode = std::get<2>(GetParam()); + const float padsValue = std::get<3>(GetParam()); + const PadTransformationTestValues testValues = std::get<4>(GetParam()); + + const auto precisionAfterActualOp = testValues.actual.dequantization.convert.empty() ? + testValues.actual.precisionBeforeDequantization : testValues.actual.dequantization.convert.outPrecision; + + actualFunction = ngraph::builder::subgraph::PadFunction::get( + inputShape, + testValues.actual.precisionBeforeDequantization, + testValues.actual.dequantization, + pads.first, + pads.second, + padsMode, + padsValue, + precisionAfterActualOp, + { {}, {}, {} }); + + SimpleLowPrecisionTransformer transformer; + transformer.add(testValues.params); + transformer.transform(actualFunction); + + referenceFunction = ngraph::builder::subgraph::PadFunction::get( + inputShape, + testValues.expected.precisionBeforeDequantization, + testValues.expected.dequantizationBefore, + pads.first, + pads.second, + padsMode, + padsValue, + testValues.expected.precisionAfterOperation, + testValues.expected.dequantizationAfter); + } + + static std::string getTestCaseName(testing::TestParamInfo obj) { + const ngraph::PartialShape inputShape = std::get<0>(obj.param); + const auto pads = std::get<1>(obj.param); + const ngraph::op::PadMode padsMode = std::get<2>(obj.param); + const float padsValue = std::get<3>(obj.param); + const PadTransformationTestValues testValues = std::get<4>(obj.param); + + std::ostringstream result; + result << "mode_" << padsMode << "_"; + if (padsMode == ngraph::op::PadMode::CONSTANT) { + result << "pad_value_{ " << padsValue << " }"; + } + + result << "_" << + toString(testValues.params) << "_" << + inputShape << "_" << pads.first << "_" << pads.second << "_" << + testValues.actual.precisionBeforeDequantization << "_" << + testValues.actual.dequantization << "_" << + testValues.expected.dequantizationBefore; + + return result.str(); + } +}; + +TEST_P(PadTransformation, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, actualFunction, true, true); + ASSERT_TRUE(res.first) << res.second; +} + +const std::vector inputShapes = { + {1, 3, 6, 6}, + {4, 3, 6, 6}, + {Dimension::dynamic(), 3, 6, Dimension::dynamic()} +}; + +const std::pair, std::vector> padsBySpatialDimensions = { + {0, 0, 2, 1}, + {0, 0, 1, 2} +}; + +// test-cases with common logic for all modes +// (per-tensor & per-channel quantizations without subtracts, pads by spatial dimensions) +// and test-case without dequantization +namespace commonTestCases { +std::vector allModes = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC, + ngraph::op::PadMode::CONSTANT, +}; + +const std::vector deqWithoutSub = { + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {3.f}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {3.f}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{}, {}, {}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::f32, + {{}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::f32, + {{}, {}, {}}, + ngraph::element::f32, + {{}, {}, {{3.f, 1.f, 2.f}}} + } + }, + { + LayerTransformation::createParamsU8I8().setUpdatePrecisions(false), + { + ngraph::element::f32, + {{}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::f32, + {{}, {}, {}}, + ngraph::element::f32, + {{}, {}, {{3.f, 1.f, 2.f}}} + } + } +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::ValuesIn(allModes), + ::testing::Values(0.f), + ::testing::ValuesIn(deqWithoutSub)), + PadTransformation::getTestCaseName); +} // namespace commonTestCases + +// test-cases with common logic for "EDGE", "REFLECT", and "SYMMETRIC" modes: +// pads by spatial dimensions, dequantization with subtract +namespace dqWithSubtract { +std::vector modesInWhichSubPropagated = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC, +}; + +const std::vector deqWithSub = { + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {128.f}, {3.f}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {128.f}, {3.f}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {64.f}, {3.f}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {64.f}, {3.f}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}} + } + } +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::ValuesIn(modesInWhichSubPropagated), + ::testing::Values(0.f), + ::testing::ValuesIn(deqWithSub)), + PadTransformation::getTestCaseName); +} // namespace dqWithSubtract + +// dequantization with subtract and "CONSTANT" mode, also dequantization and padding by the same dimension +namespace testCasesForConstantMode { +const std::vector testValuesForConstantMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {64.f}, {3.f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {64.f}, {3.f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}} + } + } +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForConstantMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForConstantMode + +// dequantization with "CONSTANT" mode (non zero value) and non unique pad dimension: dequantization isn't propagated +namespace testCasesForConstantModeWithNonZeroValues { +const std::vector testValuesForConstantMode2 = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + } +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(1.f), + ::testing::ValuesIn(testValuesForConstantMode2)), + PadTransformation::getTestCaseName); +} // namespace testCasesForConstantModeWithNonZeroValues + +namespace testCasesForConstantModeAndUniquePadDimension { +const std::pair, std::vector> padsByUniqueDimension = { + {0, 0, 2, 0}, + {0, 0, 1, 0} +}; + +const std::vector testValuesForConstantMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {{64.f, 64.f, 64.f, 32.f, 32.f, 32.f}, ngraph::element::f32, {1, 1, 6, 1}}, + {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}} + } + }, + { + ngraph::element::i8, + {}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {{0.f, 0.f, 64.f, 64.f, 64.f, 32.f, 32.f, 32.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}}, + {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}} + } + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {64.f}, + {3.f} + } + }, + { + ngraph::element::i8, + {}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}}, + {3.f} + } + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsByUniqueDimension), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForConstantMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForConstantModeAndUniquePadDimension + +namespace testCasesForNonZeroConstantModeAndUniquePadDimension { +const std::pair, std::vector> padsByUniqueDimension = { + {0, 0, 2, 0}, + {0, 0, 1, 0} +}; + +const std::vector testValuesForConstantMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {}, + {{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}} + } + }, + { + ngraph::element::i8, + {}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {}, + {{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}} + } + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {64.f}, + {3.f} + } + }, + { + ngraph::element::i8, + {}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}}, + {{1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}} + } + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsByUniqueDimension), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(2.f), + ::testing::ValuesIn(testValuesForConstantMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForNonZeroConstantModeAndUniquePadDimension + +namespace testCasesForEdgeMode { +const std::vector testValuesForEdgeMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}} + } + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}, + {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}} + } + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::Values(ngraph::op::PadMode::EDGE), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForEdgeMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForEdgeMode + +namespace testCasesForReflectMode { +const std::vector testValuesForReflectMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}} + } + }, + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}} + }, + ngraph::element::f32, + {{}, {}, {}} + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::Values(ngraph::op::PadMode::REFLECT), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForReflectMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForReflectMode + +namespace testCasesForSymetricMode { +const std::vector testValuesForSymetricMode = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + { + {ngraph::element::f32}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}, + {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}} + } + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + { + {ngraph::element::f32}, + {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}, + {{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}} + } + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapes), + ::testing::Values(padsBySpatialDimensions), + ::testing::Values(ngraph::op::PadMode::SYMMETRIC), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForSymetricMode)), + PadTransformation::getTestCaseName); +} // namespace testCasesForSymetricMode + +namespace testCasesWithDynamicChannels { +const std::vector inputShapesWithDynamicChannels = { + {Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()} +}; + +std::vector allModes = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC, + ngraph::op::PadMode::CONSTANT, +}; + +const std::vector testValuesForDynamicChannels = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}}, + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapesWithDynamicChannels), + ::testing::Values(padsBySpatialDimensions), + ::testing::ValuesIn(allModes), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForDynamicChannels)), + PadTransformation::getTestCaseName); +} // namespace testCasesWithDynamicChannels + +namespace testCasesWithDynamicRank { +const std::vector inputShapesWithDynamicRank = { + ngraph::PartialShape::dynamic() +}; + +std::vector allModes = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC, + ngraph::op::PadMode::CONSTANT, +}; + +const std::vector testValuesForDynamicRank = { + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {3.f}}, + ngraph::element::f32, + {{}, {}, {}}, + } + }, + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}, + ngraph::element::f32, + {{}, {}, {}}, + } + }, +}; + +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(inputShapesWithDynamicRank), + ::testing::Values(padsBySpatialDimensions), + ::testing::ValuesIn(allModes), + ::testing::Values(0.f), + ::testing::ValuesIn(testValuesForDynamicRank)), + PadTransformation::getTestCaseName); +} // namespace testCasesWithDynamicRank +} // namespace diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/reshape_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/reshape_transformation.cpp index 377c8ca043b..6a67202125c 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/reshape_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/reshape_transformation.cpp @@ -332,6 +332,26 @@ const std::vector testValues = { } } }, + // U8: no subtract 4D -> 3D: rfcn-resnet101-coco + { + { 100, 4, 1, 1 }, + { -1, 1, 400}, + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + { + {ngraph::element::f32}, {}, {{0.1f, 0.1f, 0.1f, 0.1f}, ngraph::element::f32, {1, 4, 1, 1}} + } + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + { + {ngraph::element::f32}, {}, {{0.1f}, ngraph::element::f32, {}} + } + } + }, // U8: no subtract 4D -> 6D: channels are not affected: no subtract { { 1, 3, 4, 5 }, @@ -887,6 +907,30 @@ const std::vector testValues = { {{0.1f, 0.01f, 0.1f}, ngraph::element::f32, {1, 3, 1}} } } + }, + // U8: without subtract 2D -> 2D + { + { 1, 3 }, + { 1, -1 }, + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + { + {ngraph::element::f32}, + {}, + {{0.1f, 0.01f, 0.1f}, ngraph::element::f32, {1, 3}} + } + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + { + {ngraph::element::f32}, + {}, + {{0.1f, 0.01f, 0.1f}, ngraph::element::f32, {1, 3}} + } + } } }; diff --git a/inference-engine/tests/functional/inference_engine/transformations/convert_gather_downgrade_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/convert_gather_downgrade_test.cpp new file mode 100644 index 00000000000..16235dfbf7a --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/transformations/convert_gather_downgrade_test.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" + +using namespace testing; + +TEST(TransformationTests, ConvertGather7toGather1) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); + + auto gather_v7 = std::make_shared(data, indices, axis, 0); + + f = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); + + auto gather_v1 = std::make_shared(data, indices, axis); + + f_ref = std::make_shared(ngraph::NodeVector{gather_v1}, ngraph::ParameterVector{data, indices}); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, ConvertGather7toGather1_nonzero_batch_dims) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1}); + + auto gather_v7 = std::make_shared(data, indices, axis, -1); + + f = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + // if batch_dims != 0 Gather-7 must remain + ASSERT_EQ(count_ops_of_type(f), 0); + ASSERT_EQ(count_ops_of_type(f), 1); +} + +TEST(TransformationTests, ConvertGather8toGather7) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1}); + int64_t batch_dims = 1; + + auto gather_v8 = std::make_shared(data, indices, axis, batch_dims); + + f = std::make_shared(ngraph::NodeVector{gather_v8}, ngraph::ParameterVector{data, indices}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1}); + int64_t batch_dims = 1; + + auto gather_v7 = std::make_shared(data, indices, axis, batch_dims); + + f_ref = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} diff --git a/inference-engine/tests/functional/inference_engine/transformations/convert_gather_v7_to_gather_v1_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/convert_gather_upgrade_test.cpp similarity index 68% rename from inference-engine/tests/functional/inference_engine/transformations/convert_gather_v7_to_gather_v1_test.cpp rename to inference-engine/tests/functional/inference_engine/transformations/convert_gather_upgrade_test.cpp index 6d5d309a02f..690f883b0aa 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/convert_gather_v7_to_gather_v1_test.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/convert_gather_upgrade_test.cpp @@ -10,32 +10,18 @@ #include #include #include +#include +#include #include -#include +#include #include #include "common_test_utils/ngraph_test_utils.hpp" using namespace testing; -TEST(TransformationTests, ConvertGather7toGather1) { +TEST(TransformationTests, ConvertGather1toGather7) { std::shared_ptr f(nullptr), f_ref(nullptr); - { - auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); - auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); - auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); - - auto gather_v7 = std::make_shared(data, indices, axis, 0); - - f = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); - - ngraph::pass::Manager manager; - manager.register_pass(); - manager.register_pass(); - manager.run_passes(f); - ASSERT_NO_THROW(check_rt_info(f)); - } - { auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); @@ -43,32 +29,58 @@ TEST(TransformationTests, ConvertGather7toGather1) { auto gather_v1 = std::make_shared(data, indices, axis); - f_ref = std::make_shared(ngraph::NodeVector{gather_v1}, ngraph::ParameterVector{data, indices}); + f = std::make_shared(ngraph::NodeVector{gather_v1}, ngraph::ParameterVector{data, indices}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); + + auto gather_v7 = std::make_shared(data, indices, axis, 0); + + f_ref = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); } auto res = compare_functions(f, f_ref); ASSERT_TRUE(res.first) << res.second; } -TEST(TransformationTests, ConvertGather7toGather1_nonzero_batch_dims) { +TEST(TransformationTests, ConvertGather7toGather8) { std::shared_ptr f(nullptr), f_ref(nullptr); { auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1}); - - auto gather_v7 = std::make_shared(data, indices, axis, -1); + int64_t batch_dims = 1; + auto gather_v7 = std::make_shared(data, indices, axis, batch_dims); f = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); ASSERT_NO_THROW(check_rt_info(f)); } - // if batch_dims != 0 Gather-7 must remain - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); + { + auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); + auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); + auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1}); + int64_t batch_dims = 1; + + auto gather_v8 = std::make_shared(data, indices, axis, batch_dims); + + f_ref = std::make_shared(ngraph::NodeVector{gather_v8}, ngraph::ParameterVector{data, indices}); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; } diff --git a/inference-engine/tests/functional/inference_engine/transformations/convert_gather_v1_to_gather_v7_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/convert_gather_v1_to_gather_v7_test.cpp deleted file mode 100644 index db39785cc4f..00000000000 --- a/inference-engine/tests/functional/inference_engine/transformations/convert_gather_v1_to_gather_v7_test.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common_test_utils/ngraph_test_utils.hpp" - -using namespace testing; - -TEST(TransformationTests, ConvertGather1toGather7) { - std::shared_ptr f(nullptr), f_ref(nullptr); - { - auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); - auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); - auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); - - auto gather_v1 = std::make_shared(data, indices, axis); - - f = std::make_shared(ngraph::NodeVector{gather_v1}, ngraph::ParameterVector{data, indices}); - - ngraph::pass::Manager manager; - manager.register_pass(); - manager.register_pass(); - manager.run_passes(f); - ASSERT_NO_THROW(check_rt_info(f)); - } - - { - auto data = std::make_shared(ngraph::element::f32, ngraph::Shape{2, 3}); - auto indices = std::make_shared(ngraph::element::i32, ngraph::Shape{2, 2}); - auto axis = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {0}); - - auto gather_v7 = std::make_shared(data, indices, axis, 0); - - f_ref = std::make_shared(ngraph::NodeVector{gather_v7}, ngraph::ParameterVector{data, indices}); - } - - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; -} diff --git a/inference-engine/tests/functional/inference_engine/transformations/convert_interpolate1_to_interpolate4_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/convert_interpolate1_to_interpolate4_test.cpp index 12177f78cbc..bc205748fd1 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/convert_interpolate1_to_interpolate4_test.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/convert_interpolate1_to_interpolate4_test.cpp @@ -52,9 +52,9 @@ TEST(TransformationTests, ConvertInterpolate1ToInterpolate4) { auto default_scales_node = opset1::Constant::create(ngraph::element::f32, Shape{4}, {1.f, 1.f, 4.0f / 3.0f, 4.0f / 3.0f}); auto axes_node = opset1::Constant::create(ngraph::element::i64, Shape{4}, {0, 1, 2, 3}); - auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::nearest, - opset4::Interpolate::ShapeCalcMode::sizes, std::vector{0, 0, 0, 0}, std::vector{0, 0, 0, 0}, - opset4::Interpolate::CoordinateTransformMode::asymmetric, opset4::Interpolate::NearestMode::simple, + auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::NEAREST, + opset4::Interpolate::ShapeCalcMode::SIZES, std::vector{0, 0, 0, 0}, std::vector{0, 0, 0, 0}, + opset4::Interpolate::CoordinateTransformMode::ASYMMETRIC, opset4::Interpolate::NearestMode::SIMPLE, false, -0.75); auto interpolate4 = std::make_shared(data_node, out_shape_node, default_scales_node, axes_node, interpolate4_attr); @@ -97,9 +97,9 @@ TEST(TransformationTests, ConvertInterpolate1ToInterpolate4_1) { auto default_scales_node = opset1::Constant::create(ngraph::element::f32, Shape{2}, {4.0f / 3.0f, 4.0f / 3.0f}); auto axes_node = opset1::Constant::create(ngraph::element::i64, Shape{2}, {2, 3}); - auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::linear_onnx, - opset4::Interpolate::ShapeCalcMode::sizes, std::vector{0, 0, 0, 0}, std::vector{0, 0, 0, 0}, - opset4::Interpolate::CoordinateTransformMode::asymmetric, opset4::Interpolate::NearestMode::simple, + auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::LINEAR_ONNX, + opset4::Interpolate::ShapeCalcMode::SIZES, std::vector{0, 0, 0, 0}, std::vector{0, 0, 0, 0}, + opset4::Interpolate::CoordinateTransformMode::ASYMMETRIC, opset4::Interpolate::NearestMode::SIMPLE, true, -0.75); auto interpolate4 = std::make_shared(data_node, out_shape_node, default_scales_node, axes_node, interpolate4_attr); diff --git a/inference-engine/tests/functional/inference_engine/transformations/fc_bias_fusion_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/fc_bias_fusion_test.cpp index ebe78956bf5..303fe952582 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/fc_bias_fusion_test.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/fc_bias_fusion_test.cpp @@ -95,6 +95,43 @@ TEST(TransformationTests, FullyConnectedBiasFusionTest2D) { ASSERT_TRUE(res.first) << res.second; } + +TEST(TransformationTests, FullyConnectedBiasFusionTestBias1x1) { + std::shared_ptr function(nullptr), function_ref(nullptr); + { + auto input1 = std::make_shared(ngraph::element::f32, ngraph::Shape{1, 128}); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{786, 128}, {1}); + auto empty_bias = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{786}, {0}); + auto fc = std::make_shared(input1, weights, empty_bias, ngraph::Shape{1, 786}); + + auto const_bias = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{1, 1}, {1}); + auto add = std::make_shared(fc, const_bias); + + function = std::make_shared(ngraph::NodeVector{add}, ngraph::ParameterVector{input1}); + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.register_pass([](std::shared_ptr function) { + check_rt_info(function); + }); + manager.register_pass(); + ASSERT_NO_THROW(manager.run_passes(function)); + } + + { + auto input1 = std::make_shared(ngraph::element::f32, ngraph::Shape{1, 128}); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{786, 128}, {1}); + auto bias = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{786}, {1}); + auto fc = std::make_shared(input1, weights, bias, ngraph::Shape{1, 786}); + + function_ref = std::make_shared(ngraph::NodeVector{fc}, ngraph::ParameterVector{input1}); + } + + auto res = compare_functions(function, function_ref); + ASSERT_TRUE(res.first) << res.second; +} + TEST(TransformationTests, FullyConnectedBiasFusionDynamic) { auto input1 = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic()); auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{786, 128}, {1}); diff --git a/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_decomposition_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_decomposition_test.cpp new file mode 100644 index 00000000000..668331ff45a --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_decomposition_test.cpp @@ -0,0 +1,91 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" + +using namespace testing; + +TEST(TransformationTests, NormalizeL2DecomositionFusionWithMax) { + std::shared_ptr f, f_ref; + const float eps_value = 0.000099f; + { + auto input = std::make_shared(ngraph::element::f16, ngraph::PartialShape::dynamic(3)); + auto axes_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {1, 2}); + auto normalize_l2 = std::make_shared(input, axes_const, eps_value, ngraph::op::EpsMode::MAX); + + f = std::make_shared(ngraph::NodeVector{normalize_l2}, ngraph::ParameterVector{input}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + { + auto input = std::make_shared(ngraph::element::f16, ngraph::PartialShape::dynamic(3)); + auto exp = ngraph::opset8::Constant::create(ngraph::element::f16, ngraph::Shape{}, {2.f}); + auto pow = std::make_shared(input, exp); + auto axes_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {1, 2}); + auto reduce_sum = std::make_shared(pow, axes_const, true); + auto eps_const = ngraph::opset8::Constant::create(ngraph::element::f16, ngraph::Shape{}, {eps_value}); + auto max = std::make_shared(reduce_sum, eps_const); + auto sqrt = std::make_shared(max); + auto divide = std::make_shared(input, sqrt); + + f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); + } + + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; +} + +TEST(TransformationTests, NormalizeL2DecomositionFusionWithAdd) { + std::shared_ptr f, f_ref; + const float eps_value = 0.000099f; + { + auto input = std::make_shared(ngraph::element::f16, ngraph::PartialShape::dynamic(3)); + auto axes_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {0, 1}); + auto normalize_l2 = std::make_shared(input, axes_const, eps_value, ngraph::op::EpsMode::ADD); + + f = std::make_shared(ngraph::NodeVector{normalize_l2}, ngraph::ParameterVector{input}); + + ngraph::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + } + + { + auto input = std::make_shared(ngraph::element::f16, ngraph::PartialShape::dynamic(3)); + auto exp = ngraph::opset8::Constant::create(ngraph::element::f16, ngraph::Shape{}, {2.f}); + auto pow = std::make_shared(input, exp); + auto axes_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, {0, 1}); + auto reduce_sum = std::make_shared(pow, axes_const, true); + auto eps_const = ngraph::opset8::Constant::create(ngraph::element::f16, ngraph::Shape{}, {eps_value}); + auto max = std::make_shared(reduce_sum, eps_const); + auto sqrt = std::make_shared(max); + auto divide = std::make_shared(input, sqrt); + + f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); + } + + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; +} diff --git a/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_fusion_test.cpp b/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_fusion_test.cpp index f1d496013a4..fecf5c05b22 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_fusion_test.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/normalize_l2_fusion_test.cpp @@ -36,7 +36,7 @@ TEST(TransformationTests, NormalizeL2FusionWithMax) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); ASSERT_NO_THROW(check_rt_info(f)); } @@ -49,8 +49,9 @@ TEST(TransformationTests, NormalizeL2FusionWithMax) { f_ref = std::make_shared(ngraph::NodeVector{normalize_l2}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectExp) { @@ -71,7 +72,7 @@ TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectExp) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); } @@ -89,8 +90,9 @@ TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectExp) { f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectEpsValueShape) { @@ -110,7 +112,7 @@ TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectEpsValueShape) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); } @@ -128,8 +130,9 @@ TEST(TransformationTests, NormalizeL2FusionWithMaxIncorrectEpsValueShape) { f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } TEST(TransformationTests, NormalizeL2FusionWithAdd) { @@ -150,7 +153,7 @@ TEST(TransformationTests, NormalizeL2FusionWithAdd) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); ASSERT_NO_THROW(check_rt_info(f)); } @@ -163,8 +166,9 @@ TEST(TransformationTests, NormalizeL2FusionWithAdd) { f_ref = std::make_shared(ngraph::NodeVector{normalize_l2}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectExp) { @@ -185,7 +189,7 @@ TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectExp) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); ASSERT_NO_THROW(check_rt_info(f)); } @@ -204,8 +208,9 @@ TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectExp) { f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectEpsValueShape) { @@ -225,7 +230,7 @@ TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectEpsValueShape) { ngraph::pass::Manager manager; manager.register_pass(); - manager.register_pass(); + manager.register_pass(); manager.run_passes(f); } @@ -243,6 +248,7 @@ TEST(TransformationTests, NormalizeL2FusionWithAddIncorrectEpsValueShape) { f_ref = std::make_shared(ngraph::NodeVector{divide}, ngraph::ParameterVector{input}); } - auto res = compare_functions(f, f_ref); - ASSERT_TRUE(res.first) << res.second; + const auto fc = FunctionsComparator::with_default().enable(FunctionsComparator::ATTRIBUTES); + const auto res = fc.compare(f, f_ref); + ASSERT_TRUE(res.valid) << res.message; } diff --git a/inference-engine/tests/functional/plugin/cpu/CMakeLists.txt b/inference-engine/tests/functional/plugin/cpu/CMakeLists.txt index cde17b0a209..761ddb19580 100644 --- a/inference-engine/tests/functional/plugin/cpu/CMakeLists.txt +++ b/inference-engine/tests/functional/plugin/cpu/CMakeLists.txt @@ -30,3 +30,5 @@ addIeTargetTest( LABELS CPU ) + +set_ie_threading_interface_for(${TARGET_NAME}) diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/config.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/config.cpp index 00ece757453..aec20bce2cd 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/config.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/config.cpp @@ -30,11 +30,6 @@ namespace { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> AutoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}, {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "YES"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}, {std::string("AUTO_"), "NAN"}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, CorrectConfigTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -53,7 +48,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigs)), + ::testing::ValuesIn(MultiConfigs)), CorrectConfigTests::getTestCaseName); const std::vector> inconfigs = { @@ -71,13 +66,6 @@ namespace { {InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_LIMIT, "NAN"}} }; - const std::vector> autoinconfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}, - {InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, "OFF"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}, - {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "ON"}} - }; - const std::vector> multiconf = { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_CPU}} }; @@ -96,6 +84,13 @@ namespace { ::testing::ValuesIn(multiconf)), CorrectConfigAPITests::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, CorrectConfigAPITests, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_AUTO), + ::testing::ValuesIn(multiconf)), + CorrectConfigAPITests::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, IncorrectConfigTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -114,7 +109,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoinconfigs)), + ::testing::ValuesIn(multiinconfigs)), IncorrectConfigTests::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, IncorrectConfigAPITests, @@ -135,7 +130,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoinconfigs)), + ::testing::ValuesIn(multiinconfigs)), IncorrectConfigAPITests::getTestCaseName); } // namespace \ No newline at end of file diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_integration.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_integration.cpp index 040911489e5..e209712f2ba 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_integration.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_integration.cpp @@ -47,7 +47,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( smoke_IEClassGetMetricTest, IEClassGetMetricTest_OPTIMIZATION_CAPABILITIES, - ::testing::Values("CPU", "AUTO")); + ::testing::Values("CPU")); INSTANTIATE_TEST_SUITE_P( smoke_IEClassGetMetricTest, IEClassGetMetricTest_RANGE_FOR_ASYNC_INFER_REQUESTS, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_threading_tests.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_threading_tests.cpp index fe294e97075..288ac006dd7 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_threading_tests.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/core_threading_tests.cpp @@ -10,7 +10,7 @@ const Params params[] = { std::tuple{ CommonTestUtils::DEVICE_CPU, {{ CONFIG_KEY(PERF_COUNT), CONFIG_VALUE(YES) }}}, std::tuple{ CommonTestUtils::DEVICE_HETERO, {{ "TARGET_FALLBACK", CommonTestUtils::DEVICE_CPU }}}, std::tuple{ CommonTestUtils::DEVICE_MULTI, {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU }}}, - std::tuple{ CommonTestUtils::DEVICE_AUTO, {{AUTO_CONFIG_KEY(DEVICE_LIST), CommonTestUtils::DEVICE_CPU }}}, + std::tuple{ CommonTestUtils::DEVICE_AUTO, {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU }}}, }; const Params paramsStreams[] = { diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/exec_graph_info.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/exec_graph_info.cpp index ee0bad4bb1f..73f8114a1f6 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/exec_graph_info.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/exec_graph_info.cpp @@ -18,9 +18,6 @@ namespace { const std::vector> multiConfigs = { {{ InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> autoConfigs = { - {{ InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}} - }; INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, ExecGraphTests, ::testing::Combine( @@ -40,6 +37,6 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), ExecGraphTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request.cpp index e866ffad849..07b3cf9ca40 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request.cpp @@ -24,10 +24,6 @@ namespace { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> Autoconfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_CPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -46,7 +42,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(Autoconfigs)), + ::testing::ValuesIn(Multiconfigs)), InferRequestTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_callback.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_callback.cpp index 8483b82c3db..a22af7eda78 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_callback.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_callback.cpp @@ -21,10 +21,6 @@ const std::vector> multiConfigs = { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU}} }; -const std::vector> autoConfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_CPU}} -}; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, CallbackTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -43,6 +39,6 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, CallbackTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), CallbackTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_config.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_config.cpp index 9743bc7e35b..42c426ca383 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_config.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_config.cpp @@ -60,6 +60,13 @@ namespace { ::testing::ValuesIn(multiConfigs)), InferConfigTests::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, InferConfigTests, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_AUTO), + ::testing::ValuesIn(multiConfigs)), + InferConfigTests::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferConfigInTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -74,4 +81,11 @@ namespace { ::testing::ValuesIn(MultiInConfigs)), InferConfigInTests::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, InferConfigInTests, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_AUTO), + ::testing::ValuesIn(MultiInConfigs)), + InferConfigInTests::getTestCaseName); + } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_input.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_input.cpp index 73bc9fb8f97..a2776a3da90 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_input.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_input.cpp @@ -25,10 +25,6 @@ namespace { {InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}} }; - const std::vector> autoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestInputTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -47,7 +43,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), InferRequestInputTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_output.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_output.cpp index 36ad2752244..3a8f8bf9c91 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_output.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/infer_request_output.cpp @@ -21,10 +21,6 @@ namespace { {InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}} }; - const std::vector> autoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestOutputTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -43,7 +39,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), InferRequestOutputTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/ov_core_integration.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/ov_core_integration.cpp index 21b83b0330c..1a3baecddb6 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/ov_core_integration.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/ov_core_integration.cpp @@ -48,7 +48,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( smoke_OVClassGetMetricTest, OVClassGetMetricTest_OPTIMIZATION_CAPABILITIES, - ::testing::Values("CPU", "AUTO")); + ::testing::Values("CPU")); INSTANTIATE_TEST_SUITE_P( smoke_OVClassGetMetricTest, OVClassGetMetricTest_RANGE_FOR_ASYNC_INFER_REQUESTS, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_blob_of_kind.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_blob_of_kind.cpp index 0ce335bcfad..5b2355476ec 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_blob_of_kind.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_blob_of_kind.cpp @@ -15,7 +15,6 @@ const std::vector blobKinds = { }; const SetBlobOfKindConfig cpuConfig{}; //nothing special -const SetBlobOfKindConfig autoConfig{}; const SetBlobOfKindConfig multiConfig{{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU}}; const SetBlobOfKindConfig heteroConfig{{ "TARGET_FALLBACK", CommonTestUtils::DEVICE_CPU }}; @@ -34,8 +33,8 @@ INSTANTIATE_TEST_SUITE_P(smoke_SetBlobOfKindMULTI, SetBlobOfKindTest, INSTANTIATE_TEST_SUITE_P(smoke_SetBlobOfKindAUTO, SetBlobOfKindTest, ::testing::Combine(::testing::ValuesIn(blobKinds), - ::testing::Values(CommonTestUtils::DEVICE_AUTO + std::string(":") + CommonTestUtils::DEVICE_CPU), - ::testing::Values(autoConfig)), + ::testing::Values(CommonTestUtils::DEVICE_AUTO), + ::testing::Values(multiConfig)), SetBlobOfKindTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_SetBlobOfKindHETERO, SetBlobOfKindTest, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_preprocess.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_preprocess.cpp index d3450e08ee2..2acb232ea70 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_preprocess.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/set_preprocess.cpp @@ -27,10 +27,6 @@ namespace { {{ InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> autoConfigs = { - {{ InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_CPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, PreprocessTest, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -56,7 +52,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), PreprocessTest::getTestCaseName); @@ -169,7 +165,7 @@ namespace { ::testing::Bool(), ::testing::Bool(), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), PreprocessConversionTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, PreprocessDynamicallyInSetBlobTest, @@ -183,7 +179,7 @@ namespace { ::testing::Values(true), // only SetBlob ::testing::Values(true), // only SetBlob ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), PreprocessDynamicallyInSetBlobTest::getTestCaseName); } // namespace \ No newline at end of file diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/test_plugin.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/test_plugin.cpp index f8728390c9e..c03c1a4f121 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/test_plugin.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/test_plugin.cpp @@ -21,10 +21,6 @@ namespace { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> AutoConfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_CPU}} - }; - const std::vector> configsInput = { {}, {{InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}} @@ -36,10 +32,6 @@ namespace { {InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}} }; - const std::vector> AutoConfigsInputOutput = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_CPU}} - }; - const std::vector> configsOutput = { {}, {{InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}} @@ -64,7 +56,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigsInputOutput)), + ::testing::ValuesIn(MultiConfigsInputOutput)), BehaviorTestOutput::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, BehaviorTests, @@ -85,7 +77,7 @@ namespace { ::testing::Combine( ::testing::Values(InferenceEngine::Precision::FP32), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigs)), + ::testing::ValuesIn(MultiConfigs)), BehaviorTests::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, BehaviorTestInput, @@ -106,7 +98,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigsInputOutput)), + ::testing::ValuesIn(MultiConfigsInputOutput)), BehaviorTestInput::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/version.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/version.cpp index 66b5a3c0668..269e736abd6 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/version.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/behavior/version.cpp @@ -14,10 +14,6 @@ namespace { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_CPU}} }; - const std::vector> Autoconfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_CPU}} - }; - const std::vector> Heteroconfigs = { {{ HETERO_CONFIG_KEY(DUMP_GRAPH_DOT) , CommonTestUtils::DEVICE_CPU}} }; @@ -40,7 +36,7 @@ namespace { ::testing::Combine( ::testing::Values(InferenceEngine::Precision::FP32), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(Autoconfigs)), + ::testing::ValuesIn(Multiconfigs)), VersionTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, VersionTest, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/configuration_tests/configuration_tests.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/configuration_tests/configuration_tests.cpp index 48f4b0bc4d2..58aca4da213 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/configuration_tests/configuration_tests.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/configuration_tests/configuration_tests.cpp @@ -6,10 +6,20 @@ #include "configuration_tests/configuration_tests.hpp" #include "threading/ie_istreams_executor.hpp" #include "ie_plugin_config.hpp" +#if (defined(__APPLE__) || defined(_WIN32)) +#include "ie_system_conf.h" +#endif namespace { #if (defined(__APPLE__) || defined(_WIN32)) -auto defaultBindThreadParameter = InferenceEngine::Parameter{std::string{CONFIG_VALUE(NUMA)}}; +auto defaultBindThreadParameter = InferenceEngine::Parameter{[] { + auto numaNodes = InferenceEngine::getAvailableNUMANodes(); + if (numaNodes.size() > 1) { + return std::string{CONFIG_VALUE(NUMA)}; + } else { + return std::string{CONFIG_VALUE(NO)}; + } +}()}; #else auto defaultBindThreadParameter = InferenceEngine::Parameter{std::string{CONFIG_VALUE(YES)}}; #endif diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp new file mode 100644 index 00000000000..0817e340d83 --- /dev/null +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp @@ -0,0 +1,197 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "low_precision_transformations/pad_transformation.hpp" + + +using namespace LayerTestsDefinitions; + +namespace { +const std::vector netPrecisions = { + ngraph::element::f32, + // ngraph::element::f16 +}; + +const std::vector inputShapes = { + { 1, 3, 16, 16}, + { 4, 3, 16, 16} +}; + +const std::vector trasformationParamValues = { + LayerTestsUtils::LayerTransformationParamsNGraphFactory::createParamsU8I8() +}; + +namespace commonTestCases { +const std::vector padModes = { + ngraph::op::PadMode::CONSTANT, + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC +}; + +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "U8" + }, + // per-channel quantization with the same values + { + { + 256ul, ngraph::Shape{ 1, 3, 1, 1 }, + { -127.f, -127.f, -127.f }, + { 128.f, 128.f, 128.f }, + { 0.f, 0.f, 0.f }, + { 255.f, 255.f, 255.f } + }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "U8" + }, + // per-channel quantization with different values + { + { + 256ul, + ngraph::Shape{ 1, 3, 1, 1 }, + { -127.f, 0.f, 128.f / 2.f }, + { 128.f / 4.f, 128.f / 2.f, 128.f }, + { 0.f, 0.f, 0.f }, + { 255.f / 4.f, 255.f / 2.f, 255.f } + }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "U8" + }, +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::ValuesIn(padModes), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace commonTestCases + +namespace testCasesForConstantMode { +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "FP32" + }, + // tensor quantization with subtract, non zero padValue and pad by unique dimension + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } }, + { 0, 0, 2, 0 }, + { 0, 0, 1, 0 }, + 2.f, + "Pad", + "U8" + }, + // per-channel quantization with different values, non zero padValue and pad by channel + { + { + 256ul, + ngraph::Shape{ 1, 3, 1, 1 }, + { -127.f, 0.f, 128.f / 2.f }, + { 128.f / 4.f, 128.f / 2.f, 128.f }, + { 0.f, 0.f, 0.f }, + { 255.f / 4.f, 255.f / 2.f, 255.f } + }, + { 0, 1, 0, 0 }, + { 0, 0, 0, 0 }, + 2.f, + "Pad", + "U8" + }, + // per-channel quantization with subtract + { + { + 256ul, + ngraph::Shape{ 1, 3, 1, 1 }, + { -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f }, + { -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f } + }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "FP32" + }, +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace testCasesForConstantMode + +namespace testCasesForOtherModes { +const std::vector modesWithoutConstant = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC +}; + +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "U8" + }, + // per-channel quantization with subtract + { + { + 256ul, + ngraph::Shape{ 1, 3, 1, 1 }, + { -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f }, + { -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f } + }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + 0.f, + "Pad", + "U8" + }, +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::ValuesIn(modesWithoutConstant), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace testCasesForOtherModes +} // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp index 9e9e7796295..3155580319d 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp @@ -103,13 +103,18 @@ const std::vector single_deform_groups = {3}; const auto deformableConv2DParams_SingleTestCase = ::testing::Combine( ::testing::ValuesIn(single_deform_vals), - ::testing::ValuesIn(single_kernel), ::testing::ValuesIn(strides), - ::testing::ValuesIn(padBegins), ::testing::ValuesIn(padEnds), - ::testing::ValuesIn(dilations), ::testing::ValuesIn(groups), - ::testing::ValuesIn(single_deform_groups), ::testing::ValuesIn(numOutChannels), + ::testing::ValuesIn(single_kernel), + ::testing::ValuesIn(strides), + ::testing::ValuesIn(padBegins), + ::testing::ValuesIn(padEnds), + ::testing::ValuesIn(dilations), + ::testing::ValuesIn(groups), + ::testing::ValuesIn(single_deform_groups), + ::testing::ValuesIn(numOutChannels), ::testing::Values(ngraph::op::PadType::EXPLICIT), ::testing::ValuesIn(with_bilinear_interpolation_pad), - ::testing::ValuesIn(with_modulated_scalar)); + ::testing::ValuesIn(with_modulated_scalar) +); INSTANTIATE_TEST_SUITE_P( smoke_DeformableConvolution2D_SingleTestCase, DeformableConvolutionLayerTest, diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/interpolate.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/interpolate.cpp index 5d617ce9c90..acea736e2cc 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/interpolate.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/interpolate.cpp @@ -21,38 +21,38 @@ const std::vector> inShapes = { }; const std::vector modesWithoutNearest = { - ngraph::op::v4::Interpolate::InterpolateMode::linear, - ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx, - ngraph::op::v4::Interpolate::InterpolateMode::cubic, + ngraph::op::v4::Interpolate::InterpolateMode::LINEAR, + ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX, + ngraph::op::v4::Interpolate::InterpolateMode::CUBIC, }; const std::vector nearestMode = { - ngraph::op::v4::Interpolate::InterpolateMode::nearest, + ngraph::op::v4::Interpolate::InterpolateMode::NEAREST, }; const std::vector coordinateTransformModes = { - ngraph::op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn, - ngraph::op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, - ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric, - ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners, + ngraph::op::v4::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN, + ngraph::op::v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, + ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC, + ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS, }; const std::vector shapeCalculationMode = { - ngraph::op::v4::Interpolate::ShapeCalcMode::sizes, - ngraph::op::v4::Interpolate::ShapeCalcMode::scales, + ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES, + ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES, }; const std::vector nearestModes = { - ngraph::op::v4::Interpolate::NearestMode::simple, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, - ngraph::op::v4::Interpolate::NearestMode::floor, - ngraph::op::v4::Interpolate::NearestMode::ceil, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil, + ngraph::op::v4::Interpolate::NearestMode::SIMPLE, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, + ngraph::op::v4::Interpolate::NearestMode::FLOOR, + ngraph::op::v4::Interpolate::NearestMode::CEIL, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL, }; const std::vector defaultNearestMode = { - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, }; const std::vector> pads = { diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp index 8019fc072a8..f46f975f979 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp @@ -7,6 +7,7 @@ #include #include "functional_test_utils/skip_tests_config.hpp" +#include "ie_parallel.hpp" std::vector disabledTestPatterns() { std::vector retVector{ @@ -79,6 +80,11 @@ std::vector disabledTestPatterns() { // azure is failing after #6199 R"(.*/NmsLayerTest.*)" }; + +#if ((IE_THREAD == IE_THREAD_TBB) || (IE_THREAD == IE_THREAD_TBB_AUTO)) + retVector.emplace_back(R"(.*ReusableCPUStreamsExecutor.*)"); +#endif + #ifdef __APPLE__ // TODO: Issue 55717 //retVector.emplace_back(R"(.*smoke_LPT.*ReduceMinTransformation.*f32.*)"); diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/subgraph_tests/concat_resize_concat.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/subgraph_tests/concat_resize_concat.cpp index 2dee7ff9937..dd442cd9102 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/subgraph_tests/concat_resize_concat.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/subgraph_tests/concat_resize_concat.cpp @@ -57,10 +57,10 @@ protected: // preresize layer ngraph::opset4::Interpolate::InterpolateAttrs attrs; - attrs.mode = ngraph::opset4::Interpolate::InterpolateMode::linear_onnx; - attrs.shape_calculation_mode = ngraph::opset4::Interpolate::ShapeCalcMode::sizes; - attrs.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::asymmetric; - attrs.nearest_mode = ngraph::opset4::Interpolate::NearestMode::ceil; + attrs.mode = ngraph::opset4::Interpolate::InterpolateMode::LINEAR_ONNX; + attrs.shape_calculation_mode = ngraph::opset4::Interpolate::ShapeCalcMode::SIZES; + attrs.coordinate_transformation_mode = ngraph::opset4::Interpolate::CoordinateTransformMode::ASYMMETRIC; + attrs.nearest_mode = ngraph::opset4::Interpolate::NearestMode::CEIL; std::vector shape = {3, 3 }; std::vector scales = {1.5, 1.5 }; diff --git a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp index b3d599d9f91..7392cbdb530 100644 --- a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp +++ b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp @@ -144,28 +144,28 @@ const std::vector netPrecisions = { }; const std::vector coordinateTransformModes = { - ngraph::op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn, - ngraph::op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel, - ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel, - ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric, - ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners, + ngraph::op::v4::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN, + ngraph::op::v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL, + ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL, + ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC, + ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS, }; const std::vector shapeCalculationMode = { - ngraph::op::v4::Interpolate::ShapeCalcMode::sizes, - ngraph::op::v4::Interpolate::ShapeCalcMode::scales, + ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES, + ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES, }; const std::vector nearestModes = { - ngraph::op::v4::Interpolate::NearestMode::simple, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, - ngraph::op::v4::Interpolate::NearestMode::floor, - ngraph::op::v4::Interpolate::NearestMode::ceil, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil, + ngraph::op::v4::Interpolate::NearestMode::SIMPLE, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, + ngraph::op::v4::Interpolate::NearestMode::FLOOR, + ngraph::op::v4::Interpolate::NearestMode::CEIL, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL, }; const std::vector defNearestModes = { - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, }; const std::vector> pads = { diff --git a/inference-engine/tests/functional/plugin/cpu/test_utils/fusing_test_utils.cpp b/inference-engine/tests/functional/plugin/cpu/test_utils/fusing_test_utils.cpp index 6f24854affb..d0b4441dfdf 100644 --- a/inference-engine/tests/functional/plugin/cpu/test_utils/fusing_test_utils.cpp +++ b/inference-engine/tests/functional/plugin/cpu/test_utils/fusing_test_utils.cpp @@ -76,7 +76,7 @@ void CpuTestWithFusing::CheckPluginRelatedResults(InferenceEngine::ExecutableNet std::shared_ptr postFunctionMgr::addPostOps(const ngraph::element::Type &ngPrc, ngraph::ParameterVector ¶ms, const std::shared_ptr &lastNode) const { - auto clonedPostFunction = clone_function(*_pFunction); + auto clonedPostFunction = ngraph::clone_function(*_pFunction); clonedPostFunction->set_friendly_name(_pFunction->get_friendly_name()); clonedPostFunction->replace_node(clonedPostFunction->get_parameters()[0], lastNode); return clonedPostFunction->get_result()->get_input_node_shared_ptr(0); diff --git a/inference-engine/tests/functional/plugin/gna/pass_tests/eltwise_split_over_channels_pass.cpp b/inference-engine/tests/functional/plugin/gna/pass_tests/eltwise_split_over_channels_pass.cpp index 5f69ab02615..dd6424be051 100644 --- a/inference-engine/tests/functional/plugin/gna/pass_tests/eltwise_split_over_channels_pass.cpp +++ b/inference-engine/tests/functional/plugin/gna/pass_tests/eltwise_split_over_channels_pass.cpp @@ -54,8 +54,8 @@ protected: auto params = ngraph::builder::makeParams(ngPrc, { inputShape }); auto const_mult2 = ngraph::builder::makeConstant(ngPrc, inputShape, {-1.0f}); - auto sum = ngraph::builder::makeEltwise(params[0], const_mult2, ngraph::helpers::EltwiseTypes::MULTIPLY); - function = std::make_shared(sum, params, "EltwiseSplitOverChannelsPassTest"); + auto mul = ngraph::builder::makeEltwise(params[0], const_mult2, ngraph::helpers::EltwiseTypes::MULTIPLY); + function = std::make_shared(mul, params, "EltwiseSplitOverChannelsPassTest"); } }; @@ -77,7 +77,8 @@ const std::vector> configs = { const std::vector> inputShape = { {1, 67000}, - {1, 500000} + {1, 500000}, + {1, 936, 513} }; INSTANTIATE_TEST_SUITE_P(smoke_EltwiseSplitOverChennels, EltwiseSplitOverChannelsPassTest, diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/import_export_tests/import_reshape_permute_conv.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/import_export_tests/import_reshape_permute_conv.cpp index 0d824402305..a17c52a97b5 100644 --- a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/import_export_tests/import_reshape_permute_conv.cpp +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/import_export_tests/import_reshape_permute_conv.cpp @@ -11,7 +11,7 @@ using namespace LayerTestsDefinitions; namespace { -class ImportReshapePermuteConvGNA : public ImportReshapePermuteConv { +class ImportExportGNAModelUnchanged : public ImportReshapePermuteConv { private: void exportImportNetwork() override { { @@ -42,8 +42,14 @@ private: std::string fileName = "exported_model.blob"; }; -TEST_P(ImportReshapePermuteConvGNA, CompareWithRefImpl) { - Run(); +class ImportExportGNAModelChanged : public ImportExportGNAModelUnchanged {}; + +TEST_P(ImportExportGNAModelUnchanged, ReshapePermuteConv) { + TestRun(false); +}; + +TEST_P(ImportExportGNAModelChanged, ReshapePermuteConv) { + TestRun(true); }; const std::vector netPrecisions = { @@ -58,15 +64,25 @@ const std::vector> exportConfigs = { } }; -const std::vector> importConfigs = { +const std::vector> importConfigsChanged = { { {"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, {"GNA_SCALE_FACTOR_0", "32767"} - }, + } +}; + +const std::vector> importConfigsUnchanged = { { {"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, {"GNA_SCALE_FACTOR_0", "327.67"} }, + { + {"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, + {"GNA_SCALE_FACTOR_0", "1"} + }, + { + {"GNA_DEVICE_MODE", "GNA_SW_EXACT"} + } }; const std::vector appHeaders = { @@ -74,13 +90,22 @@ const std::vector appHeaders = { "APPLICATION_HEADER" }; -INSTANTIATE_TEST_SUITE_P(smoke_ImportNetworkCase, ImportReshapePermuteConvGNA, +INSTANTIATE_TEST_CASE_P(smoke_ImportNetworkGNA, ImportExportGNAModelUnchanged, ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_GNA), ::testing::ValuesIn(exportConfigs), - ::testing::ValuesIn(importConfigs), + ::testing::ValuesIn(importConfigsUnchanged), ::testing::ValuesIn(appHeaders)), - ImportReshapePermuteConvGNA::getTestCaseName); + ImportExportGNAModelUnchanged::getTestCaseName); + +INSTANTIATE_TEST_CASE_P(smoke_ImportNetworkGNA, ImportExportGNAModelChanged, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::ValuesIn(exportConfigs), + ::testing::ValuesIn(importConfigsChanged), + ::testing::ValuesIn(appHeaders)), + ImportExportGNAModelChanged::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp index 9de08e5f84f..71c0cfc3d70 100644 --- a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp @@ -47,6 +47,7 @@ std::map, std::vector>> basic = { {{1, 4, 4, 128}, {{}}}, {{8}, {{}}}, {{5}, {{}}}, + {{1, 936, 513}, {{}}} }; const auto basicCases = ::testing::Combine( diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/transpose_conv_transpose_squeeze.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/transpose_conv_transpose_squeeze.cpp new file mode 100644 index 00000000000..afbf956ee19 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/transpose_conv_transpose_squeeze.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include + +#include "subgraph_tests/transpose_conv_transpose_squeeze.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace SubgraphTestsDefinitions; + +namespace { + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16, +}; + +const std::vector> configs = { + {{"GNA_DEVICE_MODE", "GNA_SW_FP32"}}, + {{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}} +}; + +const std::vector> inputShapes = { + {1, 8192} +}; + +const std::vector> kernels = {{1, 3}, {1, 4}, {1, 8}, {1, 9}}; +const std::vector> strides = {{1, 1}}; +const std::vector inputChannels = {64}; +const std::vector outputChannels {4, 8, 16}; + +const auto convParams = ::testing::Combine( + ::testing::ValuesIn(kernels), + ::testing::ValuesIn(strides), + ::testing::ValuesIn(inputChannels), + ::testing::ValuesIn(outputChannels) +); + +INSTANTIATE_TEST_SUITE_P(smoke_TransposeConvTest, TransposeConvTest, + ::testing::Combine( + convParams, + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::ValuesIn(configs)), + TransposeConvTest::getTestCaseName); + +} // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/config.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/config.cpp index 5788c3ee270..22a13191dc5 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/config.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/config.cpp @@ -35,19 +35,6 @@ namespace { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_GPU}, {InferenceEngine::PluginConfigParams::KEY_DEVICE_ID, "DEVICE_UNKNOWN"}} }; - - const std::vector> autoinconfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "ON"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, "unknown_file"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_DUMP_KERNELS, "ON"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_TUNING_MODE, "TUNING_UNKNOWN_MODE"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_DEVICE_ID, "DEVICE_UNKNOWN"}} - }; IE_SUPPRESS_DEPRECATED_END INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, IncorrectConfigTests, @@ -68,7 +55,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoinconfigs)), + ::testing::ValuesIn(multiinconfigs)), IncorrectConfigTests::getTestCaseName); @@ -103,17 +90,6 @@ namespace { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_GPU}} }; - const std::vector> autoconf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "YES"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}, - {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "YES"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}, - {std::string("AUTO_"), "NAN"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}, - {std::string("AUTO_"), "NAN"}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, CorrectConfigAPITests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -139,7 +115,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoconf)), + ::testing::ValuesIn(multiconf)), CorrectConfigAPITests::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, IncorrectConfigAPITests, @@ -160,7 +136,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoinconfigs)), + ::testing::ValuesIn(multiinconfigs)), IncorrectConfigAPITests::getTestCaseName); diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request.cpp index 07e6f78f9ef..ad94fdaa7e2 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request.cpp @@ -18,11 +18,6 @@ namespace { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_GPU}} }; - const std::vector> autoconfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_GPU}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -41,7 +36,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoconfigs)), + ::testing::ValuesIn(configs)), InferRequestTests::getTestCaseName); } // namespace \ No newline at end of file diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_callback.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_callback.cpp index a0108e84339..8c8a0e7fb32 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_callback.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_callback.cpp @@ -19,14 +19,6 @@ const std::vector> multiConfigs = { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_GPU}} }; -const std::vector> autoConfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_GPU}} -}; - -const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} -}; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, CallbackTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -45,13 +37,6 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, CallbackTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), - CallbackTests::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, CallbackTests, - ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(multiConfigs)), CallbackTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_input.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_input.cpp index f63be4c8854..bce8d53a25d 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_input.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_input.cpp @@ -25,14 +25,6 @@ namespace { InferenceEngine::PluginConfigParams::GPU_THROUGHPUT_AUTO}} }; - const std::vector> autoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}} - }; - - const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestInputTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -51,14 +43,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), - InferRequestInputTests::getTestCaseName); - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, InferRequestInputTests, - ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(multiConfigs)), InferRequestInputTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_output.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_output.cpp index 638106e6a75..b4e40a831b7 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_output.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/infer_request_output.cpp @@ -21,14 +21,6 @@ namespace { {InferenceEngine::PluginConfigParams::KEY_GPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::GPU_THROUGHPUT_AUTO}} }; - const std::vector> autoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}} - }; - - const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestOutputTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -47,13 +39,6 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), - InferRequestOutputTests::getTestCaseName); - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, InferRequestOutputTests, - ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(multiConfigs)), InferRequestOutputTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/set_preprocess.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/set_preprocess.cpp index 136cb96436c..97cdf1789e6 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/set_preprocess.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/set_preprocess.cpp @@ -22,14 +22,6 @@ namespace { {{ InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , CommonTestUtils::DEVICE_GPU}} }; - const std::vector> autoConfigs = { - {{ InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_GPU}} - }; - - const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, PreprocessTest, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -48,17 +40,9 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoConfigs)), + ::testing::ValuesIn(multiConfigs)), PreprocessTest::getTestCaseName); - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, PreprocessTest, - ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), - PreprocessTest::getTestCaseName); - - const std::vector ioPrecisions = { InferenceEngine::Precision::FP32, InferenceEngine::Precision::U8 diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/test_plugin.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/test_plugin.cpp index 3d181f59150..98069d07303 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/test_plugin.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/test_plugin.cpp @@ -31,14 +31,6 @@ namespace { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_GPU}} }; - const std::vector> AutoConfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_GPU}} - }; - - const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - const std::vector> configsInput = { {}, {{InferenceEngine::PluginConfigParams::KEY_GPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::GPU_THROUGHPUT_AUTO}} @@ -73,14 +65,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigs)), - BehaviorTestOutput::getTestCaseName); - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, BehaviorTestOutput, - ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(MultiConfigsInputOutput)), BehaviorTestOutput::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, BehaviorTests, @@ -101,14 +86,7 @@ namespace { ::testing::Combine( ::testing::Values(InferenceEngine::Precision::FP32), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigs)), - BehaviorTests::getTestCaseName); - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, BehaviorTests, - ::testing::Combine( - ::testing::Values(InferenceEngine::Precision::FP32), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(MultiConfigs)), BehaviorTests::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, BehaviorTestInput, @@ -129,15 +107,7 @@ namespace { ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(AutoConfigs)), - BehaviorTestInput::getTestCaseName); - - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, BehaviorTestInput, - ::testing::Combine( - ::testing::ValuesIn(netPrecisionsForAutoCG), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(MultiConfigsInputOutput)), BehaviorTestInput::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/version.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/version.cpp index 6b69c22855e..c02a209e9d5 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/version.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/behavior/version.cpp @@ -14,14 +14,6 @@ namespace { {{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_GPU}} }; - const std::vector> Autoconfigs = { - {{ AUTO_CONFIG_KEY(DEVICE_LIST) , CommonTestUtils::DEVICE_GPU}} - }; - - const std::vector> auto_cpu_gpu_conf = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_GPU}} - }; - const std::vector> Heteroconfigs = { {{ HETERO_CONFIG_KEY(DUMP_GRAPH_DOT) , CommonTestUtils::DEVICE_GPU}} }; @@ -44,14 +36,7 @@ namespace { ::testing::Combine( ::testing::Values(InferenceEngine::Precision::FP32), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(Autoconfigs)), - VersionTest::getTestCaseName); - - INSTANTIATE_TEST_SUITE_P(smoke_AutoCG_BehaviorTests, VersionTest, - ::testing::Combine( - ::testing::Values(InferenceEngine::Precision::FP32), - ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(auto_cpu_gpu_conf)), + ::testing::ValuesIn(Multiconfigs)), VersionTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, VersionTest, diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp new file mode 100644 index 00000000000..3494a22c579 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/low_precision_transformations/pad_transformation.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "low_precision_transformations/pad_transformation.hpp" + + +using namespace LayerTestsDefinitions; + +namespace { +const std::vector netPrecisions = { + ngraph::element::f32, + ngraph::element::f16 +}; + +const std::vector inputShapes = { + { 1, 3, 16, 16}, +}; + +const std::vector trasformationParamValues = { + LayerTestsUtils::LayerTransformationParamsNGraphFactory::createParamsU8I8() +}; + +namespace commonTestCases { + +const std::vector padModes = { + ngraph::op::PadMode::CONSTANT, + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC +}; + +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + }, + // per-channel quantization + { + { + 256ul, + ngraph::Shape{ 1, 3, 1, 1 }, + { -127.f, 0.f, 128.f / 2.f }, + { 128.f / 4.f, 128.f / 2.f, 128.f }, + { 0.f, 0.f, 0.f }, + { 255.f / 4.f, 255.f / 2.f, 255.f } + }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + } +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::ValuesIn(padModes), + ::testing::Values(CommonTestUtils::DEVICE_GPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace commonTestCases + +namespace testCasesForConstantMode { + +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + }, +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::Values(ngraph::op::PadMode::CONSTANT), + ::testing::Values(CommonTestUtils::DEVICE_GPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace testCasesForConstantMode + +namespace testCasesForOtherModes { + +const std::vector modesWithoutConstant = { + ngraph::op::PadMode::EDGE, + ngraph::op::PadMode::REFLECT, + ngraph::op::PadMode::SYMMETRIC +}; + +const std::vector params = { + // tensor quantization + { + { 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + }, +}; + +INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(inputShapes), + ::testing::ValuesIn(modesWithoutConstant), + ::testing::Values(CommonTestUtils::DEVICE_GPU), + ::testing::ValuesIn(trasformationParamValues), + ::testing::ValuesIn(params)), + PadTransformation::getTestCaseName); +} // namespace testCasesForOtherModes + +} // namespace diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/interpolate.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/interpolate.cpp index c26f168d628..dc4a2c56f57 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/interpolate.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/interpolate.cpp @@ -43,20 +43,20 @@ const std::vector coordina }; const std::vector shapeCalculationMode = { - ngraph::op::v4::Interpolate::ShapeCalcMode::sizes, - ngraph::op::v4::Interpolate::ShapeCalcMode::scales, + ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES, + ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES, }; const std::vector nearestModes = { - ngraph::op::v4::Interpolate::NearestMode::simple, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, - ngraph::op::v4::Interpolate::NearestMode::floor, - ngraph::op::v4::Interpolate::NearestMode::ceil, - ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil, + ngraph::op::v4::Interpolate::NearestMode::SIMPLE, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, + ngraph::op::v4::Interpolate::NearestMode::FLOOR, + ngraph::op::v4::Interpolate::NearestMode::CEIL, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL, }; const std::vector defaultNearestMode = { - ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor, + ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR, }; const std::vector> pads = { diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/skip_tests_config.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/skip_tests_config.cpp index a01c38da854..cbd31ad0075 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/skip_tests_config.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/skip_tests_config.cpp @@ -61,6 +61,9 @@ std::vector disabledTestPatterns() { R"(.*NormalizeL2LayerTest.*axes=\(\).*)", // Not allowed dynamic loop tests on GPU - R"(.*smoke_StaticShapeLoop_dynamic_exit.*)" + R"(.*smoke_StaticShapeLoop_dynamic_exit.*)", + + // TODO: until issue is xxx-59670 is resolved + R"(.*Gather8LayerTest.*)" }; } diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/config.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/config.cpp index 490db81c352..7de19efce6a 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/config.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/config.cpp @@ -167,8 +167,6 @@ std::vector> getCorrectConfigs() { {{VPU_CONFIG_KEY(PRINT_RECEIVE_TENSOR_TIME), CONFIG_VALUE(YES)}}, {{VPU_CONFIG_KEY(PRINT_RECEIVE_TENSOR_TIME), CONFIG_VALUE(NO)}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2480)}}, - {{VPU_CONFIG_KEY(DETECT_NETWORK_BATCH), CONFIG_VALUE(YES)}}, {{VPU_CONFIG_KEY(DETECT_NETWORK_BATCH), CONFIG_VALUE(NO)}}, @@ -259,19 +257,11 @@ INSTANTIATE_TEST_SUITE_P(smoke_Multi_BehaviorTests, CorrectConfigTests, ::testing::ValuesIn(getCorrectMultiConfigs())), CorrectConfigTests::getTestCaseName); -const std::vector>& getCorrectAutoConfigs() { - static const std::vector> correctAutoConfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_MYRIAD}, {InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, "YES"}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , CommonTestUtils::DEVICE_MYRIAD}, {std::string("AUTO_"), "NAN"}} - }; - return correctAutoConfigs; -} - INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, CorrectConfigTests, ::testing::Combine( ::testing::ValuesIn(getPrecisions()), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(getCorrectAutoConfigs())), + ::testing::ValuesIn(getCorrectMultiConfigs())), CorrectConfigTests::getTestCaseName); const std::vector>& getDefaultEntries() { @@ -317,7 +307,6 @@ const std::vector>& getDefaul {KEY_CONFIG_FILE, {std::string()}}, {InferenceEngine::MYRIAD_DDR_TYPE, {InferenceEngine::MYRIAD_DDR_AUTO}}, {InferenceEngine::MYRIAD_ENABLE_FORCE_RESET, {false}}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), {std::string()}}, {InferenceEngine::MYRIAD_CHECK_PREPROCESSING_INSIDE_MODEL, {true}}, {InferenceEngine::MYRIAD_ENABLE_EARLY_ELTWISE_RELU_FUSION, {true}}, {InferenceEngine::MYRIAD_ENABLE_CUSTOM_RESHAPE_PARAM, {false}}, @@ -354,9 +343,6 @@ const std::vector>& getIncorrectConfigs() { {{VPU_CONFIG_KEY(PRINT_RECEIVE_TENSOR_TIME), "ON"}}, {{VPU_CONFIG_KEY(PRINT_RECEIVE_TENSOR_TIME), "OFF"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "0"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "1"}}, - {{VPU_CONFIG_KEY(DETECT_NETWORK_BATCH), "ON"}}, {{VPU_CONFIG_KEY(DETECT_NETWORK_BATCH), "OFF"}}, @@ -906,18 +888,6 @@ const std::vector>& getIncorrectMultiConfigs( {InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}, {VPU_CONFIG_KEY(HW_STAGES_OPTIMIZATION), "ON"} }, - { - {InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}, - }, - { - {InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "0"}, - }, - { - {InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "1"}, - }, { {InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}, {VPU_CONFIG_KEY(PRINT_RECEIVE_TENSOR_TIME), "OFF"} @@ -930,44 +900,6 @@ const std::vector>& getIncorrectMultiConfigs( return incorrectMultiConfigs; } -const std::vector>& getIncorrectAutoConfigs() { - static const std::vector> incorrectAutoConfigs = { - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {KEY_LOG_LEVEL, "INCORRECT_LOG_LEVEL"}, - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {InferenceEngine::MYRIAD_PROTOCOL, "BLUETOOTH"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {InferenceEngine::MYRIAD_ENABLE_HW_ACCELERATION, "ON"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {InferenceEngine::MYRIAD_ENABLE_RECEIVING_TENSOR_TIME, "ON"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {KEY_PERF_COUNT, "ON"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {InferenceEngine::MYRIAD_THROUGHPUT_STREAMS, "ONE"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {KEY_EXCLUSIVE_ASYNC_REQUESTS, "ON"} - }, - { - {InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_AUTO}, - {InferenceEngine::MYRIAD_DDR_TYPE, "1GB"} - }, - }; - return incorrectAutoConfigs; -} - INSTANTIATE_TEST_SUITE_P(smoke_Multi_BehaviorTests, IncorrectConfigTests, ::testing::Combine( ::testing::ValuesIn(getPrecisions()), @@ -979,7 +911,7 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, IncorrectConfigTests, ::testing::Combine( ::testing::ValuesIn(getPrecisions()), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(getIncorrectAutoConfigs())), + ::testing::ValuesIn(getIncorrectMultiConfigs())), IncorrectConfigTests::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, IncorrectConfigSingleOptionTests, @@ -1020,6 +952,6 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, IncorrectConfigAPITests, ::testing::Combine( ::testing::ValuesIn(getPrecisions()), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(getIncorrectAutoConfigs())), + ::testing::ValuesIn(getIncorrectMultiConfigs())), IncorrectConfigAPITests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/infer_request.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/infer_request.cpp index 341a320ec3d..f466f2d7172 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/infer_request.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/behavior/infer_request.cpp @@ -17,11 +17,6 @@ const std::vector> configs = { {{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, CommonTestUtils::DEVICE_MYRIAD}} }; -const std::vector> autoconfigs = { - {{InferenceEngine::KEY_AUTO_DEVICE_LIST, CommonTestUtils::DEVICE_MYRIAD}}, - {{InferenceEngine::KEY_AUTO_DEVICE_LIST , std::string(CommonTestUtils::DEVICE_CPU) + "," + CommonTestUtils::DEVICE_MYRIAD}} -}; - INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), @@ -40,6 +35,6 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, InferRequestTests, ::testing::Combine( ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_AUTO), - ::testing::ValuesIn(autoconfigs)), + ::testing::ValuesIn(configs)), InferRequestTests::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/interpolate.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/interpolate.cpp index 31d17ca51ba..23257e8acba 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/interpolate.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/interpolate.cpp @@ -126,8 +126,8 @@ const std::vector> defaultScales = { }; const std::vector shapeCalculationMode = { - ngraph::op::v4::Interpolate::ShapeCalcMode::sizes, - ngraph::op::v4::Interpolate::ShapeCalcMode::scales, + ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES, + ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES, }; const auto interpolateCasesNearestMode2x = ::testing::Combine( diff --git a/inference-engine/tests/functional/plugin/shared/include/base/import_export_base/import_export_base.hpp b/inference-engine/tests/functional/plugin/shared/include/base/import_export_base/import_export_base.hpp index d8f30c23f2d..da62acf4bb5 100644 --- a/inference-engine/tests/functional/plugin/shared/include/base/import_export_base/import_export_base.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/base/import_export_base/import_export_base.hpp @@ -23,6 +23,7 @@ class ImportNetworkTestBase : public testing::WithParamInterface obj); void Run() override; + void TestRun(bool isModelChanged); protected: std::map exportConfiguration; diff --git a/inference-engine/tests/functional/plugin/shared/include/behavior/config.hpp b/inference-engine/tests/functional/plugin/shared/include/behavior/config.hpp index 84e095de094..3b305ebbf5f 100644 --- a/inference-engine/tests/functional/plugin/shared/include/behavior/config.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/behavior/config.hpp @@ -19,6 +19,7 @@ #include #include "ie_common.h" #include "common_test_utils/common_utils.hpp" +#include "common_test_utils/file_utils.hpp" #include "functional_test_utils/plugin_cache.hpp" #include "functional_test_utils/blob_utils.hpp" #include @@ -82,6 +83,17 @@ namespace BehaviorTestsDefinitions { ASSERT_NO_THROW(ie->LoadNetwork(cnnNet, targetDevice, configuration)); } + TEST_P(CorrectConfigTests, CanUseCache) { + // Skip test according to plugin specific disabledTestPatterns() (if any) + SKIP_IF_CURRENT_TEST_IS_DISABLED() + // Create CNNNetwork from ngrpah::Function + InferenceEngine::CNNNetwork cnnNet(function); + ie->SetConfig({ { CONFIG_KEY(CACHE_DIR), "./test_cache" } }); + ASSERT_NO_THROW(ie->LoadNetwork(cnnNet, targetDevice, configuration)); + ASSERT_NO_THROW(ie->LoadNetwork(cnnNet, targetDevice, configuration)); + CommonTestUtils::removeDir("./test_cache"); + } + using CorrectSingleOptionCustomValueConfigTests = BehaviorTestsUtils::BehaviorTestsSingleOptionCustom; TEST_P(CorrectSingleOptionCustomValueConfigTests, CheckCustomValueOfConfig) { diff --git a/inference-engine/tests/functional/plugin/shared/include/behavior/exec_graph_info.hpp b/inference-engine/tests/functional/plugin/shared/include/behavior/exec_graph_info.hpp index e0287824940..9b93bbef0e2 100644 --- a/inference-engine/tests/functional/plugin/shared/include/behavior/exec_graph_info.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/behavior/exec_graph_info.hpp @@ -58,7 +58,8 @@ TEST_P(ExecGraphTests, CheckExecGraphInfoBeforeExecution) { // Create CNNNetwork from ngrpah::Function InferenceEngine::CNNNetwork cnnNet(function); InferenceEngine::CNNNetwork execGraph; - if (targetDevice != CommonTestUtils::DEVICE_MULTI && + if (targetDevice != CommonTestUtils::DEVICE_AUTO && + targetDevice != CommonTestUtils::DEVICE_MULTI && targetDevice != CommonTestUtils::DEVICE_TEMPLATE && targetDevice != CommonTestUtils::DEVICE_GNA) { // Load CNNNetwork to target plugins @@ -126,7 +127,8 @@ TEST_P(ExecGraphTests, CheckExecGraphInfoAfterExecution) { // Create CNNNetwork from ngrpah::Function InferenceEngine::CNNNetwork cnnNet(function); InferenceEngine::CNNNetwork execGraph; - if (targetDevice != CommonTestUtils::DEVICE_MULTI && + if (targetDevice != CommonTestUtils::DEVICE_AUTO && + targetDevice != CommonTestUtils::DEVICE_MULTI && targetDevice != CommonTestUtils::DEVICE_TEMPLATE && targetDevice != CommonTestUtils::DEVICE_GNA) { // Load CNNNetwork to target plugins @@ -206,7 +208,8 @@ TEST_P(ExecGraphTests, CheckExecGraphInfoSerialization) { // Create CNNNetwork from ngrpah::Function InferenceEngine::CNNNetwork cnnNet(function); InferenceEngine::CNNNetwork execGraph; - if (targetDevice != CommonTestUtils::DEVICE_MULTI && + if (targetDevice != CommonTestUtils::DEVICE_AUTO && + targetDevice != CommonTestUtils::DEVICE_MULTI && targetDevice != CommonTestUtils::DEVICE_TEMPLATE && targetDevice != CommonTestUtils::DEVICE_GNA) { // Load CNNNetwork to target plugins diff --git a/inference-engine/tests/functional/plugin/shared/include/low_precision_transformations/pad_transformation.hpp b/inference-engine/tests/functional/plugin/shared/include/low_precision_transformations/pad_transformation.hpp new file mode 100644 index 00000000000..2cdc21f1378 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/low_precision_transformations/pad_transformation.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/base/low_precision_transformations/layer_transformation.hpp" +#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp" + +namespace LayerTestsDefinitions { +class PadTransformationParam { +public: + ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize; + std::vector padsBegin; + std::vector padsEnd; + float padValue; + std::string layerName; + std::string expectedKernelType; +}; + +typedef std::tuple< + ngraph::element::Type, + ngraph::PartialShape, + ngraph::op::PadMode, + std::string, + ngraph::pass::low_precision::LayerTransformation::Params, + PadTransformationParam +> PadTransformationParams; + +class PadTransformation : + public testing::WithParamInterface, + public LayerTestsUtils::LayerTransformation { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; + void Run() override; +}; +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/concat_multi_input.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/concat_multi_input.hpp index 1cbe78719e2..e3363c09fb7 100644 --- a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/concat_multi_input.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/concat_multi_input.hpp @@ -18,4 +18,11 @@ TEST_P(ConcatMultiInput, CompareWithRefConstOnly) { Run(); }; +TEST_P(ConcatMultiInput, CompareWithRefMemory) { + GenerateMemoryModel(); + LoadNetwork(); + GenerateInputs(); + Infer(); +}; + } // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/transpose_conv_transpose_squeeze.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/transpose_conv_transpose_squeeze.hpp new file mode 100644 index 00000000000..2b03be212a3 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/transpose_conv_transpose_squeeze.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/subgraph/transpose_conv_transpose_squeeze.hpp" + +namespace SubgraphTestsDefinitions { + +TEST_P(TransposeConvTest, CompareWithRefImpl) { + Run(); +}; + +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/base/import_export_base/import_export_base.cpp b/inference-engine/tests/functional/plugin/shared/src/base/import_export_base/import_export_base.cpp index c30945dc914..c4a0f038dd1 100644 --- a/inference-engine/tests/functional/plugin/shared/src/base/import_export_base/import_export_base.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/base/import_export_base/import_export_base.cpp @@ -42,14 +42,18 @@ void ImportNetworkTestBase::exportImportNetwork() { } void ImportNetworkTestBase::Run() { - SKIP_IF_CURRENT_TEST_IS_DISABLED() + TestRun(false); +} +void ImportNetworkTestBase::TestRun(bool isModelChanged) { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + // load export configuration and save outputs configuration.insert(exportConfiguration.begin(), exportConfiguration.end()); LoadNetwork(); GenerateInputs(); Infer(); + auto actualOutputs = GetOutputs(); - const auto& actualOutputs = GetOutputs(); auto referenceOutputs = CalculateRefs(); Compare(referenceOutputs, actualOutputs); @@ -57,6 +61,14 @@ void ImportNetworkTestBase::Run() { configuration[configItem.first] = configItem.second; } + // for import with different scale factor need to use import configuration to get refference outputs. + if (isModelChanged) { + LoadNetwork(); + GenerateInputs(); + Infer(); + actualOutputs = GetOutputs(); + } + const auto compiledExecNetwork = executableNetwork; exportImportNetwork(); const auto importedExecNetwork = executableNetwork; @@ -75,6 +87,7 @@ void ImportNetworkTestBase::Run() { ASSERT_NO_THROW(compiledExecNetwork.GetOutputsInfo()[next_output.first]); } auto importedOutputs = GetOutputs(); + ASSERT_EQ(actualOutputs.size(), importedOutputs.size()); for (size_t i = 0; i < actualOutputs.size(); i++) { diff --git a/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/pad_transformation.cpp b/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/pad_transformation.cpp new file mode 100644 index 00000000000..80a7a23b959 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/pad_transformation.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "low_precision_transformations/pad_transformation.hpp" +#include +#include +#include +#include + +#include "lpt_ngraph_functions/pad_function.hpp" + +namespace LayerTestsDefinitions { + +std::string PadTransformation::getTestCaseName(testing::TestParamInfo obj) { + ngraph::element::Type netPrecision; + ngraph::PartialShape inputShape; + ngraph::op::PadMode padMode; + std::string targetDevice; + ngraph::pass::low_precision::LayerTransformation::Params params; + PadTransformationParam param; + std::tie(netPrecision, inputShape, padMode, targetDevice, params, param) = obj.param; + + std::ostringstream result; + result << getTestCaseNameByParams(netPrecision, inputShape, targetDevice, params) + << "_" << param.fakeQuantize << "_" + << CommonTestUtils::vec2str(param.padsBegin) << CommonTestUtils::vec2str(param.padsEnd) << "_" + << padMode << "_" << (padMode == ngraph::op::PadMode::CONSTANT ? "" : std::to_string(param.padValue)); + return result.str(); +} + +void PadTransformation::SetUp() { + ngraph::element::Type netPrecision; + ngraph::PartialShape inputShape; + ngraph::op::PadMode mode; + ngraph::pass::low_precision::LayerTransformation::Params params; + PadTransformationParam param; + std::tie(netPrecision, inputShape, mode, targetDevice, params, param) = this->GetParam(); + + function = ngraph::builder::subgraph::PadFunction::get( + inputShape, + netPrecision, + param.fakeQuantize, + param.padsBegin, + param.padsEnd, + mode, + param.padValue); +} + +void PadTransformation::Run() { + LayerTestsCommon::Run(); + + const auto params = std::get<5>(GetParam()); + const auto actualPrecision = getRuntimePrecisionByType(params.layerName); + const auto expectedPrecision = params.expectedKernelType; + + EXPECT_EQ(actualPrecision, expectedPrecision); +} + +TEST_P(PadTransformation, CompareWithRefImpl) { + Run(); +}; + +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/fake_quantize.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/fake_quantize.hpp index 5ed65139cf4..0b0623ae3c1 100644 --- a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/fake_quantize.hpp +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/fake_quantize.hpp @@ -63,42 +63,4 @@ protected: int32_t seed = 1; }; - -//TODO after update all plugins remove *Revise types -typedef std::tuple< - size_t, // fake quantize levels - std::vector, // fake quantize inputs shape - std::vector, // fake quantize (inputLow, inputHigh, outputLow, outputHigh) or empty for random - std::vector, // input generator data (low, high, resolution) or empty for default - ngraph::op::AutoBroadcastSpec // fake quantize broadcast mode -> fqSpecificParamsRevise; -typedef std::tuple< - fqSpecificParamsRevise, - InferenceEngine::Precision, // Net precision - InferenceEngine::Precision, // Input precision - InferenceEngine::Precision, // Output precision - InferenceEngine::Layout, // Input layout - InferenceEngine::Layout, // Output layout - InferenceEngine::SizeVector, // Input shapes - LayerTestsUtils::TargetDevice, // Device name - - std::pair> // Additional backend configuration and alis name to it -> fqLayerTestParamsSetRevise; - -class FakeQuantizeLayerTestRevise : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon { -public: - static std::string getTestCaseName(const testing::TestParamInfo& obj); - InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo &info) const override; -protected: - void SetUp() override; - void UpdateSeed(); - - protected: - float inputDataMin = 0.0; - float inputDataMax = 10.0; - float inputDataResolution = 1.0; - int32_t seed = 1; -}; - } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/concat_multi_input.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/concat_multi_input.hpp index 6715dc78946..d599aba181a 100644 --- a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/concat_multi_input.hpp +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/concat_multi_input.hpp @@ -32,6 +32,7 @@ private: public: void GenerateStridedSliceModel(); void GenerateConstOnlyModel(); + void GenerateMemoryModel(); static std::string getTestCaseName(testing::TestParamInfo obj); protected: diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/transpose_conv_transpose_squeeze.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/transpose_conv_transpose_squeeze.hpp new file mode 100644 index 00000000000..2811ed7c9de --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/transpose_conv_transpose_squeeze.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/layer_test_utils.hpp" +#include "ngraph_functions/builders.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" + +namespace SubgraphTestsDefinitions { + +typedef std::tuple< + std::vector, // Kernel Shape + std::vector, // Strides + size_t, // Input channels + size_t // Output channels +> ConvParams; + +typedef std::tuple< + ConvParams, + InferenceEngine::Precision, // Net precision + InferenceEngine::SizeVector, // Input shapes + LayerTestsUtils::TargetDevice, // Device name + std::map // Additional backend configuration and alis name to it +> TransposeConvTestParams; + +class TransposeConvTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; + InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo &info) const override; + +protected: + float inputDataMin = 0.0; + float inputDataMax = 0.2; + float inputDataResolution = 1; + int32_t seed = 1; +}; + +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp index 3c1639b978f..b9f679cb2a9 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp @@ -313,6 +313,7 @@ void LayerTestsCommon::LoadNetwork() { } void LayerTestsCommon::GenerateInputs() { + inputs.clear(); const auto& inputsInfo = executableNetwork.GetInputsInfo(); const auto& functionParams = function->get_parameters(); for (int i = 0; i < functionParams.size(); ++i) { diff --git a/inference-engine/tests/functional/shared_test_classes/src/single_layer/fake_quantize.cpp b/inference-engine/tests/functional/shared_test_classes/src/single_layer/fake_quantize.cpp index ed0731ccd33..edb32c6de2b 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/single_layer/fake_quantize.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/single_layer/fake_quantize.cpp @@ -118,116 +118,4 @@ void FakeQuantizeLayerTest::UpdateSeed() { << "seed = " << seed << std::endl; } - - -std::string FakeQuantizeLayerTestRevise::getTestCaseName(const testing::TestParamInfo& obj) { - fqSpecificParamsRevise fqParams; - InferenceEngine::Precision netPrecision; - InferenceEngine::Precision inPrc, outPrc; - InferenceEngine::Layout inLayout, outLayout; - InferenceEngine::SizeVector inputShapes; - std::string targetDevice; - std::pair> config; - std::tie(fqParams, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, targetDevice, config) = obj.param; - size_t levels; - std::vector constShape; - std::vector fqDirectArgs; - std::vector inputArg; - ngraph::op::AutoBroadcastSpec broadcast; - std::tie(levels, constShape, fqDirectArgs, inputArg, broadcast) = fqParams; - - std::ostringstream result; - result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; - result << "CS=" << CommonTestUtils::vec2str(constShape) << "_"; - result << "LEVELS=" << levels << "_"; - result << "netPRC=" << netPrecision.name() << "_"; - result << "inPRC=" << inPrc.name() << "_"; - result << "outPRC=" << outPrc.name() << "_"; - result << "inL=" << inLayout << "_"; - result << "outL=" << outLayout << "_"; - result << "trgDev=" << targetDevice; - if (!config.first.empty()) { - result << "_targetConfig=" << config.first; - } - if (!fqDirectArgs.empty()) { - result << "_fqArgs=" << fqDirectArgs[0] << "_" << fqDirectArgs[1] << "_" << fqDirectArgs[2] << "_" << fqDirectArgs[3]; - } - if (inputArg.size() == 3) { - result << "_inputArg=" << inputArg[0] << "_" << inputArg[1] << "_" << inputArg[2]; - } - result << "_" << broadcast.m_type; - return result.str(); -} - -void FakeQuantizeLayerTestRevise::SetUp() { - fqSpecificParamsRevise fqParams; - std::vector inputShape; - std::pair> config; - auto netPrecision = InferenceEngine::Precision::UNSPECIFIED; - std::tie(fqParams, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, targetDevice, config) = this->GetParam(); - InferenceEngine::SizeVector kernel, stride, dilation; - size_t levels; - std::vector constShape; - std::vector fqDirectArg; - std::vector inputArg; - ngraph::op::AutoBroadcastSpec broadcast; - std::tie(levels, constShape, fqDirectArg, inputArg, broadcast) = fqParams; - if (inputArg.size() == 3) { - inputDataMin = inputArg[0]; - inputDataMax = inputArg[1]; - inputDataResolution = inputArg[2]; - } - if (fqDirectArg.size() != 0) { - threshold = (fqDirectArg[3] - fqDirectArg[2]) / levels; - } - auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); - auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes(params)); - - UpdateSeed(); - - std::shared_ptr fakeQNode; - if (fqDirectArg.empty()) { - int32_t ngraphSeed = seed; - if (NGRAPH_SEED != USE_CLOCK_TIME) { - ngraphSeed = NGRAPH_SEED; - } - std::cout << "\033[0;32m" << "[ ] " << "\033[0;0m" - << "ngraphSeed = " << ngraphSeed << std::endl; - fakeQNode = ngraph::builder::makeFakeQuantize(paramOuts[0], ngPrc, levels, constShape, ngraphSeed); - } else { - fakeQNode = ngraph::builder::makeFakeQuantize( - paramOuts[0], - ngPrc, - levels, - constShape, - {fqDirectArg[0]}, - {fqDirectArg[1]}, - {fqDirectArg[2]}, - {fqDirectArg[3]}); - } - auto fq = std::dynamic_pointer_cast(fakeQNode); - - ngraph::ResultVector results{std::make_shared(fq)}; - function = std::make_shared(results, params, "fakeQuantize"); - - configuration = config.second; -} - -InferenceEngine::Blob::Ptr FakeQuantizeLayerTestRevise::GenerateInput(const InferenceEngine::InputInfo &info) const { - return FuncTestUtils::createAndFillBlob(info.getTensorDesc(), inputDataMax - inputDataMin, inputDataMin, 1 / inputDataResolution, - seed); -} - -void FakeQuantizeLayerTestRevise::UpdateSeed() { - if (BASE_SEED == USE_CLOCK_TIME) { - seed = std::chrono::system_clock::now().time_since_epoch().count(); - } else if (BASE_SEED == USE_INCREMENTAL_SEED) { - seed += 9999; - } else { - seed = BASE_SEED; - } - std::cout << "\033[0;32m" << "[ ] " << "\033[0;0m" - << "seed = " << seed << std::endl; -} } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/subgraph/concat_multi_input.cpp b/inference-engine/tests/functional/shared_test_classes/src/subgraph/concat_multi_input.cpp index b8e33799575..a19a410fef9 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/subgraph/concat_multi_input.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/subgraph/concat_multi_input.cpp @@ -105,4 +105,23 @@ void ConcatMultiInput::GenerateConstOnlyModel() { function = std::make_shared(results, input_vector, "ConcatConstOnly"); } +void ConcatMultiInput::GenerateMemoryModel() { + int axis = 1; + auto input = ngraph::builder::makeParams(ngPrc, { inputShapes[0] }); + + auto variable = std::make_shared(ngraph::VariableInfo{ngraph::PartialShape::dynamic(), ngraph::element::dynamic, "concat_input_memory"}); + auto mem_i = std::make_shared(ngPrc, inputShapes[0]); + auto mem_r = std::make_shared(mem_i, variable); + + ngraph::OutputVector concat_input; + concat_input.push_back(mem_r); + concat_input.push_back(input.at(0)); + auto concat = std::make_shared(concat_input, axis); + + auto mem_w = std::make_shared(input.at(0), variable); + + auto res = std::make_shared(concat); + function = std::make_shared(ngraph::ResultVector{res}, ngraph::SinkVector{mem_w}, input, "ConcatMemory"); +} + } // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/subgraph/reduce_eltwise.cpp b/inference-engine/tests/functional/shared_test_classes/src/subgraph/reduce_eltwise.cpp index b51ca490090..14c2cf95ff6 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/subgraph/reduce_eltwise.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/subgraph/reduce_eltwise.cpp @@ -31,8 +31,7 @@ void ReduceEltwiseTest::SetUp() { CommonTestUtils::OpType opType; bool keepDims; InferenceEngine::Precision netPrecision; - std::string targetName; - std::tie(inputShape, axes, opType, keepDims, netPrecision, targetName) = this->GetParam(); + std::tie(inputShape, axes, opType, keepDims, netPrecision, targetDevice) = this->GetParam(); auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); auto paramOuts = ngraph::helpers::convert2OutputVector( diff --git a/inference-engine/tests/functional/shared_test_classes/src/subgraph/transpose_conv_transpose_squeeze.cpp b/inference-engine/tests/functional/shared_test_classes/src/subgraph/transpose_conv_transpose_squeeze.cpp new file mode 100644 index 00000000000..1b26740ed0d --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/src/subgraph/transpose_conv_transpose_squeeze.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/subgraph/transpose_conv_transpose_squeeze.hpp" + +namespace SubgraphTestsDefinitions { + +std::string TransposeConvTest::getTestCaseName(testing::TestParamInfo obj) { + ConvParams convParams; + InferenceEngine::Precision netPrecision; + InferenceEngine::SizeVector inputShapes; + std::string targetDevice; + std::map config; + std::tie(convParams, netPrecision, inputShapes, targetDevice, config) = obj.param; + + std::vector inputArg; + std::vector kernelShape; + std::vector strides; + size_t inputChannels; + size_t outputChannels; + std::tie(kernelShape, strides, inputChannels, outputChannels) = convParams; + + std::ostringstream result; + result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "trgDev=" << targetDevice; + for (auto const& configItem : config) { + result << "_configItem=" << configItem.first << "_" << configItem.second; + } + result << "_KERNEL=" << CommonTestUtils::vec2str(kernelShape) << "_"; + result << "STRIDES=" << CommonTestUtils::vec2str(strides) << "_"; + result << "IC=" << inputChannels << "_"; + result << "OC=" << outputChannels; + return result.str(); +} + +void TransposeConvTest::SetUp() { + ConvParams conv_params; + std::vector input_shape; + std::map config; + auto net_precision = InferenceEngine::Precision::UNSPECIFIED; + std::tie(conv_params, net_precision, input_shape, targetDevice, config) = this->GetParam(); + configuration.insert(config.begin(), config.end()); + + std::vector kernel_shape, strides; + size_t input_channels, output_channels; + std::tie(kernel_shape, strides, input_channels, output_channels) = conv_params; + auto ng_prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(net_precision); + auto params = ngraph::builder::makeParams(ng_prc, {input_shape}); + + std::vector nchw_order = { 0, 3, 1, 2 }; + std::vector nhwc_order = { 0, 2, 3, 1 }; + std::vector conv_input_shape = {1, 1, input_shape[0] * input_shape[1] / input_channels, input_channels}; + auto reshape_pattern = std::make_shared(ngraph::element::Type_t::i64, ngraph::Shape{conv_input_shape.size()}, conv_input_shape); + auto reshape = std::make_shared(params[0], reshape_pattern, false); + + const auto input_order1 = std::make_shared(ngraph::element::i64, + ngraph::Shape({conv_input_shape.size()}), + nchw_order); + auto transpose1 = std::make_shared(reshape, input_order1); + + float weight_val = 0.02; + auto filter_weights_node = ngraph::builder::makeConstant(ng_prc, {output_channels, input_channels, kernel_shape[0], kernel_shape[1]}, + { weight_val }); + + auto conv = std::make_shared(transpose1, filter_weights_node, strides, std::vector{ 0, 0 }, + std::vector{ 0, 0 }, std::vector{ 1, 1 }, + ngraph::op::PadType::VALID); + + const auto input_order2 = std::make_shared(ngraph::element::i64, + ngraph::Shape({conv_input_shape.size()}), + nhwc_order); + auto transpose2 = std::make_shared(conv, input_order2); + + auto constant_squeeze = std::make_shared(ngraph::element::Type_t::i64, ngraph::Shape{1}, std::vector{0}); + auto squeeze = std::make_shared(transpose2, constant_squeeze); + + function = std::make_shared(squeeze, params, "transposeConv"); +} + +InferenceEngine::Blob::Ptr TransposeConvTest::GenerateInput(const InferenceEngine::InputInfo &info) const { + return FuncTestUtils::createAndFillBlob(info.getTensorDesc(), inputDataMax - inputDataMin, inputDataMin, 1 / inputDataResolution, + seed); +} +} // namespace SubgraphTestsDefinitions \ No newline at end of file diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/file_utils.cpp b/inference-engine/tests/ie_test_utils/common_test_utils/file_utils.cpp index decb88d6e1b..a272a97741a 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/file_utils.cpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/file_utils.cpp @@ -20,6 +20,7 @@ # include #endif +NGRAPH_SUPPRESS_DEPRECATED_START namespace CommonTestUtils { std::string getExecutableDirectory() { diff --git a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index c653bf4fe8c..e3693da7e53 100644 --- a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -46,6 +46,7 @@ VERIFIED_OP_REFERENCES = [ 'GatherElements-6', 'GatherND-5', 'Gelu-7', + 'Greater-1' 'GRN-1', 'GroupConvolution-1', 'GroupConvolutionBackpropData-1', @@ -61,6 +62,7 @@ VERIFIED_OP_REFERENCES = [ 'LSTMSequence-5', 'LogicalAnd-1' 'LogicalOr-1' + 'LogicalXor-1' 'LogSoftmax-5', 'Loop-5', 'MVN-1', diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/pad_function.hpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/pad_function.hpp new file mode 100644 index 00000000000..0d2c36382f4 --- /dev/null +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/pad_function.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp" +#include "lpt_ngraph_functions/common/dequantization_operations.hpp" + +namespace ngraph { +namespace builder { +namespace subgraph { + +class PadFunction { +public: +static std::shared_ptr get( + const PartialShape& inputShape, + const element::Type precisionBeforeDequantization, + const builder::subgraph::DequantizationOperations& dequantizationBefore, + const std::vector& padsBegin, + const std::vector& padsEnd, + const op::PadMode mode, + const float padValue, + const element::Type precisionAfterOperation, + const builder::subgraph::DequantizationOperations& dequantizationAfter); + +static std::shared_ptr get( + const PartialShape& inputShape, + const element::Type inputPrecision, + const builder::subgraph::FakeQuantizeOnData& fakeQuantizeOnData, + const std::vector& padsBegin, + const std::vector& padsEnd, + const op::PadMode mode, + const float padValue = 0.f); +}; +} // namespace subgraph +} // namespace builder +} // namespace ngraph diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/fake_quantize_precision_selection_function.cpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/fake_quantize_precision_selection_function.cpp index cb645f11401..6d180e4b35f 100644 --- a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/fake_quantize_precision_selection_function.cpp +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/fake_quantize_precision_selection_function.cpp @@ -149,7 +149,7 @@ std::shared_ptr FakeQuantizePrecisionSelectionFunction::getRef std::shared_ptr branch1Multiply = std::make_shared( convolution, - std::make_shared(precision, Shape({1, 1, 1, 1}), std::vector({ 0.0001f }))); + std::make_shared(precision, Shape({}), std::vector({ 0.0001f }))); // just another branch diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/pad_function.cpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/pad_function.cpp new file mode 100644 index 00000000000..fc1cb604ae5 --- /dev/null +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/pad_function.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + + +#include +#include "ngraph_functions/subgraph_builders.hpp" +#include "lpt_ngraph_functions/common/builders.hpp" +#include "lpt_ngraph_functions/pad_function.hpp" +#include "low_precision/network_helper.hpp" + +namespace ngraph { +namespace builder { +namespace subgraph { +std::shared_ptr PadFunction::get( + const PartialShape& inputShape, + const element::Type precisionBeforeDequantization, + const builder::subgraph::DequantizationOperations& dequantizationBefore, + const std::vector& padsBegin, + const std::vector& padsEnd, + const op::PadMode mode, + const float padValue, + const element::Type precisionAfterOperation, + const builder::subgraph::DequantizationOperations& dequantizationAfter) { + const auto input = std::make_shared(precisionBeforeDequantization, inputShape); + const auto deqBefore = makeDequantization(input, dequantizationBefore); + + const auto padsBeginConst = opset1::Constant::create(element::u64, Shape{ padsBegin.size() }, padsBegin); + const auto padsEndConst = opset1::Constant::create(element::u64, Shape{ padsEnd.size() }, padsEnd); + const auto padsValueConst = opset1::Constant::create(deqBefore->get_output_element_type(0), Shape{}, { padValue }); + + const auto pad = std::make_shared>( + std::vector{ precisionAfterOperation, element::u64, element::u64, precisionAfterOperation}, + std::vector{ precisionAfterOperation }, + op::TemporaryReplaceOutputType(deqBefore, precisionAfterOperation).get(), + op::TemporaryReplaceOutputType(padsBeginConst, element::u64).get(), + op::TemporaryReplaceOutputType(padsEndConst, element::u64).get(), + op::TemporaryReplaceOutputType(padsValueConst, precisionAfterOperation).get(), + mode); + + const auto deqAfter = makeDequantization(pad, dequantizationAfter); + deqAfter->set_friendly_name("Pad"); + + const auto function = std::make_shared( + ResultVector{ std::make_shared(deqAfter) }, + ngraph::ParameterVector{ input }, "PadTransformation"); + + return function; +} + +std::shared_ptr PadFunction::get( + const PartialShape& inputShape, + const element::Type inputPrecision, + const builder::subgraph::FakeQuantizeOnData& fakeQuantize, + const std::vector& padsBegin, + const std::vector& padsEnd, + const op::PadMode mode, + const float padValue) { + const auto input = std::make_shared(inputPrecision, inputShape); + const auto fqOnData = makeFakeQuantize(input, inputPrecision, fakeQuantize); + + const auto padsBeginConst = opset1::Constant::create(element::u64, Shape{ padsBegin.size() }, padsBegin); + const auto padsEndConst = opset1::Constant::create(element::u64, Shape{ padsEnd.size() }, padsEnd); + const auto padsValueConst = opset1::Constant::create(inputPrecision, Shape{}, { padValue }); + const auto pad = std::make_shared(fqOnData, padsBeginConst, padsEndConst, padsValueConst, mode); + pad->set_friendly_name("Pad"); + + const auto function = std::make_shared( + ResultVector{ std::make_shared(pad) }, + ParameterVector{ input }, "PadTransformation"); + + return function; +} + +} // namespace subgraph +} // namespace builder +} // namespace ngraph diff --git a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp index 6b3043a0063..18af1da8868 100644 --- a/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp +++ b/inference-engine/tests/ngraph_helpers/ngraph_functions/src/utils/ngraph_helpers.cpp @@ -696,16 +696,16 @@ std::ostream& operator<<(std::ostream & os, ngraph::helpers::LogicalTypes type) std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::InterpolateMode type) { switch (type) { - case ngraph::op::v4::Interpolate::InterpolateMode::cubic: + case ngraph::op::v4::Interpolate::InterpolateMode::CUBIC: os << "cubic"; break; - case ngraph::op::v4::Interpolate::InterpolateMode::linear: + case ngraph::op::v4::Interpolate::InterpolateMode::LINEAR: os << "linear"; break; - case ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx: + case ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX: os << "linear_onnx"; break; - case ngraph::op::v4::Interpolate::InterpolateMode::nearest: + case ngraph::op::v4::Interpolate::InterpolateMode::NEAREST: os << "nearest"; break; default: @@ -716,19 +716,19 @@ std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::Interpo std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::CoordinateTransformMode type) { switch (type) { - case ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS: os << "align_corners"; break; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC: os << "asymmetric"; break; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL: os << "half_pixel"; break; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL: os << "pytorch_half_pixel"; break; - case ngraph::op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn: + case ngraph::op::v4::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN: os << "tf_half_pixel_for_nn"; break; default: @@ -739,19 +739,19 @@ std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::Coordin std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::NearestMode type) { switch (type) { - case ngraph::op::v4::Interpolate::NearestMode::ceil: + case ngraph::op::v4::Interpolate::NearestMode::CEIL: os << "ceil"; break; - case ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil: + case ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL: os << "round_prefer_ceil"; break; - case ngraph::op::v4::Interpolate::NearestMode::floor: + case ngraph::op::v4::Interpolate::NearestMode::FLOOR: os << "floor"; break; - case ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor: + case ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR: os << "round_prefer_floor"; break; - case ngraph::op::v4::Interpolate::NearestMode::simple: + case ngraph::op::v4::Interpolate::NearestMode::SIMPLE: os << "simple"; break; default: @@ -762,10 +762,10 @@ std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::Nearest std::ostream& operator<<(std::ostream & os, ngraph::op::v4::Interpolate::ShapeCalcMode type) { switch (type) { - case ngraph::op::v4::Interpolate::ShapeCalcMode::scales: + case ngraph::op::v4::Interpolate::ShapeCalcMode::SCALES: os << "scales"; break; - case ngraph::op::v4::Interpolate::ShapeCalcMode::sizes: + case ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES: os << "sizes"; break; default: diff --git a/inference-engine/tests/unit/frontends/onnx_import/onnx_importer_test.cpp b/inference-engine/tests/unit/frontends/onnx_import/onnx_importer_test.cpp index 6c7fa1aeda5..a86ded8b8d4 100644 --- a/inference-engine/tests/unit/frontends/onnx_import/onnx_importer_test.cpp +++ b/inference-engine/tests/unit/frontends/onnx_import/onnx_importer_test.cpp @@ -11,6 +11,8 @@ #include "ngraph/file_util.hpp" #include "onnx_import/onnx.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START + TEST(ONNX_Importer_Tests, ImportBasicModel) { auto model_file_path = CommonTestUtils::getModelFromTestModelZoo( ngraph::file_util::path_join(ONNX_MODELS_DIR, "add_abc_initializers.onnx")); diff --git a/inference-engine/tests/unit/gna/gna_get_2d_reshaped_data.cpp b/inference-engine/tests/unit/gna/gna_get_2d_reshaped_data.cpp index 5af1bf88fa7..5e96984e152 100644 --- a/inference-engine/tests/unit/gna/gna_get_2d_reshaped_data.cpp +++ b/inference-engine/tests/unit/gna/gna_get_2d_reshaped_data.cpp @@ -65,7 +65,7 @@ class Get2DReshapedDataTest : public ::testing::Test { InferenceEngine::Layout layout) const { auto data = std::make_shared(input_name, InferenceEngine::TensorDesc(precision, input_shape.first, layout)); - auto new_data = GNAPluginNS::Get2DReshapedData(data, max_batch_size); + auto new_data = GNAPluginNS::Get2DReshapedData(data, 1, max_batch_size); ASSERT_EQ(new_data->getDims(), input_shape.second); ASSERT_EQ(new_data->getPrecision(), precision); ASSERT_EQ(new_data->getLayout(), layout); diff --git a/inference-engine/tests/unit/gna/gna_get_aligned_split_sizes.cpp b/inference-engine/tests/unit/gna/gna_get_aligned_split_sizes.cpp new file mode 100644 index 00000000000..5d017248e49 --- /dev/null +++ b/inference-engine/tests/unit/gna/gna_get_aligned_split_sizes.cpp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +// to suppress deprecated definition errors +#define IMPLEMENT_INFERENCE_ENGINE_PLUGIN +#include "layers/gna_split_layer.hpp" + +namespace { + +using GetAlignedSplitSizesData = std::tuple< + uint32_t, // total size + uint32_t, // maximum split size + uint32_t, // alignment + std::vector // expected sizes +>; + +const std::vector data = { + GetAlignedSplitSizesData{1024, 100, 64, std::vector(16, 64)}, + GetAlignedSplitSizesData{151, 100, 64, std::vector{64, 64, 23}}, + GetAlignedSplitSizesData{151, 65, 32, std::vector{64, 64, 23}}, + GetAlignedSplitSizesData{151, 65, 1, std::vector{65, 65, 21}} +}; + +TEST(GetAlignedSplitSizesTest, testAlignedSplitSizes) { + for (const auto &dataItem : data) { + auto sizes = GNAPluginNS::GetAlignedSplitSizes(std::get<0>(dataItem), std::get<1>(dataItem), + std::get<2>(dataItem)); + ASSERT_EQ(sizes, std::get<3>(dataItem)); + } +} + +} // namespace \ No newline at end of file diff --git a/inference-engine/tests/unit/vpu/base/graph_transformer_tests.cpp b/inference-engine/tests/unit/vpu/base/graph_transformer_tests.cpp index 0b57b4527a1..15cfffd0343 100644 --- a/inference-engine/tests/unit/vpu/base/graph_transformer_tests.cpp +++ b/inference-engine/tests/unit/vpu/base/graph_transformer_tests.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -362,7 +361,7 @@ void GraphTransformerTest::InitCompileEnv() { ? InferenceEngine::PluginConfigParams::YES : InferenceEngine::PluginConfigParams::NO); } - CompileEnv::init(platform, config, _log); + CompileEnv::init(config, _log); compileEnvInitialized = true; } @@ -452,7 +451,6 @@ IE_SUPPRESS_DEPRECATED_START configuration.registerDeprecatedOption(VPU_CONFIG_KEY(CUSTOM_LAYERS)); configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE)); configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(FORCE_RESET)); - configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(PLATFORM)); IE_SUPPRESS_DEPRECATED_END return configuration; diff --git a/inference-engine/tests/unit/vpu/base/graph_transformer_tests.hpp b/inference-engine/tests/unit/vpu/base/graph_transformer_tests.hpp index 2e125a6e30b..8f57ad1ad46 100644 --- a/inference-engine/tests/unit/vpu/base/graph_transformer_tests.hpp +++ b/inference-engine/tests/unit/vpu/base/graph_transformer_tests.hpp @@ -134,7 +134,6 @@ PluginConfiguration createConfiguration(); class GraphTransformerTest : public ::testing::Test { public: - ncDevicePlatform_t platform = ncDevicePlatform_t::NC_MYRIAD_X; PluginConfiguration config; StageBuilder::Ptr stageBuilder; diff --git a/inference-engine/tests/unit/vpu/blob_reader_tests.cpp b/inference-engine/tests/unit/vpu/blob_reader_tests.cpp index 65f16f6cae0..8c3e9a86aed 100644 --- a/inference-engine/tests/unit/vpu/blob_reader_tests.cpp +++ b/inference-engine/tests/unit/vpu/blob_reader_tests.cpp @@ -51,7 +51,7 @@ public: ASSERT_NO_THROW(_network = InferenceEngine::CNNNetwork(fn_ptr)); auto log = std::make_shared("GraphCompiler", LogLevel::None, consoleOutput()); - _compiledGraph = compileNetwork(_network, ncDevicePlatform_t::NC_MYRIAD_X, createConfiguration(), log, _mockCore); + _compiledGraph = compileNetwork(_network, createConfiguration(), log, _mockCore); } CNNNetwork _network; diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/aot_behavior_tests.cpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/aot_behavior_tests.cpp index b67029dbedc..b0b0cbffa7f 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/aot_behavior_tests.cpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/aot_behavior_tests.cpp @@ -127,7 +127,6 @@ class AOTBehaviorTests : public BehaviorPluginTest { #endif // _WIN32 ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_ANY_PROTOCOL; - deviceDesc.platform = NC_ANY_PLATFORM; ncDeviceOpenParams_t deviceOpenParams = {}; deviceOpenParams.watchdogHndl = m_watchdogHndl; diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.cpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.cpp index 5016a4a3b9d..c31465b1928 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.cpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.cpp @@ -28,11 +28,9 @@ MyriadDevicesInfo::MyriadDevicesInfo() { std::vector MyriadDevicesInfo::getDevicesList( const ncDeviceProtocol_t deviceProtocol, - const ncDevicePlatform_t devicePlatform, const XLinkDeviceState_t state) { deviceDesc_t req_deviceDesc = {}; req_deviceDesc.protocol = convertProtocolToXlink(deviceProtocol); - req_deviceDesc.platform = convertPlatformToXlink(devicePlatform); deviceDesc_t deviceDescArray[NC_MAX_DEVICES] = {}; unsigned int foundDevices = 0; @@ -49,11 +47,9 @@ std::vector MyriadDevicesInfo::getDevicesList( int MyriadDevicesInfo::getAmountOfDevices( const ncDeviceProtocol_t deviceProtocol, - const ncDevicePlatform_t devicePlatform, const XLinkDeviceState_t state) { deviceDesc_t req_deviceDesc = {}; req_deviceDesc.protocol = convertProtocolToXlink(deviceProtocol); - req_deviceDesc.platform = convertPlatformToXlink(devicePlatform); deviceDesc_t deviceDescArray[NC_MAX_DEVICES] = {}; unsigned int foundDevices = 0; diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.hpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.hpp index ed9265f868c..ad7faee1969 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.hpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_devices.hpp @@ -29,7 +29,6 @@ public: std::vector getDevicesList( const ncDeviceProtocol_t deviceProtocol = NC_ANY_PROTOCOL, - const ncDevicePlatform_t devicePlatform = NC_ANY_PLATFORM, const XLinkDeviceState_t state = X_LINK_ANY_STATE); inline bool isMyriadXDevice(const std::string &device_name); @@ -39,7 +38,6 @@ public: inline bool isMyriadUnbootedDevice(const std::string &device_name); int getAmountOfDevices(const ncDeviceProtocol_t deviceProtocol = NC_ANY_PROTOCOL, - const ncDevicePlatform_t devicePlatform = NC_ANY_PLATFORM, const XLinkDeviceState_t state = X_LINK_ANY_STATE); inline long getAmountOfBootedDevices(const ncDeviceProtocol_t deviceProtocol); @@ -71,9 +69,9 @@ bool MyriadDevicesInfo::isMyriadUnbootedDevice(const std::string &device_name) { } long MyriadDevicesInfo::getAmountOfUnbootedDevices(const ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED); + return getAmountOfDevices(deviceProtocol, X_LINK_UNBOOTED); } long MyriadDevicesInfo::getAmountOfBootedDevices(const ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_ANY_PLATFORM, X_LINK_BOOTED); + return getAmountOfDevices(deviceProtocol, X_LINK_BOOTED); } diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_load_network_case.cpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_load_network_case.cpp index 1dd11961d06..3801ff0077e 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_load_network_case.cpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/helpers/myriad_load_network_case.cpp @@ -25,6 +25,6 @@ void MyriadLoadNetworkTestCase::LoadNetwork() { } bool MyriadLoadNetworkTestCase::IsDeviceAvailable(std::string device_name) { - auto act_devices = getDevicesList(NC_ANY_PROTOCOL, NC_ANY_PLATFORM, X_LINK_UNBOOTED); + auto act_devices = getDevicesList(NC_ANY_PROTOCOL, X_LINK_UNBOOTED); return std::find(act_devices.begin(), act_devices.end(), device_name) != act_devices.end(); } diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_boot_tests.cpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_boot_tests.cpp index 0998c48e25c..95fa056270b 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_boot_tests.cpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_boot_tests.cpp @@ -45,7 +45,7 @@ class MYRIADBoot : public MyriadDevicesInfo, * @brief Boot any free device */ void bootOneDevice() { - ASSERT_NO_ERROR(ncDeviceLoadFirmware(NC_ANY_PLATFORM, firmwareDir)); + ASSERT_NO_ERROR(ncDeviceLoadFirmware(firmwareDir)); } }; diff --git a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_watchdog_tests.cpp b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_watchdog_tests.cpp index 6e4e6f38519..1362e9e82bd 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_watchdog_tests.cpp +++ b/inference-engine/tests_deprecated/behavior/vpu/myriad_tests/vpu_watchdog_tests.cpp @@ -84,7 +84,6 @@ class MYRIADWatchdog : public BehaviorPluginTest, ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_ANY_PROTOCOL; - deviceDesc.platform = NC_ANY_PLATFORM; ncDeviceOpenParams_t deviceOpenParams = {}; deviceOpenParams.watchdogHndl = m_watchdogHndl; diff --git a/inference-engine/tests_deprecated/behavior/vpu/shared_tests_instances/plugin_tests/vpu_test_data.hpp b/inference-engine/tests_deprecated/behavior/vpu/shared_tests_instances/plugin_tests/vpu_test_data.hpp index 6a1ab38d36a..64e0a577f9a 100644 --- a/inference-engine/tests_deprecated/behavior/vpu/shared_tests_instances/plugin_tests/vpu_test_data.hpp +++ b/inference-engine/tests_deprecated/behavior/vpu/shared_tests_instances/plugin_tests/vpu_test_data.hpp @@ -81,10 +81,6 @@ const std::vector deviceSpecificConfigurations = { BEH_MYRIAD.withConfig({{InferenceEngine::MYRIAD_PROTOCOL, InferenceEngine::MYRIAD_USB}}), BEH_MYRIAD.withConfig({{InferenceEngine::MYRIAD_PROTOCOL, InferenceEngine::MYRIAD_PCIE}}), - // Deprecated - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2450)}}), - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2480)}}), - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PROTOCOL), VPU_MYRIAD_CONFIG_VALUE(USB)}}), BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PROTOCOL), VPU_MYRIAD_CONFIG_VALUE(PCIE)}}), }; @@ -192,17 +188,6 @@ const BehTestParams withIncorrectConfValues[] = { BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-1"}}), BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "MICRON"}}), - - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}}), - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "0"}}), - BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "1"}}), - - BEH_MULTI_CONFIG.withConfig({{MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, "MYRIAD"}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}}), - BEH_MULTI_CONFIG.withConfig({{MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, "MYRIAD"}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "0"}}), - BEH_MULTI_CONFIG.withConfig({{MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, "MYRIAD"}, - {VPU_MYRIAD_CONFIG_KEY(PLATFORM), "1"}}), }; const BehTestParams withIncorrectConfKeys[] = { diff --git a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_blob_test.cpp b/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_blob_test.cpp index 6128ac1ee1b..2dba65615b7 100644 --- a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_blob_test.cpp +++ b/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_blob_test.cpp @@ -197,7 +197,6 @@ TEST_F(myriadConfigsWithBlobImportTests_smoke, TryingToSetRuntimeOptionDoesNotPr {InferenceEngine::MYRIAD_ENABLE_RECEIVING_TENSOR_TIME, CONFIG_VALUE(YES)} }; if (vpu::tests::deviceForceReset()) { config.insert({InferenceEngine::MYRIAD_ENABLE_FORCE_RESET, CONFIG_VALUE(NO)}); - config.insert({VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2480)}); } InferenceEngine::ExecutableNetwork importedNetwork; diff --git a/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.cpp b/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.cpp index 209a4ef3057..b6b82f72eb2 100644 --- a/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.cpp +++ b/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -66,12 +65,11 @@ void graphTransformerFunctionalTests::SetUp() { vpuLayersTests::SetUp(); _stageBuilder = std::make_shared(); - _platform = CheckMyriadX() ? ncDevicePlatform_t::NC_MYRIAD_X : ncDevicePlatform_t::NC_MYRIAD_2; } void graphTransformerFunctionalTests::CreateModel() { const auto compilerLog = std::make_shared("Test", LogLevel::Info, consoleOutput()); - CompileEnv::init(_platform, _configuration, compilerLog); + CompileEnv::init(_configuration, compilerLog); AutoScope autoDeinit([] { CompileEnv::free(); }); @@ -147,7 +145,6 @@ IE_SUPPRESS_DEPRECATED_START _configuration.registerDeprecatedOption(VPU_CONFIG_KEY(CUSTOM_LAYERS)); _configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE)); _configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(FORCE_RESET)); - _configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(PLATFORM)); IE_SUPPRESS_DEPRECATED_END _inputsInfo.clear(); @@ -192,7 +189,6 @@ int64_t graphTransformerFunctionalTests::CompileAndInfer(Blob::Ptr& inputBlob, B auto compiledGraph = compileModel( _gtModel, - _platform, _configuration, compilerLog); diff --git a/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.hpp b/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.hpp index ff3063b217f..535a694d681 100644 --- a/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.hpp +++ b/inference-engine/tests_deprecated/functional/vpu/graph_transformer/gt_functional_tests.hpp @@ -31,6 +31,5 @@ protected: vpu::Data _dataIntermediate; private: - ncDevicePlatform_t _platform = ncDevicePlatform_t::NC_MYRIAD_X; InferenceEngine::ExecutableNetwork _executableNetwork; }; diff --git a/inference-engine/tests_deprecated/functional/vpu/myriad_tests/myriad_configs_tests.cpp b/inference-engine/tests_deprecated/functional/vpu/myriad_tests/myriad_configs_tests.cpp index 70fdb6c20d2..800a13ca39b 100644 --- a/inference-engine/tests_deprecated/functional/vpu/myriad_tests/myriad_configs_tests.cpp +++ b/inference-engine/tests_deprecated/functional/vpu/myriad_tests/myriad_configs_tests.cpp @@ -58,18 +58,6 @@ TEST_P(myriadIncorrectModelsConfigsTests_nightly, LoadNetworkWithIncorrectConfig // Tests initiation //------------------------------------------------------------------------------ -static const std::vector myriadCorrectPlatformConfigValues = { - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2450)}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2480)}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), ""}} -}; - -static const std::vector myriadIncorrectPlatformConfigValues = { - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), " 0"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "MyriadX"}} -}; - static const std::vector myriadCorrectPackageTypeConfigValues = { // Please do not use other types of DDR in tests with a real device, because it may hang. {{InferenceEngine::MYRIAD_DDR_TYPE, InferenceEngine::MYRIAD_DDR_AUTO}}, @@ -87,12 +75,6 @@ static const std::vector myriadIncorrectPackageTypeConfigValues = { {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-MICRON_1GB"}}, }; -INSTANTIATE_TEST_SUITE_P(MyriadConfigs, myriadCorrectModelsConfigsTests_nightly, - ::testing::ValuesIn(myriadCorrectPlatformConfigValues)); - -INSTANTIATE_TEST_SUITE_P(MyriadConfigs, myriadIncorrectModelsConfigsTests_nightly, - ::testing::ValuesIn(myriadIncorrectPlatformConfigValues)); - INSTANTIATE_TEST_SUITE_P(MyriadPackageConfigs, myriadCorrectModelsConfigsTests_nightly, ::testing::ValuesIn(myriadCorrectPackageTypeConfigValues)); diff --git a/inference-engine/tests_deprecated/helpers/tests_vpu_common.hpp b/inference-engine/tests_deprecated/helpers/tests_vpu_common.hpp index 18d17be9337..1ea84fc4fde 100644 --- a/inference-engine/tests_deprecated/helpers/tests_vpu_common.hpp +++ b/inference-engine/tests_deprecated/helpers/tests_vpu_common.hpp @@ -62,16 +62,8 @@ static bool hasMyriad2() { static bool hasAppropriateStick(const config_t &config) { bool suitsConfig; - auto platform = config.find(VPU_MYRIAD_CONFIG_KEY(PLATFORM)); - if (platform == config.end() || platform->second.empty()) { - suitsConfig = hasMyriad2() || hasMyriadX(); - } else { - bool hasRequestedMyriad2 = - platform->second == VPU_MYRIAD_CONFIG_VALUE(2450) && hasMyriad2(); - bool hasRequestedMyriadX = - platform->second == VPU_MYRIAD_CONFIG_VALUE(2480) && hasMyriadX(); - suitsConfig = hasRequestedMyriad2 || hasRequestedMyriadX; - } + bool hasRequestedMyriadX = hasMyriadX(); + suitsConfig = hasRequestedMyriadX; return suitsConfig; } diff --git a/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.cpp b/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.cpp index eedf042217c..a75d0ba7621 100644 --- a/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.cpp +++ b/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.cpp @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -264,7 +263,6 @@ IE_SUPPRESS_DEPRECATED_START configuration.registerDeprecatedOption(VPU_CONFIG_KEY(CUSTOM_LAYERS)); configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE)); configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(FORCE_RESET)); - configuration.registerDeprecatedOption(VPU_MYRIAD_CONFIG_KEY(PLATFORM)); IE_SUPPRESS_DEPRECATED_END return configuration; @@ -310,7 +308,7 @@ void GraphTransformerTest::InitCompileEnv() { ? InferenceEngine::PluginConfigParams::YES : InferenceEngine::PluginConfigParams::NO); } - CompileEnv::init(platform, config, _log); + CompileEnv::init(config, _log); compileEnvInitialized = true; } diff --git a/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.hpp b/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.hpp index 94d394b4c09..6b6ea91212a 100644 --- a/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.hpp +++ b/inference-engine/tests_deprecated/unit/engines/vpu/graph_transformer_tests.hpp @@ -180,7 +180,6 @@ PluginConfiguration createConfiguration(); class GraphTransformerTest : public TestsCommon { public: - ncDevicePlatform_t platform = ncDevicePlatform_t::NC_MYRIAD_X; PluginConfiguration config; StageBuilder::Ptr stageBuilder; diff --git a/inference-engine/tests_deprecated/unit/engines/vpu/myriad_tests/myriad_engine_tests.cpp b/inference-engine/tests_deprecated/unit/engines/vpu/myriad_tests/myriad_engine_tests.cpp index 7bd1ad415b9..e2222fbc86d 100644 --- a/inference-engine/tests_deprecated/unit/engines/vpu/myriad_tests/myriad_engine_tests.cpp +++ b/inference-engine/tests_deprecated/unit/engines/vpu/myriad_tests/myriad_engine_tests.cpp @@ -22,20 +22,6 @@ TEST_P(MyriadEngineSetIncorrectConfigTest, SetIncorrectConfig) { IE_SUPPRESS_DEPRECATED_START -static const std::vector myriadCorrectPlatformConfigValues = { - // Deprecated - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2450)}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_MYRIAD_CONFIG_VALUE(2480)}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), ""}} -}; - -static const std::vector myriadIncorrectPlatformConfigValues = { - // Deprecated - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "-1"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), " 0"}}, - {{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "MyriadX"}} -}; - static const std::vector myriadCorrectProtocolConfigValues = { {{InferenceEngine::MYRIAD_PROTOCOL, InferenceEngine::MYRIAD_PCIE}}, {{InferenceEngine::MYRIAD_PROTOCOL, InferenceEngine::MYRIAD_USB}}, @@ -50,12 +36,10 @@ static const std::vector myriadCorrectProtocolConfigValues = { static const std::vector myriadIncorrectProtocolConfigValues = { // Protocols {{InferenceEngine::MYRIAD_PROTOCOL, "0"}}, - {{InferenceEngine::MYRIAD_PROTOCOL, "2450"}}, {{InferenceEngine::MYRIAD_PROTOCOL, "PCI"}}, // Deprecated {{VPU_MYRIAD_CONFIG_KEY(PROTOCOL), "0"}}, - {{VPU_MYRIAD_CONFIG_KEY(PROTOCOL), "2450"}}, {{VPU_MYRIAD_CONFIG_KEY(PROTOCOL), "PCI"}}, }; @@ -106,13 +90,6 @@ static const std::vector myriadIncorrectPackageTypeConfigValues = { IE_SUPPRESS_DEPRECATED_END -/// Platform -INSTANTIATE_TEST_SUITE_P(MyriadPlatformConfigs, MyriadEngineSetCorrectConfigTest, - ::testing::ValuesIn(myriadCorrectPlatformConfigValues)); - -INSTANTIATE_TEST_SUITE_P(MyriadPlatformConfigs, MyriadEngineSetIncorrectConfigTest, - ::testing::ValuesIn(myriadIncorrectPlatformConfigValues)); - /// Protocol INSTANTIATE_TEST_SUITE_P(MyriadProtocolConfigs, MyriadEngineSetCorrectConfigTest, ::testing::ValuesIn(myriadCorrectProtocolConfigValues)); diff --git a/inference-engine/thirdparty/clDNN/api/cldnn/runtime/utils.hpp b/inference-engine/thirdparty/clDNN/api/cldnn/runtime/utils.hpp index 7b66ff43a7b..1d744896dfb 100644 --- a/inference-engine/thirdparty/clDNN/api/cldnn/runtime/utils.hpp +++ b/inference-engine/thirdparty/clDNN/api/cldnn/runtime/utils.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace cldnn { diff --git a/inference-engine/thirdparty/clDNN/src/include/loop_inst.h b/inference-engine/thirdparty/clDNN/src/include/loop_inst.h index c63df1a06e8..a6a8e578540 100644 --- a/inference-engine/thirdparty/clDNN/src/include/loop_inst.h +++ b/inference-engine/thirdparty/clDNN/src/include/loop_inst.h @@ -381,39 +381,39 @@ public: size_t total_bytes; backedge_memory_mapping( - std::shared_ptr from_primitive, std::shared_ptr to_primitive, - std::vector from_mems, memory::ptr initial_mem, cldnn::stream& stream, backedge_type type = CONCAT_OUTPUT): - from_primitive(from_primitive), - to_primitive(to_primitive), - from_mems(from_mems), - initial_mem(initial_mem), - stream(stream), - type(type), + std::shared_ptr _from_primitive, std::shared_ptr _to_primitive, + std::vector _from_mems, memory::ptr _initial_mem, cldnn::stream& _stream, backedge_type _type = CONCAT_OUTPUT): + from_primitive(_from_primitive), + to_primitive(_to_primitive), + from_mems(_from_mems), + initial_mem(_initial_mem), + stream(_stream), + type(_type), total_bytes(initial_mem->get_layout().bytes_count()) { validate_backedge_memory(); } backedge_memory_mapping( - std::shared_ptr from_primitive, std::shared_ptr to_primitive, - memory::ptr from_mem, memory::ptr initial_mem, cldnn::stream& stream, backedge_type type = SINGLE_SHARED): - from_primitive(from_primitive), - to_primitive(to_primitive), - from_mems{from_mem}, - initial_mem(initial_mem), - stream(stream), - type(type), + std::shared_ptr _from_primitive, std::shared_ptr _to_primitive, + memory::ptr _from_mem, memory::ptr _initial_mem, cldnn::stream& _stream, backedge_type _type = SINGLE_SHARED): + from_primitive(_from_primitive), + to_primitive(_to_primitive), + from_mems{_from_mem}, + initial_mem(_initial_mem), + stream(_stream), + type(_type), total_bytes(initial_mem->get_layout().bytes_count()) { validate_backedge_memory(); } backedge_memory_mapping( - std::shared_ptr from_primitive, std::shared_ptr to_primitive, - memory::ptr initial_mem, cldnn::stream& stream, backedge_type type = SINGLE): - from_primitive(from_primitive), - to_primitive(to_primitive), - initial_mem(initial_mem), - stream(stream), - type(type), + std::shared_ptr _from_primitive, std::shared_ptr _to_primitive, + memory::ptr _initial_mem, cldnn::stream& _stream, backedge_type _type = SINGLE): + from_primitive(_from_primitive), + to_primitive(_to_primitive), + initial_mem(_initial_mem), + stream(_stream), + type(_type), total_bytes(initial_mem->get_layout().bytes_count()) { validate_backedge_memory(); } diff --git a/inference-engine/thirdparty/clDNN/src/input_layout.cpp b/inference-engine/thirdparty/clDNN/src/input_layout.cpp index ddc4c5470ac..d7bfa069192 100644 --- a/inference-engine/thirdparty/clDNN/src/input_layout.cpp +++ b/inference-engine/thirdparty/clDNN/src/input_layout.cpp @@ -12,6 +12,18 @@ #include #include +namespace { +bool has_optimized_users(input_layout_node const& node) { + for (auto& user : node.get_users()) { + if (user->can_be_optimized()) { + return true; + } + } + + return false; +} +} // namespace + namespace cldnn { primitive_type_id input_layout::type_id() { static primitive_type_base instance; @@ -23,7 +35,8 @@ input_layout_node::typed_program_node(const std::shared_ptr dprim, can_share_buffer(false); } -input_layout_inst::typed_primitive_inst(network& network, input_layout_node const& node) : parent(network, node) { +input_layout_inst::typed_primitive_inst(network& network, input_layout_node const& node) + : parent(network, node, !network.is_internal() || has_optimized_users(node)) { _has_valid_input = false; // by default input for 'input_layout' is invalid as long as user doesn't call set_data } diff --git a/inference-engine/thirdparty/clDNN/tests/test_cases/fusings_gpu_test.cpp b/inference-engine/thirdparty/clDNN/tests/test_cases/fusings_gpu_test.cpp index 00fea3995cc..d683d117286 100644 --- a/inference-engine/thirdparty/clDNN/tests/test_cases/fusings_gpu_test.cpp +++ b/inference-engine/thirdparty/clDNN/tests/test_cases/fusings_gpu_test.cpp @@ -8034,7 +8034,6 @@ struct scatter_nd_update_test_params { tensor input_shape; tensor indices_shape; tensor updates_shape; - int max_number_in_indices; int indices_rank; data_types data_type; format input_format; @@ -8044,49 +8043,49 @@ struct scatter_nd_update_test_params { size_t expected_not_fused_primitives; }; -#define CASE_SCATTER_ND_UPDATE_FP16_4D_1 {6, 1, 1, 1}, {3, 1, 1, 1}, {3, 1, 1, 1}, 6, 1, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_4D_2 {6, 6, 1, 1}, {3, 2, 1, 1}, {3, 1, 1, 1}, 6, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_4D_3 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 6, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_4D_4 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 6, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_4D_5 {6, 7, 8, 9}, {6, 2, 1, 1}, {6, 9, 1, 8}, 6, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_4D_6 {6, 7, 8, 9}, {6, 3, 1, 1}, {6, 8, 1, 1}, 6, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_1 {6, 1, 1, 1}, {3, 1, 1, 1}, {3, 1, 1, 1}, 1, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_2 {6, 6, 1, 1}, {3, 2, 1, 1}, {3, 1, 1, 1}, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_3 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_4 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_5 {6, 7, 8, 9}, {6, 2, 1, 1}, {6, 9, 1, 8}, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_4D_6 {6, 7, 8, 9}, {6, 3, 1, 1}, {6, 8, 1, 1}, 2, data_types::f16, format::bfyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_1 {6, 7, 8, 9, 10}, {5, 1, 1, 1, 1}, {5, 7, 8, 9, 10}, 6, 1, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_2 {6, 7, 8, 9, 10}, {5, 2, 1, 1, 1}, {5, 10, 1, 8, 9}, 6, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_3 {6, 7, 8, 9, 10}, {5, 3, 1, 1, 1}, {5, 9, 1, 1, 8}, 6, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_4 {6, 7, 8, 9, 10}, {5, 4, 1, 1, 1}, {5, 8, 1, 1, 1}, 6, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_5 {6, 7, 8, 9, 10}, {5, 5, 1, 1, 1}, {5, 1, 1, 1, 1}, 6, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_6 {6, 7, 8, 9, 10}, {5, 2, 1, 1, 2}, {5, 2, 8, 9, 10}, 6, 3, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_7 {6, 7, 8, 9, 10}, {5, 2, 1, 1, 3}, {5, 2, 1, 8, 9}, 6, 3, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_8 {6, 7, 8, 9, 10}, {5, 2, 1, 4, 3}, {5, 2, 1, 8, 3}, 6, 4, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_5D_9 {6, 7, 8, 9, 10}, {5, 2, 1, 3, 3}, {5, 2, 8, 9, 3}, 6, 4, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_1 {6, 7, 8, 9, 10}, {5, 1, 1, 1}, {5, 7, 8, 9, 10}, 1, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_2 {6, 7, 8, 9, 10}, {5, 2, 1, 1}, {5, 10, 1, 8, 9}, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_3 {6, 7, 8, 9, 10}, {5, 3, 1, 1}, {5, 9, 1, 1, 8}, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_4 {6, 7, 8, 9, 10}, {5, 4, 1, 1}, {5, 8, 1, 1, 1}, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_5 {6, 7, 8, 9, 10}, {5, 5, 1, 1}, {5, 1, 1, 1, 1}, 2, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_6 {6, 7, 8, 9, 10}, {5, 2, 1, 2}, {5, 2, 8, 9, 10}, 3, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_7 {6, 7, 8, 9, 10}, {5, 2, 1, 3}, {5, 2, 1, 8, 9}, 3, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_8 {6, 7, 8, 9, 10}, {5, 2, 4, 3}, {5, 2, 1, 8, 3}, 4, data_types::f16, format::bfzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_5D_9 {6, 7, 8, 9, 10}, {5, 2, 3, 3}, {5, 2, 8, 9, 3}, 4, data_types::f16, format::bfzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_1 {6, 7, 8, 9, 10, 11}, {5, 1, 1, 1}, {5, 7, 8, 9, 10, 11}, 6, 1, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_2 {6, 7, 8, 9, 10, 11}, {5, 2, 1, 1}, {5, 11, 1, 8, 9, 10}, 6, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_3 {6, 7, 8, 9, 10, 11}, {5, 3, 1, 1}, {5, 10, 1, 1, 8, 9}, 6, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_4 {6, 7, 8, 9, 10, 11}, {5, 4, 1, 1}, {5, 9, 1, 1, 1, 8}, 6, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_5 {6, 7, 8, 9, 2, 2}, {5, 5, 1, 1}, {5, 8, 1, 1, 1, 1}, 6, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP16_6D_6 {6, 7, 8, 9, 2, 2}, {5, 6, 1, 1}, {5, 1, 1, 1, 1, 1}, 6, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_1 {6, 7, 8, 9, 10, 11}, {5, 1, 1, 1}, {5, 7, 8, 9, 10, 11}, 1, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_2 {6, 7, 8, 9, 10, 11}, {5, 2, 1, 1}, {5, 11, 1, 8, 9, 10}, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_3 {6, 7, 8, 9, 10, 11}, {5, 3, 1, 1}, {5, 10, 1, 1, 8, 9}, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_4 {6, 7, 8, 9, 10, 11}, {5, 4, 1, 1}, {5, 9, 1, 1, 1, 8}, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_5 {6, 7, 8, 9, 2, 2}, {5, 5, 1, 1}, {5, 8, 1, 1, 1, 1}, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP16_6D_6 {6, 7, 8, 9, 2, 2}, {5, 6, 1, 1}, {5, 1, 1, 1, 1, 1}, 2, data_types::f16, format::bfwzyx, data_types::f16, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_1 {6, 1, 1, 1}, {3, 1, 1, 1}, {3, 1, 1, 1}, 6, 1, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_2 {6, 6, 1, 1}, {3, 2, 1, 1}, {3, 1, 1, 1}, 6, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_3 {6, 7, 8, 1}, {5, 1, 1, 1}, {5, 7, 8, 1}, 6, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_4 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 6, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_5 {6, 7, 8, 9}, {6, 2, 1, 1}, {6, 9, 1, 8}, 6, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_4D_6 {6, 7, 8, 9}, {6, 3, 1, 1}, {6, 8, 1, 1}, 6, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_1 {6, 1, 1, 1}, {3, 1, 1, 1}, {3, 1, 1, 1}, 1, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_2 {6, 6, 1, 1}, {3, 2, 1, 1}, {3, 1, 1, 1}, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_3 {6, 7, 8, 1}, {5, 1, 1, 1}, {5, 7, 8, 1}, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_4 {6, 7, 8, 9}, {5, 1, 1, 1}, {5, 7, 8, 9}, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_5 {6, 7, 8, 9}, {6, 2, 1, 1}, {6, 9, 1, 8}, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_4D_6 {6, 7, 8, 9}, {6, 3, 1, 1}, {6, 8, 1, 1}, 2, data_types::f32, format::bfyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_5D_1 {6, 7, 8, 9, 10}, {5, 1, 1, 1, 1}, {5, 7, 8, 9, 10}, 6, 1, data_types::f32, format::bfzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_5D_2 {6, 7, 8, 9, 10}, {5, 2, 1, 1, 1}, {5, 10, 1, 8, 9}, 6, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_5D_3 {6, 7, 8, 9, 10}, {5, 3, 1, 1, 1}, {5, 9, 1, 1, 8}, 6, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_5D_4 {6, 7, 8, 9, 10}, {5, 4, 1, 1, 1}, {5, 8, 1, 1, 1}, 6, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_5D_5 {6, 7, 8, 9, 10}, {5, 5, 1, 1, 1}, {5, 1, 1, 1, 1}, 6, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_5D_1 {6, 7, 8, 9, 10}, {5, 1, 1, 1}, {5, 7, 8, 9, 10}, 1, data_types::f32, format::bfzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_5D_2 {6, 7, 8, 9, 10}, {5, 2, 1, 1}, {5, 10, 1, 8, 9}, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_5D_3 {6, 7, 8, 9, 10}, {5, 3, 1, 1}, {5, 9, 1, 1, 8}, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_5D_4 {6, 7, 8, 9, 10}, {5, 4, 1, 1}, {5, 8, 1, 1, 1}, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_5D_5 {6, 7, 8, 9, 10}, {5, 5, 1, 1}, {5, 1, 1, 1, 1}, 2, data_types::f32, format::bfzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_1 {6, 7, 8, 9, 10, 11}, {5, 1, 1, 1}, {5, 7, 8, 9, 10, 11}, 6, 1, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_2 {6, 7, 8, 9, 10, 11}, {5, 2, 1, 1}, {5, 11, 1, 8, 9, 10}, 6, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_3 {6, 7, 8, 9, 10, 11}, {5, 3, 1, 1}, {5, 10, 1, 1, 8, 9}, 6, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_4 {6, 7, 8, 9, 10, 11}, {5, 4, 1, 1}, {5, 9, 1, 1, 1, 8}, 6, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_5 {6, 7, 8, 9, 2, 2}, {5, 5, 1, 1}, {5, 8, 1, 1, 1, 1}, 6, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx -#define CASE_SCATTER_ND_UPDATE_FP32_6D_6 {6, 7, 8, 9, 2, 2}, {5, 6, 1, 1}, {5, 1, 1, 1, 1, 1}, 6, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_1 {6, 7, 8, 9, 10, 11}, {5, 1, 1, 1}, {5, 7, 8, 9, 10, 11}, 1, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_2 {6, 7, 8, 9, 10, 11}, {5, 2, 1, 1}, {5, 11, 1, 8, 9, 10}, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_3 {6, 7, 8, 9, 10, 11}, {5, 3, 1, 1}, {5, 10, 1, 1, 8, 9}, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_4 {6, 7, 8, 9, 10, 11}, {5, 4, 1, 1}, {5, 9, 1, 1, 1, 8}, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_5 {6, 7, 8, 9, 2, 2}, {5, 5, 1, 1}, {5, 8, 1, 1, 1, 1}, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx +#define CASE_SCATTER_ND_UPDATE_FP32_6D_6 {6, 7, 8, 9, 2, 2}, {5, 6, 1, 1}, {5, 1, 1, 1, 1, 1}, 2, data_types::f32, format::bfwzyx, data_types::f32, format::bfyx class ScatterNDUpdatePrimitiveFusingTest : public ::BaseFusingTest { public: @@ -8104,7 +8103,7 @@ public: } layout get_indices_layout(scatter_nd_update_test_params& p) { - return layout{ p.data_type, p.input_format, p.indices_shape }; + return layout{ p.data_type, get_default_format(p.indices_rank), p.indices_shape }; } layout get_updates_layout(scatter_nd_update_test_params& p) { @@ -8114,13 +8113,80 @@ public: layout get_per_channel_layout(scatter_nd_update_test_params& p) { return layout{ p.default_type, p.default_format, tensor{1, p.input_shape.feature[0], 1, 1} }; } + + format get_default_format(int rank = 4) { + if (rank <= 4) + return cldnn::format::bfyx; + else if (rank == 5) + return cldnn::format::bfzyx; + else + return cldnn::format::bfwzyx; + } + + template + T generate_random_val(int min, int max, int k = 8) { + static std::default_random_engine generator(random_seed); + // 1/k is the resolution of the floating point numbers + std::uniform_int_distribution distribution(k * min, k * max); + T val = (T)distribution(generator); + val /= k; + + return val; + } + + template + std::vector generate_unique_indices(scatter_nd_update_test_params& p) { + std::set> unique_indices; + std::vector result; + auto indices_shape = p.indices_shape.sizes(get_default_format(p.indices_rank)); + auto last_indices_dim = indices_shape.back(); + + auto count = 1; + for (size_t i = 0; i < indices_shape.size() - 1; i++) + count *= indices_shape[i]; + + while (unique_indices.size() != count) { + std::vector indices; + for (size_t i = 0; i < last_indices_dim; i++) + indices.push_back(generate_random_val(0, indices_shape[i])); + + unique_indices.insert(indices); + } + + std::for_each(unique_indices.begin(), + unique_indices.end(), + [&](const std::vector& indices) { + result.insert(result.end(), indices.begin(), indices.end()); + }); + + return result; + } + + cldnn::memory::ptr get_indices_mem(scatter_nd_update_test_params& p) { + auto indices_layout = get_indices_layout(p); + auto prim = engine.allocate_memory(indices_layout); + if (indices_layout.data_type == data_types::f32) { + VF rnd_vec = generate_unique_indices(p); + set_values(prim, rnd_vec); + } else if (indices_layout.data_type == data_types::f16) { + VF rnd_vec = generate_unique_indices(p); + set_values(prim, rnd_vec); + } else if (indices_layout.data_type == data_types::i8) { + VF rnd_vec = generate_unique_indices(p); + set_values(prim, rnd_vec); + } else { + throw std::runtime_error("Unsupported data type for indicies of scatter_nd_update primitive"); + } + + return prim; + } }; class scatter_nd_update_quantize : public ScatterNDUpdatePrimitiveFusingTest {}; TEST_P(scatter_nd_update_quantize, basic) { auto p = GetParam(); create_topologies(input_layout("input", get_input_layout(p)), - data("scatter_nd_update_indices", get_mem(get_indices_layout(p), 0, p.max_number_in_indices)), + data("scatter_nd_update_indices", get_indices_mem(p)), data("scatter_nd_update_updates", get_mem(get_updates_layout(p), 0, 100)), data("in_lo", get_mem(get_per_channel_layout(p), min_random, 0)), data("in_hi", get_mem(get_per_channel_layout(p), 1, max_random)), @@ -8128,7 +8194,7 @@ TEST_P(scatter_nd_update_quantize, basic) { data("out_hi", get_mem(get_single_element_layout(p), 127)), scatter_nd_update("scatter_nd_update_prim", "input", "scatter_nd_update_indices", "scatter_nd_update_updates", p.indices_rank), quantize("quantize", "scatter_nd_update_prim", "in_lo", "in_hi", "out_lo", "out_hi", 255, data_types::i8), - reorder("reorder_bfyx", "quantize", p.default_format, data_types::f32) + reorder("reorder_bfyx", "quantize", p.input_format, data_types::f32) ); tolerance = 1.f; execute(p); @@ -8183,7 +8249,7 @@ class scatter_nd_update_scale_activation_eltwise : public ScatterNDUpdatePrimiti TEST_P(scatter_nd_update_scale_activation_eltwise, basic) { auto p = GetParam(); create_topologies(input_layout("input", get_input_layout(p)), - data("scatter_nd_update_indices", get_mem(get_indices_layout(p), 0, p.max_number_in_indices)), + data("scatter_nd_update_indices", get_indices_mem(p)), data("scatter_nd_update_updates", get_mem(get_updates_layout(p), 0, 100)), data("scale_data", get_mem(get_per_channel_layout(p), -1, 1)), data("eltwise_data", get_mem(layout{ p.data_type, p.input_format, p.input_shape })), @@ -8191,7 +8257,7 @@ TEST_P(scatter_nd_update_scale_activation_eltwise, basic) { activation("activation", "scatter_nd_update_prim", activation_func::abs), scale("scale", "activation", "scale_data"), eltwise("eltwise", { "scale", "eltwise_data" }, eltwise_mode::sum, p.data_type), - reorder("reorder_bfyx", "eltwise", p.default_format, data_types::f32) + reorder("reorder_bfyx", "eltwise", p.input_format, data_types::f32) ); tolerance = 1.f; diff --git a/inference-engine/thirdparty/clDNN/tests/test_cases/memory_test.cpp b/inference-engine/thirdparty/clDNN/tests/test_cases/memory_test.cpp index 861cd2672cd..4582f2ad063 100644 --- a/inference-engine/thirdparty/clDNN/tests/test_cases/memory_test.cpp +++ b/inference-engine/thirdparty/clDNN/tests/test_cases/memory_test.cpp @@ -449,7 +449,7 @@ TEST(memory_pool, shared_dep_two_output) { network network(*engine, topo, bo); auto outputs = network.execute(); - EXPECT_EQ(engine->get_max_used_device_memory(), (uint64_t)256); + EXPECT_EQ(engine->get_max_used_device_memory(), (uint64_t)192); } TEST(memory_pool, non_opt_intermidate_opt_after) { diff --git a/inference-engine/thirdparty/mkl-dnn b/inference-engine/thirdparty/mkl-dnn index fdc6f62b118..7e4430d9398 160000 --- a/inference-engine/thirdparty/mkl-dnn +++ b/inference-engine/thirdparty/mkl-dnn @@ -1 +1 @@ -Subproject commit fdc6f62b1184dab86dbadd55fc4bc49dcde9dba5 +Subproject commit 7e4430d9398af63e94943815dace4b44f12ddbee diff --git a/inference-engine/thirdparty/movidius/mvnc/include/mvnc.h b/inference-engine/thirdparty/movidius/mvnc/include/mvnc.h index b4585e14aa3..c25f7cebdea 100644 --- a/inference-engine/thirdparty/movidius/mvnc/include/mvnc.h +++ b/inference-engine/thirdparty/movidius/mvnc/include/mvnc.h @@ -124,12 +124,6 @@ typedef enum { NC_RW_ENABLE_ASYNC_DMA = 2102 // enable/disable asynchronous DMA on device } ncDeviceOption_t; -typedef enum { - NC_ANY_PLATFORM = 0, - NC_MYRIAD_2 = 2450, - NC_MYRIAD_X = 2480, -} ncDevicePlatform_t; - typedef enum { NC_ANY_PROTOCOL = 0, NC_USB, @@ -158,7 +152,6 @@ struct ncDeviceHandle_t { struct ncDeviceDescr_t { ncDeviceProtocol_t protocol; - ncDevicePlatform_t platform; char name[NC_MAX_NAME_SIZE]; }; diff --git a/inference-engine/thirdparty/movidius/mvnc/include/mvnc_data.h b/inference-engine/thirdparty/movidius/mvnc/include/mvnc_data.h index a010e912893..331c0bfbaa9 100644 --- a/inference-engine/thirdparty/movidius/mvnc/include/mvnc_data.h +++ b/inference-engine/thirdparty/movidius/mvnc/include/mvnc_data.h @@ -16,8 +16,7 @@ extern "C" XLinkProtocol_t convertProtocolToXlink(const ncDeviceProtocol_t ncProtocol); ncDeviceProtocol_t convertProtocolToNC(const XLinkProtocol_t xLinkProtocol); -XLinkPlatform_t convertPlatformToXlink(const ncDevicePlatform_t ncProtocol); -ncDevicePlatform_t convertPlatformToNC(const XLinkPlatform_t xLinkProtocol); +XLinkPlatform_t convertPlatformToXlink(); int copyNcDeviceDescrToXLink( const struct ncDeviceDescr_t *in_ncDeviceDesc, deviceDesc_t *out_deviceDesc); diff --git a/inference-engine/thirdparty/movidius/mvnc/include/mvnc_ext.h b/inference-engine/thirdparty/movidius/mvnc/include/mvnc_ext.h index 66155be76f6..2efafb610e7 100644 --- a/inference-engine/thirdparty/movidius/mvnc/include/mvnc_ext.h +++ b/inference-engine/thirdparty/movidius/mvnc/include/mvnc_ext.h @@ -16,14 +16,14 @@ extern "C" * @param devicePlatform Platform to boot * @param customFirmwareDir Path to directory with firmware to load. If NULL, use default */ -MVNC_EXPORT_API ncStatus_t ncDeviceLoadFirmware(const ncDevicePlatform_t devicePlatform, const char* customFirmwareDir); +MVNC_EXPORT_API ncStatus_t ncDeviceLoadFirmware(const char* customFirmwareDir); /** * @brief Reset all devices */ MVNC_EXPORT_API ncStatus_t ncDeviceResetAll(); -MVNC_EXPORT_API char* ncPlatformToStr(ncDevicePlatform_t devicePlatform); +MVNC_EXPORT_API char* ncPlatformToStr(); MVNC_EXPORT_API char* ncProtocolToStr(ncDeviceProtocol_t deviceProtocol); #ifdef __cplusplus diff --git a/inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.c b/inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.c index 03447a36a9a..de5d39bb7c8 100644 --- a/inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.c +++ b/inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.c @@ -150,12 +150,8 @@ char* ncProtocolToStr(const ncDeviceProtocol_t deviceProtocol) { } } -char* ncPlatformToStr(const ncDevicePlatform_t platform) { - switch(platform) { - case NC_MYRIAD_2: return "NC_MYRIAD_2"; - case NC_MYRIAD_X: return "NC_MYRIAD_X"; - default: return "NC_ANY_PLATFORM"; - } +char* ncPlatformToStr() { + return "NC_MYRIAD_X"; } int mvnc_memcpy(void* dest, size_t destsz, void const* src, size_t count) { @@ -1186,21 +1182,20 @@ ncStatus_t ncAvailableDevices(struct ncDeviceDescr_t *deviceDescrPtr, return NC_OK; } -ncStatus_t ncDeviceLoadFirmware(const ncDevicePlatform_t devicePlatform, const char* customFirmwareDir) { - mvLog(MVLOG_WARN, "Boot (%s) without connecting to it", ncPlatformToStr(devicePlatform)); +ncStatus_t ncDeviceLoadFirmware(const char* customFirmwareDir) { + mvLog(MVLOG_WARN, "Boot (%s) without connecting to it", ""); XLinkError_t rc; ncStatus_t sc; // Find device with specific platform deviceDesc_t deviceDesc = {0}; deviceDesc_t in_deviceDesc = { - .platform = convertPlatformToXlink(devicePlatform), .protocol = X_LINK_USB_VSC }; rc = XLinkFindFirstSuitableDevice(X_LINK_UNBOOTED, in_deviceDesc, &deviceDesc); if (rc) { - mvLog(MVLOG_WARN, "Failed to find (%s) platform device", ncPlatformToStr(devicePlatform)); + mvLog(MVLOG_WARN, "Failed to find (%s) platform device", ""); return NC_DEVICE_NOT_FOUND; } @@ -2668,14 +2663,7 @@ static ncStatus_t getDeviceOption(struct _devicePrivate_t *d, mv_strncpy((char *) data, *dataLength, d->dev_addr, *dataLength - 1); break; case NC_RO_DEVICE_PLATFORM: - if (d->dev_attr.fw_version[1] == 0x2480){ - *(ncDevicePlatform_t *) data = NC_MYRIAD_X; - } else if (d->dev_attr.fw_version[1] == 0x2450) { - *(ncDevicePlatform_t *) data = NC_MYRIAD_2; - } else { - *(ncDevicePlatform_t *) data = NC_ANY_PLATFORM; - } - *dataLength = sizeof(ncDevicePlatform_t); + *dataLength = sizeof(data); break; case NC_RO_DEVICE_PROTOCOL: *(ncDeviceProtocol_t *) data = convertProtocolToNC(d->protocol); @@ -2821,7 +2809,7 @@ ncStatus_t ncDeviceGetOption(struct ncDeviceHandle_t * deviceHandle, CHECK_HANDLE_CORRECT(deviceHandle); ncStatus_t rc; - if (!dataLength || (*dataLength != 0 && !data)) { + if (!dataLength) { mvLog(MVLOG_ERROR, "Some of the parameters are NULL"); return NC_INVALID_PARAMETERS; } diff --git a/inference-engine/thirdparty/movidius/mvnc/src/mvnc_data.c b/inference-engine/thirdparty/movidius/mvnc/src/mvnc_data.c index ddebe959e4a..b8ceafc0504 100644 --- a/inference-engine/thirdparty/movidius/mvnc/src/mvnc_data.c +++ b/inference-engine/thirdparty/movidius/mvnc/src/mvnc_data.c @@ -35,35 +35,12 @@ ncDeviceProtocol_t convertProtocolToNC( } } -XLinkPlatform_t convertPlatformToXlink( - const ncDevicePlatform_t ncProtocol) { - switch (ncProtocol) { - case NC_ANY_PLATFORM: return X_LINK_ANY_PLATFORM; - case NC_MYRIAD_2: return X_LINK_MYRIAD_2; - case NC_MYRIAD_X: return X_LINK_MYRIAD_X; - default: return X_LINK_ANY_PLATFORM; - } -} - -ncDevicePlatform_t convertPlatformToNC( - const XLinkPlatform_t xLinkProtocol) { - switch (xLinkProtocol) { - case X_LINK_ANY_PLATFORM: return NC_ANY_PLATFORM; - case X_LINK_MYRIAD_2: return NC_MYRIAD_2; - case X_LINK_MYRIAD_X: return NC_MYRIAD_X; - default: - mvLog(MVLOG_WARN, "This convertation not supported, set to NC_ANY_PLATFORM"); - return NC_ANY_PLATFORM; - } -} - int copyNcDeviceDescrToXLink(const struct ncDeviceDescr_t *in_ncDeviceDesc, deviceDesc_t *out_deviceDesc) { CHECK_HANDLE_CORRECT(in_ncDeviceDesc); CHECK_HANDLE_CORRECT(out_deviceDesc); out_deviceDesc->protocol = convertProtocolToXlink(in_ncDeviceDesc->protocol); - out_deviceDesc->platform = convertPlatformToXlink(in_ncDeviceDesc->platform); mv_strncpy(out_deviceDesc->name, XLINK_MAX_NAME_SIZE, in_ncDeviceDesc->name, XLINK_MAX_NAME_SIZE - 1); return NC_OK; @@ -75,7 +52,6 @@ int copyXLinkDeviceDescrToNc(const deviceDesc_t *in_DeviceDesc, CHECK_HANDLE_CORRECT(out_ncDeviceDesc); out_ncDeviceDesc->protocol = convertProtocolToNC(in_DeviceDesc->protocol); - out_ncDeviceDesc->platform = convertPlatformToNC(in_DeviceDesc->platform); mv_strncpy(out_ncDeviceDesc->name, XLINK_MAX_NAME_SIZE, in_DeviceDesc->name, XLINK_MAX_NAME_SIZE - 1); return NC_OK; diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.cpp index f21da7a63ad..bb66bef31e1 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.cpp @@ -57,7 +57,6 @@ void MvncTestsCommon::openDevices(const int devicesToBoot, ncDeviceHandle_t **de amountOfBooted = 0; ncDeviceDescr_t ncDeviceDesc = {}; ncDeviceDesc.protocol = NC_USB; - ncDeviceDesc.platform = NC_ANY_PLATFORM; for (int index = 0; index < devicesToBoot; ++index) { ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandlers[index], ncDeviceDesc, m_ncDeviceOpenParams)); @@ -71,7 +70,7 @@ void MvncTestsCommon::bootOneDevice(ncDeviceProtocol_t deviceProtocol) { if (deviceProtocol == NC_PCIE) { GTEST_FATAL_FAILURE_("Boot doesn't supported for PCIe protocol\n"); } - ASSERT_NO_ERROR(ncDeviceLoadFirmware(NC_ANY_PLATFORM, firmwareDir)); + ASSERT_NO_ERROR(ncDeviceLoadFirmware(firmwareDir)); } @@ -123,7 +122,6 @@ void MvncLoggingTests::SetUp() { MvncOpenDevice::SetUp(); _deviceDesc.protocol = _deviceProtocol; - _deviceDesc.platform = NC_ANY_PLATFORM; for (int index = 0; index < availableDevices_; ++index) { ASSERT_NO_ERROR(ncDeviceOpen(&_deviceHandles[index], _deviceDesc, m_ncDeviceOpenParams)); diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.h b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.h index ba513c23dcc..496caaa95a8 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.h +++ b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.h @@ -137,12 +137,6 @@ static const std::vector myriadProtocols = { NC_PCIE }; -static const std::vector myriadPlatforms = { - NC_MYRIAD_2, - NC_MYRIAD_X -}; - - namespace { /** * @brief Converter from enum to string @@ -153,9 +147,8 @@ namespace { return ncProtocolToStr(info.param); } - std::string operator()( - const ::testing::TestParamInfo &info) const { - return std::string("USB_") + ncPlatformToStr(info.param); + std::string operator()() const { + return std::string("USB_"); } }; } diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.cpp index 3f288b12412..9f6913066e6 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.cpp @@ -14,7 +14,6 @@ void MvncOpenUSBDevice::SetUp() { availableDevices_ = getAmountOfNotBootedDevices(NC_USB); deviceDesc_.protocol = NC_USB; - deviceDesc_.platform = NC_ANY_PLATFORM; } //------------------------------------------------------------------------------ diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.h b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.h index 3714e0b98e9..aecce0815b0 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.h +++ b/inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_usb_test_cases.h @@ -29,12 +29,11 @@ class MvncCloseUSBDevice : public MvncOpenUSBDevice { //------------------------------------------------------------------------------ // class MvncDevicePlatform //------------------------------------------------------------------------------ -class MvncDevicePlatform : public MvncOpenUSBDevice, - public testing::WithParamInterface{ +class MvncDevicePlatform : public MvncOpenUSBDevice + { public: long available_myriadX_ = 0; long available_myriad2_ = 0; - ncDevicePlatform_t devicePlatform_; ~MvncDevicePlatform() override = default; diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.cpp index 57c39e9adab..dea7cf0d2a7 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.cpp @@ -10,11 +10,9 @@ // Implementations of helpers - counters //------------------------------------------------------------------------------ int getAmountOfDevices(const ncDeviceProtocol_t deviceProtocol, - const ncDevicePlatform_t devicePlatform, const XLinkDeviceState_t state) { deviceDesc_t req_deviceDesc = {}; req_deviceDesc.protocol = convertProtocolToXlink(deviceProtocol); - req_deviceDesc.platform = convertPlatformToXlink(devicePlatform); deviceDesc_t deviceDescArray[NC_MAX_DEVICES] = {}; unsigned int foundDevices = 0; @@ -24,22 +22,6 @@ int getAmountOfDevices(const ncDeviceProtocol_t deviceProtocol, return foundDevices; } -long getAmountOfMyriadXDevices(ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_MYRIAD_X); -} - -long getAmountOfMyriad2Devices(ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_MYRIAD_2); -} - -long getAmountOfBootedDevices(ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_ANY_PLATFORM, X_LINK_BOOTED); -} - -long getAmountOfNotBootedDevices(ncDeviceProtocol_t deviceProtocol) { - return getAmountOfDevices(deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED); -} - long getAmountOfPCIeDevices() { return getAmountOfDevices(NC_PCIE); } @@ -52,12 +34,10 @@ long getAmountOfUSBDevices() { // Implementations of helpers - get devices //------------------------------------------------------------------------------ std::vector getDevicesList(const ncDeviceProtocol_t deviceProtocol, - const ncDevicePlatform_t devicePlatform, const XLinkDeviceState_t state) { deviceDesc_t req_deviceDesc = {}; req_deviceDesc.protocol = convertProtocolToXlink(deviceProtocol); - req_deviceDesc.platform = convertPlatformToXlink(devicePlatform); deviceDesc_t deviceDescArray[NC_MAX_DEVICES] = {}; unsigned int foundDevices = 0; @@ -112,16 +92,8 @@ bool isSameProtocolDevice(const std::string &deviceName, const ncDeviceProtocol_ } bool -isSamePlatformUSBDevice(const std::string &deviceName, const ncDevicePlatform_t expectedPlatform) { - switch (expectedPlatform) { - case NC_MYRIAD_2: return isMyriad2USBDevice(deviceName); - case NC_MYRIAD_X: return isMyriadXUSBDevice(deviceName); - case NC_ANY_PLATFORM: - return isMyriad2USBDevice(deviceName) || isMyriadXUSBDevice(deviceName); - default: - std::cout << "Unknown device platform" << std::endl; - return false; - } +isSamePlatformUSBDevice(const std::string &deviceName) { + return isMyriadXUSBDevice(deviceName); } //------------------------------------------------------------------------------ diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.h b/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.h index c6c8d8ae715..9ddef27cb12 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.h +++ b/inference-engine/thirdparty/movidius/mvnc/tests/helpers/mvnc_test_helper.h @@ -56,7 +56,6 @@ extern "C" void initialize_usb_boot(); * @param[in] deviceProtocol Count only platform specific devices */ int getAmountOfDevices(const ncDeviceProtocol_t deviceProtocol = NC_ANY_PROTOCOL, - const ncDevicePlatform_t devicePlatform = NC_ANY_PLATFORM, const XLinkDeviceState_t state = X_LINK_ANY_STATE); long getAmountOfMyriadXDevices(ncDeviceProtocol_t deviceProtocol = NC_ANY_PROTOCOL); @@ -79,7 +78,6 @@ long getAmountOfUSBDevices(); */ std::vector getDevicesList( const ncDeviceProtocol_t deviceProtocol = NC_ANY_PROTOCOL, - const ncDevicePlatform_t devicePlatform = NC_ANY_PLATFORM, const XLinkDeviceState_t state = X_LINK_ANY_STATE); //------------------------------------------------------------------------------ @@ -107,8 +105,7 @@ bool isSameProtocolDevice(const std::string &deviceName, /** * @brief Check that device matches the specified platform for USB */ -bool isSamePlatformUSBDevice(const std::string &deviceName, - const ncDevicePlatform_t expectedPlatform); +bool isSamePlatformUSBDevice(const std::string &deviceName); //------------------------------------------------------------------------------ // Helpers - file loader diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_no_boot_tests.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_no_boot_tests.cpp index fe8c522ac3c..7b30165be11 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_no_boot_tests.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_no_boot_tests.cpp @@ -15,7 +15,6 @@ TEST_F(MvncNoBootOpenDevice, OpenAndClose) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_USB; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, watchdogInterval, firmwarePath)); ASSERT_NO_ERROR(ncDeviceClose(&deviceHandle)); @@ -28,7 +27,6 @@ TEST_F(MvncNoBootOpenDevice, OpenTwiceSameHandler) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_USB; - deviceDesc.platform = NC_ANY_PLATFORM; char dev_addr_first_open[MAX_DEV_NAME]; unsigned int data_length_first = MAX_DEV_NAME; @@ -60,7 +58,6 @@ TEST_F(MvncNoBootOpenDevice, OpenDeviceWithOneXLinkInitializion) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_USB; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, watchdogInterval, firmwarePath)); ASSERT_NO_ERROR(ncDeviceClose(&deviceHandle)); @@ -93,7 +90,6 @@ TEST_F(MvncNoBootCloseDevice, AlreadyBootedDeviceWillNotReboot) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_USB; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, watchdogInterval, firmwarePath)); ASSERT_NO_ERROR(ncDeviceClose(&deviceHandle)); diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_stress_tests.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_stress_tests.cpp index 2f7f74ce630..1d0153bd039 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_stress_tests.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_stress_tests.cpp @@ -19,7 +19,6 @@ TEST_P(MvncStressTests, OpenClose1001) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; for (int i = 0; i < iterations; ++i) { printf("Iteration %d of %d\n", i, iterations); @@ -36,7 +35,6 @@ TEST_P(MvncStressTests, AllocateDeallocateGraph1001) { const int iterations = 1001; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; // Load graph const std::string blobPath = "bvlc_googlenet_fp16.blob"; @@ -79,7 +77,6 @@ TEST_P(MvncStressTests, FullCycleOfWork101Times) { const int iterations = 101; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; const std::string blobPath = "bvlc_googlenet_fp16.blob"; std::vector blob; diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_common.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_common.cpp index 11c8c58c711..8a3c9a1162b 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_common.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_common.cpp @@ -92,7 +92,6 @@ TEST_F(MvncTestsCommon, OpenUSBThenPCIEAndClose) { std::string actDeviceName; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_USB; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle_USB, deviceDesc, m_ncDeviceOpenParams)); @@ -127,7 +126,6 @@ TEST_F(MvncTestsCommon, OpenPCIEThenUSBAndClose) { std::string actDeviceName; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_PCIE; - deviceDesc.platform = NC_ANY_PLATFORM; // Open PCIe device ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle_PCIe, deviceDesc, m_ncDeviceOpenParams)); @@ -164,7 +162,6 @@ TEST_P(MvncOpenDevice, OpenAndClose) { std::string deviceName; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, m_ncDeviceOpenParams)); @@ -190,7 +187,6 @@ TEST_P(MvncOpenDevice, AllHandleFieldsInitialized) { ncDeviceHandle_t* deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, m_ncDeviceOpenParams)); @@ -217,7 +213,6 @@ TEST_P(MvncOpenDevice, OpenTwiceSameHandler) { ncDeviceHandle_t *deviceHandle = nullptr; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; char dev_addr_first_open[MAX_DEV_NAME]; unsigned int data_length_first = MAX_DEV_NAME; @@ -254,7 +249,6 @@ TEST_P(MvncOpenDevice, DISABLED_OpenSameDeviceTwiceDifferentHandlers) { ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle1, deviceDesc, m_ncDeviceOpenParams)); @@ -278,7 +272,6 @@ TEST_P(MvncOpenDevice, OpenTwiceWithOneXLinkInitializion) { ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = _deviceProtocol; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, m_ncDeviceOpenParams)); @@ -304,8 +297,7 @@ TEST_P(MvncOpenDevice, WatchdogShouldResetDeviceWithoutConnection) { deviceDesc_t deviceDescToBoot = {}; deviceDesc_t in_deviceDesc = {}; in_deviceDesc.protocol = convertProtocolToXlink(_deviceProtocol); - in_deviceDesc.platform = convertPlatformToXlink(NC_ANY_PLATFORM); - int expectAvailableDevices = getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED); + int expectAvailableDevices = getAmountOfDevices(_deviceProtocol, X_LINK_UNBOOTED); XLinkError_t rc = X_LINK_ERROR; auto waittm = std::chrono::system_clock::now() + std::chrono::seconds(5); @@ -321,11 +313,11 @@ TEST_P(MvncOpenDevice, WatchdogShouldResetDeviceWithoutConnection) { std::this_thread::sleep_for(5_sec); ASSERT_EQ(expectAvailableDevices - 1, - getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED)); + getAmountOfDevices(_deviceProtocol, X_LINK_UNBOOTED)); std::this_thread::sleep_for(15_sec); ASSERT_EQ(expectAvailableDevices, - getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED)); + getAmountOfDevices(_deviceProtocol, X_LINK_UNBOOTED)); } //------------------------------------------------------------------------------ diff --git a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_usb.cpp b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_usb.cpp index 5e98b1a77e4..b30912bdabf 100644 --- a/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_usb.cpp +++ b/inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_usb.cpp @@ -24,7 +24,6 @@ TEST_F(MvncOpenUSBDevice, ShouldOpenDeviceAfterChangeConnectTimeoutFromZero) { std::string actDeviceName; ncDeviceDescr_t deviceDesc = {}; deviceDesc.protocol = NC_ANY_PROTOCOL; - deviceDesc.platform = NC_ANY_PLATFORM; ASSERT_NO_ERROR(ncSetDeviceConnectTimeout(0)); ASSERT_ERROR(ncDeviceOpen(&deviceHandle, deviceDesc, m_ncDeviceOpenParams)); @@ -175,19 +174,10 @@ TEST_F(MvncOpenUSBDevice, CheckErrorWhenPlatformConflictWithName) { if (availableDevices_ == 0) GTEST_SKIP(); - ncDevicePlatform_t wrongPlatform = NC_ANY_PLATFORM; auto availableDevices = getDevicesList(); ASSERT_TRUE(availableDevices.size()); - - if(isMyriadXUSBDevice(availableDevices[0])) { - wrongPlatform = NC_MYRIAD_2; - } else { - wrongPlatform = NC_MYRIAD_X; - } - strncpy(deviceDesc_.name, availableDevices[0].c_str(), NC_MAX_NAME_SIZE); - deviceDesc_.platform = wrongPlatform; ASSERT_ERROR(ncDeviceOpen(&deviceHandle_, deviceDesc_, m_ncDeviceOpenParams)); } @@ -236,7 +226,7 @@ TEST_P(MvncDevicePlatform, OpenAndClose) { unsigned int size = MAX_DEV_NAME; ASSERT_NO_ERROR(ncDeviceGetOption(deviceHandle_, NC_RO_DEVICE_NAME, deviceName, &size)); - EXPECT_TRUE(isSamePlatformUSBDevice(deviceName, devicePlatform_)); + EXPECT_TRUE(isSamePlatformUSBDevice(deviceName)); ASSERT_NO_ERROR(ncDeviceClose(&deviceHandle_, m_watchdogHndl)); diff --git a/inference-engine/tools/compile_tool/main.cpp b/inference-engine/tools/compile_tool/main.cpp index 056228fdd0c..68b1a1416a5 100644 --- a/inference-engine/tools/compile_tool/main.cpp +++ b/inference-engine/tools/compile_tool/main.cpp @@ -184,10 +184,6 @@ static std::map configure() { auto config = parseConfigFile(); if (isMYRIAD) { -IE_SUPPRESS_DEPRECATED_START - config[VPU_MYRIAD_CONFIG_KEY(PLATFORM)] = "VPU_MYRIAD_2480"; -IE_SUPPRESS_DEPRECATED_END - if (!FLAGS_VPU_NUMBER_OF_SHAVES.empty()) { config[InferenceEngine::MYRIAD_NUMBER_OF_SHAVES] = FLAGS_VPU_NUMBER_OF_SHAVES; } diff --git a/model-optimizer/automation/package_BOM.txt b/model-optimizer/automation/package_BOM.txt index a7cedc9af26..7ab49918925 100644 --- a/model-optimizer/automation/package_BOM.txt +++ b/model-optimizer/automation/package_BOM.txt @@ -436,6 +436,7 @@ extensions/front/tf/GatherTree_ext.py extensions/front/tf/GNMT_DynamicSequenceLengths.py extensions/front/tf/identity_ext.py extensions/front/tf/identityN_to_identity.py +extensions/front/tf/if_ext.py extensions/front/tf/InterpolateTransposes.py extensions/front/tf/IteratorGetNext_ext.py extensions/front/tf/log_softmax_ext.py @@ -701,6 +702,7 @@ extensions/ops/GRU.py extensions/ops/GRUCell.py extensions/ops/hard_sigmoid.py extensions/ops/identity.py +extensions/ops/If.py extensions/ops/instance_normalization.py extensions/ops/interp.py extensions/ops/interpolate.py @@ -927,6 +929,7 @@ mo/front/tf/extractors/native_tf.py mo/front/tf/extractors/pack.py mo/front/tf/extractors/random_uniform.py mo/front/tf/extractors/strided_slice.py +mo/front/tf/extractors/subgraph_utils.py mo/front/tf/extractors/utils.py mo/front/tf/graph_utils.py mo/front/tf/loader.py @@ -1050,6 +1053,7 @@ mo/utils/ir_reader/extenders/experimental_extender.py mo/utils/ir_reader/extenders/ExtractImagePatches_extender.py mo/utils/ir_reader/extenders/fakequantize_extender.py mo/utils/ir_reader/extenders/GRUCell_extender.py +mo/utils/ir_reader/extenders/if_extender.py mo/utils/ir_reader/extenders/interpolate_extender.py mo/utils/ir_reader/extenders/loop_extender.py mo/utils/ir_reader/extenders/LSTMCell_extender.py diff --git a/model-optimizer/extensions/front/tf/if_ext.py b/model-optimizer/extensions/front/tf/if_ext.py new file mode 100644 index 00000000000..2389c1c19a3 --- /dev/null +++ b/model-optimizer/extensions/front/tf/if_ext.py @@ -0,0 +1,69 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +from extensions.ops.If import If +from extensions.ops.parameter import Parameter +from mo.front.common.register_custom_ops import check_for_duplicates +from mo.front.extractor import FrontExtractorOp, extract_node_attrs +from mo.front.tf.extractor import tf_op_extractor, tf_op_extractors +from mo.front.tf.extractors.subgraph_utils import update_body_graph, convert_graph_inputs_to_parameters, \ + get_graph_proto, create_internal_graph +from mo.graph.graph import Node, Graph + + +def extract_if(cls, if_node: Node): + If.update_node_stat(if_node, {}) + + # check that required body and condition functions exist in the graph library + main_graph = if_node.graph + then_graph_proto = get_graph_proto(main_graph, 'then_branch', if_node) + else_graph_proto = get_graph_proto(main_graph, 'else_branch', if_node) + + then_graph = create_internal_graph(main_graph) + if_node['then_graph'] = then_graph + + else_graph = create_internal_graph(main_graph) + if_node['else_graph'] = else_graph + + # create Parameter nodes for the then/else graphs + for input_index, (body_graph, body_graph_proto) in enumerate(zip((then_graph, else_graph), (then_graph_proto, + else_graph_proto))): + + body_parameters, body_parameter_names = convert_graph_inputs_to_parameters(body_graph, body_graph_proto) + + # update the If body graph with the body function graph + body_results = [] + update_body_graph(body_graph, body_graph_proto, body_parameter_names, body_results) + + body_graph.stage = 'front' + + # connect external input ports with body parameter nodes except input with condition + for idx in range(0, len(body_parameters)): + If.connect_body_input(if_node, not input_index, idx + 1, body_parameters[idx]) + + # connect body outputs with If operation output ports + for idx in range(len(body_results)): + If.connect_body_output(if_node, not input_index, idx, body_results[idx]) + + # run function to parse body nodes attributes similar to the main graph + extract_node_attrs(body_graph, lambda node: tf_op_extractor(node, check_for_duplicates(tf_op_extractors))) + + return cls.enabled + + +class IfExtractor(FrontExtractorOp): + op = 'If' + enabled = True + + @classmethod + def extract(cls, if_node: Node): + return extract_if(cls, if_node) + + +class StatelessIfExtractor(FrontExtractorOp): + op = 'StatelessIf' + enabled = True + + @classmethod + def extract(cls, if_node: Node): + return extract_if(cls, if_node) diff --git a/model-optimizer/extensions/front/tf/while_ext.py b/model-optimizer/extensions/front/tf/while_ext.py index 3887c5fe757..b9451cff1b5 100644 --- a/model-optimizer/extensions/front/tf/while_ext.py +++ b/model-optimizer/extensions/front/tf/while_ext.py @@ -1,68 +1,14 @@ # Copyright (C) 2018-2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -import copy - from extensions.ops.loop import Loop from extensions.ops.parameter import Parameter from mo.front.common.register_custom_ops import check_for_duplicates from mo.front.extractor import extract_node_attrs, FrontExtractorOp from mo.front.tf.extractor import tf_op_extractor, tf_op_extractors, create_tf_edge -from mo.front.tf.extractors.utils import tf_dtype_extractor +from mo.front.tf.extractors.subgraph_utils import update_body_graph, convert_graph_inputs_to_parameters, \ + get_graph_proto, create_internal_graph from mo.graph.graph import add_opoutput, Graph, Node -from mo.ops.op import PermuteAttrs - - -def update_body_graph(body_graph: Graph, subgraph_proto: dict, - body_parameter_names: list, body_results: list): - """ - Updates the loop body graph with a sub-graph (for body or condition functions) - :param body_graph: a loop body graph to be updated - :param subgraph_proto: a sub-graph in a protobuf format to be added into the loop body graph - :param body_parameter_names: a (unchanged) list of parameters in the loop body graph - :param body_results: a list of Result nodes that is extended with a list from a sub-graph - """ - # create a map from a node name in original model to a name in a loop body graph assuming - # that names in the original model are unique - # initially, the map contains names for parameters that are common for the body and condition graphs - map_original_name = {} - for idx, pb_node in enumerate(subgraph_proto['input_arg']): - map_original_name[pb_node.name] = body_parameter_names[idx] - - # walk through all nodes (non-parameter and non-result nodes) and add into the loop body graph - for pb_node in subgraph_proto['node_def']: - # create an NX node - id = body_graph.unique_id(pb_node.name) - map_original_name[pb_node.name] = id - body_graph.add_node(id, pb=pb_node, kind='op') - if hasattr(body_graph, 'op_names_statistic') and hasattr(pb_node, 'op'): - body_graph.op_names_statistic[pb_node.op] += 1 - - # add incoming edges based on data_nodes_map - for dst_port, inp in enumerate(pb_node.input): - orig_src_id = inp.split(":")[0] - - # TODO: avoid this temporal workaround for TF 2.4 or higher RNN layers: - # skip control flow dependency - if orig_src_id[0] == '^': - continue - - src_id = map_original_name[orig_src_id] - src_port = 0 if len(inp.split(":")) == 1 else int(inp.split(":")[-1]) - assert (body_graph.has_node(src_id)) - - body_graph.add_edges_from([create_tf_edge(src_id + ":" + str(src_port), id, dst_port)]) - - # create Result nodes in the loop body graph - for output in subgraph_proto['output_arg']: - output_name = subgraph_proto['ret'][output.name] - orig_src_id = output_name.split(":")[0] - src_id = map_original_name[orig_src_id] - src_port = 0 if len(output_name.split(":")) == 1\ - else int(output_name.split(":")[-1]) - assert body_graph.has_node(src_id), 'The body graph does not contain output with name "{}"'.format( - src_id) - body_results.append(Node(body_graph, add_opoutput(body_graph, src_id, src_port, False))) class WhileExtractor(FrontExtractorOp): @@ -77,49 +23,16 @@ class WhileExtractor(FrontExtractorOp): @classmethod def extract(cls, loop_node): Loop.update_node_stat(loop_node, {}) - loop_name = loop_node.soft_get('name', loop_node.id) # check that required body and condition functions exist in the graph library main_graph = loop_node.graph - body_graph_name = loop_node.pb.attr['body'].func.name - cond_graph_name = loop_node.pb.attr['cond'].func.name - assert 'library' in main_graph.graph, 'The graph does not contain a library that is required ' \ - 'by node with name "{}".'.format(loop_name) - library_graph = main_graph.graph['library'] + body_graph_proto = get_graph_proto(main_graph, 'body', loop_node) + cond_graph_proto = get_graph_proto(main_graph, 'cond', loop_node) - assert body_graph_name in library_graph, 'The library does not contain a function with name "{}" ' \ - 'that is required by node ' \ - 'with name "{}".'.format(body_graph_name, loop_name) - body_graph_proto = library_graph[body_graph_name] - - assert cond_graph_name in library_graph, 'The library does not contain a function with name "{}" ' \ - 'that is required by node ' \ - 'with name "{}".'.format(cond_graph_name, loop_name) - cond_graph_proto = library_graph[cond_graph_name] - - body_graph = Graph() - # fill the body graph - for attr_key in main_graph.graph.keys(): - if attr_key != 'library': - body_graph.graph[attr_key] = copy.deepcopy(main_graph.graph[attr_key]) - else: - # it is sufficient to have a link to the library - body_graph.graph['library'] = main_graph.graph['library'] + body_graph = create_internal_graph(main_graph) loop_node['body'] = body_graph - # create Parameter nodes for the body graph - body_parameters = [] - body_parameter_names = [] - for idx, pb_node in enumerate(body_graph_proto['input_arg']): - param_id = body_graph.unique_id(pb_node.name) - body_graph.add_node(param_id, name=param_id, kind='op', op='Parameter', pb=None, shape=None) - parameter_node = Node(body_graph, pb_node.name) - Parameter.update_node_stat(parameter_node, - {'data_type': tf_dtype_extractor(pb_node.type), - 'permute_attrs': PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])} - ) - body_parameters.append(parameter_node) - body_parameter_names.append(param_id) + body_parameters, body_parameter_names = convert_graph_inputs_to_parameters(body_graph, body_graph_proto) # update the loop body graph with the body function graph body_results = [] @@ -172,7 +85,7 @@ class WhileExtractor(FrontExtractorOp): Loop.add_back_edge(loop_node, body_parameters[idx], body_results[idx]) # connect body outputs with Loop operation output ports except the execution condition result - for idx in range(len(body_results)-1): + for idx in range(len(body_results) - 1): Loop.connect_body_output(loop_node, idx, body_results[idx]) # run function to parse body nodes attributes similar to the main graph diff --git a/model-optimizer/extensions/load/tf/loader.py b/model-optimizer/extensions/load/tf/loader.py index 6d5c8978861..ae0f79b178b 100644 --- a/model-optimizer/extensions/load/tf/loader.py +++ b/model-optimizer/extensions/load/tf/loader.py @@ -138,8 +138,8 @@ def graph_or_sub_graph_has_nhwc_ops(graph: Graph): NHWC_conv_detected = True break - # for the Loop node we need to check that the body does not contain marker ops as well - if node.op == 'Loop': - NHWC_conv_detected |= graph_or_sub_graph_has_nhwc_ops(node.body) - # TODO check for If op when it is implemented + if node.has('sub_graphs'): + for sub_graph_name in node['sub_graphs']: + NHWC_conv_detected |= graph_or_sub_graph_has_nhwc_ops(node.soft_get(sub_graph_name)) + return NHWC_conv_detected diff --git a/model-optimizer/extensions/ops/If.py b/model-optimizer/extensions/ops/If.py new file mode 100644 index 00000000000..7e930971277 --- /dev/null +++ b/model-optimizer/extensions/ops/If.py @@ -0,0 +1,328 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import logging as log +import numpy as np + +from mo.front.common.partial_infer.utils import int64_array +from mo.graph.graph import Node, Graph +from mo.middle.passes.infer import partial_infer +from mo.ops.op import Op + + +class If(Op): + """ + If operation is an operation which has an input with condition which defines what sub-graph "then" or "else" to be + executed. + """ + op = 'If' + enabled = False + + def __init__(self, graph: Graph, attrs: dict): + base_attrs = { + 'type': self.op, + 'op': self.op, + 'then_graph': None, # an Graph object with a "then" body sub-graph (condition is True) + 'else_graph': None, # an Graph object with a "else" body sub-graph (condition is False) + 'sub_graphs': ['then_graph', 'else_graph'], # built-in attribute with all sub-graphs + 'version': 'opset8', + 'infer': self.infer, + 'type_infer': self.type_infer, + } + base_attrs.update(attrs) + super().__init__(graph, base_attrs, attrs) + + def port_map_attrs(self): + return [ + 'external_port_id', + 'internal_layer_id' + ] + + @staticmethod + def connect_body_input(if_node: Node, condition: bool, if_input_port_idx: int, body_parameter: Node): + """ + Update the specified body parameter and connect it with If input + + :param if_node: the If node + :param condition: the boolean defining a condition (then/else) graph to add connect the body + :param if_input_port_idx: the input port index to connect + :param body_parameter: the body parameter node to connect + :return: None + """ + assert if_node.soft_get('op') == 'If' + assert body_parameter.soft_get('op') == 'Parameter' + sub_graph = if_node.then_graph if condition else if_node.else_graph + assert body_parameter.id in sub_graph + body_parameter['input_id'] = if_input_port_idx + + @staticmethod + def connect_body_output(if_node: Node, condition: bool, if_output_port_idx: int, internal_result: Node): + """ + Update the specified output port and connect it with If output + + :param if_node: the If node + :param condition: the boolean defining a condition (then/else) graph to add connect the body + :param if_output_port_idx: the output port index to connect + :param internal_result: the body Result node to connect + :return: None + """ + assert if_node.soft_get('op') == 'If' + assert internal_result.soft_get('op') == 'Result' + sub_graph = if_node.then_graph if condition else if_node.else_graph + assert internal_result.id in sub_graph + internal_result['output_id'] = if_output_port_idx + + @staticmethod + def update_body_parameters_type(if_node: Node, condition: bool): + """ + Update the data type for If body Parameter nodes based on data type of the outer graph nodes producing data + for them. + + :param if_node: The If node + :param condition: the boolean defining a condition (then/else) graph + :return: None + """ + assert if_node.soft_get('type') == 'If' + + subgraph = if_node.then_graph if condition else if_node.else_graph + for node in subgraph.get_op_nodes(): + if node.has('input_id'): + assert node.soft_get('type') == 'Parameter' + input_port_id = node['input_id'] + input_type = if_node.in_port(input_port_id).get_data_type() + node.data_type = input_type + log.debug('Updated data type for the body node with name "{}" with value {}' + .format(node.name, node.data_type)) + + @staticmethod + def update_body_parameters_shape(if_node: Node, condition: bool): + """ + Update shape for If body parameters. + + :param if_node: The If node + :param condition: the boolean defining a condition (then/else) graph to add connect the body + :return: None + """ + subgraph = if_node.then_graph if condition else if_node.else_graph + for node in subgraph.get_op_nodes(): + if node.has('input_id'): + assert node.soft_get('type') == 'Parameter' + input_port_id = node['input_id'] + input_shape = if_node.in_port(input_port_id).data.get_shape() + if node.soft_get('shape', None) is None: + node['shape'] = None + node.shape = input_shape.copy() + log.debug('Updated shape for the body node with name "{}" with value {}' + .format(node.soft_get('name', node.soft_get('id')), node.shape)) + + @staticmethod + def results_mapping_and_finding_fake_outputs(output_nodes_in_subgraph, branch_name, outputs_mapping): + """ + This method checked result nodes in subgraph and set map between output from If operation and internal subgraph + result. Also This method return True if internal graph has fake results. + + :param output_nodes_in_subgraph: Result node with attribute 'output_id' + :param branch_name: name of subgraph + :param outputs_mapping: map between If operation output ID and subgraph results + + :return: True if all results of subgraph are empty tensors + """ + graph_contain_fake_outputs = True + + for output_node in output_nodes_in_subgraph: + assert output_node.soft_get('type') == 'Result' + port_id = output_node['output_id'] + assert port_id in outputs_mapping.keys(), 'Incorrect mapping then_graph outputs with {0} outputs! ' \ + 'Can\'t find port with ID {1} in If operation.' \ + .format(output_node.name, port_id) + outputs_mapping[port_id][branch_name] = output_node + out_node_shape = output_node.in_port(0).data.get_shape() + graph_contain_fake_outputs = graph_contain_fake_outputs and np.any(out_node_shape == 0) + return graph_contain_fake_outputs + + @staticmethod + def update_if_output_ports_shape(if_node: Node): + """ + Update shape and values for If output ports. + + :param if_node: The If node to update output ports and shapes + :return: None + """ + + then_outputs = [node for node in if_node.then_graph.get_op_nodes() if node.has('output_id')] + else_outputs = [node for node in if_node.else_graph.get_op_nodes() if node.has('output_id')] + outputs_mapping = {} + outputs_number = len(if_node.out_ports()) + + if outputs_number == 0 and len(if_node.out_ports(control_flow=True)) != 0: + # Some models have if with control flow outputs. + # These shape inference for such ifs + # TODO: need to rethink and redo support for control flow edges in if operation + for node in if_node.out_nodes(control_flow=True).values(): + node.shape = int64_array([]) + return + + for port_id in if_node.out_ports().keys(): + outputs_mapping[port_id] = {} + + # variables then_contains_fake_outputs/else_contains_fake_outputs contains True value + # if all outputs from then_body/else_body have shape [0]. It means then_body/else_body does not return data + # and further shape_inference for this branch is not possible. + # TODO: exclude support fake_outputs from this code when we will support shape_inference with empty tensors + + then_contains_fake_outputs = \ + If.results_mapping_and_finding_fake_outputs(then_outputs, 'then_graph', outputs_mapping) + else_contains_fake_outputs = \ + If.results_mapping_and_finding_fake_outputs(else_outputs, 'else_graph', outputs_mapping) + + # use_then_shape is True when else_body or when both bodies do not return data. If use_then_shape is True If's + # outputs will have the same shapes as then_body results + use_then_shape = else_contains_fake_outputs or not then_contains_fake_outputs + + for port_id in outputs_mapping: + then_else_nodes = outputs_mapping[port_id] + assert 'then_graph' in then_else_nodes.keys(), 'then_graph does not connect with If.out_port[{0}] ' \ + 'in {1} node!'.format(port_id, if_node.name) + assert 'else_graph' in then_else_nodes.keys(), 'else_graph does not connect with If.out_port[{0}] ' \ + 'in {1} node!'.format(port_id, if_node.name) + + then_shape = then_else_nodes['then_graph'].in_port(0).data.get_shape() + else_shape = then_else_nodes['else_graph'].in_port(0).data.get_shape() + + if not (then_shape == else_shape).all(): + log.debug("If node {0} has dynamic output [{1}] because output shape from then_graph is {2} and " + "else_graph {3}".format(if_node.name, port_id, then_shape, else_shape)) + if_node.out_port(port_id).data.set_shape(then_shape if use_then_shape else else_shape) + + @staticmethod + def update_if_output_ports_type(if_node: Node): + """ + Update types for If output ports. + + :param if_node: The If node to update output ports and types + :return: None + """ + then_outputs = [node for node in if_node.then_graph.get_op_nodes() if node.has('output_id')] + else_outputs = [node for node in if_node.else_graph.get_op_nodes() if node.has('output_id')] + outputs_mapping = {} + outputs_number = len(if_node.out_ports()) + assert outputs_number == len(then_outputs), 'Incorrect number outputs in then_graph of If with"' \ + 'name {0}! then_graph must has {1} outputs' \ + .format(if_node.name, outputs_number) + assert outputs_number == len(else_outputs), 'Incorrect number outputs in else_graph of If with"' \ + 'name {0}! else_graph must has {1} outputs' \ + .format(if_node.name, outputs_number) + for port_id in if_node.out_ports().keys(): + outputs_mapping[port_id] = {} + port_ids = outputs_mapping.keys() + for then_output_node in then_outputs: + assert then_output_node.soft_get('type') == 'Result' + port_id = then_output_node['output_id'] + assert port_id in port_ids, 'Incorrect mapping then_graph outputs with {0} outputs! ' \ + 'Can\'t find port with ID {1} in If operation.' \ + .format(then_output_node.name, port_id) + outputs_mapping[port_id]['then_graph'] = then_output_node + + for else_output_node in else_outputs: + assert else_output_node.soft_get('type') == 'Result' + port_id = else_output_node['output_id'] + assert port_id in port_ids, 'Incorrect mapping then_graph outputs with {0} outputs! ' \ + 'Can\'t find port with ID {1} in If operation.' \ + .format(else_output_node.name, port_id) + outputs_mapping[port_id]['else_graph'] = else_output_node + + for port_id in outputs_mapping: + then_else_nodes = outputs_mapping[port_id] + assert 'then_graph' in then_else_nodes.keys(), 'then_graph does not connect with If.out_port[{0}] ' \ + 'in {1} node!'.format(port_id, if_node.name) + assert 'else_graph' in then_else_nodes.keys(), 'else_graph does not connect with If.out_port[{0}] ' \ + 'in {1} node!'.format(port_id, if_node.name) + then_type = then_else_nodes['then_graph'].in_port(0).get_data_type() + else_type = then_else_nodes['else_graph'].in_port(0).get_data_type() + assert then_type == else_type, 'Cannot get type for if.out_port[{0}]! ' \ + 'Types in then_graph and else_graph are not equal!'.format(port_id) + if_node.out_port(port_id).set_data_type(then_type) + + @staticmethod + def re_numerate_internal_id_and_get_if_id(if_node): + """ + This method is called before IR generation. This method sets internal_layer_id. + + :param if_node: The If node where is necessary to set internal_layer_id in bodies. + :return: if_node + """ + then_graph_nodes = if_node.then_graph.nodes() + for idx in range(len(if_node.then_graph.get_op_nodes())): + then_graph_nodes[idx]['internal_layer_id'] = idx + else_graph_nodes = if_node.else_graph.nodes() + for idx in range(len(if_node.else_graph.get_op_nodes())): + else_graph_nodes[idx]['internal_layer_id'] = idx + return if_node.node + + def substitute_ie_attrs(self, new_attrs: dict): + """ + Replace standard list of attribute in layer/data by attributes + delivered by backend_attrs + """ + + port_map_attrs = self.port_map_attrs() + new_attrs.update({ + 'IE': [( + 'layer', + [('id', lambda node: self.re_numerate_internal_id_and_get_if_id(node)), 'name', 'type', 'version'], + [ + '@ports', + ('then_port_map', [], [ + ('@list', lambda node: self.generate_port_map(node, True, 'in'), + ('input', port_map_attrs, [])), + ('@list', lambda node: self.generate_port_map(node, True, 'out'), + ('output', port_map_attrs, [])), + ]), + ('else_port_map', [], [ + ('@list', lambda node: self.generate_port_map(node, False, 'in'), + ('input', port_map_attrs, [])), + ('@list', lambda node: self.generate_port_map(node, False, 'out'), + ('output', port_map_attrs, [])), + ]), + ('then_body', [], [('@network', 'then_graph')]), + ('else_body', [], [('@network', 'else_graph')]), + ])] + }) + + @staticmethod + def generate_port_map(if_node: Node, condition: bool, dir: str): + """ + Extract port_map attributes from if_node and its subgraphs attributes. + + :param if_node: The If node + :param condition: the boolean defining a condition (then/else) graph + :param dir: the str value defining type (for inputs or for putputs) of port_map + :return: port_map -> list of dictionaries with to values(external_port_id or internal_layer_id) + """ + port_map = [] + subgraph = if_node.then_graph if condition else if_node.else_graph + name_of_connection = 'input_id' if dir == 'in' else 'output_id' + + for internal_node in subgraph.get_op_nodes(): + if internal_node.has(name_of_connection): + port_map.append({'external_port_id': internal_node[name_of_connection], + 'internal_layer_id': internal_node['internal_layer_id']}) + + return port_map + + @staticmethod + def infer(if_node: Node): + If.update_body_parameters_shape(if_node, True) + If.update_body_parameters_shape(if_node, False) + partial_infer(if_node.then_graph) + partial_infer(if_node.else_graph) + If.update_if_output_ports_shape(if_node) + + @staticmethod + def type_infer(if_node: Node): + from mo.middle.passes.infer import type_infer + If.update_body_parameters_type(if_node, True) + If.update_body_parameters_type(if_node, False) + type_infer(if_node.then_graph) + type_infer(if_node.else_graph) + If.update_if_output_ports_type(if_node) diff --git a/model-optimizer/extensions/ops/gather.py b/model-optimizer/extensions/ops/gather.py index e5ca196fca7..30b45735965 100644 --- a/model-optimizer/extensions/ops/gather.py +++ b/model-optimizer/extensions/ops/gather.py @@ -18,7 +18,7 @@ class Gather(Op): super().__init__(graph, { 'op': self.op, 'type': self.op, - 'version': 'opset7', + 'version': 'opset8', 'batch_dims': 0, 'infer': self.infer, 'force_precision_in_ports': {1: 'int32', 2: 'int64'}, @@ -31,7 +31,7 @@ class Gather(Op): def backend_attrs(self): version = self.get_opset() - if version == 'opset7': + if version in ['opset7', 'opset8']: return ['batch_dims'] elif version == 'opset1': return [] @@ -75,7 +75,7 @@ class Gather(Op): # we import PermuteInputs locally because it uses Gather inside and we have recursive imports from mo.graph.perm_inputs import PermuteInputs - PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis') + PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'axis') batch_dims_range = indices_shape[:batch_dims] out_shape = np.concatenate((data_shape[:axis], indices_shape[batch_dims:], data_shape[axis + 1:])) diff --git a/model-optimizer/mo/front/tf/extractors/subgraph_utils.py b/model-optimizer/mo/front/tf/extractors/subgraph_utils.py new file mode 100644 index 00000000000..ac7479cd9eb --- /dev/null +++ b/model-optimizer/mo/front/tf/extractors/subgraph_utils.py @@ -0,0 +1,108 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import copy + +from extensions.ops.parameter import Parameter +from mo.front.tf.extractor import tf_op_extractor, tf_op_extractors, create_tf_edge +from mo.front.tf.extractors.utils import tf_dtype_extractor +from mo.graph.graph import Graph, Node, add_opoutput +from mo.ops.op import PermuteAttrs + + +def update_body_graph(body_graph: Graph, subgraph_proto: dict, + body_parameter_names: list, body_results: list): + """ + Updates the loop body graph with a sub-graph (for body or condition functions) + :param body_graph: a loop body graph to be updated + :param subgraph_proto: a sub-graph in a protobuf format to be added into the loop body graph + :param body_parameter_names: a (unchanged) list of parameters in the loop body graph + :param body_results: a list of Result nodes that is extended with a list from a sub-graph + """ + # create a map from a node name in original model to a name in a loop body graph assuming + # that names in the original model are unique + # initially, the map contains names for parameters that are common for the body and condition graphs + map_original_name = {} + for idx, pb_node in enumerate(subgraph_proto['input_arg']): + map_original_name[pb_node.name] = body_parameter_names[idx] + + # walk through all nodes (non-parameter and non-result nodes) and add into the loop body graph + for pb_node in subgraph_proto['node_def']: + # create an NX node + id = body_graph.unique_id(pb_node.name) + map_original_name[pb_node.name] = id + body_graph.add_node(id, pb=pb_node, kind='op') + if hasattr(body_graph, 'op_names_statistic') and hasattr(pb_node, 'op'): + body_graph.op_names_statistic[pb_node.op] += 1 + + # add incoming edges based on data_nodes_map + for dst_port, inp in enumerate(pb_node.input): + orig_src_id = inp.split(":")[0] + + # TODO: avoid this temporal workaround for TF 2.4 or higher RNN layers: + # skip control flow dependency + if orig_src_id[0] == '^': + continue + + src_id = map_original_name[orig_src_id] + src_port = 0 if len(inp.split(":")) == 1 else int(inp.split(":")[-1]) + assert (body_graph.has_node(src_id)) + + body_graph.add_edges_from([create_tf_edge(src_id + ":" + str(src_port), id, dst_port)]) + + # create Result nodes in the loop body graph + for output in subgraph_proto['output_arg']: + output_name = subgraph_proto['ret'][output.name] + orig_src_id = output_name.split(":")[0] + src_id = map_original_name[orig_src_id] + src_port = 0 if len(output_name.split(":")) == 1 \ + else int(output_name.split(":")[-1]) + assert body_graph.has_node(src_id), 'The body graph does not contain output with name "{}"'.format( + src_id) + body_results.append(Node(body_graph, add_opoutput(body_graph, src_id, src_port, False))) + + return True + + +def get_graph_proto(external_graph: Graph, graph_id: str, node_with_graph: Node): + graph_name = node_with_graph.pb.attr[graph_id].func.name + node_name = node_with_graph.soft_get('name', node_with_graph.id) + + assert 'library' in external_graph.graph, 'The graph does not contain a library that is required ' \ + 'by node with name "{}".'.format(node_name) + + library_graph = external_graph.graph['library'] + + assert graph_name in library_graph, 'The library does not contain a function with name "{}" ' \ + 'that is required by node ' \ + 'with name "{}".'.format(graph_name, node_name) + return library_graph[graph_name] + + +def create_internal_graph(external_graph: Graph): + internal_graph = Graph() + # fill the body graph + for attr_key in external_graph.graph.keys(): + if attr_key != 'library': + internal_graph.graph[attr_key] = copy.deepcopy(external_graph.graph[attr_key]) + else: + # it is sufficient to have a link to the library + internal_graph.graph['library'] = external_graph.graph['library'] + return internal_graph + + +def convert_graph_inputs_to_parameters(internal_graph, internal_graph_proto): + # create Parameter nodes for the body graph + body_parameters = [] + body_parameter_names = [] + for idx, pb_node in enumerate(internal_graph_proto['input_arg']): + param_id = internal_graph.unique_id(pb_node.name) + internal_graph.add_node(param_id, name=param_id, kind='op', op='Parameter', pb=None, shape=None) + parameter_node = Node(internal_graph, pb_node.name) + Parameter.update_node_stat(parameter_node, + {'data_type': tf_dtype_extractor(pb_node.type), + 'permute_attrs': PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])} + ) + body_parameters.append(parameter_node) + body_parameter_names.append(param_id) + return body_parameters, body_parameter_names diff --git a/model-optimizer/mo/pipeline/common.py b/model-optimizer/mo/pipeline/common.py index cd86ef26851..3d3264c67a8 100644 --- a/model-optimizer/mo/pipeline/common.py +++ b/model-optimizer/mo/pipeline/common.py @@ -194,7 +194,8 @@ def prepare_emit_ir(graph: Graph, data_type: str, output_dir: str, output_model_ # do not run the type inference in sub-graphs. It will be called automatically as part of the type inference of # the TensorIterator nodes type_infer(graph) - RemoveUselessConvert().find_and_replace_pattern(graph) + + for_graph_and_each_sub_graph_recursively(graph, RemoveUselessConvert().find_and_replace_pattern) ResultRename().find_and_replace_pattern(graph) diff --git a/model-optimizer/mo/utils/ir_engine/compare_graphs.py b/model-optimizer/mo/utils/ir_engine/compare_graphs.py index 11c5312be4a..ecaaad4b3ea 100644 --- a/model-optimizer/mo/utils/ir_engine/compare_graphs.py +++ b/model-optimizer/mo/utils/ir_engine/compare_graphs.py @@ -66,7 +66,7 @@ def compare_graphs(graph: Graph, graph_ref: Graph, last_node: str, last_node_ref ref_node_type = node_ref.type if node_ref.has_valid("type") else None for attr in graph_ref.node[node_ref.id]: if graph_ref.node[node_ref.id][attr] is None or attr in ['name', 'id', '_in_ports', '_out_ports', - 'infer', 'IE', 'biases', 'weights', 'custom', 'offset']: + 'infer', 'IE', 'biases', 'weights', 'custom', 'offset', 'ir_data_attrs']: continue if attr not in graph.node[node.id]: stderr.append('Current node "{}" with type {} has missing attribute {}'.format(node.id, cur_node_type, attr)) diff --git a/model-optimizer/mo/utils/ir_engine/ir_engine.py b/model-optimizer/mo/utils/ir_engine/ir_engine.py index 35d95486c5f..3d534017828 100644 --- a/model-optimizer/mo/utils/ir_engine/ir_engine.py +++ b/model-optimizer/mo/utils/ir_engine/ir_engine.py @@ -208,6 +208,7 @@ class IREngine(object): for attr in layer: if attr.tag == 'data': new_attrs = self.__normalize_attrs(attr.attrib) + new_attrs['ir_data_attrs'] = attr.attrib if layer.attrib['type'] == 'Const': assert 'offset' in new_attrs and 'size' in new_attrs, \ 'Incorrect attributes for Const layer, {} instead of {}!'.format(new_attrs.keys(), ['offset', 'size']) @@ -239,34 +240,8 @@ class IREngine(object): xml_body_child = list(layer.iterfind('body')) assert len(xml_body_child) == 1 - body_ir = IREngine(path_to_xml=None, - path_to_bin=self.path_to_bin, - xml_tree=ElementTree(xml_body_child[0])) - self.graph.graph['hashes'].update(body_ir.graph.graph['hashes']) - - # Find port_map section and take an input_port_map & output_port_map - xml_port_map = list(layer.iterfind('port_map')) - if not len(xml_port_map) == 1: - log.warning("TensorIterator body won\'t be compared due to missing port_map section!") - continue - xml_port_map = xml_port_map[0] - - input_layers = [] - input_port_map = [] - output_port_map = [] - - for port in xml_port_map: - if port.tag == 'input': - if 'internal_layer_id' not in port.attrib: - log.warning("internal_layer_id attrib not found in input section") - else: - input_layers.append(Node(body_ir.graph, port.attrib['internal_layer_id'])) - input_port_map.append(self.__normalize_attrs(port.attrib)) - elif port.tag == 'output': - if 'internal_layer_id' not in port.attrib: - log.warning("internal_layer_id attrib not found in output section") - else: - output_port_map.append(self.__normalize_attrs(port.attrib)) + body_ir, input_port_map, output_port_map, input_layers = \ + self.__read_subgraph(layer, layer_attrs, xml_body_child, 'port_map') body_ir.input_node = input_layers[0] layer_attrs.update({'body': body_ir}) @@ -286,6 +261,12 @@ class IREngine(object): layer_attrs.update({'back_edges': back_edges}) + elif attr.tag == 'then_body' or attr.tag == 'else_body': + assert layer.attrib['type'] == 'If', "Incorrect IR! The operation {0}" \ + " has sub-graphs for If operation" + layer_attrs = self.__read_if(layer, layer_attrs) + continue + return layer_id, layer_attrs @staticmethod @@ -404,3 +385,54 @@ class IREngine(object): if not isinstance(other, IREngine): raise AttributeError("IREngine can be compared only with IREngine object type") return self.compare(other)[0] + + def __read_subgraph(self, layer, layer_attrs, body_child, port_map_name): + body_ir = IREngine(path_to_xml=None, + path_to_bin=self.path_to_bin, + xml_tree=ElementTree(body_child[0])) + + self.graph.graph['hashes'].update(body_ir.graph.graph['hashes']) + + xml_port_map = list(layer.iterfind(port_map_name)) + assert not len(xml_port_map) != 1, "If then_body won\'t be compared due to missing {1} section in node {0}! " \ + .format(layer_attrs['name'], port_map_name) + xml_port_map = xml_port_map[0] + + input_layers = [] + input_port_map = [] + output_port_map = [] + + for port in xml_port_map: + if port.tag == 'input': + if 'internal_layer_id' not in port.attrib: + log.warning("internal_layer_id attrib not found in input section") + else: + input_layers.append(Node(body_ir.graph, port.attrib['internal_layer_id'])) + input_port_map.append(self.__normalize_attrs(port.attrib)) + elif port.tag == 'output': + if 'internal_layer_id' not in port.attrib: + log.warning("internal_layer_id attrib not found in output section") + else: + output_port_map.append(self.__normalize_attrs(port.attrib)) + + return body_ir, input_port_map, output_port_map, input_layers + + def __read_if(self, layer, layer_attrs): + + xml_then_body_child = list(layer.iterfind('then_body')) + xml_else_body_child = list(layer.iterfind('else_body')) + assert len(xml_then_body_child) == 1 and len(xml_else_body_child) == 1, "If operation has only one subgraph" + + then_body_ir, then_input_port_map, then_output_port_map, _ = \ + self.__read_subgraph(layer, layer_attrs, xml_then_body_child, 'then_port_map') + layer_attrs.update({'then_graph': then_body_ir}) + layer_attrs.update({'then_input_port_map': then_input_port_map}) + layer_attrs.update({'then_output_port_map': then_output_port_map}) + + else_body_ir, else_input_port_map, else_output_port_map, _ = \ + self.__read_subgraph(layer, layer_attrs, xml_else_body_child, 'else_port_map') + layer_attrs.update({'else_graph': else_body_ir}) + layer_attrs.update({'else_input_port_map': else_input_port_map}) + layer_attrs.update({'else_output_port_map': else_output_port_map}) + + return layer_attrs diff --git a/model-optimizer/mo/utils/ir_reader/extender.py b/model-optimizer/mo/utils/ir_reader/extender.py index 5dc617f2629..13bc5dddaed 100644 --- a/model-optimizer/mo/utils/ir_reader/extender.py +++ b/model-optimizer/mo/utils/ir_reader/extender.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import logging as log +import numpy as np from mo.front.common.partial_infer.utils import int64_array from mo.utils import class_registration @@ -35,8 +36,29 @@ class Extender(object): node[attribute] = [node[attribute]] @staticmethod - def const_shape_infer(node: Node): - i = len(node.in_nodes()) - for num in node.out_nodes(): - node.out_node(num).shape = int64_array(node.ports[i][0]) + def use_shapes_from_ir(node: Node): + # This function used instead of operation shape inference function to set all output shapes the same as + # restored from IR. Firstly, check equality of old (restored from IR) and + # new (calculated while shape inference) input shapes + node['new_input_shapes'] = list() + for n in node.in_ports(): + if not node.in_port(n).disconnected(): # We use such condition to handle optional inputs + node.new_input_shapes.append(node.in_port(n).data.get_shape()) + assert len(node.new_input_shapes) == len(node.old_input_shapes), \ + 'Something wrong happened while {} node with type {} copy shape inference!'.format(node.name, node.type) + for new_input_shape, old_input_shape in zip(node.new_input_shapes, node.old_input_shapes): + assert np.array_equal(new_input_shape, old_input_shape), \ + 'Something wrong happened while {} node with type {} copy shape inference!'.format(node.name, node.type) + + # We need to use number of connected input ports to avoid errors with numbering + # in node.ports dictionary, where used numbers of input nodes + connected_input_ports = [] + for n in node.in_ports(): + if not node.in_port(n).disconnected(): + connected_input_ports.append(node.in_port(n)) + i = len(connected_input_ports) + + # Set all output shapes the same as restored from IR + for num in node.out_ports(): + node.out_port(num).data.set_shape(int64_array(node.ports[i][0])) i += 1 diff --git a/model-optimizer/mo/utils/ir_reader/extenders/LSTMCell_extender.py b/model-optimizer/mo/utils/ir_reader/extenders/LSTMCell_extender.py index 0810207c86f..0ea1cd24796 100644 --- a/model-optimizer/mo/utils/ir_reader/extenders/LSTMCell_extender.py +++ b/model-optimizer/mo/utils/ir_reader/extenders/LSTMCell_extender.py @@ -12,4 +12,4 @@ class LSTMCell_extender(Extender): def extend(op: Node): if not op.has_valid('activations'): op['activations'] = None - op['infer'] = Extender.const_shape_infer + op['infer'] = Extender.use_shapes_from_ir diff --git a/model-optimizer/mo/utils/ir_reader/extenders/deconvolution_extender.py b/model-optimizer/mo/utils/ir_reader/extenders/deconvolution_extender.py index e291afafe1a..fea1f11d0e6 100644 --- a/model-optimizer/mo/utils/ir_reader/extenders/deconvolution_extender.py +++ b/model-optimizer/mo/utils/ir_reader/extenders/deconvolution_extender.py @@ -50,13 +50,4 @@ def common_backpropdata_extender(op: Node): def backpropdata_infer(op: Node): - op['new_input_shapes'] = list() - for n in op.in_nodes(): - op.new_input_shapes.append(op.in_node(n).shape) - assert len(op.new_input_shapes) == len(op.old_input_shapes) - - for i in range(len(op.new_input_shapes)): - assert np.array_equal(op.new_input_shapes[i], op.old_input_shapes[i]), 'Something wrong happened while ' \ - '{} shape infer with type {}!'.format(op.name, op.type) - - Extender.const_shape_infer(op) + Extender.use_shapes_from_ir(op) diff --git a/model-optimizer/mo/utils/ir_reader/extenders/if_extender.py b/model-optimizer/mo/utils/ir_reader/extenders/if_extender.py new file mode 100644 index 00000000000..8165c40015c --- /dev/null +++ b/model-optimizer/mo/utils/ir_reader/extenders/if_extender.py @@ -0,0 +1,41 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +from mo.utils.graph import Node +from mo.utils.ir_reader.extender import Extender +from mo.utils.ir_reader.layer_to_class import copy_graph_with_ops + + +class IfExtender(Extender): + op = 'If' + + @staticmethod + def set_input_output_id(subgraph, input_port_map, output_port_map): + for node in subgraph.get_op_nodes(): + if not node.has_valid('id'): + continue + node_id = int(node.soft_get('id')) + for if_input_mapping_elem in input_port_map: + if node_id == if_input_mapping_elem['internal_layer_id']: + node['input_id'] = if_input_mapping_elem['external_port_id'] + for if_out_mapping_elem in output_port_map: + if node_id == if_out_mapping_elem['internal_layer_id']: + node['output_id'] = if_out_mapping_elem['external_port_id'] + + @staticmethod + def extend(op: Node): + assert op.has('then_graph'), 'There is no "then_body" attribute in the If op {}.'.format(op.name) + assert op.has('else_graph'), 'There is no "else_body" attribute in the If op {}.'.format(op.name) + # Now op.body is an IREngine, we need to replace it with IREngine.graph + op.then_graph.graph.graph['cmd_params'] = op.graph.graph['cmd_params'] + op.then_graph.graph.graph['ir_version'] = op.graph.graph['ir_version'] + op.then_graph.graph.name = op.name + '/then_body' + + op.else_graph.graph.graph['cmd_params'] = op.graph.graph['cmd_params'] + op.else_graph.graph.graph['ir_version'] = op.graph.graph['ir_version'] + op.else_graph.graph.name = op.name + '/else_body' + op.then_graph = copy_graph_with_ops(op.then_graph.graph) + op.else_graph = copy_graph_with_ops(op.else_graph.graph) + + IfExtender.set_input_output_id(op.then_graph, op.then_input_port_map, op.then_output_port_map) + IfExtender.set_input_output_id(op.else_graph, op.else_input_port_map, op.else_output_port_map) diff --git a/model-optimizer/mo/utils/ir_reader/extenders/tensoriterator_extender.py b/model-optimizer/mo/utils/ir_reader/extenders/tensoriterator_extender.py index 6a65d5eef93..151b7bdf8f3 100644 --- a/model-optimizer/mo/utils/ir_reader/extenders/tensoriterator_extender.py +++ b/model-optimizer/mo/utils/ir_reader/extenders/tensoriterator_extender.py @@ -40,4 +40,4 @@ class TensorIterator_extender(Extender): del(edge['from-layer']) del(edge['to-layer']) - op['infer'] = Extender.const_shape_infer + op['infer'] = Extender.use_shapes_from_ir diff --git a/model-optimizer/mo/utils/ir_reader/layer_to_class.py b/model-optimizer/mo/utils/ir_reader/layer_to_class.py index f9f5fd9fb1d..a3800cb2347 100644 --- a/model-optimizer/mo/utils/ir_reader/layer_to_class.py +++ b/model-optimizer/mo/utils/ir_reader/layer_to_class.py @@ -185,15 +185,17 @@ def groupconv_to_conv(op: Node): if weights_node.type == 'Const': weights_node.value = np.reshape(weights_node.value, new_shape) elif weights_node.type == 'Reshape': - # we remove reshape node added in ConvolutionWithGroupsResolver pass + # We remove reshape node added in ConvolutionWithGroupsResolver pass assert weights_node.in_port(0).get_source().data.get_shape() == new_shape, \ 'Weight shape and calculated shape mismatch in GroupConv node {}.'.format(op.name) op.in_port(1).disconnect() - weights_node.in_port(0).get_source().get_connection().set_destination(op.in_port(1)) + # We use add_destination method here to support case with multiple destinations of source port + weights_node.in_port(0).get_source().get_connection().add_destination(op.in_port(1)) + weights_node.in_port(0).disconnect() else: assert op.in_port(1).get_source().data.get_shape() == new_shape, \ 'Weight shape and calculated shape mismatch in GroupConv node {}.'.format(op.name) - # we need to set this attrs for correct shape infer as convolution + # We need to set this attrs for correct shape infer as convolution op['group'] = group # The only way GroupConvolution with 'group' = 1 appears in IR is by converting from TF DepthwiseConv2dNative. # In this case we need to specify 'op' parameter for the @@ -218,9 +220,6 @@ def backprop_to_deconv(op: Node): if op.has_valid('output_padding'): # In this case we need to create Deconvolution as Convolution op['type_to_create'] = 'Convolution' - op['old_input_shapes'] = list() - for n in op.in_nodes(): - op.old_input_shapes.append(int64_array(op.in_node(n).shape)) def ti_add_edge_attrs(op: Node): @@ -344,6 +343,11 @@ def copy_graph_with_ops(graph: Graph) -> Graph: # Create a new copy of graph with correct attributes (shape & type infer, backend attrs etc.) for op in graph.get_op_nodes(): + # Save input shapes restored from IR + op['old_input_shapes'] = list() + for n in op.in_nodes(): + op.old_input_shapes.append(int64_array(op.in_node(n).shape)) + # Apply extenders to nodes in source graph if op.type in Extender.registered_ops: Extender.get_extender_class_by_name(op.type).extend(op) @@ -356,9 +360,26 @@ def copy_graph_with_ops(graph: Graph) -> Graph: if op_type in custom_ops: node = custom_ops[op_type](new_graph, op.attrs()).create_node() else: - assert op_type in Op.registered_ops, 'Operation {} not found in MO operations, ' \ - 'please check it!'.format(op_type) - node = Op.get_op_class_by_name(op_type)(new_graph, op.attrs()).create_node() + if op_type not in Op.registered_ops: + log.warning('Operation {} is not found in MO operations, please check it! ' + 'Simple shape infer function is used'.format(op_type)) + node = Op(new_graph, op.attrs()).create_node() + node['infer'] = Extender.use_shapes_from_ir + if 'ir_data_attrs' in op: + node['IE'] = [('layer', + [('id', lambda node: node.node), 'name', 'type', 'version'], + [('data', + list(op.ir_data_attrs.keys()), + []), + '@ports', + '@consts'])] + + else: + node = Op.get_op_class_by_name(op_type)(new_graph, op.attrs()).create_node() + + # This attribute is no longer needed and we can delete it + if 'ir_data_attrs' in node: + del node['ir_data_attrs'] if op.has_and_set('need_copy_input_blobs'): copy_input_blobs(op, node) diff --git a/model-optimizer/mo/utils/versions_checker.py b/model-optimizer/mo/utils/versions_checker.py index b9495f35041..f384f77e865 100644 --- a/model-optimizer/mo/utils/versions_checker.py +++ b/model-optimizer/mo/utils/versions_checker.py @@ -30,6 +30,26 @@ def check_python_version(): return 1 +def get_imported_module_version(imported_module): + """ + Get imported module version + :return: version(str) or raise AttributeError exception + """ + version_attrs = ("__version__", "VERSION", "version") + installed_version = None + for attr in version_attrs: + installed_version = getattr(imported_module, attr, None) + if isinstance(installed_version, str): + return installed_version + else: + installed_version = None + + if installed_version is None: + raise AttributeError("{} module doesn't have version attribute".format(imported_module)) + else: + return installed_version + + def parse_and_filter_versions_list(required_fw_versions, version_list, env_setup): """ Please do not add parameter type annotations (param:type). @@ -210,7 +230,7 @@ def get_environment_setup(framework): try: if framework == 'tf': exec("import tensorflow") - env_setup['tensorflow'] = sys.modules["tensorflow"].__version__ + env_setup['tensorflow'] = get_imported_module_version(sys.modules["tensorflow"]) exec("del tensorflow") except (AttributeError, ImportError): pass @@ -250,7 +270,7 @@ def check_requirements(framework=None): try: importable_name = modules.get(name, name) exec("import {}".format(importable_name)) - installed_version = sys.modules[importable_name].__version__ + installed_version = get_imported_module_version(sys.modules[importable_name]) version_check(name, installed_version, required_version, key, not_satisfied_versions) exec("del {}".format(importable_name)) except (AttributeError, ImportError): diff --git a/model-optimizer/unit_tests/extensions/load/tf/loader_test.py b/model-optimizer/unit_tests/extensions/load/tf/loader_test.py index b84da4f98b4..7b02dfe7556 100644 --- a/model-optimizer/unit_tests/extensions/load/tf/loader_test.py +++ b/model-optimizer/unit_tests/extensions/load/tf/loader_test.py @@ -44,7 +44,7 @@ class TFLoaderTest(unittest.TestCase): # create fake Loop operation nodes = { **regular_op('input', {'op': 'Parameter'}), - **regular_op('loop', {'op': 'Loop', 'body': body_graph}), + **regular_op('loop', {'op': 'Loop', 'body': body_graph, 'sub_graphs': ['body']}), **result('result'), } edges = [*connect_front('input', '0:loop'), @@ -65,4 +65,3 @@ class TFLoaderTest(unittest.TestCase): def test_no_convolution_main_and_sub_graph(self): self.assertFalse(graph_or_sub_graph_has_nhwc_ops(self.build_loop_graph(self.build_parameter_result_graph()))) - diff --git a/model-optimizer/unit_tests/extensions/ops/If_test.py b/model-optimizer/unit_tests/extensions/ops/If_test.py new file mode 100644 index 00000000000..5e757f5c9c1 --- /dev/null +++ b/model-optimizer/unit_tests/extensions/ops/If_test.py @@ -0,0 +1,127 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import numpy as np +import numpy.testing as npt +import unittest + +from extensions.ops.If import If +from mo.ops.shape import Shape +from extensions.ops.elementwise import Add, Mul +from extensions.ops.identity import Identity +from extensions.ops.parameter import Parameter +from mo.front.common.partial_infer.concat import concat_infer +from mo.front.common.partial_infer.utils import int64_array +from mo.graph.graph import Node, Graph +from mo.middle.passes.infer import partial_infer +from mo.ops.concat import Concat +from mo.ops.eltwise import eltwise_infer +from mo.ops.result import Result +from unit_tests.utils.graph import build_graph_with_edge_attrs, build_graph +from unit_tests.utils.graph import regular_op_with_empty_data, connect, const, result, valued_const_with_data, \ + regular_op, empty_data + + +class TestIf(unittest.TestCase): + def test_simple_shape_inf(self): + then_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1, + 'shape': None, 'infer': Parameter.infer}), + **regular_op_with_empty_data('param_2', {'type': 'Parameter', 'kind': 'op', 'input_id': 2, + 'shape': None, 'infer': Parameter.infer}), + **regular_op_with_empty_data('add', {'type': 'Add', 'kind': 'op', 'op': 'Add', + 'infer': lambda node: eltwise_infer(node, + Add.operation)}), + **regular_op_with_empty_data('mul', {'type': 'Mul', 'kind': 'op', 'op': 'Mul', + 'infer': lambda node: eltwise_infer(node, + Mul.operation)}), + **regular_op_with_empty_data('res1', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 0}), + **regular_op_with_empty_data('res2', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 1})} + then_graph_edges = [*connect('param_1', '0:add'), + *connect('param_2', '1:add'), + *connect('param_1', '1:mul'), + *connect('param_2', '0:mul'), + *connect('add', 'res1'), + *connect('mul', 'res2'), + ] + + else_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1, + 'shape': None, 'infer': Parameter.infer}), + **regular_op_with_empty_data('param_2', {'type': 'Parameter', 'kind': 'op', 'input_id': 3, + 'shape': None, 'infer': Parameter.infer}), + **regular_op_with_empty_data('identity', + {'kind': 'op', 'op': 'Identity', 'infer': Identity.infer}), + **regular_op_with_empty_data('identity_1', + {'kind': 'op', 'op': 'Identity', 'infer': Identity.infer}), + **regular_op_with_empty_data('res1', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 0}), + **regular_op_with_empty_data('res2', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 1})} + else_graph_edges = [*connect('param_1', 'identity'), + *connect('param_2', 'identity_1'), + *connect('identity_1', 'res2'), + *connect('identity', 'res1'), ] + then_graph = build_graph_with_edge_attrs(then_graph_nodes, then_graph_edges) + else_graph = build_graph_with_edge_attrs(else_graph_nodes, else_graph_edges) + external_graph_nodes = { + **valued_const_with_data('cond', np.array([True], dtype=np.bool)), + **valued_const_with_data('input_2', int64_array([3, 2, 1])), + **valued_const_with_data('input_1', int64_array([1, 2, 3])), + **valued_const_with_data('input_3', int64_array([8, 4])), + **regular_op('if', {'kind': 'op', 'op': 'If', 'then_graph': then_graph, + 'else_graph': else_graph, 'infer': If.infer}), + **empty_data('if_d_1'), + **empty_data('if_d_2'), + **result('res_1'), + **result('res_2')} + external_graph_edges = [*connect('cond', '0:if'), + *connect('input_1', '1:if'), + *connect('input_2', '2:if'), + *connect('input_3', '3:if'), + ('if', 'if_d_1', {'out': 0}), + ('if', 'if_d_2', {'out': 1}), + ('if_d_1', 'res_1'), + ('if_d_2', 'res_2')] + + graph = build_graph(external_graph_nodes, external_graph_edges) + graph.stage = 'middle' + partial_infer(graph) + res_1 = Node(graph, 'res_1') + res_2 = Node(graph, 'res_2') + npt.assert_array_equal(res_1.in_port(0).data.get_shape(), int64_array([3])) + npt.assert_array_equal(res_2.in_port(0).data.get_shape(), int64_array([3])) + + def test_fake_results(self): + then_graph_nodes = {**valued_const_with_data('fake_const', int64_array(0)), + **regular_op_with_empty_data('shapeof', + {'kind': 'op', 'type': 'ShapeOf', 'op': 'ShapeOf', 'infer': Shape.infer, + 'output_type': np.int64}), + **regular_op_with_empty_data('res_1', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 0})} + then_graph_edges = [*connect('fake_const', 'shapeof'), + *connect('shapeof', 'res_1'), + ] + + else_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1, + 'shape': None, 'infer': Parameter.infer}), + **regular_op_with_empty_data('res_1', {'kind': 'op', 'type': 'Result', 'op': 'Result', + 'infer': lambda x: 0, 'output_id': 0})} + else_graph_edges = [*connect('param_1', 'res_1')] + then_graph = build_graph_with_edge_attrs(then_graph_nodes, then_graph_edges) + else_graph = build_graph_with_edge_attrs(else_graph_nodes, else_graph_edges) + external_graph_nodes = { + **valued_const_with_data('cond', np.array([True], dtype=np.bool)), + **valued_const_with_data('input_1', int64_array([[1, 2, 3], [3, 2, 3]])), + **regular_op_with_empty_data('if', {'kind': 'op', 'op': 'If', 'then_graph': then_graph, + 'else_graph': else_graph, 'infer': If.infer}), + **result('res_1')} + external_graph_edges = [*connect('cond', '0:if'), + *connect('input_1', '1:if'), + *connect('if', 'res_1')] + + graph = build_graph(external_graph_nodes, external_graph_edges) + graph.stage = 'middle' + partial_infer(graph) + res_1 = Node(graph, 'res_1') + npt.assert_array_equal(res_1.in_port(0).data.get_shape(), int64_array([2,3])) diff --git a/model-optimizer/unit_tests/extensions/ops/gather_test.py b/model-optimizer/unit_tests/extensions/ops/gather_test.py index 4891e4d8b92..e372e04eaba 100644 --- a/model-optimizer/unit_tests/extensions/ops/gather_test.py +++ b/model-optimizer/unit_tests/extensions/ops/gather_test.py @@ -114,6 +114,12 @@ class TestGatherPartialInfer(unittest.TestCase): indices=[0, 0, 4], ref_value=[1, 1, 5]) + def test_axis_0_batch_dims_0_negative_indices(self): + self.build_and_test_value_inference(axis=0, batch_dims=0, + data=[1, 2, 3, 4, 5], + indices=[-1, -2, -3], + ref_value=[5, 4, 3]) + def test_axis_1_batch_dims_1(self): self.build_and_test_value_inference(axis=1, batch_dims=1, data=[[1, 2, 3, 4, 5], @@ -155,6 +161,27 @@ class TestGatherPartialInfer(unittest.TestCase): [33, 34, 35, 36], [29, 30, 31, 32]]]]) + def test_axis_2_batch_dims_1_with_negative_indices(self): + self.build_and_test_value_inference(axis=2, batch_dims=1, + data=[[[[ 1, 2, 3, 4], # <-- first batch + [ 5, 6, 7, 8], + [ 9, 10, 11, 12], + [13, 14, 15, 16], + [17, 18, 19, 20]]], + [[[21, 22, 23, 24], # < -- second batch + [25, 26, 27, 28], + [29, 30, 31, 32], + [33, 34, 35, 36], + [37, 38, 39, 40]]]], # data_shape = (2, 1, 5, 4) + indices=[[-4, -3, -1], + [-1, 3, 2]], + ref_value=[[[[ 5, 6, 7, 8], + [ 9, 10, 11, 12], + [17, 18, 19, 20]]], + [[[37, 38, 39, 40], + [33, 34, 35, 36], + [29, 30, 31, 32]]]]) + def test_axis_2_batch_dims_mimus_1(self): self.build_and_test_value_inference(axis=2, batch_dims=-1, data=[[[[ 1, 2, 3, 4], # <-- first batch diff --git a/ngraph/core/include/ngraph/attribute_visitor.hpp b/ngraph/core/include/ngraph/attribute_visitor.hpp index 95994579209..5fd9a62a2ef 100644 --- a/ngraph/core/include/ngraph/attribute_visitor.hpp +++ b/ngraph/core/include/ngraph/attribute_visitor.hpp @@ -12,12 +12,14 @@ #include "ngraph/type.hpp" #include "ngraph/type/element_type.hpp" +namespace ov { +class Function; +} namespace ngraph { template class ValueAccessor; class VisitorAdapter; class Node; -class Function; /// \brief Visits the attributes of a node, primarily for serialization-like tasks. /// @@ -95,7 +97,7 @@ public: /// \brief Provides API to handle nGraph Function attribute type, accessed as ValueAccessor /// \param name attribute name /// \param adapter reference to a Function ValueAccessor - virtual void on_adapter(const std::string& name, ValueAccessor>& adapter); + virtual void on_adapter(const std::string& name, ValueAccessor>& adapter); /// The generic visitor. There must be a definition of AttributeAdapter that can convert /// to a ValueAccessor for one of the on_adpater methods. diff --git a/ngraph/core/include/ngraph/deprecated.hpp b/ngraph/core/include/ngraph/deprecated.hpp index c6ba7ac7ade..89c95eb7b81 100644 --- a/ngraph/core/include/ngraph/deprecated.hpp +++ b/ngraph/core/include/ngraph/deprecated.hpp @@ -4,52 +4,9 @@ #pragma once -// -// The NGRAPH_DEPRECATED macro can be used to deprecate a function declaration. For example: -// -// NGRAPH_DEPRECATED("replace with groxify"); -// void frobnicate() -// -// The macro will expand to a deprecation attribute supported by the compiler, -// so any use of `frobnicate` will produce a compiler warning. -// +#include "openvino/core/deprecated.hpp" -#if defined(_WIN32) -# define NGRAPH_DEPRECATED(msg) __declspec(deprecated(msg)) -#elif defined(__INTEL_COMPILER) -# define NGRAPH_DEPRECATED(msg) __attribute__((deprecated(msg))) -#elif defined(__GNUC__) -# define NGRAPH_DEPRECATED(msg) __attribute__((deprecated((msg)))) -#else -# define NGRAPH_DEPRECATED(msg) -#endif - -// Suppress warning "-Wdeprecated-declarations" / C4996 -#if defined(_MSC_VER) -# define NGRAPH_DO_PRAGMA(x) __pragma(x) -#elif defined(__GNUC__) -# define NGRAPH_DO_PRAGMA(x) _Pragma(# x) -#else -# define NGRAPH_DO_PRAGMA(x) -#endif - -#if defined(_MSC_VER) && !defined(__clang__) -# define NGRAPH_SUPPRESS_DEPRECATED_START \ - NGRAPH_DO_PRAGMA(warning(push)) \ - NGRAPH_DO_PRAGMA(warning(disable : 4996)) -# define NGRAPH_SUPPRESS_DEPRECATED_END NGRAPH_DO_PRAGMA(warning(pop)) -#elif defined(__INTEL_COMPILER) -# define NGRAPH_SUPPRESS_DEPRECATED_START \ - NGRAPH_DO_PRAGMA(warning(push)) \ - NGRAPH_DO_PRAGMA(warning(disable : 1478)) -NGRAPH_DO_PRAGMA(warning(disable : 1786)) -# define NGRAPH_SUPPRESS_DEPRECATED_END NGRAPH_DO_PRAGMA(warning(pop)) -#elif defined(__clang__) || ((__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 405)) -# define NGRAPH_SUPPRESS_DEPRECATED_START \ - NGRAPH_DO_PRAGMA(GCC diagnostic push) \ - NGRAPH_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations") -# define NGRAPH_SUPPRESS_DEPRECATED_END NGRAPH_DO_PRAGMA(GCC diagnostic pop) -#else -# define NGRAPH_SUPPRESS_DEPRECATED_START -# define NGRAPH_SUPPRESS_DEPRECATED_END -#endif +#define NGRAPH_DEPRECATED(msg) OPENVINO_DEPRECATED(msg) +#define NGRAPH_ENUM_DEPRECATED(msg) OPENVINO_ENUM_DEPRECATED(msg) +#define NGRAPH_SUPPRESS_DEPRECATED_START OPENVINO_SUPPRESS_DEPRECATED_START +#define NGRAPH_SUPPRESS_DEPRECATED_END OPENVINO_SUPPRESS_DEPRECATED_END diff --git a/ngraph/core/include/ngraph/dimension.hpp b/ngraph/core/include/ngraph/dimension.hpp index 5ba014d3a96..9d748b26b30 100644 --- a/ngraph/core/include/ngraph/dimension.hpp +++ b/ngraph/core/include/ngraph/dimension.hpp @@ -4,171 +4,9 @@ #pragma once -#include - -#include -#include - -#include "ngraph/deprecated.hpp" #include "ngraph/interval.hpp" -#include "ngraph/ngraph_visibility.hpp" +#include "openvino/core/dimension.hpp" namespace ngraph { -/// \brief Class representing a dimension, which may be dynamic (undetermined until runtime), -/// in a shape or shape-like object. -/// -/// Static dimensions may be implicitly converted from value_type. A dynamic dimension is -/// constructed with Dimension() or Dimension::dynamic(). -class NGRAPH_API Dimension { -public: - using value_type = int64_t; - - /// \brief Construct a static dimension. - /// \param dimension Value of the dimension. - Dimension(value_type dimension); - - /// \brief Construct a dynamic dimension with bounded range - /// \param min_dimension The lower inclusive limit for the dimension - /// \param mas_dimension The upper inclusive limit for the dimension - Dimension(value_type min_dimension, value_type max_dimension); - - /// \brief Construct a dynamic dimension with range [0, ...] - Dimension() = default; - - bool operator==(const Dimension& dimension) const { - return m_dimension == dimension.m_dimension; - } - bool operator!=(const Dimension& dimension) const { - return m_dimension != dimension.m_dimension; - } - /// \brief Check whether this dimension is static. - /// \return `true` if the dimension is static, else `false`. - bool is_static() const { - return m_dimension.size() == 1; - } - /// \brief Check whether this dimension is dynamic. - /// \return `false` if the dimension is static, else `true`. - bool is_dynamic() const { - return m_dimension.size() != 1; - } - /// \brief Convert this dimension to `value_type`. This dimension must be static and - /// non-negative. - /// \throws std::invalid_argument If this dimension is dynamic or negative. - value_type get_length() const; - - value_type get_min_length() const; - value_type get_max_length() const; - - /// \brief Return the interval of valid lengths - const Interval& get_interval() const { - return m_dimension; - } - Interval& get_interval() { - return m_dimension; - } - /// \brief Check whether this dimension represents the same scheme as the argument (both - /// dynamic, or equal). - /// \param dim The other dimension to compare this dimension to. - /// \return `true` if this dimension and `dim` are both dynamic, or if they are both - /// static and equal; otherwise, `false`. - bool same_scheme(const Dimension& dim) const; - /// \brief Try to merge two Dimension objects together. - /// \param[out] dst Reference to write the merged Dimension into. - /// \param d1 First dimension to merge. - /// \param d2 Second dimension to merge. - /// \return `true` if merging succeeds, else `false`. - /// - /// \li If `d1` is dynamic, writes `d2` to `dst` and returns `true`. - /// \li If `d2` is dynamic, writes `d1` to `dst` and returns `true`. - /// \li If `d1` and `d2` are static and equal, writes `d1` to `dst` and returns `true`. - /// \li If `d1` and `d2` are both static and unequal, leaves `dst` unchanged and - /// returns `false`. - static bool merge(Dimension& dst, const Dimension d1, const Dimension d2); - - /// \brief Try to merge two Dimension objects together with implicit broadcasting - /// of unit-sized dimension to non unit-sized dimension - static bool broadcast_merge(Dimension& dst, const Dimension d1, const Dimension d2); - - /// \brief Check whether this dimension is capable of being merged with the argument - /// dimension. - /// \param d The dimension to compare this dimension with. - /// \return `true` if this dimension is compatible with `d`, else `false`. - /// - /// Two dimensions are considered compatible if it is possible to merge them. (See - /// Dimension::merge.) - bool compatible(const Dimension& d) const; - - /// \brief Check whether this dimension is a relaxation of the argument. - /// \param d The dimension to compare this dimension with. - /// \return `true` if this dimension relaxes `d`, else `false`. - /// - /// A dimension `d1` _relaxes_ (or _is a relaxation of_) `d2` if `d1` and `d2` are static - /// and equal, or `d1` is dynamic. - /// - /// `d1.relaxes(d2)` is equivalent to `d2.refines(d1)`. - bool relaxes(const Dimension& d) const; - - /// \brief Check whether this dimension is a refinement of the argument. - /// \param d The dimension to compare this dimension with. - /// \return `true` if this dimension relaxes `d`, else `false`. - /// - /// A dimension `d2` _refines_ (or _is a refinement of_) `d1` if `d1` and `d2` are static - /// and equal, or `d2` is dynamic. - /// - /// `d1.refines(d2)` is equivalent to `d2.relaxes(d1)`. - bool refines(const Dimension& d) const; - - /// \brief Create a dynamic dimension. - /// \return A dynamic dimension. - static Dimension dynamic() { - return Dimension(); - } - /// \brief Addition operator for Dimension. - /// \param dim Right operand for addition. - /// \return Smallest interval dimension enclosing inputs - Dimension operator+(const Dimension& dim) const; - - /// \brief Subtraction operator for Dimension. - /// \param dim Right operand for subtraction. - /// \return Smallest interval dimension enclosing inputs - Dimension operator-(const Dimension& dim) const; - - /// \brief Multiplication operator for Dimension. - /// \param dim Right operand for multiplicaiton. - /// \return Smallest interval containing all "produces" which are 0 if either of `this` or - /// `dim` has length `0`, else unbounded if either is unbounded, else product of lengths. - Dimension operator*(const Dimension& dim) const; - - /// \brief Add-into operator for Dimension. - /// \param dim Right operand for addition. - /// \return A reference to `*this`, after updating `*this` to the value `*this + dim`. - Dimension& operator+=(const Dimension& dim) { - return (*this = *this + dim); - } - /// \brief Multiply-into operator for Dimension. - /// \param dim Right operand for multiplication. - /// \return A reference to `*this`, after updating `*this` to the value `*this * dim`. - Dimension& operator*=(const Dimension& dim) { - return (*this = *this * dim); - } - /// \brief Intersection of dimensions - Dimension operator&(const Dimension& dim) const; - /// \brief Intersection of dimensions - Dimension& operator&=(const Dimension& dim); - -private: - Dimension(const Interval& interval) : m_dimension(interval) {} - - // The actual numerical value of the dimension. - Interval m_dimension{}; -}; - -/// \brief Insert a human-readable representation of a dimension into an output stream. -/// \param str The output stream targeted for insertion. -/// \param dimension The dimension to be inserted into `str`. -/// \return A reference to `str` after insertion. -/// -/// Inserts the string `?` if `dimension` is dynamic; else inserts `dimension.get_length()`. -NGRAPH_API -std::ostream& operator<<(std::ostream& str, const Dimension& dimension); +using ov::Dimension; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/file_util.hpp b/ngraph/core/include/ngraph/file_util.hpp index 8199edd3bd7..32626b8973e 100644 --- a/ngraph/core/include/ngraph/file_util.hpp +++ b/ngraph/core/include/ngraph/file_util.hpp @@ -5,34 +5,42 @@ #pragma once #include -#include #include #include +#include "ngraph/deprecated.hpp" +#include "ngraph/ngraph_visibility.hpp" + namespace ngraph { namespace file_util { /// \brief Returns the name with extension for a given path /// \param path The path to the output file +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string get_file_name(const std::string& path); /// \brief Returns the file extension /// \param path The path to the output file +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string get_file_ext(const std::string& path); /// \brief Returns the directory portion of the given path /// \param path The path to the output file +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string get_directory(const std::string& path); /// \brief Joins multiple paths into a single path /// \param s1 Left side of path /// \param s2 Right side of path +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string path_join(const std::string& s1, const std::string& s2); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string path_join(const std::string& s1, const std::string& s2, const std::string& s3); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string path_join(const std::string& s1, const std::string& s2, const std::string& s3, const std::string& s4); @@ -40,6 +48,7 @@ std::string path_join(const std::string& s1, const std::string& s2, const std::s /// \param path The path to iterate over /// \param func A callback function called with each file or directory encountered /// \param recurse Optional parameter to enable recursing through path +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API void iterate_files(const std::string& path, std::function func, @@ -48,21 +57,25 @@ void iterate_files(const std::string& path, /// \brief Change Linux-style path ('/') to Windows-style ('\\') /// \param path The path to change file separator +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API void convert_path_win_style(std::string& path); /// \brief Conversion from wide character string to a single-byte chain. /// \param wstr A wide-char string /// \return A multi-byte string +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string wstring_to_string(const std::wstring& wstr); /// \brief Conversion from single-byte chain to wide character string. /// \param str A null-terminated string /// \return A wide-char string +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::wstring multi_byte_char_to_wstring(const char* str); /// \brief Remove path components which would allow traversing up a directory tree. /// \param path A path to file /// \return A sanitiazed path +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::string sanitize_path(const std::string& path); } // namespace file_util } // namespace ngraph diff --git a/ngraph/core/include/ngraph/function.hpp b/ngraph/core/include/ngraph/function.hpp index 9c391a7bf88..2bc16a37b62 100644 --- a/ngraph/core/include/ngraph/function.hpp +++ b/ngraph/core/include/ngraph/function.hpp @@ -4,274 +4,8 @@ #pragma once -#include -#include -#include -#include -#include -#include - -#include "ngraph/ngraph_visibility.hpp" -#include "ngraph/node.hpp" -#include "ngraph/op/assign.hpp" -#include "ngraph/op/parameter.hpp" -#include "ngraph/op/read_value.hpp" -#include "ngraph/op/result.hpp" -#include "ngraph/op/sink.hpp" -#include "ngraph/op/util/variable.hpp" +#include "openvino/core/function.hpp" namespace ngraph { -/// A user-defined function. -class NGRAPH_API Function { -public: - static constexpr DiscreteTypeInfo type_info{"Function", 0}; - const DiscreteTypeInfo& get_type_info() const { - return type_info; - } - Function(const NodeVector& results, const ParameterVector& parameters, const std::string& name = ""); - - Function(const OutputVector& results, const ParameterVector& parameters, const std::string& name = ""); - - Function(const std::shared_ptr& result, const ParameterVector& parameters, const std::string& name = ""); - - Function(const ResultVector& results, const ParameterVector& parameters, const std::string& name = ""); - - Function(const ResultVector& results, - const SinkVector& sinks, - const ParameterVector& parameters, - const std::string& name = ""); - - Function(const OutputVector& results, - const SinkVector& sinks, - const ParameterVector& parameters, - const std::string& name = ""); - - Function(const ResultVector& results, - const SinkVector& sinks, - const ParameterVector& parameters, - const VariableVector& variables, - const std::string& name = ""); - - Function(const OutputVector& results, - const SinkVector& sinks, - const ParameterVector& parameters, - const VariableVector& variables, - const std::string& name = ""); - - Function(const ResultVector& results, - const ParameterVector& parameters, - const VariableVector& variables, - const std::string& name = ""); - - Function(const OutputVector& results, - const ParameterVector& parameters, - const VariableVector& variables, - const std::string& name = ""); - - /// Constructs a Function. Lists of parameters and variables will be generated automatically - /// based on traversing the graph from the results. - explicit Function(const OutputVector& results, const std::string& name = ""); - - /// Constructs a Function. Lists of parameters and variables will be generated automatically - /// based on traversing the graph from the results and the sinks. - Function(const OutputVector& results, const SinkVector& sinks, const std::string& name = ""); - - virtual ~Function() = default; - /// Return the number of outputs for this function. - size_t get_output_size() const; - - /// Return the op that generates output i - std::shared_ptr get_output_op(size_t i) const; - - Output output(size_t i) const; - - /// Return the element type of output i - const element::Type& get_output_element_type(size_t i) const; - - /// Return the shape of element i - const Shape& get_output_shape(size_t i) const; - - /// Return the partial shape of element i - const PartialShape& get_output_partial_shape(size_t i) const; - - /// Check that there is a single result and return it. - std::shared_ptr get_result() const; - - /// \brief Get the unique name of the function. - /// \returns A const reference to the function's unique name. - const std::string& get_name() const; - - /// \brief Sets a friendly name for a function. This does not overwrite the unique name - /// of the function and is retrieved via get_friendly_name(). Used mainly for - /// debugging. - /// \param name is the friendly name to set - void set_friendly_name(const std::string& name); - - /// \brief Gets the friendly name for a function. If no friendly name has been set via - /// set_friendly_name then the function's unique name is returned. - /// \returns A const reference to the function's friendly name. - const std::string& get_friendly_name() const; - - std::vector> get_ops() const; - std::vector> get_ordered_ops() const; - void map_unordered_ops(std::function f) const; - - friend std::ostream& operator<<(std::ostream&, const Function&); - // updates graph and m_results list - void replace_node(std::shared_ptr old, std::shared_ptr repl); - - void validate_nodes_and_infer_types() const; - - /// \brief Returns the sum of the size of all nodes in the graph plus the size of - /// all constant data. This has little value beyond comparing the relative size of - /// graphs and should not be considered the actual memory consumption of a graph. - size_t get_graph_size() const; - - /// \brief Returns true if any of the op's defined in the function contains partial shape - bool is_dynamic() const; - - /// \brief Replace the `parameter_index`th parameter of the function with `parameter`. - /// - /// All users of the `parameter_index`th parameter are redirected to `parameter`, and the - /// `parameter_index`th entry in the function parameter list is replaced with `parameter`. - /// - /// \param parameter_index The index of the parameter to replace. - /// \param parameter The parameter to substitute for the `parameter_index`th parameter. - void replace_parameter(size_t parameter_index, const std::shared_ptr& parameter); - - using topological_sort_t = - std::function>(const std::vector>& root_nodes)>; - void set_topological_sort(topological_sort_t); - - virtual bool visit_attributes(AttributeVisitor& visitor); - - /// Return the function parameters - const ParameterVector& get_parameters() const { - return m_parameters; - }; - /// Return a list of function's outputs - const ResultVector& get_results() const { - return m_results; - }; - /// Index for parameter, or -1 - int64_t get_parameter_index(const std::shared_ptr& parameter) const; - - /// Index for value or result referencing it, or -1 - int64_t get_result_index(const Output& value) const; - - /// \brief Evaluate the function on inputs, putting results in outputs. - /// \param output_tensors Tensors for the outputs to compute. One for each result - /// \param input_tensors Tensors for the inputs. One for each inputs. - /// \param evaluation_context Storage of additional settings and attributes that can be used - /// when evaluating the function. This additional information can be shared across nodes. - bool evaluate(const HostTensorVector& output_tensors, - const HostTensorVector& input_tensors, - EvaluationContext evaluation_context = EvaluationContext()) const; - - /// \brief Return a list of function's sinks. - const SinkVector& get_sinks() const { - return m_sinks; - } - /// \brief Add new sink nodes to the list. Method doesn't validate graph, it should be done - /// manually after all changes. - /// \param sinks new sink nodes - void add_sinks(const SinkVector& sinks); - - /// \brief Delete sink node from the list of sinks. Method doesn't delete node from graph. - /// \param sink Sink to delete - void remove_sink(const std::shared_ptr& sink); - - /// \brief Add new Result nodes to the list. Method doesn't validate graph, it should be - /// done manually after all changes. - /// \param results new Result nodes - void add_results(const ResultVector& results); - - /// \brief Delete Result node from the list of results. Method will not delete node from - /// graph. - /// \param result Result node to delete - void remove_result(const std::shared_ptr& result); - - /// \brief Add new Parameter nodes to the list. - /// - /// Method doesn't change or validate graph, it should be done manually. - /// For example, if you want to replace `ReadValue` node by `Parameter`, you should do the - /// following steps: - /// * replace node `ReadValue` by `Parameter` in graph - /// * call add_parameter() to add new input to the list - /// * call graph validation to check correctness of changes - /// - /// \param params new Parameter nodes - void add_parameters(const ParameterVector& params); - - /// \brief Delete Parameter node from the list of parameters. Method will not delete node - /// from graph. You need to replace Parameter with other operation manually. - /// Attention: Indexing of parameters can be changed. - /// - /// Possible use of method is to replace input by variable. For it the following steps - /// should be done: - /// * `Parameter` node should be replaced by `ReadValue` - /// * call remove_parameter(param) to remove input from the list - /// * check if any parameter indexes are saved/used somewhere, update it for all inputs - /// because indexes can be changed - /// * call graph validation to check all changes - /// - /// \param param Parameter node to delete - void remove_parameter(const std::shared_ptr& param); - - /// \brief Add new variables to the list. Method doesn't validate graph, it should be done - /// manually after all changes. - /// \param variables new variables to add - void add_variables(const VariableVector& variables); - - /// \brief Delete variable from the list of variables. - /// Method doesn't delete nodes that used this variable from the graph. - /// \param variable Variable to delete - void remove_variable(const VariablePtr& variable); - - /// \brief Return a list of function's variables. - const VariableVector& get_variables() const { - return m_variables; - } - - /// \brief Return a variable by specified variable_id. - VariablePtr get_variable_by_id(const std::string& variable_id) const; - -private: - Function(const Function&) = delete; - Function(const Function&&) = delete; - Function& operator=(const Function&) = delete; - - /// \brief Depending on the options selected, - /// checks all the Parameter/Variables are registered in the list of Function - /// parameters/variables or finds all Parameters/Variables in a function and registers them. - /// \param detect_variables If this flag is true, then it finds all Variables in a function - /// and registers them, otherwise checks all the Variables are registered. - /// \param detect_parameters If this flag is true, then it finds all Parameters in a - /// function and registers them, otherwise checks all the Parameters are registered. - void prerequirements(bool detect_variables, bool detect_parameters); - - static std::atomic m_next_instance_id; - std::string m_name; - const std::string m_unique_name; - size_t m_placement{0}; - topological_sort_t m_topological_sorter; - - ResultVector m_results; - // List of the nodes with side effect in graph. - // These nodes are not outputs of graph but should not be removed even if have no children. - SinkVector m_sinks; - ParameterVector m_parameters; - VariableVector m_variables; -}; - -template <> -class NGRAPH_API AttributeAdapter> : public DirectValueAccessor> { -public: - AttributeAdapter(std::shared_ptr& value) : DirectValueAccessor>(value) {} - - static constexpr DiscreteTypeInfo type_info{"AttributeAdapter>", 0}; - const DiscreteTypeInfo& get_type_info() const override { - return type_info; - } -}; +using ov::Function; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/graph_util.hpp b/ngraph/core/include/ngraph/graph_util.hpp index 5ae57bf382c..f017172ca51 100644 --- a/ngraph/core/include/ngraph/graph_util.hpp +++ b/ngraph/core/include/ngraph/graph_util.hpp @@ -228,6 +228,7 @@ void replace_nodes(const std::shared_ptr& f, parameter_replacement_map, const std::unordered_map, std::shared_ptr>& body_replacement_map); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API NodeVector find_common_args(std::shared_ptr target, std::shared_ptr replacement); @@ -330,9 +331,11 @@ void validate_nodes_and_infer_types(const T& nodes) { } // Check if all paths from X to a result go through Y +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_post_dominated(Node* X, Node* Y); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_equal_to_const_value(const std::string& const_value, const Output& reduce_constant); @@ -360,6 +363,7 @@ std::shared_ptr clone_function(const ngraph::Function& func, N NGRAPH_API std::shared_ptr clone_function(const ngraph::Function& func); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::pair, std::shared_ptr> insert_result_parameter_split( const std::shared_ptr& src_node, @@ -370,15 +374,19 @@ void insert_new_node_between(const std::shared_ptr& src_node, const std::shared_ptr& dst_node, const std::shared_ptr& new_node); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::shared_ptr make_zero(const element::Type& element_type, const Shape& shape); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::shared_ptr make_constant_from_string(std::string val, const element::Type& element_type, const Shape& shape); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_zero(const Output& reduce_constant); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API NodeVector get_subgraph_outputs(const NodeVector& nodes, const NodeVector& exclusions, @@ -391,6 +399,7 @@ NodeVector get_subgraph_outputs(const NodeVector& nodes, NGRAPH_API NodeVector extract_subgraph(const NodeVector& results, const NodeVector& args); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_one(const Output& reduce_constant); @@ -403,20 +412,25 @@ NGRAPH_API bool is_used(Node* node); // Returns count of `node` users that are still live in the graph +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API size_t get_user_count(Node* node); // Return true if a node's user could potentially overwrite // the output of this node with in-place kernels +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool possibly_overwritten(Node* node); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_strided(const Strides& strides); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool is_valid_rank(const std::shared_ptr& node, std::vector valid_ranks); +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API void plot_graph(std::shared_ptr f, const std::string& filename, @@ -424,16 +438,19 @@ void plot_graph(std::shared_ptr f, /// \return A vector containing handles for each input of dst that is connected to an output /// of `src`. +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::vector> get_inputs_from(Node& src, Node& dst); /// \return A vector containing a handle for each output of src that is connected to an input /// of `dst`. +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API std::vector> get_outputs_to(Node& src, Node& dst); /// Checks the func for graph cycles starting from results going backwards, then from parameters /// going forward. /// It returns true if a cycle is found and the first cycle encountered. +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") NGRAPH_API bool check_for_cycles(const ngraph::Function* func, ngraph::NodeVector& cycle_nodes, bool& is_bkwd_cycle); diff --git a/ngraph/core/include/ngraph/interval.hpp b/ngraph/core/include/ngraph/interval.hpp index ea8089b6e4e..f241e572ea4 100644 --- a/ngraph/core/include/ngraph/interval.hpp +++ b/ngraph/core/include/ngraph/interval.hpp @@ -4,117 +4,8 @@ #pragma once -#include -#include -#include -#include -#include - -#include "ngraph/ngraph_visibility.hpp" +#include "openvino/core/interval.hpp" namespace ngraph { -/// \brief Interval arithmetic -/// -/// An interval is the set of integers from m_min_val through m_max_val. -/// The value s_max acts like infinity. The -/// addition, subtraction, or multiplication of intervals is the smallest interval -/// containing the sums, differences, or products of elements of the two intervals. An empty -/// interval is canonicalized to [s_max, s_max]. -class NGRAPH_API Interval { -public: - using value_type = std::int64_t; - using size_type = std::uint64_t; - - /// \brief Interval of everything - Interval() = default; - /// \brief Copy constructor - Interval(const Interval& interval) = default; - - /// \brief Closed interval {x|min_val <= x <= max_val} - Interval(value_type min_val, value_type max_val); - - /// \brief Single-valued interval; just contains val - Interval(value_type val); - - Interval& operator=(const Interval& interval) = default; - - /// \brief The number of elements in the interval. Zero if max < min. - size_type size() const { - if (m_max_val == s_max) { - return m_min_val == s_max ? 0 : s_max; - } - return m_max_val - m_min_val + 1; - } - /// \brief Returns true if the interval has no elements - bool empty() const { - return m_min_val == s_max; - } - /// \brief the inclusive lower bound of the interval - value_type get_min_val() const { - return m_min_val; - } - /// \brief Set the inclusive lower bound of the interval - void set_min_val(value_type val) { - m_min_val = val; - } - /// \brief the inclusive upper bound of the interval - value_type get_max_val() const { - return m_max_val; - } - /// \brief Set the inclusive upper bound of the interval - void set_max_val(value_type val) { - m_max_val = val; - } - /// \brief True if the upper bound is finite - bool has_upper_bound() const { - return m_max_val != s_max; - } - /// \brief True if min and max bounds match - bool operator==(const Interval& interval) const; - bool operator!=(const Interval& interval) const; - - /// \brief The interval whose elements are a sum of an element from each interval - Interval operator+(const Interval& interval) const; - - /// \brief Extend this interval to sums of elements in this interval and interval - Interval& operator+=(const Interval& interval); - - /// \brief The interval whose elements are a difference of an element from each interval - Interval operator-(const Interval& interval) const; - - /// \brief Extend this interval to differences of elements in this interval and interval - Interval& operator-=(const Interval& interval); - - /// \brief The smallest interval whose elements are a product of an element from each - /// interval - Interval operator*(const Interval& interval) const; - - /// \brief Extend this interval to products of elements in this interval and interval - Interval& operator*=(const Interval& interval); - - /// \brief The interval that is the intersection of this interval and interval - Interval operator&(const Interval& interval) const; - - /// \brief Change this interval to only include elements also in interval - Interval& operator&=(const Interval& interval); - - /// \brief True if this interval includes value - bool contains(value_type value) const { - return m_min_val <= value && value <= m_max_val; - } - /// \brief True if this interval includes all the values in interval - bool contains(const Interval& interval) const; - - /// \brief The value used for no upper bound - static constexpr value_type s_max{std::numeric_limits::max()}; - -protected: - void canonicalize(); - - value_type m_min_val{0}; - value_type m_max_val{s_max}; -}; - -NGRAPH_API -std::ostream& operator<<(std::ostream& str, const Interval& interval); +using ov::Interval; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/ngraph_visibility.hpp b/ngraph/core/include/ngraph/ngraph_visibility.hpp index 685aa2014a5..caeaa3f3bce 100644 --- a/ngraph/core/include/ngraph/ngraph_visibility.hpp +++ b/ngraph/core/include/ngraph/ngraph_visibility.hpp @@ -3,32 +3,6 @@ // #include "ngraph/visibility.hpp" +#include "openvino/core/core_visibility.hpp" -// Now we use the generic helper definitions above to define NGRAPH_API -// NGRAPH_API is used for the public API symbols. It either DLL imports or DLL exports -// (or does nothing for static build) - -#ifdef _WIN32 -# pragma warning(disable : 4251) -# pragma warning(disable : 4275) -#endif - -#ifdef NGRAPH_STATIC_LIBRARY // defined if we are building or calling NGRAPH as a static library -# define NGRAPH_API -#else -# ifdef ngraph_EXPORTS // defined if we are building the NGRAPH DLL (instead of using it) -# define NGRAPH_API NGRAPH_HELPER_DLL_EXPORT -# else -# define NGRAPH_API NGRAPH_HELPER_DLL_IMPORT -# endif // ngraph_EXPORTS -#endif // NGRAPH_STATIC_LIBRARY - -#ifndef ENABLE_UNICODE_PATH_SUPPORT -# ifdef _WIN32 -# if defined __INTEL_COMPILER || defined _MSC_VER -# define ENABLE_UNICODE_PATH_SUPPORT -# endif -# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__) -# define ENABLE_UNICODE_PATH_SUPPORT -# endif -#endif +#define NGRAPH_API OPENVINO_API diff --git a/ngraph/core/include/ngraph/node.hpp b/ngraph/core/include/ngraph/node.hpp index aebef5257d9..e3c4b1a39e4 100644 --- a/ngraph/core/include/ngraph/node.hpp +++ b/ngraph/core/include/ngraph/node.hpp @@ -47,8 +47,6 @@ class Output; class AttributeVisitor; class Node; -class Function; - namespace runtime { class HostTensor; } @@ -475,12 +473,16 @@ public: /// \throw std::out_of_range if the node does not have at least `output_index+1` outputs. Output output(size_t output_index) const; + NGRAPH_SUPPRESS_DEPRECATED_START + NGRAPH_DEPRECATED("This method is deprecated and will be removed soon.") void set_op_annotations(std::shared_ptr op_annotations) { m_op_annotations = op_annotations; } + NGRAPH_DEPRECATED("This method is deprecated and will be removed soon.") std::shared_ptr get_op_annotations() const { return m_op_annotations; } + NGRAPH_SUPPRESS_DEPRECATED_END virtual bool match_value(pattern::Matcher* matcher, const Output& pattern_value, @@ -503,7 +505,9 @@ private: std::set> m_provenance_group; std::deque m_inputs; std::deque m_outputs; + NGRAPH_SUPPRESS_DEPRECATED_START std::shared_ptr m_op_annotations; + NGRAPH_SUPPRESS_DEPRECATED_END std::map> m_rt_info; }; diff --git a/ngraph/core/include/ngraph/op/cum_sum.hpp b/ngraph/core/include/ngraph/op/cum_sum.hpp index 945b5e66065..a2edb446a4d 100644 --- a/ngraph/core/include/ngraph/op/cum_sum.hpp +++ b/ngraph/core/include/ngraph/op/cum_sum.hpp @@ -14,46 +14,6 @@ namespace v0 { /// /// Compute the cumulative sum of the input tensor along the axis specified. /// -/// ## Parameters -/// -/// | | Description | -/// | -------------------- | -/// --------------------------------------------------------------------------------------------------| -/// | `exclusive` | If set to 1 will return exclusive sum in which the top -/// element -/// is not included. | -/// | | In other terms, if set to 1, the j-th output element -/// would be -/// the -/// sum of the first (j-1) elements.| -/// | | Otherwise, it would be the sum of the first j elements. -/// | -/// -/// | | Description | -/// | -------------------- | -------------------------------------------------- | -/// | `reverse` | if set to 1, performs the sum in reverse direction | -/// -/// ## Inputs -/// -/// | | Description | -/// | ----- | ------------------------------------------------------ | -/// | `arg` | An input tensor of any shape and numeric element type. | -/// -/// | | Description | -/// | ----- | -/// ------------------------------------------------------------------------------------------------| -/// | `axis`| zero dimension tensor specifying axis position along which cumulative sum -/// must -/// be performed. | -/// -/// ## Output -/// -/// | Description | -/// | -/// ------------------------------------------------------------------------------------| -/// | Output tensor of the same type as `arg` with cumulative sums of the arg's elements -/// | - class NGRAPH_API CumSum : public Op { public: NGRAPH_RTTI_DECLARATION; @@ -92,8 +52,8 @@ public: } private: - bool m_exclusive; - bool m_reverse; + bool m_exclusive = false; + bool m_reverse = false; }; } // namespace v0 using v0::CumSum; diff --git a/ngraph/core/include/ngraph/op/gather.hpp b/ngraph/core/include/ngraph/op/gather.hpp index a788953614d..c81397fcf12 100644 --- a/ngraph/core/include/ngraph/op/gather.hpp +++ b/ngraph/core/include/ngraph/op/gather.hpp @@ -9,13 +9,13 @@ namespace ngraph { namespace op { namespace v1 { -/// \brief Gather slices from axis of params according to indices +/// \brief Gather slices from axis of data according to indices class NGRAPH_API Gather : public op::util::GatherBase { public: NGRAPH_RTTI_DECLARATION; static const int64_t AXIS_NOT_SET_VALUE = std::numeric_limits::max(); Gather() = default; - /// \param params The tensor from which slices are gathered + /// \param data The tensor from which slices are gathered /// \param indices Tensor with indexes to gather /// \param axis The tensor is a dimension index to gather data from Gather(const Output& params, const Output& indices, const Output& axis); @@ -28,7 +28,7 @@ public: } // namespace v1 namespace v7 { -/// \brief Gather slices from axis of params according to indices +/// \brief Gather slices from axis of data according to indices class NGRAPH_API Gather : public op::util::GatherBase { public: NGRAPH_RTTI_DECLARATION; @@ -53,7 +53,8 @@ public: } // namespace v7 namespace v8 { -/// \brief Gather slices from axis of params according to indices +/// \brief Gather slices from axis of data according to indices. Negative indices +/// are supported and indicate reverse indexing from the end class NGRAPH_API Gather : public op::util::GatherBase { public: NGRAPH_RTTI_DECLARATION; diff --git a/ngraph/core/include/ngraph/op/gelu.hpp b/ngraph/core/include/ngraph/op/gelu.hpp index 91058554376..78f683120c2 100644 --- a/ngraph/core/include/ngraph/op/gelu.hpp +++ b/ngraph/core/include/ngraph/op/gelu.hpp @@ -6,21 +6,17 @@ #include "ngraph/node.hpp" #include "ngraph/op/op.hpp" -#include "ngraph/op/util/fused_op.hpp" #include "ngraph/op/util/unary_elementwise_arithmetic.hpp" namespace ngraph { namespace op { -NGRAPH_SUPPRESS_DEPRECATED_START namespace v0 { /// \brief Gaussian Error Linear Unit /// f(x) = 0.5 * x * (1 + erf( x / sqrt(2) ) -class NGRAPH_API Gelu : public ngraph::op::util::FusedOp { +class NGRAPH_API Gelu : public Op { public: - static constexpr NodeTypeInfo type_info{"Gelu", 0}; - const NodeTypeInfo& get_type_info() const override { - return type_info; - } + NGRAPH_RTTI_DECLARATION; + Gelu(); /// \brief Constructs a Gelu operation. /// @@ -28,15 +24,13 @@ public: Gelu(const Output& data); bool visit_attributes(AttributeVisitor& visitor) override; - virtual OutputVector decompose_op() const override; - void pre_validate_and_infer_types() override; + void validate_and_infer_types() override; virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; }; } // namespace v0 using v0::Gelu; -NGRAPH_SUPPRESS_DEPRECATED_END /// \brief Specifies the approximation to calculate Gelu enum class GeluApproximationMode { TANH, ERF }; diff --git a/ngraph/core/include/ngraph/op/hard_sigmoid.hpp b/ngraph/core/include/ngraph/op/hard_sigmoid.hpp index 01b7d31a014..1a6c56d2fe1 100644 --- a/ngraph/core/include/ngraph/op/hard_sigmoid.hpp +++ b/ngraph/core/include/ngraph/op/hard_sigmoid.hpp @@ -5,9 +5,7 @@ #pragma once #include "ngraph/node.hpp" -#include "ngraph/op/util/fused_op.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START +#include "ngraph/op/op.hpp" namespace ngraph { namespace op { @@ -15,7 +13,7 @@ namespace v0 { /// \brief Parameterized, bounded sigmoid-like, piecewise linear /// function. min(max(alpha*x + beta, 0), 1) /// -class NGRAPH_API HardSigmoid : public ngraph::op::util::FusedOp { +class NGRAPH_API HardSigmoid : public Op { public: NGRAPH_RTTI_DECLARATION; @@ -30,13 +28,10 @@ public: HardSigmoid(const Output& data, const Output& alpha, const Output& beta); bool visit_attributes(AttributeVisitor& visitor) override; - virtual void pre_validate_and_infer_types() override; - virtual OutputVector decompose_op() const override; + virtual void validate_and_infer_types() override; virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; }; } // namespace v0 using v0::HardSigmoid; } // namespace op } // namespace ngraph - -NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/core/include/ngraph/op/if.hpp b/ngraph/core/include/ngraph/op/if.hpp new file mode 100644 index 00000000000..32ed1d5b846 --- /dev/null +++ b/ngraph/core/include/ngraph/op/if.hpp @@ -0,0 +1,94 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "ngraph/function.hpp" +#include "ngraph/op/parameter.hpp" +#include "ngraph/op/util/multi_subgraph_base.hpp" + +namespace ngraph { +namespace op { +namespace v8 { +/// \brief If operation. +class NGRAPH_API If : public util::MultiSubGraphOp { +public: + enum BodyIndexes { THEN_BODY_INDEX = 0, ELSE_BODY_INDEX = 1 }; + + NGRAPH_RTTI_DECLARATION; + bool visit_attributes(AttributeVisitor& visitor) override; + + /// \brief Constructs If with condition + /// + /// \param execution_condition condition node. + If(const Output& execution_condition); + If(); + + std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; + + /// \brief gets then_body as ngraph::Function. + /// + /// \return then_body as ngraph::Function. + const std::shared_ptr& get_then_body() const { + return m_bodies[THEN_BODY_INDEX]; + } + + /// \brief gets else_body as ngraph::Function. + /// + /// \return else_body as ngraph::Function. + const std::shared_ptr& get_else_body() const { + return m_bodies[ELSE_BODY_INDEX]; + } + + /// \brief sets new ngraph::Function as new then_body. + /// + /// \param body new body for 'then' branch. + void set_then_body(const std::shared_ptr& body) { + m_bodies[THEN_BODY_INDEX] = body; + } + + /// \brief sets new ngraph::Function as new else_body. + /// + /// \param body new body for 'else' branch. + void set_else_body(const std::shared_ptr& body) { + m_bodies[ELSE_BODY_INDEX] = body; + } + + /// \brief sets new input to the operation associated with parameters + /// of each sub-graphs + /// + /// \param value input to operation + /// \param then_parameter parameter for then_body or nullptr + /// \param else_parameter parameter for else_body or nullpt + void set_input(const Output& value, + const std::shared_ptr& then_parameter, + const std::shared_ptr& else_parameter); + + /// \brief sets new output from the operation associated with results + /// of each sub-graphs + /// + /// \param then_result result from then_body + /// \param else_parameter result from else_body + /// \return output from operation + Output set_output(const std::shared_ptr& then_result, const std::shared_ptr& else_result); + + void validate_and_infer_types() override; + bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; + + bool has_evaluate() const override; + +private: + using OutputMap = std::map>; + + void validate_and_infer_type_body(const std::shared_ptr& body, + const ngraph::op::util::MultiSubgraphInputDescriptionVector& input_descriptors); + + OutputMap get_mapping_outputs_on_body_description( + const ngraph::op::util::MultiSubgraphOutputDescriptionVector& output_descriptors); +}; +} // namespace v8 +} // namespace op +} // namespace ngraph \ No newline at end of file diff --git a/ngraph/core/include/ngraph/op/interpolate.hpp b/ngraph/core/include/ngraph/op/interpolate.hpp index e54acccdf51..c4a84dee8e0 100644 --- a/ngraph/core/include/ngraph/op/interpolate.hpp +++ b/ngraph/core/include/ngraph/op/interpolate.hpp @@ -41,7 +41,16 @@ class NGRAPH_API Interpolate : public Op { public: NGRAPH_RTTI_DECLARATION; - enum class InterpolateMode { nearest, linear, cubic, area }; + enum class InterpolateMode { + NEAREST, + LINEAR, + CUBIC, + AREA, + nearest NGRAPH_ENUM_DEPRECATED("Please use NEAREST instead") = NEAREST, + linear NGRAPH_ENUM_DEPRECATED("Please use LINEAR instead") = LINEAR, + cubic NGRAPH_ENUM_DEPRECATED("Please use CUBIC instead") = CUBIC, + area NGRAPH_ENUM_DEPRECATED("Please use AREA instead") = AREA + }; Interpolate() = default; /// \brief Constructs a Interpolate operation @@ -54,7 +63,7 @@ public: void validate_and_infer_types() override; - virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; + std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; const InterpolateAttrs& get_attrs() const { return m_attrs; @@ -74,7 +83,12 @@ public: /// /// sizes - output shape for interpolated axes is calculated using input `sizes` /// scales - output shape for interpolated axes is calculated using input `scales` - enum class ShapeCalcMode { sizes, scales }; + enum class ShapeCalcMode { + SIZES, + SCALES, + sizes NGRAPH_ENUM_DEPRECATED("Please use SIZES instead") = SIZES, + scales NGRAPH_ENUM_DEPRECATED("Please use SCALES instead") = SCALES + }; /// \brief Interpolation mode /// @@ -82,29 +96,54 @@ public: /// linear - linear interpolation as in TensorFlow /// linear_onnx - linear interpolation as in ONNX /// cubic - cubic interpolation - enum class InterpolateMode { nearest, linear, linear_onnx, cubic }; + enum class InterpolateMode { + NEAREST, + LINEAR, + LINEAR_ONNX, + CUBIC, + nearest NGRAPH_ENUM_DEPRECATED("Please use NEAREST instead") = NEAREST, + linear NGRAPH_ENUM_DEPRECATED("Please use LINEAR instead") = LINEAR, + linear_onnx NGRAPH_ENUM_DEPRECATED("Please use LINEAR_ONNX instead") = LINEAR_ONNX, + cubic NGRAPH_ENUM_DEPRECATED("Please use CUBIC instead") = CUBIC + }; /// \brief Mode of the calculation of the source coordinate from resized one /// /// These modes are modes from ONNX runtime. enum class CoordinateTransformMode { - half_pixel, - pytorch_half_pixel, - asymmetric, - tf_half_pixel_for_nn, - align_corners + HALF_PIXEL, + PYTORCH_HALF_PIXEL, + ASYMMETRIC, + TF_HALF_PIXEL_FOR_NN, + ALIGN_CORNERS, + half_pixel NGRAPH_ENUM_DEPRECATED("Please use HALF_PIXEL instead") = HALF_PIXEL, + pytorch_half_pixel NGRAPH_ENUM_DEPRECATED("Please use PYTORCH_HALF_PIXEL instead") = PYTORCH_HALF_PIXEL, + asymmetric NGRAPH_ENUM_DEPRECATED("Please use ASYMMETRIC instead") = ASYMMETRIC, + tf_half_pixel_for_nn NGRAPH_ENUM_DEPRECATED("Please use TF_HALF_PIXEL_FOR_NN instead") = TF_HALF_PIXEL_FOR_NN, + align_corners NGRAPH_ENUM_DEPRECATED("Please use ALIGN_CORNERS instead") = ALIGN_CORNERS }; /// \brief Round modes for the nearest interpolation. - enum class NearestMode { round_prefer_floor, round_prefer_ceil, floor, ceil, simple }; + enum class NearestMode { + ROUND_PREFER_FLOOR, + ROUND_PREFER_CEIL, + FLOOR, + CEIL, + SIMPLE, + round_prefer_floor NGRAPH_ENUM_DEPRECATED("Please use ROUND_PREFER_FLOOR instead") = ROUND_PREFER_FLOOR, + round_prefer_ceil NGRAPH_ENUM_DEPRECATED("Please use ROUND_PREFER_CEIL instead") = ROUND_PREFER_CEIL, + floor NGRAPH_ENUM_DEPRECATED("Please use FLOOR instead") = FLOOR, + ceil NGRAPH_ENUM_DEPRECATED("Please use CEIL instead") = CEIL, + simple NGRAPH_ENUM_DEPRECATED("Please use SIMPLE instead") = SIMPLE + }; struct InterpolateAttrs { // specifies type of interpolation // one of `nearest`, `linear`, `linear_onnx`, `cubic` Required. - InterpolateMode mode = InterpolateMode::nearest; + InterpolateMode mode = InterpolateMode::NEAREST; // specifies shape calculation mode // one of `sizes`, `scales` Required - ShapeCalcMode shape_calculation_mode = ShapeCalcMode::sizes; + ShapeCalcMode shape_calculation_mode = ShapeCalcMode::SIZES; // specify the number of pixels to add to the beginning of the image being // interpolated. This addition of pixels is done before interpolation // calculation. @@ -116,11 +155,11 @@ public: // specifies how to transform the coordinate in the resized tensor to the // coordinate in the original tensor. one of `half_pixel`, `pytorch_half_pixel`, // `asymmetric`, `tf_half_pixel_for_nn`, `align_corners` - CoordinateTransformMode coordinate_transformation_mode = CoordinateTransformMode::half_pixel; + CoordinateTransformMode coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; // specifies round mode when `mode == nearest` and is used only when `mode == // nearest`. one of `round_prefer_floor`, `round_prefer_ceil`, `floor`, `ceil`, // `simple` - NearestMode nearest_mode = NearestMode::round_prefer_floor; + NearestMode nearest_mode = NearestMode::ROUND_PREFER_FLOOR; // a flag that specifies whether to perform anti-aliasing. default is `false` bool antialias = false; // specifies the parameter *a* for cubic interpolation (see, e.g. @@ -132,10 +171,10 @@ public: InterpolateAttrs(InterpolateMode mode, ShapeCalcMode shape_calculation_mode, - std::vector pads_begin, - std::vector pads_end, - CoordinateTransformMode coordinate_transformation_mode = CoordinateTransformMode::half_pixel, - NearestMode nearest_mode = NearestMode::round_prefer_floor, + const std::vector& pads_begin, + const std::vector& pads_end, + CoordinateTransformMode coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL, + NearestMode nearest_mode = NearestMode::ROUND_PREFER_FLOOR, bool antialias = false, double cube_coeff = -0.75) : mode(mode), @@ -176,7 +215,7 @@ public: void validate_and_infer_types() override; - virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; + std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; bool has_evaluate() const override; diff --git a/ngraph/core/include/ngraph/op/lstm_sequence.hpp b/ngraph/core/include/ngraph/op/lstm_sequence.hpp index 4745afa8b46..75638c6c411 100644 --- a/ngraph/core/include/ngraph/op/lstm_sequence.hpp +++ b/ngraph/core/include/ngraph/op/lstm_sequence.hpp @@ -14,13 +14,11 @@ #include "ngraph/op/constant.hpp" #include "ngraph/op/lstm_cell.hpp" #include "ngraph/op/util/attr_types.hpp" -#include "ngraph/op/util/fused_op.hpp" #include "ngraph/op/util/rnn_cell_base.hpp" namespace ngraph { namespace op { namespace v0 { -NGRAPH_SUPPRESS_DEPRECATED_START /// /// \brief Class for lstm sequence node. @@ -31,7 +29,7 @@ NGRAPH_SUPPRESS_DEPRECATED_START /// \sa LSTMCell, RNNCell, GRUCell /// /// -class NGRAPH_API LSTMSequence : public util::FusedOp { +class NGRAPH_API LSTMSequence : public Op { public: NGRAPH_RTTI_DECLARATION; LSTMSequence(); @@ -76,7 +74,6 @@ public: virtual void validate_and_infer_types() override; bool visit_attributes(AttributeVisitor& visitor) override; - virtual OutputVector decompose_op() const override; virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; @@ -138,8 +135,6 @@ private: bool m_input_forget; LSTMWeightsFormat m_weights_format; }; - -NGRAPH_SUPPRESS_DEPRECATED_END } // namespace v0 namespace v5 { diff --git a/ngraph/core/include/ngraph/op/max_pool.hpp b/ngraph/core/include/ngraph/op/max_pool.hpp index 26130dcde28..53096055b64 100644 --- a/ngraph/core/include/ngraph/op/max_pool.hpp +++ b/ngraph/core/include/ngraph/op/max_pool.hpp @@ -89,8 +89,7 @@ public: const op::RoundingType rounding_type = op::RoundingType::FLOOR, const PadType auto_pad = op::PadType::EXPLICIT, const element::Type index_element_type = element::i64, - const int64_t axis = 0, - const float pads_value = -std::numeric_limits::infinity()); + const int64_t axis = 0); bool visit_attributes(AttributeVisitor& visitor) override; void validate_and_infer_types() override; @@ -121,19 +120,10 @@ public: m_axis = axis; } - // \return The value stored in the padding cells. - float get_pads_value() const { - return m_pads_value; - } - void set_pads_value(const float pads_value) { - m_pads_value = pads_value; - } - private: Strides m_dilations; - element::Type m_index_element_type{element::i32}; + element::Type m_index_element_type{element::i64}; int64_t m_axis{0}; - float m_pads_value{-std::numeric_limits::infinity()}; }; } // namespace v8 } // namespace op diff --git a/ngraph/core/include/ngraph/op/mvn.hpp b/ngraph/core/include/ngraph/op/mvn.hpp index 2e69787deb6..406e2893963 100644 --- a/ngraph/core/include/ngraph/op/mvn.hpp +++ b/ngraph/core/include/ngraph/op/mvn.hpp @@ -6,16 +6,14 @@ #include "ngraph/node.hpp" #include "ngraph/op/op.hpp" -#include "ngraph/op/util/fused_op.hpp" namespace ngraph { namespace op { -NGRAPH_SUPPRESS_DEPRECATED_START namespace v0 { /// \brief Operator performing Mean Variance Normalization /// -class NGRAPH_API MVN : public ngraph::op::util::FusedOp { +class NGRAPH_API MVN : public Op { public: NGRAPH_RTTI_DECLARATION; @@ -43,8 +41,6 @@ public: /// MVN(const Output& data, AxisSet reduction_axes, bool normalize_variance = true, double eps = 1e-9); - virtual OutputVector decompose_op() const override; - virtual void validate_and_infer_types() override; bool visit_attributes(AttributeVisitor& visitor) override; @@ -76,8 +72,6 @@ private: } // namespace v0 using v0::MVN; -NGRAPH_SUPPRESS_DEPRECATED_END - /// \brief Specifies how eps is applied in MVN enum class MVNEpsMode { // Apply eps inside sqrt diff --git a/ngraph/core/include/ngraph/op/parameter.hpp b/ngraph/core/include/ngraph/op/parameter.hpp index f2c6cb9cfa1..0795cc5cc7f 100644 --- a/ngraph/core/include/ngraph/op/parameter.hpp +++ b/ngraph/core/include/ngraph/op/parameter.hpp @@ -7,7 +7,6 @@ #include "ngraph/op/op.hpp" namespace ngraph { -class Function; namespace op { namespace v0 { /// \brief A function parameter. @@ -30,7 +29,7 @@ public: void validate_and_infer_types() override; - virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; + std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; bool is_relevant_to_shapes() const; void set_is_relevant_to_shapes(bool is_relevant); diff --git a/ngraph/core/include/ngraph/op/util/multi_subgraph_base.hpp b/ngraph/core/include/ngraph/op/util/multi_subgraph_base.hpp index 1b335a2d457..0cc89d9c387 100644 --- a/ngraph/core/include/ngraph/op/util/multi_subgraph_base.hpp +++ b/ngraph/core/include/ngraph/op/util/multi_subgraph_base.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include #include "ngraph/op/op.hpp" diff --git a/ngraph/core/include/ngraph/op/util/op_annotations.hpp b/ngraph/core/include/ngraph/op/util/op_annotations.hpp index ce122caf6c8..121a4201dce 100644 --- a/ngraph/core/include/ngraph/op/util/op_annotations.hpp +++ b/ngraph/core/include/ngraph/op/util/op_annotations.hpp @@ -6,20 +6,23 @@ #include +#include "ngraph/deprecated.hpp" #include "ngraph/except.hpp" #include "ngraph/ngraph_visibility.hpp" namespace ngraph { namespace op { namespace util { -struct oi_pair { +struct NGRAPH_DEPRECATED("It is obsolete structure and will be removed soon") oi_pair { size_t output; size_t input; bool destructive; }; /// \brief Base class for annotations added to graph ops -class NGRAPH_API OpAnnotations { + +class NGRAPH_DEPRECATED("It is obsolete structure and will be removed soon") NGRAPH_API OpAnnotations { + NGRAPH_SUPPRESS_DEPRECATED_START public: virtual ~OpAnnotations() = default; @@ -47,6 +50,7 @@ private: std::vector m_in_place_oi_pairs; bool m_cacheable = false; + NGRAPH_SUPPRESS_DEPRECATED_END }; } // namespace util } // namespace op diff --git a/ngraph/core/include/ngraph/op/util/variable_context.hpp b/ngraph/core/include/ngraph/op/util/variable_context.hpp index 9deda94f4fc..71253347123 100644 --- a/ngraph/core/include/ngraph/op/util/variable_context.hpp +++ b/ngraph/core/include/ngraph/op/util/variable_context.hpp @@ -5,12 +5,12 @@ #pragma once #include -#include -#include #include #include "ngraph/op/util/variable.hpp" #include "ngraph/op/util/variable_value.hpp" +#include "ngraph/output_vector.hpp" +#include "ngraph/variant.hpp" namespace ngraph { using VariableValuePtr = std::shared_ptr; @@ -70,9 +70,11 @@ private: /// The values associated with a particular Variable. VariableMap m_variable_values; }; +} // namespace ngraph +namespace ov { template <> -class NGRAPH_API VariantWrapper : public VariantImpl { +class NGRAPH_API VariantWrapper : public VariantImpl { public: static constexpr VariantTypeInfo type_info{"Variant::EvaluationContext::VariableContext", 0}; @@ -86,5 +88,4 @@ private: using Variant::init; using Variant::merge; }; - -} // namespace ngraph +} // namespace ov diff --git a/ngraph/core/include/ngraph/op/xor.hpp b/ngraph/core/include/ngraph/op/xor.hpp index 4cb671f950f..34ff6c7675c 100644 --- a/ngraph/core/include/ngraph/op/xor.hpp +++ b/ngraph/core/include/ngraph/op/xor.hpp @@ -33,7 +33,6 @@ public: virtual std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; - bool visit_attributes(AttributeVisitor& visitor) override; bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; bool has_evaluate() const override; }; diff --git a/ngraph/core/include/ngraph/ops.hpp b/ngraph/core/include/ngraph/ops.hpp index 2f07e3ef67a..a6222ae58ad 100644 --- a/ngraph/core/include/ngraph/ops.hpp +++ b/ngraph/core/include/ngraph/ops.hpp @@ -75,6 +75,7 @@ #include "ngraph/op/hsigmoid.hpp" #include "ngraph/op/hswish.hpp" #include "ngraph/op/idft.hpp" +#include "ngraph/op/if.hpp" #include "ngraph/op/interpolate.hpp" #include "ngraph/op/less.hpp" #include "ngraph/op/less_eq.hpp" diff --git a/ngraph/core/include/ngraph/opsets/opset8_tbl.hpp b/ngraph/core/include/ngraph/opsets/opset8_tbl.hpp index 28230bbed02..faf3d65593a 100644 --- a/ngraph/core/include/ngraph/opsets/opset8_tbl.hpp +++ b/ngraph/core/include/ngraph/opsets/opset8_tbl.hpp @@ -182,3 +182,4 @@ NGRAPH_OP(MatrixNms, ngraph::op::v8) NGRAPH_OP(MaxPool, ngraph::op::v8) NGRAPH_OP(MulticlassNms, ngraph::op::v8) NGRAPH_OP(RandomUniform, ngraph::op::v8) +NGRAPH_OP(If, ngraph::op::v8) diff --git a/ngraph/core/include/ngraph/partial_shape.hpp b/ngraph/core/include/ngraph/partial_shape.hpp index 118ac6c75b2..d3bfb76dd4c 100644 --- a/ngraph/core/include/ngraph/partial_shape.hpp +++ b/ngraph/core/include/ngraph/partial_shape.hpp @@ -4,390 +4,10 @@ #pragma once -#include - -#include "ngraph/attribute_adapter.hpp" #include "ngraph/dimension.hpp" -#include "ngraph/op/util/attr_types.hpp" #include "ngraph/rank.hpp" -#include "ngraph/shape.hpp" +#include "openvino/core/partial_shape.hpp" namespace ngraph { -namespace op { -struct AutoBroadcastSpec; -} - -/// \brief Class representing a shape that may be partially or totally dynamic. -/// -/// XXX: THIS CLASS IS EXPERIMENTAL AND THE ENTIRE DESIGN IS SUBJECT TO CHANGE. -/// -/// A PartialShape may have: -/// -/// \li Dynamic rank. (Informal notation: `?`) -/// \li Static rank, but dynamic dimensions on some or all axes. -/// (Informal notation examples: `{1,2,?,4}`, `{?,?,?}`) -/// \li Static rank, and static dimensions on all axes. -/// (Informal notation examples: `{1,2,3,4}`, `{6}`, `{}`) -class NGRAPH_API PartialShape { - using Dimensions = std::vector; - -public: - using iterator = Dimensions::iterator; - using const_iterator = Dimensions::const_iterator; - using reverse_iterator = Dimensions::reverse_iterator; - using const_reverse_iterator = Dimensions::const_reverse_iterator; - - /// \brief Constructs a shape with static rank from an initializer list of Dimension. - /// \param init The Dimension values for the constructed shape. - /// - /// Examples: - /// - /// \code{.cpp} - /// PartialShape s{2,3,4}; // rank=3, all dimensions static - /// PartialShape s{}; // rank=0 - /// PartialShape s{2,Dimension::dynamic(),3}; // rank=3, dimension 1 dynamic - /// \endcode - PartialShape(std::initializer_list init); - - /// \brief Constructs a PartialShape with static rank from a vector of Dimension. - /// \param dimensions The Dimension values for the constructed shape. - PartialShape(std::vector dimensions); - - /// \brief Constructs a PartialShape with static rank from a vector of dimensions values. - /// \param dimensions The Dimension values for the constructed shape. - PartialShape(const std::vector& dimensions); - - /// \brief Constructs a static PartialShape with zero rank (the shape of a scalar). - PartialShape(); - - /// \brief Constructs a static PartialShape from a Shape. - /// \param shape The Shape to convert into PartialShape. - PartialShape(const Shape& shape); - - /// \brief Check if this shape is static. - /// \return `true` if this shape is static, else `false`. - /// - /// A shape is considered static if it has static rank, and all dimensions of the shape - /// are static. - bool is_static() const; - - /// \brief Check if this shape is dynamic. - /// \return `false` if this shape is static, else `true`. - /// - /// A shape is considered static if it has static rank, and all dimensions of the shape - /// are static. - bool is_dynamic() const { - return !is_static(); - } - /// \brief Get the rank of the shape. - /// \return The rank of the shape. This will be Rank::dynamic() if the rank of - /// the shape is dynamic. - Rank rank() const { - return m_rank_is_static ? Rank(m_dimensions.size()) : Rank::dynamic(); - } - /// \brief Construct a PartialShape with the given rank and all dimensions (if any) dynamic. - /// \return A PartialShape with the given rank, and all dimensions (if any) dynamic. - static PartialShape dynamic(Rank r = Rank::dynamic()); - /// \brief Check whether this shape is compatible with the argument, i.e., whether it is - /// possible to merge them. - /// \param s The shape to be checked for compatibility with this shape. - /// \return `true` if this shape is compatible with `s`, else `false`. - /// - /// Two shapes are compatible if - /// \li one or both of them has dynamic rank, or - /// \li both shapes have dynamic and equal rank, and their dimensions are elementwise - /// compatible (see Dimension::compatible()). - bool compatible(const PartialShape& s) const; - - /// \brief Check whether this shape represents the same scheme as the argument. - /// \param s The shape whose scheme is being compared with this shape. - /// \return `true` if this shape represents the same scheme as `s`, else `false`. - /// - /// Two shapes `s1` and `s2` represent the same scheme if - /// \li they both have dynamic rank, or - /// \li they both have static and equal rank `r`, and for every `i` from `0` to `r-1`, - /// `s1[i]` represents the same scheme as `s2[i]` (see Dimension::same_scheme()). - bool same_scheme(const PartialShape& s) const; - - /// \brief Check whether this shape is a relaxation of the argument. - /// \param s The shape which is being compared against this shape. - /// \return `true` if this shape relaxes `s`, else `false`. - /// - /// Intuitively, a PartialShape `s1` is said to _relax_ `s2` (or _is a - /// relaxation_ of `s2`) if it is "more permissive" than `s2`. In other - /// words, `s1` is a relaxation of `s2` if anything you can form by - /// plugging things into the dynamic dimensions of `s2` is also - /// something you can form by plugging things into the dynamic - /// dimensions of `s1`, but not necessarily the other way around. - /// - /// `s1.relaxes(s2)` is equivalent to `s2.refines(s1)`. - /// - /// Formally, PartialShape `s1` is said to _relax_ PartialShape `s2` - /// if: - /// \li For every `i` from `0` to `r-1`, - /// either `s1[i]` contains s2[i]. - bool relaxes(const PartialShape& s) const; - - /// \brief Check whether this shape is a refinement of the argument. - /// \param s The shape which is being compared against this shape. - /// \return `true` if this shape refines `s`, else `false`. - /// - /// Intuitively, a PartialShape `s1` is said to _relax_ `s2` (or _is a - /// relaxation_ of `s2`) if it is "less permissive" than `s2`. In other - /// words, `s1` is a relaxation of `s2` if anything you can form by - /// plugging things into the dynamic dimensions of `s1` is also - /// something you can form by plugging things into the dynamic - /// dimensions of `s2`, but not necessarily the other way around. - /// - /// `s1.refines(s2)` is equivalent to `s2.relaxes(s1)`. - /// - /// Formally, PartialShape `s1` is said to _refine_ PartialShape `s2` - /// if: - /// \li `s2` has dynamic rank, or - /// \li `s1` and `s2` both have static rank `r`, and for every `i` from `0` to `r-1`, - /// either `s2[i]` is dynamic, or `s1[i]` == `s2[i]`. - bool refines(const PartialShape& s) const; - - /// \brief Checks that this shape's rank is compatible with `r`, and, if this shape's - /// rank is dynamic and `r` is static, updates this shape to have a rank of `r` - /// with dimensions all dynamic. - /// \return `true` if this shape's rank is compatible with `r`, else `false`. - bool merge_rank(Rank r); - - /// \brief Convert a static PartialShape to a Shape. - /// \return A new Shape `s` where `s[i] = size_t((*this)[i])`. - /// \throws std::invalid_argument If this PartialShape is dynamic. - Shape to_shape() const; - - /// \brief Returns `true` if all static dimensions of the tensor are non-negative, else - /// `false`. - bool all_non_negative() const; - - /// \brief Index operator for PartialShape. - /// \param i The index of the dimension being selected. - /// \return A reference to the `i`th Dimension of this shape. - const Dimension& operator[](size_t i) const; - /// \brief Index operator for PartialShape. - /// \param i The index of the dimension being selected. - /// \return A reference to the `i`th Dimension of this shape. - Dimension& operator[](size_t i); - /// \brief Returns a vector of the dimensions. This has no meaning if dynamic. - explicit operator std::vector() const { - return m_dimensions; - } - friend NGRAPH_API std::ostream& operator<<(std::ostream& str, const PartialShape& shape); - friend PartialShape operator+(const PartialShape& s1, const PartialShape& s2); - bool operator==(const PartialShape& partial_shape) const; - bool operator!=(const PartialShape& partial_shape) const; - /// Get the max bounding shape - Shape get_max_shape() const; - /// Get the min bounding shape - Shape get_min_shape() const; - /// Get the unique shape - Shape get_shape() const; - - /// \brief Try to merge one shape into another. - /// \param[in,out] dst The shape that `src` will be merged into. - /// \param src The shape that will be merged into `dst`. - /// \return `true` if merging succeeds, else `false`. - /// - /// Merges `src` into `dst`, returning `true` on success and `false` on failure. If - /// `false` is returned, the effect on `dst` is unspecified. - /// - /// To merge two partial shapes `s1` and `s2` is to find the most permissive partial shape - /// `s` that is no more permissive than `s1` or `s2`, if `s` exists. For example: - /// - /// \code - /// merge(?,?) -> ? - /// merge(?,{?,?}) -> {?,?} - /// merge({?,?},{?,?}) -> {?,?} - /// merge({1,2,3,4},?) -> {1,2,3,4} - /// merge({1,2},{1,?}) -> {1,2} - /// merge({1,2,?,?},{1,?,3,?}) -> {1,2,3,?} - /// merge({1,2,3},{1,2,3}) -> {1,2,3} - /// - /// merge({1,?},{2,?}) fails [dimension 0 constraints are inconsistent] - /// merge({?,?},{?,?,?}) fails [ranks are inconsistent] - /// \endcode - /// - /// This function (merge_into) performs the "merge" operation described above on `dst` and - /// `src`, but overwrites `dst` with the result and returns `true` if merging is - /// successful; if merging is unsuccessful, the function returns `false` and may make - /// unspecified changes to `dst`. - static bool merge_into(PartialShape& dst, const PartialShape& src); - - /// \brief Try to merge one shape into another along with implicit broadcasting - static bool broadcast_merge_into(PartialShape& dst, const PartialShape& src, const op::AutoBroadcastSpec& autob); - - /// \brief Returns a read/write iterator that points to the first - /// element in the shape. Iteration is done in ordinary - /// element order. - iterator begin() noexcept { - return m_dimensions.begin(); - } - /// \brief Returns a read-only (constant) iterator that points to the - /// first element in the shape. Iteration is done in ordinary - /// element order. - const_iterator begin() const noexcept { - return cbegin(); - } - /// \brief Returns a read/write iterator that points one past the last - /// element in the shape. Iteration is done in ordinary - /// element order. - iterator end() noexcept { - return m_dimensions.end(); - } - /// \brief Returns a read-only (constant) iterator that points one past - /// the last element in the shape. Iteration is done in ordinary - /// element order. - const_iterator end() const noexcept { - return cend(); - } - /// \brief Returns a read/write reverse iterator that points to the - /// last element in the shape. Iteration is done in reverse - /// element order. - reverse_iterator rbegin() noexcept { - return m_dimensions.rbegin(); - } - /// \brief Returns a read-only (constant) reverse iterator that points - /// to the last element in the shape. Iteration is done in - /// reverse element order. - const_reverse_iterator rbegin() const noexcept { - return crbegin(); - } - /// \brief Returns a read/write reverse iterator that points to one - /// before the first element in the shape. Iteration is done - /// in reverse element order. - reverse_iterator rend() noexcept { - return m_dimensions.rend(); - } - /// \brief Returns a read-only (constant) reverse iterator that points - /// to one before the first element in the shape. Iteration - /// is done in reverse element order. - const_reverse_iterator rend() const noexcept { - return crend(); - } - /// \brief Returns a read-only (constant) iterator that points to the - /// first element in the shape. Iteration is done in ordinary - /// element order. - const_iterator cbegin() const noexcept { - return m_dimensions.cbegin(); - } - /// \brief Returns a read-only (constant) iterator that points one past - /// the last element in the shape. Iteration is done in ordinary - /// element order. - const_iterator cend() const noexcept { - return m_dimensions.cend(); - } - /// \brief Returns a read-only (constant) reverse iterator that points - /// to the last element in the shape. Iteration is done in - /// reverse element order. - const_reverse_iterator crbegin() const noexcept { - return m_dimensions.crbegin(); - } - /// \brief Returns a read-only (constant) reverse iterator that points - /// to one before the first element in the shape. Iteration - /// is done in reverse element order. - const_reverse_iterator crend() const noexcept { - return m_dimensions.crend(); - } - -private: - // Private constructor for PartialShape::dynamic(). - PartialShape(bool rank_is_static, std::vector dimensions); - - // True if the shape's rank is static. - bool m_rank_is_static; - - /// \brief Shape types. The shape type is lazily evaluated by calling the is_static() - /// method. - /// - /// \details It is highly recommended to avoid using the Dimension& operator[](size_t) - /// operator. It sets the shape type to SHAPE_IS_UPDATED and disables shape type caching. - /// Thus, the is_static method will have linear complexity because the shape is not - /// guaranteed to remain static or dynamic. - mutable enum class ShapeType { - SHAPE_IS_UNKNOWN, // The shape type is unknown and should be calculated by checking all - // dimensions. - SHAPE_IS_UPDATED, // User has retained a link to one dimension. Therefore, we can't - // guarantee that the shape will remain static or dynamic, and its - // type will always be evaluated. - SHAPE_IS_STATIC, // The shape type is known and static. Also there are no any retained - // dimensions by non-constant reference. - SHAPE_IS_DYNAMIC // The shape type is dynamic and there are no any retained dimensions - // by non-constant reference. - } m_shape_type{ShapeType::SHAPE_IS_UNKNOWN}; - - // Shape dimensions. This has no meaning if m_rank_is_static is false. - Dimensions m_dimensions; -}; - -/// \brief Elementwise addition of two PartialShape objects. -/// \param s1 Left operand for addition. -/// \param s2 Right operand for addition. -/// \return The result of elementwise adding `s1` to `s2` (see description). -/// \throws std::invalid_argument If `s1` and `s2` have inconsistent ranks. -/// -/// \li If `s1` or `s2` has dynamic rank, returns PartialShape::dynamic(). -/// \li If `s1 and `s2` both have static rank, and their ranks are unequal, throws -/// std::invalid_argument. -/// \li If `s1` and `s2` both have static rank, and their ranks are equal, -/// returns a new shape whose `i`th dimension is `s1[i] + s2[i]`. -PartialShape operator+(const PartialShape& s1, const PartialShape& s2); - -/// \brief Inserts a human-readable representation of a PartialShape into an output stream. -/// \param str The output stream targeted for insertion. -/// \param shape The shape to be inserted into `str`. -/// \return A reference to `str` after insertion. -/// -/// The output to the stream is in "informal" notation. In other words: -/// -/// \li If `shape` has dynamic rank, inserts the string `?`. -/// \li If `shape` has static rank, inserts the string `{`, then inserts each dimension -/// of `shape` into the output stream separated by commas, then inserts `}`. -/// -/// Example: -/// -/// \code{.cpp} -/// PartialShape s1{PartialShape::dynamic())}; -/// PartialShape s2{}; -/// PartialShape s3{1,Dimension::dynamic(),2,3}; -/// PartialShape s4{2,3,4}; -/// std::cout << s1 << std::endl -/// << s2 << std::endl -/// << s3 << std::endl -/// << s4 << std::endl; -/// \endcode -/// -/// Output: -/// -/// \code -/// ? -/// {} -/// {1,?,2,3} -/// {2,3,4} -/// \endcode -NGRAPH_API -std::ostream& operator<<(std::ostream& str, const PartialShape& shape); - -template <> -class NGRAPH_API AttributeAdapter : public ValueAccessor> { -public: - AttributeAdapter(PartialShape& value) : m_ref(value) {} - - const std::vector& get() override; - void set(const std::vector& value) override; - static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; - const DiscreteTypeInfo& get_type_info() const override { - return type_info; - } - operator PartialShape&() { - return m_ref; - } - -protected: - PartialShape& m_ref; - std::vector m_buffer; - bool m_buffer_valid{false}; -}; +using ov::PartialShape; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/rank.hpp b/ngraph/core/include/ngraph/rank.hpp index 3ca58a4c243..2d17092dfb3 100644 --- a/ngraph/core/include/ngraph/rank.hpp +++ b/ngraph/core/include/ngraph/rank.hpp @@ -5,11 +5,8 @@ #pragma once #include "ngraph/dimension.hpp" +#include "openvino/core/rank.hpp" namespace ngraph { -/// \brief Alias for Dimension, used when the value represents the number of axes in a shape, -/// rather than the size of one dimension in a shape. -/// -/// XXX: THIS TYPE IS EXPERIMENTAL AND THE ENTIRE DESIGN IS SUBJECT TO CHANGE. -using Rank = Dimension; +using ov::Rank; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/type/bfloat16.hpp b/ngraph/core/include/ngraph/type/bfloat16.hpp index 7128e8250eb..53179cc6187 100644 --- a/ngraph/core/include/ngraph/type/bfloat16.hpp +++ b/ngraph/core/include/ngraph/type/bfloat16.hpp @@ -4,233 +4,8 @@ #pragma once -#include -#include -#include -#include -#include -#include - -#include "ngraph/ngraph_visibility.hpp" - -#define ROUND_MODE_TO_NEAREST_EVEN +#include "openvino/core/type/bfloat16.hpp" namespace ngraph { -class NGRAPH_API bfloat16 { -public: - constexpr bfloat16() : m_value{0} {} - bfloat16(float value) : m_value { -#if defined ROUND_MODE_TO_NEAREST - round_to_nearest(value) -#elif defined ROUND_MODE_TO_NEAREST_EVEN - round_to_nearest_even(value) -#elif defined ROUND_MODE_TRUNCATE - truncate(value) -#else -# error "ROUNDING_MODE must be one of ROUND_MODE_TO_NEAREST, ROUND_MODE_TO_NEAREST_EVEN, or ROUND_MODE_TRUNCATE" -#endif - } - {} - - template - explicit bfloat16(I value) : m_value{bfloat16{static_cast(value)}.m_value} {} - - std::string to_string() const; - size_t size() const; - template - bool operator==(const T& other) const; - template - bool operator!=(const T& other) const { - return !(*this == other); - } - template - bool operator<(const T& other) const; - template - bool operator<=(const T& other) const; - template - bool operator>(const T& other) const; - template - bool operator>=(const T& other) const; - template - bfloat16 operator+(const T& other) const; - template - bfloat16 operator+=(const T& other); - template - bfloat16 operator-(const T& other) const; - template - bfloat16 operator-=(const T& other); - template - bfloat16 operator*(const T& other) const; - template - bfloat16 operator*=(const T& other); - template - bfloat16 operator/(const T& other) const; - template - bfloat16 operator/=(const T& other); - operator float() const; - - static std::vector to_float_vector(const std::vector&); - static std::vector from_float_vector(const std::vector&); - static constexpr bfloat16 from_bits(uint16_t bits) { - return bfloat16(bits, true); - } - uint16_t to_bits() const; - friend std::ostream& operator<<(std::ostream& out, const bfloat16& obj) { - out << static_cast(obj); - return out; - } - -#define cu32(x) (F32(x).i) - - static uint16_t round_to_nearest_even(float x) { - return static_cast((cu32(x) + ((cu32(x) & 0x00010000) >> 1)) >> 16); - } - - static uint16_t round_to_nearest(float x) { - return static_cast((cu32(x) + 0x8000) >> 16); - } - - static uint16_t truncate(float x) { - return static_cast((cu32(x)) >> 16); - } - -private: - constexpr bfloat16(uint16_t x, bool) : m_value{x} {} - union F32 { - F32(float val) : f{val} {} - F32(uint32_t val) : i{val} {} - float f; - uint32_t i; - }; - - uint16_t m_value; -}; - -template -bool bfloat16::operator==(const T& other) const { -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - return (static_cast(*this) == static_cast(other)); -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif -} - -template -bool bfloat16::operator<(const T& other) const { - return (static_cast(*this) < static_cast(other)); -} - -template -bool bfloat16::operator<=(const T& other) const { - return (static_cast(*this) <= static_cast(other)); -} - -template -bool bfloat16::operator>(const T& other) const { - return (static_cast(*this) > static_cast(other)); -} - -template -bool bfloat16::operator>=(const T& other) const { - return (static_cast(*this) >= static_cast(other)); -} - -template -bfloat16 bfloat16::operator+(const T& other) const { - return {static_cast(*this) + static_cast(other)}; -} - -template -bfloat16 bfloat16::operator+=(const T& other) { - return *this = *this + other; -} - -template -bfloat16 bfloat16::operator-(const T& other) const { - return {static_cast(*this) - static_cast(other)}; -} - -template -bfloat16 bfloat16::operator-=(const T& other) { - return *this = *this - other; -} - -template -bfloat16 bfloat16::operator*(const T& other) const { - return {static_cast(*this) * static_cast(other)}; -} - -template -bfloat16 bfloat16::operator*=(const T& other) { - return *this = *this * other; -} - -template -bfloat16 bfloat16::operator/(const T& other) const { - return {static_cast(*this) / static_cast(other)}; -} - -template -bfloat16 bfloat16::operator/=(const T& other) { - return *this = *this / other; -} +using ov::bfloat16; } // namespace ngraph - -namespace std { -template <> -class numeric_limits { -public: - static constexpr bool is_specialized = true; - static constexpr ngraph::bfloat16 min() noexcept { - return ngraph::bfloat16::from_bits(0x007F); - } - static constexpr ngraph::bfloat16 max() noexcept { - return ngraph::bfloat16::from_bits(0x7F7F); - } - static constexpr ngraph::bfloat16 lowest() noexcept { - return ngraph::bfloat16::from_bits(0xFF7F); - } - static constexpr int digits = 7; - static constexpr int digits10 = 2; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr int radix = 2; - static constexpr ngraph::bfloat16 epsilon() noexcept { - return ngraph::bfloat16::from_bits(0x3C00); - } - static constexpr ngraph::bfloat16 round_error() noexcept { - return ngraph::bfloat16::from_bits(0x3F00); - } - static constexpr int min_exponent = -125; - static constexpr int min_exponent10 = -37; - static constexpr int max_exponent = 128; - static constexpr int max_exponent10 = 38; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; - static constexpr ngraph::bfloat16 infinity() noexcept { - return ngraph::bfloat16::from_bits(0x7F80); - } - static constexpr ngraph::bfloat16 quiet_NaN() noexcept { - return ngraph::bfloat16::from_bits(0x7FC0); - } - static constexpr ngraph::bfloat16 signaling_NaN() noexcept { - return ngraph::bfloat16::from_bits(0x7FC0); - } - static constexpr ngraph::bfloat16 denorm_min() noexcept { - return ngraph::bfloat16::from_bits(0); - } - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = false; - static constexpr bool is_modulo = false; - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_to_nearest; -}; -} // namespace std diff --git a/ngraph/core/include/ngraph/type/element_type.hpp b/ngraph/core/include/ngraph/type/element_type.hpp index 45ef3af2b80..78a5dc1f13a 100644 --- a/ngraph/core/include/ngraph/type/element_type.hpp +++ b/ngraph/core/include/ngraph/type/element_type.hpp @@ -8,194 +8,42 @@ #pragma once -#include -#include -#include -#include -#include - -#include "ngraph/attribute_adapter.hpp" -#include "ngraph/deprecated.hpp" -#include "ngraph/except.hpp" -#include "ngraph/ngraph_visibility.hpp" #include "ngraph/type/bfloat16.hpp" #include "ngraph/type/float16.hpp" +#include "openvino/core/type/element_type.hpp" namespace ngraph { namespace element { -enum class Type_t { - undefined, - dynamic, - boolean, - bf16, - f16, - f32, - f64, - i4, - i8, - i16, - i32, - i64, - u1, - u4, - u8, - u16, - u32, - u64 -}; +using ov::element::Type; +using ov::element::Type_t; +using TypeVector = std::vector; -class NGRAPH_API Type { -public: - Type() : m_type{element::Type_t::undefined} {} - Type(const Type&) = default; - constexpr Type(const Type_t t) : m_type{t} {} - Type(size_t bitwidth, bool is_real, bool is_signed, bool is_quantized, const std::string& cname); - Type& operator=(const Type&) = default; - const std::string& c_type_string() const; - size_t size() const; - size_t hash() const; - bool is_static() const; - bool is_dynamic() const { - return !is_static(); - } - bool is_real() const; - // TODO: We may want to revisit this definition when we do a more general cleanup of - // element types: - bool is_integral() const { - return !is_real(); - } - bool is_integral_number() const; - bool is_signed() const; - bool is_quantized() const; - size_t bitwidth() const; - // The name of this type, the enum name of this type - const std::string& get_type_name() const; - friend NGRAPH_API std::ostream& operator<<(std::ostream&, const Type&); - static std::vector get_known_types(); - - /// \brief Checks whether this element type is merge-compatible with `t`. - /// \param t The element type to compare this element type to. - /// \return `true` if this element type is compatible with `t`, else `false`. - bool compatible(const element::Type& t) const; - - /// \brief Merges two element types t1 and t2, writing the result into dst and - /// returning true if successful, else returning false. - /// - /// To "merge" two element types t1 and t2 is to find the least restrictive - /// element type t that is no more restrictive than t1 and t2, if t exists. - /// More simply: - /// - /// merge(dst,element::Type::dynamic,t) - /// writes t to dst and returns true - /// - /// merge(dst,t,element::Type::dynamic) - /// writes t to dst and returns true - /// - /// merge(dst,t1,t2) where t1, t2 both static and equal - /// writes t1 to dst and returns true - /// - /// merge(dst,t1,t2) where t1, t2 both static and unequal - /// does nothing to dst, and returns false - static bool merge(element::Type& dst, const element::Type& t1, const element::Type& t2); - - // \brief This allows switch(element_type) - constexpr operator Type_t() const { - return m_type; - } - -private: - Type_t m_type{Type_t::undefined}; -}; - -typedef std::vector TypeVector; - -constexpr Type undefined(Type_t::undefined); -constexpr Type dynamic(Type_t::dynamic); -constexpr Type boolean(Type_t::boolean); -constexpr Type bf16(Type_t::bf16); -constexpr Type f16(Type_t::f16); -constexpr Type f32(Type_t::f32); -constexpr Type f64(Type_t::f64); -constexpr Type i4(Type_t::i4); -constexpr Type i8(Type_t::i8); -constexpr Type i16(Type_t::i16); -constexpr Type i32(Type_t::i32); -constexpr Type i64(Type_t::i64); -constexpr Type u1(Type_t::u1); -constexpr Type u4(Type_t::u4); -constexpr Type u8(Type_t::u8); -constexpr Type u16(Type_t::u16); -constexpr Type u32(Type_t::u32); -constexpr Type u64(Type_t::u64); +using ov::element::bf16; +using ov::element::boolean; +using ov::element::dynamic; +using ov::element::f16; +using ov::element::f32; +using ov::element::f64; +using ov::element::i16; +using ov::element::i32; +using ov::element::i4; +using ov::element::i64; +using ov::element::i8; +using ov::element::u1; +using ov::element::u16; +using ov::element::u32; +using ov::element::u4; +using ov::element::u64; +using ov::element::u8; +using ov::element::undefined; template Type from() { - throw std::invalid_argument("Unknown type"); + return ov::element::from(); } -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); -template <> -NGRAPH_API Type from(); - -NGRAPH_API -std::ostream& operator<<(std::ostream& out, const ngraph::element::Type& obj); } // namespace element -template <> -class NGRAPH_API AttributeAdapter : public EnumAttributeAdapterBase { -public: - AttributeAdapter(element::Type_t& value) : EnumAttributeAdapterBase(value) {} - - static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; - const DiscreteTypeInfo& get_type_info() const override { - return type_info; - } -}; - -template <> -class NGRAPH_API AttributeAdapter : public ValueAccessor { -public: - AttributeAdapter(element::Type& value) : m_ref(value) {} - - const std::string& get() override; - void set(const std::string& value) override; - - static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; - const DiscreteTypeInfo& get_type_info() const override { - return type_info; - } - operator element::Type&() { - return m_ref; - } - -protected: - element::Type& m_ref; -}; - /// \brief Return the number of bytes in the compile-time representation of the element type. +NGRAPH_DEPRECATED("This method is deprecated and will be removed soon") size_t compiler_byte_size(element::Type_t et); } // namespace ngraph diff --git a/ngraph/core/include/ngraph/type/element_type_traits.hpp b/ngraph/core/include/ngraph/type/element_type_traits.hpp index 6d37c3776f0..abbf9551809 100644 --- a/ngraph/core/include/ngraph/type/element_type_traits.hpp +++ b/ngraph/core/include/ngraph/type/element_type_traits.hpp @@ -4,92 +4,11 @@ #pragma once -#include "ngraph/type/element_type.hpp" +#include "openvino/core/type/element_type_traits.hpp" namespace ngraph { -template -struct element_type_traits {}; +using ov::element_type_traits; -template -using fundamental_type_for = typename element_type_traits::value_type; +using ov::fundamental_type_for; -template <> -struct element_type_traits { - using value_type = char; -}; - -template <> -struct element_type_traits { - using value_type = bfloat16; -}; - -template <> -struct element_type_traits { - using value_type = float16; -}; - -template <> -struct element_type_traits { - using value_type = float; -}; - -template <> -struct element_type_traits { - using value_type = double; -}; - -template <> -struct element_type_traits { - using value_type = int8_t; -}; - -template <> -struct element_type_traits { - using value_type = int8_t; -}; - -template <> -struct element_type_traits { - using value_type = int16_t; -}; - -template <> -struct element_type_traits { - using value_type = int32_t; -}; - -template <> -struct element_type_traits { - using value_type = int64_t; -}; - -template <> -struct element_type_traits { - using value_type = int8_t; -}; - -template <> -struct element_type_traits { - using value_type = int8_t; -}; - -template <> -struct element_type_traits { - using value_type = uint8_t; -}; - -template <> -struct element_type_traits { - using value_type = uint16_t; -}; - -template <> -struct element_type_traits { - using value_type = uint32_t; -}; - -template <> -struct element_type_traits { - using value_type = uint64_t; -}; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/type/float16.hpp b/ngraph/core/include/ngraph/type/float16.hpp index 6a7bdf62dbb..64418d426a5 100644 --- a/ngraph/core/include/ngraph/type/float16.hpp +++ b/ngraph/core/include/ngraph/type/float16.hpp @@ -4,216 +4,8 @@ #pragma once -#include -#include -#include -#include -#include -#include - -#include "ngraph/ngraph_visibility.hpp" - -#define ROUND_MODE_TO_NEAREST_EVEN +#include "openvino/core/type/float16.hpp" namespace ngraph { -class NGRAPH_API float16 { -public: - constexpr float16() : m_value{0} {} - - static uint32_t constexpr frac_size = 10; - static uint32_t constexpr exp_size = 5; - static uint32_t constexpr exp_bias = 15; - - float16(uint32_t sign, uint32_t biased_exponent, uint32_t fraction) - : m_value((sign & 0x01) << 15 | (biased_exponent & 0x1F) << 10 | (fraction & 0x03FF)) {} - - float16(float value); - - template - explicit float16(I value) : m_value{float16{static_cast(value)}.m_value} {} - - std::string to_string() const; - size_t size() const; - template - bool operator==(const T& other) const; - template - bool operator!=(const T& other) const { - return !(*this == other); - } - template - bool operator<(const T& other) const; - template - bool operator<=(const T& other) const; - template - bool operator>(const T& other) const; - template - bool operator>=(const T& other) const; - template - float16 operator+(const T& other) const; - template - float16 operator+=(const T& other); - template - float16 operator-(const T& other) const; - template - float16 operator-=(const T& other); - template - float16 operator*(const T& other) const; - template - float16 operator*=(const T& other); - template - float16 operator/(const T& other) const; - template - float16 operator/=(const T& other); - operator float() const; - - static constexpr float16 from_bits(uint16_t bits) { - return float16(bits, true); - } - uint16_t to_bits() const; - friend std::ostream& operator<<(std::ostream& out, const float16& obj) { - out << static_cast(obj); - return out; - } - -private: - constexpr float16(uint16_t x, bool) : m_value{x} {} - union F32 { - F32(float val) : f{val} {} - F32(uint32_t val) : i{val} {} - float f; - uint32_t i; - }; - - uint16_t m_value; -}; - -template -bool float16::operator==(const T& other) const { -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - return (static_cast(*this) == static_cast(other)); -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif -} - -template -bool float16::operator<(const T& other) const { - return (static_cast(*this) < static_cast(other)); -} - -template -bool float16::operator<=(const T& other) const { - return (static_cast(*this) <= static_cast(other)); -} - -template -bool float16::operator>(const T& other) const { - return (static_cast(*this) > static_cast(other)); -} - -template -bool float16::operator>=(const T& other) const { - return (static_cast(*this) >= static_cast(other)); -} - -template -float16 float16::operator+(const T& other) const { - return {static_cast(*this) + static_cast(other)}; -} - -template -float16 float16::operator+=(const T& other) { - return *this = *this + other; -} - -template -float16 float16::operator-(const T& other) const { - return {static_cast(*this) - static_cast(other)}; -} - -template -float16 float16::operator-=(const T& other) { - return *this = *this - other; -} - -template -float16 float16::operator*(const T& other) const { - return {static_cast(*this) * static_cast(other)}; -} - -template -float16 float16::operator*=(const T& other) { - return *this = *this * other; -} - -template -float16 float16::operator/(const T& other) const { - return {static_cast(*this) / static_cast(other)}; -} - -template -float16 float16::operator/=(const T& other) { - return *this = *this / other; -} +using ov::float16; } // namespace ngraph - -namespace std { -bool NGRAPH_API isnan(ngraph::float16 x); - -template <> -class numeric_limits { -public: - static constexpr bool is_specialized = true; - static constexpr ngraph::float16 min() noexcept { - return ngraph::float16::from_bits(0x0200); - } - static constexpr ngraph::float16 max() noexcept { - return ngraph::float16::from_bits(0x7BFF); - } - static constexpr ngraph::float16 lowest() noexcept { - return ngraph::float16::from_bits(0xFBFF); - } - static constexpr int digits = 11; - static constexpr int digits10 = 3; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr int radix = 2; - static constexpr ngraph::float16 epsilon() noexcept { - return ngraph::float16::from_bits(0x1200); - } - static constexpr ngraph::float16 round_error() noexcept { - return ngraph::float16::from_bits(0x3C00); - } - static constexpr int min_exponent = -13; - static constexpr int min_exponent10 = -4; - static constexpr int max_exponent = 16; - static constexpr int max_exponent10 = 4; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; - static constexpr ngraph::float16 infinity() noexcept { - return ngraph::float16::from_bits(0x7C00); - } - static constexpr ngraph::float16 quiet_NaN() noexcept { - return ngraph::float16::from_bits(0x7FFF); - } - static constexpr ngraph::float16 signaling_NaN() noexcept { - return ngraph::float16::from_bits(0x7DFF); - } - static constexpr ngraph::float16 denorm_min() noexcept { - return ngraph::float16::from_bits(0); - } - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = false; - static constexpr bool is_modulo = false; - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_to_nearest; -}; -} // namespace std diff --git a/ngraph/core/include/ngraph/util.hpp b/ngraph/core/include/ngraph/util.hpp index 9a169f4c8e8..257912d455a 100644 --- a/ngraph/core/include/ngraph/util.hpp +++ b/ngraph/core/include/ngraph/util.hpp @@ -28,7 +28,6 @@ namespace ngraph { class Node; -class Function; class stopwatch; namespace runtime { diff --git a/ngraph/core/include/ngraph/variant.hpp b/ngraph/core/include/ngraph/variant.hpp index 7cb5362a812..1da8b047988 100644 --- a/ngraph/core/include/ngraph/variant.hpp +++ b/ngraph/core/include/ngraph/variant.hpp @@ -7,90 +7,30 @@ #include #include -#include "ngraph/ngraph_visibility.hpp" -#include "ngraph/output_vector.hpp" -#include "ngraph/type.hpp" +#include "openvino/core/variant.hpp" namespace ngraph { -class Node; -using VariantTypeInfo = DiscreteTypeInfo; +using ov::VariantTypeInfo; -class NGRAPH_API Variant { -public: - virtual ~Variant(); - virtual const VariantTypeInfo& get_type_info() const = 0; - - virtual std::shared_ptr init(const std::shared_ptr& node); - virtual std::shared_ptr merge(const ngraph::NodeVector& nodes); - virtual bool is_copyable() const; - virtual std::string to_string() { - return ""; - } -}; - -template -class VariantImpl : public Variant { -public: - using value_type = VT; - - VariantImpl(const value_type& value) : m_value(value) {} - - const value_type& get() const { - return m_value; - } - value_type& get() { - return m_value; - } - void set(const value_type& value) { - m_value = value; - } - -protected: - value_type m_value; -}; - -extern template class NGRAPH_API VariantImpl; -extern template class NGRAPH_API VariantImpl; - -template -class VariantWrapper {}; - -template <> -class NGRAPH_API VariantWrapper : public VariantImpl { -public: - static constexpr VariantTypeInfo type_info{"Variant::std::string", 0}; - const VariantTypeInfo& get_type_info() const override { - return type_info; - } - VariantWrapper(const value_type& value) : VariantImpl(value) {} -}; - -template <> -class NGRAPH_API VariantWrapper : public VariantImpl { -public: - static constexpr VariantTypeInfo type_info{"Variant::int64_t", 0}; - const VariantTypeInfo& get_type_info() const override { - return type_info; - } - VariantWrapper(const value_type& value) : VariantImpl(value) {} -}; +using ov::Variant; +using ov::VariantImpl; +using ov::VariantWrapper; template inline std::shared_ptr make_variant(const T& p) { - return std::dynamic_pointer_cast>(std::make_shared>(p)); + return ov::make_variant(p); } - template inline std::shared_ptr make_variant(const char (&s)[N]) { - return std::dynamic_pointer_cast>(std::make_shared>(s)); + return ov::make_variant(s); } #if defined(ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32) template inline std::shared_ptr make_variant(const wchar_t (&s)[N]) { - return std::dynamic_pointer_cast>(std::make_shared>(s)); + return ov::make_variant(s); } #endif -using RTMap = std::map>; +using ov::RTMap; } // namespace ngraph diff --git a/ngraph/core/include/ngraph/visibility.hpp b/ngraph/core/include/ngraph/visibility.hpp index 99ce1d76319..af6a1451bf1 100644 --- a/ngraph/core/include/ngraph/visibility.hpp +++ b/ngraph/core/include/ngraph/visibility.hpp @@ -2,18 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -// https://gcc.gnu.org/wiki/Visibility -// Generic helper definitions for shared library support -#if defined _WIN32 || defined __CYGWIN__ -# define NGRAPH_HELPER_DLL_IMPORT __declspec(dllimport) -# define NGRAPH_HELPER_DLL_EXPORT __declspec(dllexport) -# define NGRAPH_HELPER_DLL_LOCAL -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define NGRAPH_HELPER_DLL_IMPORT __attribute__((visibility("default"))) -# define NGRAPH_HELPER_DLL_EXPORT __attribute__((visibility("default"))) -# define NGRAPH_HELPER_DLL_LOCAL __attribute__((visibility("hidden"))) -#else -# define NGRAPH_HELPER_DLL_IMPORT -# define NGRAPH_HELPER_DLL_EXPORT -# define NGRAPH_HELPER_DLL_LOCAL -#endif +#include + +#define NGRAPH_HELPER_DLL_IMPORT CORE_HELPER_DLL_IMPORT +#define NGRAPH_HELPER_DLL_EXPORT CORE_HELPER_DLL_EXPORT +#define NGRAPH_HELPER_DLL_LOCAL CORE_HELPER_DLL_LOCAL diff --git a/ngraph/core/include/openvino/core/core_visibility.hpp b/ngraph/core/include/openvino/core/core_visibility.hpp new file mode 100644 index 00000000000..85adf6c1307 --- /dev/null +++ b/ngraph/core/include/openvino/core/core_visibility.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "openvino/core/visibility.hpp" + +#define OV_NEW_API 1 +// Now we use the generic helper definitions above to define NGRAPH_API +// NGRAPH_API is used for the public API symbols. It either DLL imports or DLL exports +// (or does nothing for static build) + +#ifdef _WIN32 +# pragma warning(disable : 4251) +# pragma warning(disable : 4275) +#endif + +#ifdef NGRAPH_STATIC_LIBRARY // defined if we are building or calling NGRAPH as a static library +# define OPENVINO_API +#else +# ifdef ngraph_EXPORTS // defined if we are building the NGRAPH DLL (instead of using it) +# define OPENVINO_API CORE_HELPER_DLL_EXPORT +# else +# define OPENVINO_API CORE_HELPER_DLL_IMPORT +# endif // ngraph_EXPORTS +#endif // NGRAPH_STATIC_LIBRARY + +#ifndef ENABLE_UNICODE_PATH_SUPPORT +# ifdef _WIN32 +# if defined __INTEL_COMPILER || defined _MSC_VER +# define ENABLE_UNICODE_PATH_SUPPORT +# endif +# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__) +# define ENABLE_UNICODE_PATH_SUPPORT +# endif +#endif diff --git a/ngraph/core/include/openvino/core/deprecated.hpp b/ngraph/core/include/openvino/core/deprecated.hpp new file mode 100644 index 00000000000..2d885ba9439 --- /dev/null +++ b/ngraph/core/include/openvino/core/deprecated.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +// +// The OPENVINO_DEPRECATED macro can be used to deprecate a function declaration. For example: +// +// OPENVINO_DEPRECATED("replace with groxify"); +// void frobnicate() +// +// The macro will expand to a deprecation attribute supported by the compiler, +// so any use of `frobnicate` will produce a compiler warning. +// + +#if defined(_WIN32) +# define OPENVINO_DEPRECATED(msg) __declspec(deprecated(msg)) +# if __cplusplus >= 201402L +# define OPENVINO_ENUM_DEPRECATED(msg) [[deprecated(msg)]] +# else +# define OPENVINO_ENUM_DEPRECATED(msg) +# endif +#elif defined(__INTEL_COMPILER) +# define OPENVINO_DEPRECATED(msg) __attribute__((deprecated(msg))) +# define OPENVINO_ENUM_DEPRECATED(msg) OPENVINO_DEPRECATED(msg) +#elif defined(__GNUC__) +# define OPENVINO_DEPRECATED(msg) __attribute__((deprecated((msg)))) +# if __GNUC__ < 6 && !defined(__clang__) +# define OPENVINO_ENUM_DEPRECATED(msg) +# else +# define OPENVINO_ENUM_DEPRECATED(msg) OPENVINO_DEPRECATED(msg) +# endif +#else +# define OPENVINO_DEPRECATED(msg) +# define OPENVINO_ENUM_DEPRECATED(msg) +#endif + +// Suppress warning "-Wdeprecated-declarations" / C4996 +#if defined(_MSC_VER) +# define OPENVINO_DO_PRAGMA(x) __pragma(x) +#elif defined(__GNUC__) +# define OPENVINO_DO_PRAGMA(x) _Pragma(# x) +#else +# define OPENVINO_DO_PRAGMA(x) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +# define OPENVINO_SUPPRESS_DEPRECATED_START \ + OPENVINO_DO_PRAGMA(warning(push)) \ + OPENVINO_DO_PRAGMA(warning(disable : 4996)) +# define OPENVINO_SUPPRESS_DEPRECATED_END OPENVINO_DO_PRAGMA(warning(pop)) +#elif defined(__INTEL_COMPILER) +# define OPENVINO_SUPPRESS_DEPRECATED_START \ + OPENVINO_DO_PRAGMA(warning(push)) \ + OPENVINO_DO_PRAGMA(warning(disable : 1478)) +OPENVINO_DO_PRAGMA(warning(disable : 1786)) +# define OPENVINO_SUPPRESS_DEPRECATED_END OPENVINO_DO_PRAGMA(warning(pop)) +#elif defined(__clang__) || ((__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 405)) +# define OPENVINO_SUPPRESS_DEPRECATED_START \ + OPENVINO_DO_PRAGMA(GCC diagnostic push) \ + OPENVINO_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations") +# define OPENVINO_SUPPRESS_DEPRECATED_END OPENVINO_DO_PRAGMA(GCC diagnostic pop) +#else +# define OPENVINO_SUPPRESS_DEPRECATED_START +# define OPENVINO_SUPPRESS_DEPRECATED_END +#endif diff --git a/ngraph/core/include/openvino/core/dimension.hpp b/ngraph/core/include/openvino/core/dimension.hpp new file mode 100644 index 00000000000..e5423267754 --- /dev/null +++ b/ngraph/core/include/openvino/core/dimension.hpp @@ -0,0 +1,172 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "openvino/core/core_visibility.hpp" +#include "openvino/core/interval.hpp" + +namespace ov { +/// \brief Class representing a dimension, which may be dynamic (undetermined until runtime), +/// in a shape or shape-like object. +/// +/// Static dimensions may be implicitly converted from value_type. A dynamic dimension is +/// constructed with Dimension() or Dimension::dynamic(). +class OPENVINO_API Dimension { +public: + using value_type = int64_t; + + /// \brief Construct a static dimension. + /// \param dimension Value of the dimension. + Dimension(value_type dimension); + + /// \brief Construct a dynamic dimension with bounded range + /// \param min_dimension The lower inclusive limit for the dimension + /// \param mas_dimension The upper inclusive limit for the dimension + Dimension(value_type min_dimension, value_type max_dimension); + + /// \brief Construct a dynamic dimension with range [0, ...] + Dimension() = default; + + bool operator==(const Dimension& dimension) const { + return m_dimension == dimension.m_dimension; + } + bool operator!=(const Dimension& dimension) const { + return m_dimension != dimension.m_dimension; + } + /// \brief Check whether this dimension is static. + /// \return `true` if the dimension is static, else `false`. + bool is_static() const { + return m_dimension.size() == 1; + } + /// \brief Check whether this dimension is dynamic. + /// \return `false` if the dimension is static, else `true`. + bool is_dynamic() const { + return m_dimension.size() != 1; + } + /// \brief Convert this dimension to `value_type`. This dimension must be static and + /// non-negative. + /// \throws std::invalid_argument If this dimension is dynamic or negative. + value_type get_length() const; + + value_type get_min_length() const; + value_type get_max_length() const; + + /// \brief Return the interval of valid lengths + const Interval& get_interval() const { + return m_dimension; + } + Interval& get_interval() { + return m_dimension; + } + /// \brief Check whether this dimension represents the same scheme as the argument (both + /// dynamic, or equal). + /// \param dim The other dimension to compare this dimension to. + /// \return `true` if this dimension and `dim` are both dynamic, or if they are both + /// static and equal; otherwise, `false`. + bool same_scheme(const Dimension& dim) const; + /// \brief Try to merge two Dimension objects together. + /// \param[out] dst Reference to write the merged Dimension into. + /// \param d1 First dimension to merge. + /// \param d2 Second dimension to merge. + /// \return `true` if merging succeeds, else `false`. + /// + /// \li If `d1` is dynamic, writes `d2` to `dst` and returns `true`. + /// \li If `d2` is dynamic, writes `d1` to `dst` and returns `true`. + /// \li If `d1` and `d2` are static and equal, writes `d1` to `dst` and returns `true`. + /// \li If `d1` and `d2` are both static and unequal, leaves `dst` unchanged and + /// returns `false`. + static bool merge(Dimension& dst, const Dimension d1, const Dimension d2); + + /// \brief Try to merge two Dimension objects together with implicit broadcasting + /// of unit-sized dimension to non unit-sized dimension + static bool broadcast_merge(Dimension& dst, const Dimension d1, const Dimension d2); + + /// \brief Check whether this dimension is capable of being merged with the argument + /// dimension. + /// \param d The dimension to compare this dimension with. + /// \return `true` if this dimension is compatible with `d`, else `false`. + /// + /// Two dimensions are considered compatible if it is possible to merge them. (See + /// Dimension::merge.) + bool compatible(const Dimension& d) const; + + /// \brief Check whether this dimension is a relaxation of the argument. + /// \param d The dimension to compare this dimension with. + /// \return `true` if this dimension relaxes `d`, else `false`. + /// + /// A dimension `d1` _relaxes_ (or _is a relaxation of_) `d2` if `d1` and `d2` are static + /// and equal, or `d1` is dynamic. + /// + /// `d1.relaxes(d2)` is equivalent to `d2.refines(d1)`. + bool relaxes(const Dimension& d) const; + + /// \brief Check whether this dimension is a refinement of the argument. + /// \param d The dimension to compare this dimension with. + /// \return `true` if this dimension relaxes `d`, else `false`. + /// + /// A dimension `d2` _refines_ (or _is a refinement of_) `d1` if `d1` and `d2` are static + /// and equal, or `d2` is dynamic. + /// + /// `d1.refines(d2)` is equivalent to `d2.relaxes(d1)`. + bool refines(const Dimension& d) const; + + /// \brief Create a dynamic dimension. + /// \return A dynamic dimension. + static Dimension dynamic() { + return Dimension(); + } + /// \brief Addition operator for Dimension. + /// \param dim Right operand for addition. + /// \return Smallest interval dimension enclosing inputs + Dimension operator+(const Dimension& dim) const; + + /// \brief Subtraction operator for Dimension. + /// \param dim Right operand for subtraction. + /// \return Smallest interval dimension enclosing inputs + Dimension operator-(const Dimension& dim) const; + + /// \brief Multiplication operator for Dimension. + /// \param dim Right operand for multiplicaiton. + /// \return Smallest interval containing all "produces" which are 0 if either of `this` or + /// `dim` has length `0`, else unbounded if either is unbounded, else product of lengths. + Dimension operator*(const Dimension& dim) const; + + /// \brief Add-into operator for Dimension. + /// \param dim Right operand for addition. + /// \return A reference to `*this`, after updating `*this` to the value `*this + dim`. + Dimension& operator+=(const Dimension& dim) { + return (*this = *this + dim); + } + /// \brief Multiply-into operator for Dimension. + /// \param dim Right operand for multiplication. + /// \return A reference to `*this`, after updating `*this` to the value `*this * dim`. + Dimension& operator*=(const Dimension& dim) { + return (*this = *this * dim); + } + /// \brief Intersection of dimensions + Dimension operator&(const Dimension& dim) const; + /// \brief Intersection of dimensions + Dimension& operator&=(const Dimension& dim); + +private: + Dimension(const Interval& interval) : m_dimension(interval) {} + + // The actual numerical value of the dimension. + Interval m_dimension{}; +}; + +/// \brief Insert a human-readable representation of a dimension into an output stream. +/// \param str The output stream targeted for insertion. +/// \param dimension The dimension to be inserted into `str`. +/// \return A reference to `str` after insertion. +/// +/// Inserts the string `?` if `dimension` is dynamic; else inserts `dimension.get_length()`. +OPENVINO_API +std::ostream& operator<<(std::ostream& str, const Dimension& dimension); +} // namespace ov diff --git a/ngraph/core/include/openvino/core/function.hpp b/ngraph/core/include/openvino/core/function.hpp new file mode 100644 index 00000000000..81607040dea --- /dev/null +++ b/ngraph/core/include/openvino/core/function.hpp @@ -0,0 +1,289 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "ngraph/node.hpp" +#include "ngraph/op/assign.hpp" +#include "ngraph/op/parameter.hpp" +#include "ngraph/op/read_value.hpp" +#include "ngraph/op/result.hpp" +#include "ngraph/op/sink.hpp" +#include "ngraph/op/util/variable.hpp" +#include "openvino/core/core_visibility.hpp" + +namespace ov { +/// A user-defined function. +class OPENVINO_API Function { +public: + static constexpr ngraph::DiscreteTypeInfo type_info{"Function", 0}; + const ngraph::DiscreteTypeInfo& get_type_info() const { + return type_info; + } + Function(const ngraph::NodeVector& results, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const ngraph::OutputVector& results, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const std::shared_ptr& result, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const ngraph::ResultVector& results, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const ngraph::ResultVector& results, + const ngraph::SinkVector& sinks, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const ngraph::OutputVector& results, + const ngraph::SinkVector& sinks, + const ngraph::ParameterVector& parameters, + const std::string& name = ""); + + Function(const ngraph::ResultVector& results, + const ngraph::SinkVector& sinks, + const ngraph::ParameterVector& parameters, + const ngraph::VariableVector& variables, + const std::string& name = ""); + + Function(const ngraph::OutputVector& results, + const ngraph::SinkVector& sinks, + const ngraph::ParameterVector& parameters, + const ngraph::VariableVector& variables, + const std::string& name = ""); + + Function(const ngraph::ResultVector& results, + const ngraph::ParameterVector& parameters, + const ngraph::VariableVector& variables, + const std::string& name = ""); + + Function(const ngraph::OutputVector& results, + const ngraph::ParameterVector& parameters, + const ngraph::VariableVector& variables, + const std::string& name = ""); + + /// Constructs a Function. Lists of parameters and variables will be generated automatically + /// based on traversing the graph from the results. + explicit Function(const ngraph::OutputVector& results, const std::string& name = ""); + + /// Constructs a Function. Lists of parameters and variables will be generated automatically + /// based on traversing the graph from the results and the sinks. + Function(const ngraph::OutputVector& results, const ngraph::SinkVector& sinks, const std::string& name = ""); + + virtual ~Function() = default; + /// Return the number of outputs for this function. + size_t get_output_size() const; + + /// Return the op that generates output i + std::shared_ptr get_output_op(size_t i) const; + + ngraph::Output output(size_t i) const; + + /// Return the element type of output i + const ngraph::element::Type& get_output_element_type(size_t i) const; + + /// Return the shape of element i + const ngraph::Shape& get_output_shape(size_t i) const; + + /// Return the partial shape of element i + const ngraph::PartialShape& get_output_partial_shape(size_t i) const; + + /// Check that there is a single result and return it. + std::shared_ptr get_result() const; + + /// \brief Get the unique name of the function. + /// \returns A const reference to the function's unique name. + const std::string& get_name() const; + + /// \brief Sets a friendly name for a function. This does not overwrite the unique name + /// of the function and is retrieved via get_friendly_name(). Used mainly for + /// debugging. + /// \param name is the friendly name to set + void set_friendly_name(const std::string& name); + + /// \brief Gets the friendly name for a function. If no friendly name has been set via + /// set_friendly_name then the function's unique name is returned. + /// \returns A const reference to the function's friendly name. + const std::string& get_friendly_name() const; + + std::vector> get_ops() const; + std::vector> get_ordered_ops() const; + void map_unordered_ops(std::function f) const; + + friend std::ostream& operator<<(std::ostream&, const Function&); + // updates graph and m_results list + void replace_node(std::shared_ptr old, std::shared_ptr repl); + + void validate_nodes_and_infer_types() const; + + /// \brief Returns the sum of the size of all nodes in the graph plus the size of + /// all constant data. This has little value beyond comparing the relative size of + /// graphs and should not be considered the actual memory consumption of a graph. + size_t get_graph_size() const; + + /// \brief Returns true if any of the op's defined in the function contains partial shape + bool is_dynamic() const; + + /// \brief Replace the `parameter_index`th parameter of the function with `parameter`. + /// + /// All users of the `parameter_index`th parameter are redirected to `parameter`, and the + /// `parameter_index`th entry in the function parameter list is replaced with `parameter`. + /// + /// \param parameter_index The index of the parameter to replace. + /// \param parameter The parameter to substitute for the `parameter_index`th parameter. + void replace_parameter(size_t parameter_index, const std::shared_ptr& parameter); + + using topological_sort_t = std::function>( + const std::vector>& root_nodes)>; + void set_topological_sort(topological_sort_t); + + virtual bool visit_attributes(ngraph::AttributeVisitor& visitor); + + /// Return the function parameters + const ngraph::ParameterVector& get_parameters() const { + return m_parameters; + }; + /// Return a list of function's outputs + const ngraph::ResultVector& get_results() const { + return m_results; + }; + /// Index for parameter, or -1 + int64_t get_parameter_index(const std::shared_ptr& parameter) const; + + /// Index for value or result referencing it, or -1 + int64_t get_result_index(const ngraph::Output& value) const; + + /// \brief Evaluate the function on inputs, putting results in outputs. + /// \param output_tensors Tensors for the outputs to compute. One for each result + /// \param input_tensors Tensors for the inputs. One for each inputs. + /// \param evaluation_context Storage of additional settings and attributes that can be used + /// when evaluating the function. This additional information can be shared across nodes. + bool evaluate(const ngraph::HostTensorVector& output_tensors, + const ngraph::HostTensorVector& input_tensors, + ngraph::EvaluationContext evaluation_context = ngraph::EvaluationContext()) const; + + /// \brief Return a list of function's sinks. + const ngraph::SinkVector& get_sinks() const { + return m_sinks; + } + /// \brief Add new sink nodes to the list. Method doesn't validate graph, it should be done + /// manually after all changes. + /// \param sinks new sink nodes + void add_sinks(const ngraph::SinkVector& sinks); + + /// \brief Delete sink node from the list of sinks. Method doesn't delete node from graph. + /// \param sink Sink to delete + void remove_sink(const std::shared_ptr& sink); + + /// \brief Add new Result nodes to the list. Method doesn't validate graph, it should be + /// done manually after all changes. + /// \param results new Result nodes + void add_results(const ngraph::ResultVector& results); + + /// \brief Delete Result node from the list of results. Method will not delete node from + /// graph. + /// \param result Result node to delete + void remove_result(const std::shared_ptr& result); + + /// \brief Add new Parameter nodes to the list. + /// + /// Method doesn't change or validate graph, it should be done manually. + /// For example, if you want to replace `ReadValue` node by `Parameter`, you should do the + /// following steps: + /// * replace node `ReadValue` by `Parameter` in graph + /// * call add_parameter() to add new input to the list + /// * call graph validation to check correctness of changes + /// + /// \param params new Parameter nodes + void add_parameters(const ngraph::ParameterVector& params); + + /// \brief Delete Parameter node from the list of parameters. Method will not delete node + /// from graph. You need to replace Parameter with other operation manually. + /// Attention: Indexing of parameters can be changed. + /// + /// Possible use of method is to replace input by variable. For it the following steps + /// should be done: + /// * `Parameter` node should be replaced by `ReadValue` + /// * call remove_parameter(param) to remove input from the list + /// * check if any parameter indexes are saved/used somewhere, update it for all inputs + /// because indexes can be changed + /// * call graph validation to check all changes + /// + /// \param param Parameter node to delete + void remove_parameter(const std::shared_ptr& param); + + /// \brief Add new variables to the list. Method doesn't validate graph, it should be done + /// manually after all changes. + /// \param variables new variables to add + void add_variables(const ngraph::VariableVector& variables); + + /// \brief Delete variable from the list of variables. + /// Method doesn't delete nodes that used this variable from the graph. + /// \param variable Variable to delete + void remove_variable(const ngraph::VariablePtr& variable); + + /// \brief Return a list of function's variables. + const ngraph::VariableVector& get_variables() const { + return m_variables; + } + + /// \brief Return a variable by specified variable_id. + ngraph::VariablePtr get_variable_by_id(const std::string& variable_id) const; + +private: + Function(const Function&) = delete; + Function(const Function&&) = delete; + Function& operator=(const Function&) = delete; + + /// \brief Depending on the options selected, + /// checks all the Parameter/Variables are registered in the list of Function + /// parameters/variables or finds all Parameters/Variables in a function and registers them. + /// \param detect_variables If this flag is true, then it finds all Variables in a function + /// and registers them, otherwise checks all the Variables are registered. + /// \param detect_parameters If this flag is true, then it finds all Parameters in a + /// function and registers them, otherwise checks all the Parameters are registered. + void prerequirements(bool detect_variables, bool detect_parameters); + + static std::atomic m_next_instance_id; + std::string m_name; + const std::string m_unique_name; + size_t m_placement{0}; + topological_sort_t m_topological_sorter; + + ngraph::ResultVector m_results; + // List of the nodes with side effect in graph. + // These nodes are not outputs of graph but should not be removed even if have no children. + ngraph::SinkVector m_sinks; + ngraph::ParameterVector m_parameters; + ngraph::VariableVector m_variables; +}; + +} // namespace ov +namespace ngraph { +template <> +class NGRAPH_API AttributeAdapter> + : public DirectValueAccessor> { +public: + AttributeAdapter(std::shared_ptr& value) + : DirectValueAccessor>(value) {} + + static constexpr DiscreteTypeInfo type_info{"AttributeAdapter>", 0}; + const DiscreteTypeInfo& get_type_info() const override { + return type_info; + } +}; +} // namespace ngraph diff --git a/ngraph/core/include/openvino/core/interval.hpp b/ngraph/core/include/openvino/core/interval.hpp new file mode 100644 index 00000000000..f1aa9111ea9 --- /dev/null +++ b/ngraph/core/include/openvino/core/interval.hpp @@ -0,0 +1,120 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include + +#include "openvino/core/core_visibility.hpp" + +namespace ov { +/// \brief Interval arithmetic +/// +/// An interval is the set of integers from m_min_val through m_max_val. +/// The value s_max acts like infinity. The +/// addition, subtraction, or multiplication of intervals is the smallest interval +/// containing the sums, differences, or products of elements of the two intervals. An empty +/// interval is canonicalized to [s_max, s_max]. +class OPENVINO_API Interval { +public: + using value_type = std::int64_t; + using size_type = std::uint64_t; + + /// \brief Interval of everything + Interval() = default; + /// \brief Copy constructor + Interval(const Interval& interval) = default; + + /// \brief Closed interval {x|min_val <= x <= max_val} + Interval(value_type min_val, value_type max_val); + + /// \brief Single-valued interval; just contains val + Interval(value_type val); + + Interval& operator=(const Interval& interval) = default; + + /// \brief The number of elements in the interval. Zero if max < min. + size_type size() const { + if (m_max_val == s_max) { + return m_min_val == s_max ? 0 : s_max; + } + return m_max_val - m_min_val + 1; + } + /// \brief Returns true if the interval has no elements + bool empty() const { + return m_min_val == s_max; + } + /// \brief the inclusive lower bound of the interval + value_type get_min_val() const { + return m_min_val; + } + /// \brief Set the inclusive lower bound of the interval + void set_min_val(value_type val) { + m_min_val = val; + } + /// \brief the inclusive upper bound of the interval + value_type get_max_val() const { + return m_max_val; + } + /// \brief Set the inclusive upper bound of the interval + void set_max_val(value_type val) { + m_max_val = val; + } + /// \brief True if the upper bound is finite + bool has_upper_bound() const { + return m_max_val != s_max; + } + /// \brief True if min and max bounds match + bool operator==(const Interval& interval) const; + bool operator!=(const Interval& interval) const; + + /// \brief The interval whose elements are a sum of an element from each interval + Interval operator+(const Interval& interval) const; + + /// \brief Extend this interval to sums of elements in this interval and interval + Interval& operator+=(const Interval& interval); + + /// \brief The interval whose elements are a difference of an element from each interval + Interval operator-(const Interval& interval) const; + + /// \brief Extend this interval to differences of elements in this interval and interval + Interval& operator-=(const Interval& interval); + + /// \brief The smallest interval whose elements are a product of an element from each + /// interval + Interval operator*(const Interval& interval) const; + + /// \brief Extend this interval to products of elements in this interval and interval + Interval& operator*=(const Interval& interval); + + /// \brief The interval that is the intersection of this interval and interval + Interval operator&(const Interval& interval) const; + + /// \brief Change this interval to only include elements also in interval + Interval& operator&=(const Interval& interval); + + /// \brief True if this interval includes value + bool contains(value_type value) const { + return m_min_val <= value && value <= m_max_val; + } + /// \brief True if this interval includes all the values in interval + bool contains(const Interval& interval) const; + + /// \brief The value used for no upper bound + static constexpr value_type s_max{std::numeric_limits::max()}; + +protected: + void canonicalize(); + + value_type m_min_val{0}; + value_type m_max_val{s_max}; +}; + +OPENVINO_API +std::ostream& operator<<(std::ostream& str, const Interval& interval); +} // namespace ov diff --git a/ngraph/core/include/openvino/core/partial_shape.hpp b/ngraph/core/include/openvino/core/partial_shape.hpp new file mode 100644 index 00000000000..34b59d7ab47 --- /dev/null +++ b/ngraph/core/include/openvino/core/partial_shape.hpp @@ -0,0 +1,401 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "ngraph/attribute_adapter.hpp" +#include "ngraph/op/util/attr_types.hpp" +#include "ngraph/shape.hpp" +#include "openvino/core/dimension.hpp" +#include "openvino/core/rank.hpp" + +namespace ngraph { +namespace op { +struct AutoBroadcastSpec; +} + +} // namespace ngraph + +namespace ov { + +/// \brief Class representing a shape that may be partially or totally dynamic. +/// +/// +/// A PartialShape may have: +/// +/// \li Dynamic rank. (Informal notation: `?`) +/// \li Static rank, but dynamic dimensions on some or all axes. +/// (Informal notation examples: `{1,2,?,4}`, `{?,?,?}`) +/// \li Static rank, and static dimensions on all axes. +/// (Informal notation examples: `{1,2,3,4}`, `{6}`, `{}`) +class OPENVINO_API PartialShape { + using Dimensions = std::vector; + +public: + using iterator = Dimensions::iterator; + using const_iterator = Dimensions::const_iterator; + using reverse_iterator = Dimensions::reverse_iterator; + using const_reverse_iterator = Dimensions::const_reverse_iterator; + + /// \brief Constructs a shape with static rank from an initializer list of Dimension. + /// \param init The Dimension values for the constructed shape. + /// + /// Examples: + /// + /// \code{.cpp} + /// PartialShape s{2,3,4}; // rank=3, all dimensions static + /// PartialShape s{}; // rank=0 + /// PartialShape s{2,Dimension::dynamic(),3}; // rank=3, dimension 1 dynamic + /// \endcode + PartialShape(std::initializer_list init); + + /// \brief Constructs a PartialShape with static rank from a vector of Dimension. + /// \param dimensions The Dimension values for the constructed shape. + PartialShape(std::vector dimensions); + + /// \brief Constructs a PartialShape with static rank from a vector of dimensions values. + /// \param dimensions The Dimension values for the constructed shape. + PartialShape(const std::vector& dimensions); + + /// \brief Constructs a static PartialShape with zero rank (the shape of a scalar). + PartialShape(); + + /// \brief Constructs a static PartialShape from a Shape. + /// \param shape The Shape to convert into PartialShape. + PartialShape(const ngraph::Shape& shape); + + /// \brief Check if this shape is static. + /// \return `true` if this shape is static, else `false`. + /// + /// A shape is considered static if it has static rank, and all dimensions of the shape + /// are static. + bool is_static() const; + + /// \brief Check if this shape is dynamic. + /// \return `false` if this shape is static, else `true`. + /// + /// A shape is considered static if it has static rank, and all dimensions of the shape + /// are static. + bool is_dynamic() const { + return !is_static(); + } + /// \brief Get the rank of the shape. + /// \return The rank of the shape. This will be Rank::dynamic() if the rank of + /// the shape is dynamic. + Rank rank() const { + return m_rank_is_static ? Rank(m_dimensions.size()) : Rank::dynamic(); + } + /// \brief Construct a PartialShape with the given rank and all dimensions (if any) dynamic. + /// \return A PartialShape with the given rank, and all dimensions (if any) dynamic. + static PartialShape dynamic(Rank r = Rank::dynamic()); + /// \brief Check whether this shape is compatible with the argument, i.e., whether it is + /// possible to merge them. + /// \param s The shape to be checked for compatibility with this shape. + /// \return `true` if this shape is compatible with `s`, else `false`. + /// + /// Two shapes are compatible if + /// \li one or both of them has dynamic rank, or + /// \li both shapes have dynamic and equal rank, and their dimensions are elementwise + /// compatible (see Dimension::compatible()). + bool compatible(const PartialShape& s) const; + + /// \brief Check whether this shape represents the same scheme as the argument. + /// \param s The shape whose scheme is being compared with this shape. + /// \return `true` if this shape represents the same scheme as `s`, else `false`. + /// + /// Two shapes `s1` and `s2` represent the same scheme if + /// \li they both have dynamic rank, or + /// \li they both have static and equal rank `r`, and for every `i` from `0` to `r-1`, + /// `s1[i]` represents the same scheme as `s2[i]` (see Dimension::same_scheme()). + bool same_scheme(const PartialShape& s) const; + + /// \brief Check whether this shape is a relaxation of the argument. + /// \param s The shape which is being compared against this shape. + /// \return `true` if this shape relaxes `s`, else `false`. + /// + /// Intuitively, a PartialShape `s1` is said to _relax_ `s2` (or _is a + /// relaxation_ of `s2`) if it is "more permissive" than `s2`. In other + /// words, `s1` is a relaxation of `s2` if anything you can form by + /// plugging things into the dynamic dimensions of `s2` is also + /// something you can form by plugging things into the dynamic + /// dimensions of `s1`, but not necessarily the other way around. + /// + /// `s1.relaxes(s2)` is equivalent to `s2.refines(s1)`. + /// + /// Formally, PartialShape `s1` is said to _relax_ PartialShape `s2` + /// if: + /// \li For every `i` from `0` to `r-1`, + /// either `s1[i]` contains s2[i]. + bool relaxes(const PartialShape& s) const; + + /// \brief Check whether this shape is a refinement of the argument. + /// \param s The shape which is being compared against this shape. + /// \return `true` if this shape refines `s`, else `false`. + /// + /// Intuitively, a PartialShape `s1` is said to _relax_ `s2` (or _is a + /// relaxation_ of `s2`) if it is "less permissive" than `s2`. In other + /// words, `s1` is a relaxation of `s2` if anything you can form by + /// plugging things into the dynamic dimensions of `s1` is also + /// something you can form by plugging things into the dynamic + /// dimensions of `s2`, but not necessarily the other way around. + /// + /// `s1.refines(s2)` is equivalent to `s2.relaxes(s1)`. + /// + /// Formally, PartialShape `s1` is said to _refine_ PartialShape `s2` + /// if: + /// \li `s2` has dynamic rank, or + /// \li `s1` and `s2` both have static rank `r`, and for every `i` from `0` to `r-1`, + /// either `s2[i]` is dynamic, or `s1[i]` == `s2[i]`. + bool refines(const PartialShape& s) const; + + /// \brief Checks that this shape's rank is compatible with `r`, and, if this shape's + /// rank is dynamic and `r` is static, updates this shape to have a rank of `r` + /// with dimensions all dynamic. + /// \return `true` if this shape's rank is compatible with `r`, else `false`. + bool merge_rank(Rank r); + + /// \brief Convert a static PartialShape to a Shape. + /// \return A new Shape `s` where `s[i] = size_t((*this)[i])`. + /// \throws std::invalid_argument If this PartialShape is dynamic. + ngraph::Shape to_shape() const; + + /// \brief Returns `true` if all static dimensions of the tensor are non-negative, else + /// `false`. + bool all_non_negative() const; + + /// \brief Index operator for PartialShape. + /// \param i The index of the dimension being selected. + /// \return A reference to the `i`th Dimension of this shape. + const Dimension& operator[](size_t i) const; + /// \brief Index operator for PartialShape. + /// \param i The index of the dimension being selected. + /// \return A reference to the `i`th Dimension of this shape. + Dimension& operator[](size_t i); + /// \brief Returns a vector of the dimensions. This has no meaning if dynamic. + explicit operator std::vector() const { + return m_dimensions; + } + friend OPENVINO_API std::ostream& operator<<(std::ostream& str, const PartialShape& shape); + friend PartialShape operator+(const PartialShape& s1, const PartialShape& s2); + bool operator==(const PartialShape& partial_shape) const; + bool operator!=(const PartialShape& partial_shape) const; + /// Get the max bounding shape + ngraph::Shape get_max_shape() const; + /// Get the min bounding shape + ngraph::Shape get_min_shape() const; + /// Get the unique shape + ngraph::Shape get_shape() const; + + /// \brief Try to merge one shape into another. + /// \param[in,out] dst The shape that `src` will be merged into. + /// \param src The shape that will be merged into `dst`. + /// \return `true` if merging succeeds, else `false`. + /// + /// Merges `src` into `dst`, returning `true` on success and `false` on failure. If + /// `false` is returned, the effect on `dst` is unspecified. + /// + /// To merge two partial shapes `s1` and `s2` is to find the most permissive partial shape + /// `s` that is no more permissive than `s1` or `s2`, if `s` exists. For example: + /// + /// \code + /// merge(?,?) -> ? + /// merge(?,{?,?}) -> {?,?} + /// merge({?,?},{?,?}) -> {?,?} + /// merge({1,2,3,4},?) -> {1,2,3,4} + /// merge({1,2},{1,?}) -> {1,2} + /// merge({1,2,?,?},{1,?,3,?}) -> {1,2,3,?} + /// merge({1,2,3},{1,2,3}) -> {1,2,3} + /// + /// merge({1,?},{2,?}) fails [dimension 0 constraints are inconsistent] + /// merge({?,?},{?,?,?}) fails [ranks are inconsistent] + /// \endcode + /// + /// This function (merge_into) performs the "merge" operation described above on `dst` and + /// `src`, but overwrites `dst` with the result and returns `true` if merging is + /// successful; if merging is unsuccessful, the function returns `false` and may make + /// unspecified changes to `dst`. + static bool merge_into(PartialShape& dst, const PartialShape& src); + + /// \brief Try to merge one shape into another along with implicit broadcasting + static bool broadcast_merge_into(PartialShape& dst, + const PartialShape& src, + const ngraph::op::AutoBroadcastSpec& autob); + + /// \brief Returns a read/write iterator that points to the first + /// element in the shape. Iteration is done in ordinary + /// element order. + iterator begin() noexcept { + return m_dimensions.begin(); + } + /// \brief Returns a read-only (constant) iterator that points to the + /// first element in the shape. Iteration is done in ordinary + /// element order. + const_iterator begin() const noexcept { + return cbegin(); + } + /// \brief Returns a read/write iterator that points one past the last + /// element in the shape. Iteration is done in ordinary + /// element order. + iterator end() noexcept { + return m_dimensions.end(); + } + /// \brief Returns a read-only (constant) iterator that points one past + /// the last element in the shape. Iteration is done in ordinary + /// element order. + const_iterator end() const noexcept { + return cend(); + } + /// \brief Returns a read/write reverse iterator that points to the + /// last element in the shape. Iteration is done in reverse + /// element order. + reverse_iterator rbegin() noexcept { + return m_dimensions.rbegin(); + } + /// \brief Returns a read-only (constant) reverse iterator that points + /// to the last element in the shape. Iteration is done in + /// reverse element order. + const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + /// \brief Returns a read/write reverse iterator that points to one + /// before the first element in the shape. Iteration is done + /// in reverse element order. + reverse_iterator rend() noexcept { + return m_dimensions.rend(); + } + /// \brief Returns a read-only (constant) reverse iterator that points + /// to one before the first element in the shape. Iteration + /// is done in reverse element order. + const_reverse_iterator rend() const noexcept { + return crend(); + } + /// \brief Returns a read-only (constant) iterator that points to the + /// first element in the shape. Iteration is done in ordinary + /// element order. + const_iterator cbegin() const noexcept { + return m_dimensions.cbegin(); + } + /// \brief Returns a read-only (constant) iterator that points one past + /// the last element in the shape. Iteration is done in ordinary + /// element order. + const_iterator cend() const noexcept { + return m_dimensions.cend(); + } + /// \brief Returns a read-only (constant) reverse iterator that points + /// to the last element in the shape. Iteration is done in + /// reverse element order. + const_reverse_iterator crbegin() const noexcept { + return m_dimensions.crbegin(); + } + /// \brief Returns a read-only (constant) reverse iterator that points + /// to one before the first element in the shape. Iteration + /// is done in reverse element order. + const_reverse_iterator crend() const noexcept { + return m_dimensions.crend(); + } + +private: + // Private constructor for PartialShape::dynamic(). + PartialShape(bool rank_is_static, std::vector dimensions); + + // True if the shape's rank is static. + bool m_rank_is_static; + + /// \brief Shape types. The shape type is lazily evaluated by calling the is_static() + /// method. + /// + /// \details It is highly recommended to avoid using the Dimension& operator[](size_t) + /// operator. It sets the shape type to SHAPE_IS_UPDATED and disables shape type caching. + /// Thus, the is_static method will have linear complexity because the shape is not + /// guaranteed to remain static or dynamic. + mutable enum class ShapeType { + SHAPE_IS_UNKNOWN, // The shape type is unknown and should be calculated by checking all + // dimensions. + SHAPE_IS_UPDATED, // User has retained a link to one dimension. Therefore, we can't + // guarantee that the shape will remain static or dynamic, and its + // type will always be evaluated. + SHAPE_IS_STATIC, // The shape type is known and static. Also there are no any retained + // dimensions by non-constant reference. + SHAPE_IS_DYNAMIC // The shape type is dynamic and there are no any retained dimensions + // by non-constant reference. + } m_shape_type{ShapeType::SHAPE_IS_UNKNOWN}; + + // Shape dimensions. This has no meaning if m_rank_is_static is false. + Dimensions m_dimensions; +}; + +/// \brief Elementwise addition of two PartialShape objects. +/// \param s1 Left operand for addition. +/// \param s2 Right operand for addition. +/// \return The result of elementwise adding `s1` to `s2` (see description). +/// \throws std::invalid_argument If `s1` and `s2` have inconsistent ranks. +/// +/// \li If `s1` or `s2` has dynamic rank, returns PartialShape::dynamic(). +/// \li If `s1 and `s2` both have static rank, and their ranks are unequal, throws +/// std::invalid_argument. +/// \li If `s1` and `s2` both have static rank, and their ranks are equal, +/// returns a new shape whose `i`th dimension is `s1[i] + s2[i]`. +PartialShape operator+(const PartialShape& s1, const PartialShape& s2); + +/// \brief Inserts a human-readable representation of a PartialShape into an output stream. +/// \param str The output stream targeted for insertion. +/// \param shape The shape to be inserted into `str`. +/// \return A reference to `str` after insertion. +/// +/// The output to the stream is in "informal" notation. In other words: +/// +/// \li If `shape` has dynamic rank, inserts the string `?`. +/// \li If `shape` has static rank, inserts the string `{`, then inserts each dimension +/// of `shape` into the output stream separated by commas, then inserts `}`. +/// +/// Example: +/// +/// \code{.cpp} +/// PartialShape s1{PartialShape::dynamic())}; +/// PartialShape s2{}; +/// PartialShape s3{1,Dimension::dynamic(),2,3}; +/// PartialShape s4{2,3,4}; +/// std::cout << s1 << std::endl +/// << s2 << std::endl +/// << s3 << std::endl +/// << s4 << std::endl; +/// \endcode +/// +/// Output: +/// +/// \code +/// ? +/// {} +/// {1,?,2,3} +/// {2,3,4} +/// \endcode +OPENVINO_API +std::ostream& operator<<(std::ostream& str, const PartialShape& shape); + +} // namespace ov +namespace ngraph { + +template <> +class OPENVINO_API AttributeAdapter : public ValueAccessor> { +public: + AttributeAdapter(ov::PartialShape& value) : m_ref(value) {} + + const std::vector& get() override; + void set(const std::vector& value) override; + static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; + const DiscreteTypeInfo& get_type_info() const override { + return type_info; + } + operator ov::PartialShape&() { + return m_ref; + } + +protected: + ov::PartialShape& m_ref; + std::vector m_buffer; + bool m_buffer_valid{false}; +}; +} // namespace ngraph diff --git a/ngraph/core/include/openvino/core/rank.hpp b/ngraph/core/include/openvino/core/rank.hpp new file mode 100644 index 00000000000..dc8e0fd952d --- /dev/null +++ b/ngraph/core/include/openvino/core/rank.hpp @@ -0,0 +1,14 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/dimension.hpp" + +namespace ov { +/// \brief Alias for Dimension, used when the value represents the number of axes in a shape, +/// rather than the size of one dimension in a shape. +/// +using Rank = Dimension; +} // namespace ov diff --git a/ngraph/core/include/openvino/core/type/bfloat16.hpp b/ngraph/core/include/openvino/core/type/bfloat16.hpp new file mode 100644 index 00000000000..4d7e2cd9570 --- /dev/null +++ b/ngraph/core/include/openvino/core/type/bfloat16.hpp @@ -0,0 +1,236 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "openvino/core/core_visibility.hpp" + +#define ROUND_MODE_TO_NEAREST_EVEN + +namespace ov { +class OPENVINO_API bfloat16 { +public: + constexpr bfloat16() : m_value{0} {} + bfloat16(float value) : m_value { +#if defined ROUND_MODE_TO_NEAREST + round_to_nearest(value) +#elif defined ROUND_MODE_TO_NEAREST_EVEN + round_to_nearest_even(value) +#elif defined ROUND_MODE_TRUNCATE + truncate(value) +#else +# error "ROUNDING_MODE must be one of ROUND_MODE_TO_NEAREST, ROUND_MODE_TO_NEAREST_EVEN, or ROUND_MODE_TRUNCATE" +#endif + } + {} + + template + explicit bfloat16(I value) : m_value{bfloat16{static_cast(value)}.m_value} {} + + std::string to_string() const; + size_t size() const; + template + bool operator==(const T& other) const; + template + bool operator!=(const T& other) const { + return !(*this == other); + } + template + bool operator<(const T& other) const; + template + bool operator<=(const T& other) const; + template + bool operator>(const T& other) const; + template + bool operator>=(const T& other) const; + template + bfloat16 operator+(const T& other) const; + template + bfloat16 operator+=(const T& other); + template + bfloat16 operator-(const T& other) const; + template + bfloat16 operator-=(const T& other); + template + bfloat16 operator*(const T& other) const; + template + bfloat16 operator*=(const T& other); + template + bfloat16 operator/(const T& other) const; + template + bfloat16 operator/=(const T& other); + operator float() const; + + static std::vector to_float_vector(const std::vector&); + static std::vector from_float_vector(const std::vector&); + static constexpr bfloat16 from_bits(uint16_t bits) { + return bfloat16(bits, true); + } + uint16_t to_bits() const; + friend std::ostream& operator<<(std::ostream& out, const bfloat16& obj) { + out << static_cast(obj); + return out; + } + +#define cu32(x) (F32(x).i) + + static uint16_t round_to_nearest_even(float x) { + return static_cast((cu32(x) + ((cu32(x) & 0x00010000) >> 1)) >> 16); + } + + static uint16_t round_to_nearest(float x) { + return static_cast((cu32(x) + 0x8000) >> 16); + } + + static uint16_t truncate(float x) { + return static_cast((cu32(x)) >> 16); + } + +private: + constexpr bfloat16(uint16_t x, bool) : m_value{x} {} + union F32 { + F32(float val) : f{val} {} + F32(uint32_t val) : i{val} {} + float f; + uint32_t i; + }; + + uint16_t m_value; +}; + +template +bool bfloat16::operator==(const T& other) const { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + return (static_cast(*this) == static_cast(other)); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif +} + +template +bool bfloat16::operator<(const T& other) const { + return (static_cast(*this) < static_cast(other)); +} + +template +bool bfloat16::operator<=(const T& other) const { + return (static_cast(*this) <= static_cast(other)); +} + +template +bool bfloat16::operator>(const T& other) const { + return (static_cast(*this) > static_cast(other)); +} + +template +bool bfloat16::operator>=(const T& other) const { + return (static_cast(*this) >= static_cast(other)); +} + +template +bfloat16 bfloat16::operator+(const T& other) const { + return {static_cast(*this) + static_cast(other)}; +} + +template +bfloat16 bfloat16::operator+=(const T& other) { + return *this = *this + other; +} + +template +bfloat16 bfloat16::operator-(const T& other) const { + return {static_cast(*this) - static_cast(other)}; +} + +template +bfloat16 bfloat16::operator-=(const T& other) { + return *this = *this - other; +} + +template +bfloat16 bfloat16::operator*(const T& other) const { + return {static_cast(*this) * static_cast(other)}; +} + +template +bfloat16 bfloat16::operator*=(const T& other) { + return *this = *this * other; +} + +template +bfloat16 bfloat16::operator/(const T& other) const { + return {static_cast(*this) / static_cast(other)}; +} + +template +bfloat16 bfloat16::operator/=(const T& other) { + return *this = *this / other; +} +} // namespace ov + +namespace std { +template <> +class numeric_limits { +public: + static constexpr bool is_specialized = true; + static constexpr ov::bfloat16 min() noexcept { + return ov::bfloat16::from_bits(0x007F); + } + static constexpr ov::bfloat16 max() noexcept { + return ov::bfloat16::from_bits(0x7F7F); + } + static constexpr ov::bfloat16 lowest() noexcept { + return ov::bfloat16::from_bits(0xFF7F); + } + static constexpr int digits = 7; + static constexpr int digits10 = 2; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; + static constexpr ov::bfloat16 epsilon() noexcept { + return ov::bfloat16::from_bits(0x3C00); + } + static constexpr ov::bfloat16 round_error() noexcept { + return ov::bfloat16::from_bits(0x3F00); + } + static constexpr int min_exponent = -125; + static constexpr int min_exponent10 = -37; + static constexpr int max_exponent = 128; + static constexpr int max_exponent10 = 38; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr ov::bfloat16 infinity() noexcept { + return ov::bfloat16::from_bits(0x7F80); + } + static constexpr ov::bfloat16 quiet_NaN() noexcept { + return ov::bfloat16::from_bits(0x7FC0); + } + static constexpr ov::bfloat16 signaling_NaN() noexcept { + return ov::bfloat16::from_bits(0x7FC0); + } + static constexpr ov::bfloat16 denorm_min() noexcept { + return ov::bfloat16::from_bits(0); + } + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = false; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; +}; +} // namespace std diff --git a/ngraph/core/include/openvino/core/type/element_type.hpp b/ngraph/core/include/openvino/core/type/element_type.hpp new file mode 100644 index 00000000000..b3ccc0e0219 --- /dev/null +++ b/ngraph/core/include/openvino/core/type/element_type.hpp @@ -0,0 +1,202 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +//================================================================================================ +// ElementType +//================================================================================================ + +#pragma once + +#include +#include +#include +#include +#include + +#include "ngraph/attribute_adapter.hpp" +#include "ngraph/deprecated.hpp" +#include "ngraph/except.hpp" +#include "openvino/core/core_visibility.hpp" +#include "openvino/core/type/bfloat16.hpp" +#include "openvino/core/type/float16.hpp" + +namespace ov { +namespace element { +enum class Type_t { + undefined, + dynamic, + boolean, + bf16, + f16, + f32, + f64, + i4, + i8, + i16, + i32, + i64, + u1, + u4, + u8, + u16, + u32, + u64 +}; + +class OPENVINO_API Type { +public: + Type() = default; + Type(const Type&) = default; + constexpr Type(const Type_t t) : m_type{t} {} + Type(size_t bitwidth, bool is_real, bool is_signed, bool is_quantized, const std::string& cname); + Type& operator=(const Type&) = default; + const std::string& c_type_string() const; + size_t size() const; + size_t hash() const; + bool is_static() const; + bool is_dynamic() const { + return !is_static(); + } + bool is_real() const; + // TODO: We may want to revisit this definition when we do a more general cleanup of + // element types: + bool is_integral() const { + return !is_real(); + } + bool is_integral_number() const; + bool is_signed() const; + bool is_quantized() const; + size_t bitwidth() const; + // The name of this type, the enum name of this type + const std::string& get_type_name() const; + friend OPENVINO_API std::ostream& operator<<(std::ostream&, const Type&); + static std::vector get_known_types(); + + /// \brief Checks whether this element type is merge-compatible with `t`. + /// \param t The element type to compare this element type to. + /// \return `true` if this element type is compatible with `t`, else `false`. + bool compatible(const element::Type& t) const; + + /// \brief Merges two element types t1 and t2, writing the result into dst and + /// returning true if successful, else returning false. + /// + /// To "merge" two element types t1 and t2 is to find the least restrictive + /// element type t that is no more restrictive than t1 and t2, if t exists. + /// More simply: + /// + /// merge(dst,element::Type::dynamic,t) + /// writes t to dst and returns true + /// + /// merge(dst,t,element::Type::dynamic) + /// writes t to dst and returns true + /// + /// merge(dst,t1,t2) where t1, t2 both static and equal + /// writes t1 to dst and returns true + /// + /// merge(dst,t1,t2) where t1, t2 both static and unequal + /// does nothing to dst, and returns false + static bool merge(element::Type& dst, const element::Type& t1, const element::Type& t2); + + // \brief This allows switch(element_type) + constexpr operator Type_t() const { + return m_type; + } + +private: + Type_t m_type{Type_t::undefined}; +}; + +using TypeVector = std::vector; + +constexpr Type undefined(Type_t::undefined); +constexpr Type dynamic(Type_t::dynamic); +constexpr Type boolean(Type_t::boolean); +constexpr Type bf16(Type_t::bf16); +constexpr Type f16(Type_t::f16); +constexpr Type f32(Type_t::f32); +constexpr Type f64(Type_t::f64); +constexpr Type i4(Type_t::i4); +constexpr Type i8(Type_t::i8); +constexpr Type i16(Type_t::i16); +constexpr Type i32(Type_t::i32); +constexpr Type i64(Type_t::i64); +constexpr Type u1(Type_t::u1); +constexpr Type u4(Type_t::u4); +constexpr Type u8(Type_t::u8); +constexpr Type u16(Type_t::u16); +constexpr Type u32(Type_t::u32); +constexpr Type u64(Type_t::u64); + +template +Type from() { + throw std::invalid_argument("Unknown type"); +} +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); +template <> +OPENVINO_API Type from(); + +OPENVINO_API +std::ostream& operator<<(std::ostream& out, const ov::element::Type& obj); +} // namespace element + +} // namespace ov + +namespace ngraph { + +template <> +class OPENVINO_API AttributeAdapter : public EnumAttributeAdapterBase { +public: + AttributeAdapter(ov::element::Type_t& value) : EnumAttributeAdapterBase(value) {} + + static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; + const DiscreteTypeInfo& get_type_info() const override { + return type_info; + } +}; + +template <> +class OPENVINO_API AttributeAdapter : public ValueAccessor { +public: + AttributeAdapter(ov::element::Type& value) : m_ref(value) {} + + const std::string& get() override; + void set(const std::string& value) override; + + static constexpr DiscreteTypeInfo type_info{"AttributeAdapter", 0}; + const DiscreteTypeInfo& get_type_info() const override { + return type_info; + } + operator ov::element::Type&() { + return m_ref; + } + +protected: + ov::element::Type& m_ref; +}; +} // namespace ngraph diff --git a/ngraph/core/include/openvino/core/type/element_type_traits.hpp b/ngraph/core/include/openvino/core/type/element_type_traits.hpp new file mode 100644 index 00000000000..07d4230ddbc --- /dev/null +++ b/ngraph/core/include/openvino/core/type/element_type_traits.hpp @@ -0,0 +1,95 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/type/element_type.hpp" + +namespace ov { +template +struct element_type_traits {}; + +template +using fundamental_type_for = typename element_type_traits::value_type; + +template <> +struct element_type_traits { + using value_type = char; +}; + +template <> +struct element_type_traits { + using value_type = bfloat16; +}; + +template <> +struct element_type_traits { + using value_type = float16; +}; + +template <> +struct element_type_traits { + using value_type = float; +}; + +template <> +struct element_type_traits { + using value_type = double; +}; + +template <> +struct element_type_traits { + using value_type = int8_t; +}; + +template <> +struct element_type_traits { + using value_type = int8_t; +}; + +template <> +struct element_type_traits { + using value_type = int16_t; +}; + +template <> +struct element_type_traits { + using value_type = int32_t; +}; + +template <> +struct element_type_traits { + using value_type = int64_t; +}; + +template <> +struct element_type_traits { + using value_type = int8_t; +}; + +template <> +struct element_type_traits { + using value_type = int8_t; +}; + +template <> +struct element_type_traits { + using value_type = uint8_t; +}; + +template <> +struct element_type_traits { + using value_type = uint16_t; +}; + +template <> +struct element_type_traits { + using value_type = uint32_t; +}; + +template <> +struct element_type_traits { + using value_type = uint64_t; +}; +} // namespace ov diff --git a/ngraph/core/include/openvino/core/type/float16.hpp b/ngraph/core/include/openvino/core/type/float16.hpp new file mode 100644 index 00000000000..60c1560c24a --- /dev/null +++ b/ngraph/core/include/openvino/core/type/float16.hpp @@ -0,0 +1,219 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "openvino/core/core_visibility.hpp" + +#define ROUND_MODE_TO_NEAREST_EVEN + +namespace ov { +class OPENVINO_API float16 { +public: + constexpr float16() : m_value{0} {} + + static uint32_t constexpr frac_size = 10; + static uint32_t constexpr exp_size = 5; + static uint32_t constexpr exp_bias = 15; + + float16(uint32_t sign, uint32_t biased_exponent, uint32_t fraction) + : m_value((sign & 0x01) << 15 | (biased_exponent & 0x1F) << 10 | (fraction & 0x03FF)) {} + + float16(float value); + + template + explicit float16(I value) : m_value{float16{static_cast(value)}.m_value} {} + + std::string to_string() const; + size_t size() const; + template + bool operator==(const T& other) const; + template + bool operator!=(const T& other) const { + return !(*this == other); + } + template + bool operator<(const T& other) const; + template + bool operator<=(const T& other) const; + template + bool operator>(const T& other) const; + template + bool operator>=(const T& other) const; + template + float16 operator+(const T& other) const; + template + float16 operator+=(const T& other); + template + float16 operator-(const T& other) const; + template + float16 operator-=(const T& other); + template + float16 operator*(const T& other) const; + template + float16 operator*=(const T& other); + template + float16 operator/(const T& other) const; + template + float16 operator/=(const T& other); + operator float() const; + + static constexpr float16 from_bits(uint16_t bits) { + return float16(bits, true); + } + uint16_t to_bits() const; + friend std::ostream& operator<<(std::ostream& out, const float16& obj) { + out << static_cast(obj); + return out; + } + +private: + constexpr float16(uint16_t x, bool) : m_value{x} {} + union F32 { + F32(float val) : f{val} {} + F32(uint32_t val) : i{val} {} + float f; + uint32_t i; + }; + + uint16_t m_value; +}; + +template +bool float16::operator==(const T& other) const { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + return (static_cast(*this) == static_cast(other)); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif +} + +template +bool float16::operator<(const T& other) const { + return (static_cast(*this) < static_cast(other)); +} + +template +bool float16::operator<=(const T& other) const { + return (static_cast(*this) <= static_cast(other)); +} + +template +bool float16::operator>(const T& other) const { + return (static_cast(*this) > static_cast(other)); +} + +template +bool float16::operator>=(const T& other) const { + return (static_cast(*this) >= static_cast(other)); +} + +template +float16 float16::operator+(const T& other) const { + return {static_cast(*this) + static_cast(other)}; +} + +template +float16 float16::operator+=(const T& other) { + return *this = *this + other; +} + +template +float16 float16::operator-(const T& other) const { + return {static_cast(*this) - static_cast(other)}; +} + +template +float16 float16::operator-=(const T& other) { + return *this = *this - other; +} + +template +float16 float16::operator*(const T& other) const { + return {static_cast(*this) * static_cast(other)}; +} + +template +float16 float16::operator*=(const T& other) { + return *this = *this * other; +} + +template +float16 float16::operator/(const T& other) const { + return {static_cast(*this) / static_cast(other)}; +} + +template +float16 float16::operator/=(const T& other) { + return *this = *this / other; +} +} // namespace ov + +namespace std { +bool OPENVINO_API isnan(ov::float16 x); + +template <> +class numeric_limits { +public: + static constexpr bool is_specialized = true; + static constexpr ov::float16 min() noexcept { + return ov::float16::from_bits(0x0200); + } + static constexpr ov::float16 max() noexcept { + return ov::float16::from_bits(0x7BFF); + } + static constexpr ov::float16 lowest() noexcept { + return ov::float16::from_bits(0xFBFF); + } + static constexpr int digits = 11; + static constexpr int digits10 = 3; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; + static constexpr ov::float16 epsilon() noexcept { + return ov::float16::from_bits(0x1200); + } + static constexpr ov::float16 round_error() noexcept { + return ov::float16::from_bits(0x3C00); + } + static constexpr int min_exponent = -13; + static constexpr int min_exponent10 = -4; + static constexpr int max_exponent = 16; + static constexpr int max_exponent10 = 4; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr ov::float16 infinity() noexcept { + return ov::float16::from_bits(0x7C00); + } + static constexpr ov::float16 quiet_NaN() noexcept { + return ov::float16::from_bits(0x7FFF); + } + static constexpr ov::float16 signaling_NaN() noexcept { + return ov::float16::from_bits(0x7DFF); + } + static constexpr ov::float16 denorm_min() noexcept { + return ov::float16::from_bits(0); + } + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = false; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; +}; +} // namespace std diff --git a/ngraph/core/include/openvino/core/variant.hpp b/ngraph/core/include/openvino/core/variant.hpp new file mode 100644 index 00000000000..b7bcc03a038 --- /dev/null +++ b/ngraph/core/include/openvino/core/variant.hpp @@ -0,0 +1,98 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include "ngraph/output_vector.hpp" +#include "ngraph/type.hpp" +#include "openvino/core/core_visibility.hpp" + +namespace ngraph { +class Node; +} +namespace ov { +using VariantTypeInfo = ngraph::DiscreteTypeInfo; + +class OPENVINO_API Variant { +public: + virtual ~Variant(); + virtual const VariantTypeInfo& get_type_info() const = 0; + + virtual bool is_copyable() const; + virtual std::shared_ptr init(const std::shared_ptr& node); + virtual std::shared_ptr merge(const ngraph::NodeVector& nodes); + virtual std::string to_string() { + return ""; + } +}; + +template +class VariantImpl : public Variant { +public: + using value_type = VT; + + VariantImpl(const value_type& value) : m_value(value) {} + + const value_type& get() const { + return m_value; + } + value_type& get() { + return m_value; + } + void set(const value_type& value) { + m_value = value; + } + +protected: + value_type m_value; +}; + +extern template class OPENVINO_API VariantImpl; +extern template class OPENVINO_API VariantImpl; + +template +class VariantWrapper {}; + +template <> +class OPENVINO_API VariantWrapper : public VariantImpl { +public: + static constexpr VariantTypeInfo type_info{"Variant::std::string", 0}; + const VariantTypeInfo& get_type_info() const override { + return type_info; + } + VariantWrapper(const value_type& value) : VariantImpl(value) {} +}; + +template <> +class OPENVINO_API VariantWrapper : public VariantImpl { +public: + static constexpr VariantTypeInfo type_info{"Variant::int64_t", 0}; + const VariantTypeInfo& get_type_info() const override { + return type_info; + } + VariantWrapper(const value_type& value) : VariantImpl(value) {} +}; + +template +inline std::shared_ptr make_variant(const T& p) { + return std::dynamic_pointer_cast>(std::make_shared>(p)); +} + +template +inline std::shared_ptr make_variant(const char (&s)[N]) { + return std::dynamic_pointer_cast>(std::make_shared>(s)); +} + +#if defined(ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32) +template +inline std::shared_ptr make_variant(const wchar_t (&s)[N]) { + return std::dynamic_pointer_cast>(std::make_shared>(s)); +} +#endif + +using RTMap = std::map>; +} // namespace ov diff --git a/ngraph/core/include/openvino/core/visibility.hpp b/ngraph/core/include/openvino/core/visibility.hpp new file mode 100644 index 00000000000..44cd9f4001e --- /dev/null +++ b/ngraph/core/include/openvino/core/visibility.hpp @@ -0,0 +1,19 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +// https://gcc.gnu.org/wiki/Visibility +// Generic helper definitions for shared library support +#if defined _WIN32 || defined __CYGWIN__ +# define CORE_HELPER_DLL_IMPORT __declspec(dllimport) +# define CORE_HELPER_DLL_EXPORT __declspec(dllexport) +# define CORE_HELPER_DLL_LOCAL +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define CORE_HELPER_DLL_IMPORT __attribute__((visibility("default"))) +# define CORE_HELPER_DLL_EXPORT __attribute__((visibility("default"))) +# define CORE_HELPER_DLL_LOCAL __attribute__((visibility("hidden"))) +#else +# define CORE_HELPER_DLL_IMPORT +# define CORE_HELPER_DLL_EXPORT +# define CORE_HELPER_DLL_LOCAL +#endif diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/if.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/if.hpp new file mode 100644 index 00000000000..ccb098c9edf --- /dev/null +++ b/ngraph/core/reference/include/ngraph/runtime/reference/if.hpp @@ -0,0 +1,21 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "ngraph/op/util/multi_subgraph_base.hpp" + +namespace ngraph { +namespace runtime { +namespace reference { +void if_reference(const std::vector>& body, + const std::vector& out_descs, + const std::vector& input_descs, + const HostTensorVector& out, + const HostTensorVector& args); +} +} // namespace runtime +} // namespace ngraph \ No newline at end of file diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/interpolate.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/interpolate.hpp index d9e98f7ad3a..33a45e6c04a 100644 --- a/ngraph/core/reference/include/ngraph/runtime/reference/interpolate.hpp +++ b/ngraph/core/reference/include/ngraph/runtime/reference/interpolate.hpp @@ -27,7 +27,7 @@ using InterpolateMode = ngraph::op::v4::Interpolate::InterpolateMode; class GetNearestPixel final { public: /// \brief Constructs calculation of a nearest pixel in the default mode. - GetNearestPixel() : GetNearestPixel(Nearest_mode::round_prefer_floor) {} + GetNearestPixel() : GetNearestPixel(Nearest_mode::ROUND_PREFER_FLOOR) {} /// \brief Constructs calculation of nearest pixel for the specified mode. /// @@ -58,19 +58,19 @@ private: /// \return The function to calculate the nearest pixel. Func get_func(Nearest_mode mode) { switch (mode) { - case Nearest_mode::round_prefer_ceil: + case Nearest_mode::ROUND_PREFER_CEIL: return [](float x_original, bool) { return static_cast(std::round(x_original)); }; - case Nearest_mode::floor: + case Nearest_mode::FLOOR: return [](float x_original, bool) { return static_cast(std::floor(x_original)); }; - case Nearest_mode::ceil: + case Nearest_mode::CEIL: return [](float x_original, bool) { return static_cast(std::ceil(x_original)); }; - case Nearest_mode::simple: + case Nearest_mode::SIMPLE: return [](float x_original, bool is_downsample) { if (is_downsample) { return static_cast(std::ceil(x_original)); @@ -93,7 +93,7 @@ private: class GetOriginalCoordinate final { public: /// \brief Constructs calculation of a nearest pixel in the default mode. - GetOriginalCoordinate() : GetOriginalCoordinate(Transform_mode::half_pixel) {} + GetOriginalCoordinate() : GetOriginalCoordinate(Transform_mode::HALF_PIXEL) {} /// \brief Constructs calculation of the source coordinate. /// @@ -129,22 +129,22 @@ private: /// \return The function to calculate the source coordinate. Func get_func(Transform_mode mode) { switch (mode) { - case Transform_mode::pytorch_half_pixel: + case Transform_mode::PYTORCH_HALF_PIXEL: return [](float x_resized, float x_scale, float length_resized, float) { return length_resized > 1 ? (x_resized + 0.5f) / x_scale - 0.5f : 0.0f; }; break; - case Transform_mode::asymmetric: + case Transform_mode::ASYMMETRIC: return [](float x_resized, float x_scale, float, float) { return x_resized / x_scale; }; break; - case Transform_mode::tf_half_pixel_for_nn: + case Transform_mode::TF_HALF_PIXEL_FOR_NN: return [](float x_resized, float x_scale, float, float) { return (x_resized + 0.5f) / x_scale; }; break; - case Transform_mode::align_corners: + case Transform_mode::ALIGN_CORNERS: return [](float x_resized, float, float length_resized, float length_original) { return length_resized == 1 ? 0 : x_resized * (length_original - 1) / (length_resized - 1); }; @@ -290,16 +290,16 @@ public: helper = InterpolateEvalHelper{m_attrs, input_data_shape, axes, out_shape, scales}; switch (m_interp_mode) { - case InterpolateMode::nearest: + case InterpolateMode::NEAREST: nearest_func(input_data, out); break; - case InterpolateMode::linear: + case InterpolateMode::LINEAR: linear_func(input_data, out); break; - case InterpolateMode::linear_onnx: + case InterpolateMode::LINEAR_ONNX: linear_onnx_func(input_data, out); break; - case InterpolateMode::cubic: + case InterpolateMode::CUBIC: cubic_func(input_data, out); break; } diff --git a/ngraph/core/reference/src/runtime/reference/if.cpp b/ngraph/core/reference/src/runtime/reference/if.cpp new file mode 100644 index 00000000000..e6dc5f83eef --- /dev/null +++ b/ngraph/core/reference/src/runtime/reference/if.cpp @@ -0,0 +1,45 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "ngraph/runtime/reference/if.hpp" + +#include "ngraph/op/if.hpp" +#include "ngraph/runtime/reference/function.hpp" + +namespace ngraph { +namespace runtime { +namespace reference { +void if_reference(const std::vector>& bodies, + const std::vector& out_descs, + const std::vector& input_descs, + const HostTensorVector& out, + const HostTensorVector& args) { + NGRAPH_CHECK(args.size() > 0, "If operation must have input condition value"); + + auto condition_value = args[0]->get_data_ptr()[0]; + auto branch_index = (condition_value) ? op::v8::If::THEN_BODY_INDEX : op::v8::If::ELSE_BODY_INDEX; + HostTensorVector inputs_to_body; + HostTensorVector outs_from_body; + inputs_to_body.resize(input_descs[branch_index].size()); + auto inputs_size = args.size(); + auto output_size = out.size(); + for (const auto& input_desc : input_descs[branch_index]) { + NGRAPH_CHECK(inputs_size > input_desc->m_input_index, + "Incorrect associating! If has not input with id ", + input_desc->m_input_index); + inputs_to_body[input_desc->m_body_parameter_index] = args[input_desc->m_input_index]; + } + reference::function(bodies[branch_index], inputs_to_body, outs_from_body); + for (const auto& out_descr : out_descs[branch_index]) { + NGRAPH_CHECK(output_size > out_descr->m_output_index, + "Incorrect associating! If has not output with id ", + out_descr->m_output_index); + auto res = outs_from_body[out_descr->m_body_value_index]; + out[out_descr->m_output_index]->set_shape(res->get_shape()); + out[out_descr->m_output_index]->write(res->get_data_ptr(), res->get_size_in_bytes()); + } +} +} // namespace reference +} // namespace runtime +} // namespace ngraph \ No newline at end of file diff --git a/ngraph/core/src/attribute_visitor.cpp b/ngraph/core/src/attribute_visitor.cpp index a5a62a38ff7..9beec812c2b 100644 --- a/ngraph/core/src/attribute_visitor.cpp +++ b/ngraph/core/src/attribute_visitor.cpp @@ -5,6 +5,7 @@ #include "ngraph/attribute_visitor.hpp" #include "ngraph/attribute_adapter.hpp" +#include "ngraph/function.hpp" #include "ngraph/node.hpp" using namespace std; diff --git a/ngraph/core/src/dimension.cpp b/ngraph/core/src/dimension.cpp index 8317a391537..84b156ae7b4 100644 --- a/ngraph/core/src/dimension.cpp +++ b/ngraph/core/src/dimension.cpp @@ -11,7 +11,7 @@ using namespace ngraph; -std::ostream& ngraph::operator<<(std::ostream& str, const Dimension& dimension) { +std::ostream& ov::operator<<(std::ostream& str, const Dimension& dimension) { if (dimension.is_static()) { return str << dimension.get_length(); } else if (dimension.get_interval().has_upper_bound()) { diff --git a/ngraph/core/src/file_util.cpp b/ngraph/core/src/file_util.cpp index bbc12740c56..827226d5345 100644 --- a/ngraph/core/src/file_util.cpp +++ b/ngraph/core/src/file_util.cpp @@ -42,6 +42,8 @@ # endif #endif +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace std; using namespace ngraph; diff --git a/ngraph/core/src/function.cpp b/ngraph/core/src/function.cpp index d52052c61ea..c3c3375b224 100644 --- a/ngraph/core/src/function.cpp +++ b/ngraph/core/src/function.cpp @@ -26,7 +26,7 @@ constexpr DiscreteTypeInfo Function::type_info; atomic Function::m_next_instance_id(0); void check_all_variables_registered(const std::vector>& ordered_ops, const VariableVector& variables) { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraphPass_LT, "Function::check_all_variables_registered"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraphPass_LT, "Function::check_all_variables_registered"); std::stringstream unregistered_variables; for (auto& node : ordered_ops) { const auto& variable_op = dynamic_pointer_cast(node); @@ -40,7 +40,7 @@ void check_all_variables_registered(const std::vector>& ordered void check_all_parameters_registered(const std::vector>& ordered_ops, const ParameterVector& parameters) { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraph, "Function::check_all_parameters_registered"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::check_all_parameters_registered"); std::stringstream unregistered_parameters; for (auto& node : ordered_ops) { @@ -52,7 +52,7 @@ void check_all_parameters_registered(const std::vector>& ordere } VariableVector auto_detect_variables(const std::vector>& ordered_ops) { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraph, "Function::auto_detect_variables"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::auto_detect_variables"); unordered_set variables; for (const auto& op : ordered_ops) { if (const auto& variable_op = dynamic_pointer_cast(op)) { @@ -63,7 +63,7 @@ VariableVector auto_detect_variables(const std::vector>& o } ParameterVector auto_detect_parameters(const std::vector>& ordered_ops) { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraph, "Function::auto_detect_parameters"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::auto_detect_parameters"); ParameterVector parameter_vector; for (const auto& op : ordered_ops) { if (const auto& param = dynamic_pointer_cast(op)) { @@ -168,7 +168,7 @@ Function::Function(const OutputVector& results, const SinkVector& sinks, const s Function::Function(const OutputVector& results, const string& name) : Function(results, SinkVector{}, name) {} void Function::prerequirements(bool detect_variables, bool detect_parameters) { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraph, "Function::prerequirements"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::prerequirements"); const auto& ordered_ops = get_ordered_ops(); if (detect_parameters) @@ -183,7 +183,7 @@ void Function::prerequirements(bool detect_variables, bool detect_parameters) { } void Function::validate_nodes_and_infer_types() const { - OV_ITT_SCOPED_TASK(ngraph::itt::domains::nGraph, "Function::validate_nodes_and_infer_types"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::validate_nodes_and_infer_types"); struct Counter { int cnt_assign = 0; @@ -223,7 +223,7 @@ void Function::validate_nodes_and_infer_types() const { } std::vector> Function::get_ordered_ops() const { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "Function::get_ordered_ops"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Function::get_ordered_ops"); vector> nodes; for (auto& r : get_results()) { diff --git a/ngraph/core/src/graph_util.cpp b/ngraph/core/src/graph_util.cpp index 86d897a1312..81e24b087b9 100644 --- a/ngraph/core/src/graph_util.cpp +++ b/ngraph/core/src/graph_util.cpp @@ -31,6 +31,8 @@ using namespace std; using namespace ngraph; +NGRAPH_SUPPRESS_DEPRECATED_START + void ngraph::traverse_nodes(const std::shared_ptr p, std::function)> f) { traverse_nodes(p.get(), f); } @@ -788,9 +790,7 @@ bool ngraph::replace_output_update_name(Output output, const Output& if (has_result_output && !is_type(replacement.get_node())) { replacement.get_node()->set_friendly_name(output.get_node()->get_friendly_name()); // Update output tensor name - NGRAPH_SUPPRESS_DEPRECATED_START replacement.get_tensor().set_name(output.get_node()->get_friendly_name()); - NGRAPH_SUPPRESS_DEPRECATED_END } // Save replacement tensor names before replacement as they will be diff --git a/ngraph/core/src/interval.cpp b/ngraph/core/src/interval.cpp index ff021843051..469132f3576 100644 --- a/ngraph/core/src/interval.cpp +++ b/ngraph/core/src/interval.cpp @@ -111,8 +111,7 @@ bool Interval::contains(const Interval& interval) const { constexpr Interval::value_type Interval::s_max; -namespace ngraph { -std::ostream& operator<<(std::ostream& str, const Interval& interval) { +std::ostream& ov::operator<<(std::ostream& str, const Interval& interval) { str << "Interval(" << interval.get_min_val() << ", "; auto max_val = interval.get_max_val(); if (max_val == Interval::s_max) { @@ -122,4 +121,3 @@ std::ostream& operator<<(std::ostream& str, const Interval& interval) { } return str << ")"; } -} // namespace ngraph diff --git a/ngraph/core/src/itt.hpp b/ngraph/core/src/itt.hpp index 9d96091a247..1f602780957 100644 --- a/ngraph/core/src/itt.hpp +++ b/ngraph/core/src/itt.hpp @@ -14,7 +14,7 @@ #include -namespace ngraph { +namespace ov { namespace itt { namespace domains { OV_ITT_DOMAIN(nGraph); @@ -22,7 +22,7 @@ OV_ITT_DOMAIN(nGraphPass_LT); OV_ITT_DOMAIN(ngraph_op, "nGraph::Op"); } // namespace domains } // namespace itt -} // namespace ngraph +} // namespace ov OV_CC_DOMAINS(ngraph_op); OV_ITT_DOMAIN(SIMPLE_ngraph_pass); @@ -38,7 +38,7 @@ OV_ITT_DOMAIN(SIMPLE_ngraph_pass); throw ngraph::ngraph_error(std::string(OV_PP_TOSTRING(OV_PP_CAT3(ngraph_op, _, region))) + " is disabled!") # define NGRAPH_PASS_CALLBACK(matcher) #else -# define NGRAPH_OP_SCOPE(region) OV_ITT_SCOPED_TASK(ngraph::itt::domains::ngraph_op, OV_PP_TOSTRING(region)) +# define NGRAPH_OP_SCOPE(region) OV_ITT_SCOPED_TASK(ov::itt::domains::ngraph_op, OV_PP_TOSTRING(region)) # define NGRAPH_PASS_CALLBACK(matcher) #endif diff --git a/ngraph/core/src/node.cpp b/ngraph/core/src/node.cpp index 8f533f22cf9..cbc1c9611df 100644 --- a/ngraph/core/src/node.cpp +++ b/ngraph/core/src/node.cpp @@ -344,6 +344,7 @@ void Node::merge_provenance_tags_from(const std::shared_ptr& source) } void Node::transfer_provenance_tags(const shared_ptr& replacement) { + NGRAPH_SUPPRESS_DEPRECATED_START auto common_args = ngraph::find_common_args(shared_from_this(), replacement); std::set removed_subgraph_tags; @@ -362,6 +363,7 @@ void Node::transfer_provenance_tags(const shared_ptr& replacement) { }; traverse_nodes({replacement}, set_prov_new_nodes, common_args); + NGRAPH_SUPPRESS_DEPRECATED_END } Node* Node::get_input_node_ptr(size_t index) const { @@ -798,7 +800,7 @@ bool Node::evaluate_upper(const HostTensorVector& output_values) const { } bool Node::constant_fold(OutputVector& output_values, const OutputVector& input_values) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "Node::constant_fold"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "Node::constant_fold"); if (m_rt_info.count("DISABLED_CONSTANT_FOLDING")) { return false; diff --git a/ngraph/core/src/op/convert_like.cpp b/ngraph/core/src/op/convert_like.cpp index 609ddb76993..b036e5e194a 100644 --- a/ngraph/core/src/op/convert_like.cpp +++ b/ngraph/core/src/op/convert_like.cpp @@ -36,7 +36,7 @@ shared_ptr op::v1::ConvertLike::clone_with_new_inputs(const OutputVector& } bool op::v1::ConvertLike::constant_fold(OutputVector& output_values, const OutputVector& input_values) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "op::v1::ConvertLike::constant_fold"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "op::v1::ConvertLike::constant_fold"); if (auto data_const = std::dynamic_pointer_cast(input_values[0].get_node_shared_ptr())) { auto convert = make_shared(input_values[0], input_values[1].get_element_type()); convert->constant_fold(output_values, OutputVector{data_const}); diff --git a/ngraph/core/src/op/convolution.cpp b/ngraph/core/src/op/convolution.cpp index f866a564695..c521a29bb71 100644 --- a/ngraph/core/src/op/convolution.cpp +++ b/ngraph/core/src/op/convolution.cpp @@ -96,9 +96,11 @@ shared_ptr op::v1::Convolution::clone_with_new_inputs(const OutputVector& m_auto_pad); } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v1::Convolution::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END // *** ConvolutionBackpropData OP SET 1 *** NGRAPH_RTTI_DEFINITION(op::v1::ConvolutionBackpropData, "ConvolutionBackpropData", 1); diff --git a/ngraph/core/src/op/cum_sum.cpp b/ngraph/core/src/op/cum_sum.cpp index 6f963f4186e..26c7177920a 100644 --- a/ngraph/core/src/op/cum_sum.cpp +++ b/ngraph/core/src/op/cum_sum.cpp @@ -38,14 +38,7 @@ bool op::v0::CumSum::visit_attributes(AttributeVisitor& visitor) { void op::v0::CumSum::validate_and_infer_types() { NGRAPH_OP_SCOPE(v0_CumSum_validate_and_infer_types); - element::Type arg_type = get_input_element_type(0); - PartialShape arg_shape = get_input_partial_shape(0); - set_output_type(0, arg_type, arg_shape); - - PartialShape axes_shape{PartialShape::dynamic()}; - if (get_input_partial_shape(1).is_static()) { - axes_shape = get_input_partial_shape(1); - } + set_output_type(0, get_input_element_type(0), get_input_partial_shape(0)); const auto& axis_type = get_input_element_type(1); NODE_VALIDATION_CHECK(this, @@ -53,14 +46,22 @@ void op::v0::CumSum::validate_and_infer_types() { "axis element type must be either int64_t or int32_t but got (", axis_type, ")."); + + // No axis input shape check for backward compatibility } shared_ptr op::v0::CumSum::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v0_CumSum_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), m_exclusive, m_reverse); + if (new_args.size() == 2) + return make_shared(new_args.at(0), new_args.at(1), m_exclusive, m_reverse); + else { + return make_shared(new_args.at(0), m_exclusive, m_reverse); + } } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v0::CumSum::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/ngraph/core/src/op/gelu.cpp b/ngraph/core/src/op/gelu.cpp index f25150abad1..272023cdfe2 100644 --- a/ngraph/core/src/op/gelu.cpp +++ b/ngraph/core/src/op/gelu.cpp @@ -8,26 +8,17 @@ #include #include "itt.hpp" -#include "ngraph/builder/make_constant.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/divide.hpp" -#include "ngraph/op/erf.hpp" -#include "ngraph/op/exp.hpp" -#include "ngraph/op/multiply.hpp" -#include "ngraph/op/negative.hpp" -#include "ngraph/op/subtract.hpp" #include "ngraph/runtime/reference/gelu.hpp" using namespace std; using namespace ngraph; -NGRAPH_SUPPRESS_DEPRECATED_START +// ------------------------------ V0 ------------------------------ +NGRAPH_RTTI_DEFINITION(op::v0::Gelu, "Gelu", 0); -constexpr NodeTypeInfo op::Gelu::type_info; +op::v0::Gelu::Gelu() : Op() {} -op::v0::Gelu::Gelu() : FusedOp() {} - -op::v0::Gelu::Gelu(const Output& data) : FusedOp({data}) { +op::v0::Gelu::Gelu(const Output& data) : Op({data}) { constructor_validate_and_infer_types(); } @@ -36,25 +27,6 @@ bool op::v0::Gelu::visit_attributes(AttributeVisitor& visitor) { return true; } -// f(x) = 0.5 * x * (1.0 + erf( x / sqrt(2.0) ) -OutputVector op::Gelu::decompose_op() const { - auto data = input_value(0); - - shared_ptr half = builder::make_constant(data.get_element_type(), data.get_shape(), 0.5); - - shared_ptr one = builder::make_constant(data.get_element_type(), data.get_shape(), 1.0); - - shared_ptr sqrt_two = - builder::make_constant(data.get_element_type(), data.get_shape(), std::sqrt(2.0)); - - shared_ptr add = - std::make_shared(one, - make_shared(std::make_shared(data, sqrt_two))); - shared_ptr multiply = std::make_shared(half, data); - - return {std::make_shared(multiply, add)}; -} - shared_ptr op::v0::Gelu::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v0_Gelu_clone_with_new_inputs); if (new_args.size() != 1) { @@ -63,7 +35,8 @@ shared_ptr op::v0::Gelu::clone_with_new_inputs(const OutputVector& new_arg return make_shared(new_args.at(0)); } -void op::v0::Gelu::pre_validate_and_infer_types() { +void op::v0::Gelu::validate_and_infer_types() { + NGRAPH_OP_SCOPE(v0_Gelu_validate_and_infer_types); element::Type input_element_type = get_input_element_type(0); PartialShape input_pshape = get_input_partial_shape(0); diff --git a/ngraph/core/src/op/hard_sigmoid.cpp b/ngraph/core/src/op/hard_sigmoid.cpp index 23dc7baa739..d397831c962 100644 --- a/ngraph/core/src/op/hard_sigmoid.cpp +++ b/ngraph/core/src/op/hard_sigmoid.cpp @@ -7,24 +7,17 @@ #include #include "itt.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/maximum.hpp" -#include "ngraph/op/minimum.hpp" -#include "ngraph/op/multiply.hpp" #include "ngraph/shape.hpp" using namespace std; using namespace ngraph; -NGRAPH_SUPPRESS_DEPRECATED_START +NGRAPH_RTTI_DEFINITION(op::v0::HardSigmoid, "HardSigmoid", 0); -NGRAPH_RTTI_DEFINITION(op::HardSigmoid, "HardSigmoid", 0, op::util::FusedOp); +op::v0::HardSigmoid::HardSigmoid() : Op() {} -op::HardSigmoid::HardSigmoid() : FusedOp() {} - -op::HardSigmoid::HardSigmoid(const Output& data, const Output& alpha, const Output& beta) - : FusedOp({data, alpha, beta}) { +op::v0::HardSigmoid::HardSigmoid(const Output& data, const Output& alpha, const Output& beta) + : Op({data, alpha, beta}) { constructor_validate_and_infer_types(); } @@ -33,7 +26,8 @@ bool ngraph::op::v0::HardSigmoid::visit_attributes(AttributeVisitor& visitor) { return true; } -void op::HardSigmoid::pre_validate_and_infer_types() { +void op::v0::HardSigmoid::validate_and_infer_types() { + NGRAPH_OP_SCOPE(v0_HardSigmoid_validate_and_infer_types); const auto& alpha_pshape = get_input_partial_shape(1); const auto& beta_pshape = get_input_partial_shape(2); @@ -64,28 +58,9 @@ void op::HardSigmoid::pre_validate_and_infer_types() { set_output_type(0, get_input_element_type(0), get_input_partial_shape(0)); } -OutputVector op::HardSigmoid::decompose_op() const { - const auto data = input_value(0); - - const auto one_node = ngraph::op::Constant::create(data.get_element_type(), data.get_shape(), {1.0f}); - - const auto zero_node = ngraph::op::Constant::create(data.get_element_type(), data.get_shape(), {0.0f}); - - const auto alpha_node = input_value(1).get_node_shared_ptr(); - const auto beta_node = input_value(2).get_node_shared_ptr(); - - std::shared_ptr alpha_x_plus_beta = - std::make_shared(alpha_node, data, AutoBroadcastType::NUMPY); - - alpha_x_plus_beta = std::make_shared(alpha_x_plus_beta, beta_node, AutoBroadcastType::NUMPY); - - return { - std::make_shared(std::make_shared(alpha_x_plus_beta, zero_node), one_node)}; -} - -shared_ptr op::HardSigmoid::clone_with_new_inputs(const OutputVector& new_args) const { +shared_ptr op::v0::HardSigmoid::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v0_HardSigmoid_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), new_args.at(2)); + return std::make_shared(new_args.at(0), new_args.at(1), new_args.at(2)); } diff --git a/ngraph/core/src/op/if.cpp b/ngraph/core/src/op/if.cpp new file mode 100644 index 00000000000..ea8c76d0c8e --- /dev/null +++ b/ngraph/core/src/op/if.cpp @@ -0,0 +1,267 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "ngraph/op/if.hpp" + +#include +#include +#include + +#include "itt.hpp" +#include "ngraph/factory.hpp" +#include "ngraph/graph_util.hpp" +#include "ngraph/op/util/multi_subgraph_base.hpp" +#include "ngraph/runtime/reference/if.hpp" +#include "ngraph/specialize_function.hpp" + +using namespace std; +using namespace ngraph; + +NGRAPH_RTTI_DEFINITION(ngraph::op::v8::If, "If", 8, MultiSubGraphOp); + +op::v8::If::If() : MultiSubGraphOp(2) {} + +op::v8::If::If(const Output& execution_condition) : If() { + set_argument(0, execution_condition); +} + +// This function tries to calculate the output shape of the if operation by two outputs from two +// subgraphs. +static ngraph::PartialShape resolve_shape(const ngraph::PartialShape& then_pshape, + const ngraph::PartialShape& else_pshape) { + // then_pshape - shape of output from then_body + // else_pshape - shape of output from else_body + auto then_rank = then_pshape.rank(); + auto else_rank = else_pshape.rank(); + + // if rangs of shapes are not equal or rang of one of them is dynamic function + // return shape with dynamic rank + if (then_rank.is_dynamic() || else_rank.is_dynamic() || then_rank.get_length() != else_rank.get_length()) { + return ngraph::PartialShape::dynamic(ngraph::Rank::dynamic()); + } + std::vector new_dims; + + // If rangs are equal each dimesion of then_body output is union with each dimension of + // else_body + for (auto then_it = then_pshape.cbegin(), else_it = else_pshape.cbegin(); then_it != then_pshape.cend(); + then_it++, else_it++) { + if ((*then_it).is_dynamic() || (*else_it).is_dynamic()) { + new_dims.push_back(Dimension::dynamic()); + } else if (*then_it == *else_it) { + new_dims.push_back(Dimension(*then_it)); + } else { + auto dim_min = std::min((*then_it).get_min_length(), (*else_it).get_min_length()); + auto dim_max = std::max((*then_it).get_min_length(), (*else_it).get_min_length()); + new_dims.push_back(Dimension(dim_min, dim_max)); + } + } + + return PartialShape(new_dims); +} + +bool op::v8::If::visit_attributes(AttributeVisitor& visitor) { + NGRAPH_OP_SCOPE(v8_If_visit_attributes); + m_bodies[THEN_BODY_INDEX] = std::make_shared(OutputVector{}, ParameterVector{}, "then_branch"); + m_bodies[ELSE_BODY_INDEX] = std::make_shared(OutputVector{}, ParameterVector{}, "else_branch"); + visitor.on_attribute("then_body", m_bodies[THEN_BODY_INDEX]); + visitor.on_attribute("else_body", m_bodies[ELSE_BODY_INDEX]); + visitor.on_attribute("then_inputs", m_input_descriptions[THEN_BODY_INDEX]); + visitor.on_attribute("else_inputs", m_input_descriptions[ELSE_BODY_INDEX]); + visitor.on_attribute("then_outputs", m_output_descriptions[THEN_BODY_INDEX]); + visitor.on_attribute("else_outputs", m_output_descriptions[ELSE_BODY_INDEX]); + return true; +} + +void op::v8::If::validate_and_infer_type_body( + const std::shared_ptr& body, + const ngraph::op::util::MultiSubgraphInputDescriptionVector& input_descriptors) { + for (const auto& input_description : input_descriptors) { + auto index = input_description->m_input_index; + + auto body_parameter = body->get_parameters().at(input_description->m_body_parameter_index); + auto input_partial_shape = input_value(index).get_partial_shape(); + body_parameter->set_partial_shape(input_partial_shape); + } + body->validate_nodes_and_infer_types(); +} + +void op::v8::If::validate_and_infer_types() { + NGRAPH_OP_SCOPE(v8_If_validate_and_infer_types); + + NODE_VALIDATION_CHECK(this, m_bodies.size() == 2, "If contains incorrect number of bodies:", m_bodies.size()); + + NODE_VALIDATION_CHECK(this, + m_input_descriptions.size() == 2, + "If contains incorrect number of body input descriptions:", + m_input_descriptions.size()); + NODE_VALIDATION_CHECK(this, + m_output_descriptions.size() == 2, + "If contains incorrect number of body output descriptions:", + m_output_descriptions.size()); + + const auto& if_condition = input_value(0); + const auto& if_condition_rank = if_condition.get_partial_shape().rank(); + if (if_condition_rank.is_static()) { + NODE_VALIDATION_CHECK(this, + if_condition_rank.compatible(1) || if_condition_rank.compatible(0), + "Rank of If condition input must be equal to 0 or 1"); + } + + // Trying to get cond as const value + if (const auto& cond_value = get_constant_from_source(if_condition)) { + // If cond is const shape and inference is run for one of bodies another body is skipped + auto val = cond_value->cast_vector(); + NODE_VALIDATION_CHECK(this, + val.size() == 1, + "The number of values in the If condition constant is greater than 1"); + + auto cond_index = val[0] ? THEN_BODY_INDEX : ELSE_BODY_INDEX; + auto body = m_bodies[cond_index]; + auto input_descriptors = m_input_descriptions[cond_index]; + validate_and_infer_type_body(body, input_descriptors); + auto output_nodes = outputs(); + + // shape and type inference for outputs from If operations + for (const auto& output_descr : m_output_descriptions[cond_index]) { + auto body_value = body->get_results().at(output_descr->m_body_value_index)->input_value(0); + auto body_value_partial_shape = body_value.get_partial_shape(); + set_output_type(output_descr->m_output_index, body_value.get_element_type(), body_value_partial_shape); + } + } else // condition is non constant + { + // If cond is non const, shape and type inference is run for both bodies + validate_and_infer_type_body(get_then_body(), m_input_descriptions[THEN_BODY_INDEX]); + validate_and_infer_type_body(get_else_body(), m_input_descriptions[ELSE_BODY_INDEX]); + auto output_nodes = outputs(); + + // Getting map. This map guarantees that each + // output from the body will be met in it once. + auto then_outputs_map = get_mapping_outputs_on_body_description(m_output_descriptions[THEN_BODY_INDEX]); + auto else_outputs_map = get_mapping_outputs_on_body_description(m_output_descriptions[ELSE_BODY_INDEX]); + + // Checking each output from If. Each output must be associated with one output from each + // body + for (size_t output_index = 0; output_index < output_nodes.size(); ++output_index) { + NODE_VALIDATION_CHECK(this, + then_outputs_map.count(output_index) != 0, + "Incorrect associating in then_body! Output ", + output_index, + " is not associated with results in then_body!"); + NODE_VALIDATION_CHECK(this, + else_outputs_map.count(output_index) != 0, + "Incorrect associating in else_body! Output ", + output_index, + " is not associated with results in else_body!"); + + auto then_desc = then_outputs_map.at(output_index); + auto else_desc = else_outputs_map.at(output_index); + + auto then_node_result = + m_bodies[THEN_BODY_INDEX]->get_results().at(then_desc->m_body_value_index)->input_value(0); + + auto else_node_result = + m_bodies[ELSE_BODY_INDEX]->get_results().at(else_desc->m_body_value_index)->input_value(0); + + NODE_VALIDATION_CHECK(this, + then_node_result.get_element_type() == else_node_result.get_element_type(), + "type of then_body output is not equal type of else_body output"); + + // shape inference for output and associated with it body outputs + auto partial_shape = + resolve_shape(then_node_result.get_partial_shape(), else_node_result.get_partial_shape()); + set_output_type(output_index, then_node_result.get_element_type(), partial_shape); + } + } +} + +std::shared_ptr op::v8::If::clone_with_new_inputs(const OutputVector& new_args) const { + NGRAPH_OP_SCOPE(v8_If_clone_with_new_inputs); + + check_new_args_count(this, new_args); + auto op = make_shared(); + NGRAPH_CHECK(op.get(), op != nullptr, "Cannot clone ", description(), " operation with name ", get_friendly_name()); + + op->set_arguments(new_args); + op->set_output_size(m_output_descriptions[0].size()); + op->set_then_body(clone_function(*get_then_body())); + op->set_else_body(clone_function(*get_else_body())); + + for (auto body_index = 0; body_index < 2; ++body_index) { + for (const auto& m_input_descr : m_input_descriptions[body_index]) { + op->m_input_descriptions[body_index].push_back(m_input_descr->copy()); + } + for (const auto& m_output_descr : m_output_descriptions[body_index]) { + op->m_output_descriptions[body_index].push_back(m_output_descr->copy()); + } + } + op->validate_and_infer_types(); + + return op; +} + +op::v8::If::OutputMap op::v8::If::get_mapping_outputs_on_body_description( + const ngraph::op::util::MultiSubgraphOutputDescriptionVector& output_descriptors) { + OutputMap outputs_map = OutputMap(); + std::unordered_set checked_results_in_body; + + for (const auto& output_description : output_descriptors) { + auto out_index = output_description->m_output_index; + auto internal_result_index = output_description->m_body_value_index; + NODE_VALIDATION_CHECK(this, + checked_results_in_body.count(internal_result_index) == 0, + "Incorrect associating in then_body! Result ", + internal_result_index, + " is already associated with another output!"); + NODE_VALIDATION_CHECK(this, + outputs_map.count(out_index) == 0, + "Incorrect associating in then_body! Several results try to " + "associate with the same output!"); + checked_results_in_body.insert(internal_result_index); + outputs_map.insert({out_index, output_description}); + } + + return outputs_map; +} + +bool op::v8::If::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { + NGRAPH_OP_SCOPE(v8_If_evaluate); + runtime::reference::if_reference(m_bodies, m_output_descriptions, m_input_descriptions, outputs, inputs); + return true; +} + +bool op::v8::If::has_evaluate() const { + NGRAPH_OP_SCOPE(v8_If_has_evaluate); + return true; +} + +void op::v8::If::set_input(const Output& value, + const std::shared_ptr& then_parameter, + const std::shared_ptr& else_parameter) { + NGRAPH_CHECK(then_parameter != nullptr || else_parameter != nullptr, + "Missing parameters! Both parameters are nullptr!"); + auto then_param_index = m_bodies[THEN_BODY_INDEX]->get_parameter_index(then_parameter); + auto else_param_index = m_bodies[ELSE_BODY_INDEX]->get_parameter_index(else_parameter); + NGRAPH_CHECK(then_parameter == nullptr || then_param_index != -1, + "Missing parameter ", + then_parameter->get_friendly_name(), + " for \'then_body\'!"); + NGRAPH_CHECK(else_parameter == nullptr || else_param_index != -1, + "Missing parameter ", + else_parameter->get_friendly_name(), + " for \'else_body\'!"); + set_invariant_inputs(value, {then_parameter, else_parameter}); +} + +Output op::v8::If::set_output(const std::shared_ptr& then_result, + const std::shared_ptr& else_result) { + NGRAPH_CHECK(then_result != nullptr, "Incorrect result in \"then_body\"! Result cant be \'nullptr\'"); + NGRAPH_CHECK(else_result != nullptr, "Incorrect result in \"else_body\"! Result cant be \'nullptr\'"); + auto then_result_id = m_bodies[THEN_BODY_INDEX]->get_result_index(then_result); + auto else_result_id = m_bodies[ELSE_BODY_INDEX]->get_result_index(else_result); + + NGRAPH_CHECK(then_result_id != -1, "Missing result ", then_result->get_friendly_name(), "in \'then_body\'!"); + NGRAPH_CHECK(else_result_id != -1, "Missing result ", else_result->get_friendly_name(), "in \'then_body\'!"); + + return set_body_outputs({then_result, else_result}); +} \ No newline at end of file diff --git a/ngraph/core/src/op/interpolate.cpp b/ngraph/core/src/op/interpolate.cpp index 63a337347b6..42359cde32c 100644 --- a/ngraph/core/src/op/interpolate.cpp +++ b/ngraph/core/src/op/interpolate.cpp @@ -74,10 +74,10 @@ template <> EnumNames& EnumNames::get() { static auto enum_names = EnumNames("op::v0::Interpolate::InterpolateMode", - {{"nearest", op::v0::Interpolate::InterpolateMode::nearest}, - {"linear", op::v0::Interpolate::InterpolateMode::linear}, - {"cubic", op::v0::Interpolate::InterpolateMode::cubic}, - {"area", op::v0::Interpolate::InterpolateMode::area}}); + {{"nearest", op::v0::Interpolate::InterpolateMode::NEAREST}, + {"linear", op::v0::Interpolate::InterpolateMode::LINEAR}, + {"cubic", op::v0::Interpolate::InterpolateMode::CUBIC}, + {"area", op::v0::Interpolate::InterpolateMode::AREA}}); return enum_names; } @@ -255,7 +255,7 @@ void op::v4::Interpolate::validate_and_infer_types() { } } - if (m_attrs.shape_calculation_mode == ShapeCalcMode::scales) { + if (m_attrs.shape_calculation_mode == ShapeCalcMode::SCALES) { if (const auto& const_scales = get_constant_from_source(input_value(2))) { auto scales = const_scales->cast_vector(); infer_using_scales(output_shape, axes, scales, padded_input_shape); @@ -323,7 +323,7 @@ std::vector get_scales_vector(const HostTensorVector& args, std::vector scales; size_t num_of_axes = axes.size(); - if (attrs.shape_calculation_mode == ShapeCalcMode::scales) { + if (attrs.shape_calculation_mode == ShapeCalcMode::SCALES) { float* scales_ptr = args[scales_port]->get_data_ptr(); scales.insert(scales.end(), scales_ptr, scales_ptr + num_of_axes); } else { @@ -406,7 +406,7 @@ bool op::v4::Interpolate::evaluate_interpolate(const HostTensorVector& outputs, PartialShape output_shape{padded_input_shape}; - if (m_attrs.shape_calculation_mode == ShapeCalcMode::scales) { + if (m_attrs.shape_calculation_mode == ShapeCalcMode::SCALES) { infer_using_scales(output_shape, axes, scales, padded_input_shape); } else { auto sizes = get_target_shape_vector(inputs, num_of_axes); @@ -484,10 +484,10 @@ template <> NGRAPH_API EnumNames& EnumNames::get() { static auto enum_names = EnumNames( "op::v4::Interpolate::InterpolateMode", - {{"nearest", op::v4::Interpolate::InterpolateMode::nearest}, - {"linear", op::v4::Interpolate::InterpolateMode::linear}, - {"linear_onnx", op::v4::Interpolate::InterpolateMode::linear_onnx}, - {"cubic", op::v4::Interpolate::InterpolateMode::cubic}}); + {{"nearest", op::v4::Interpolate::InterpolateMode::NEAREST}, + {"linear", op::v4::Interpolate::InterpolateMode::LINEAR}, + {"linear_onnx", op::v4::Interpolate::InterpolateMode::LINEAR_ONNX}, + {"cubic", op::v4::Interpolate::InterpolateMode::CUBIC}}); return enum_names; } @@ -501,7 +501,7 @@ template <> NGRAPH_API EnumNames& EnumNames::get() { static auto enum_names = EnumNames( "op::v4::Interpolate::ShapeCalcMode", - {{"sizes", op::v4::Interpolate::ShapeCalcMode::sizes}, {"scales", op::v4::Interpolate::ShapeCalcMode::scales}}); + {{"sizes", op::v4::Interpolate::ShapeCalcMode::SIZES}, {"scales", op::v4::Interpolate::ShapeCalcMode::SCALES}}); return enum_names; } @@ -516,11 +516,11 @@ NGRAPH_API EnumNames& EnumNames::get() { static auto enum_names = EnumNames( "op::v4::Interpolate::CoordinateTransformMode", - {{"half_pixel", op::v4::Interpolate::CoordinateTransformMode::half_pixel}, - {"pytorch_half_pixel", op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel}, - {"asymmetric", op::v4::Interpolate::CoordinateTransformMode::asymmetric}, - {"tf_half_pixel_for_nn", op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn}, - {"align_corners", op::v4::Interpolate::CoordinateTransformMode::align_corners}}); + {{"half_pixel", op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL}, + {"pytorch_half_pixel", op::v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL}, + {"asymmetric", op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC}, + {"tf_half_pixel_for_nn", op::v4::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN}, + {"align_corners", op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS}}); return enum_names; } @@ -534,11 +534,11 @@ template <> NGRAPH_API EnumNames& EnumNames::get() { static auto enum_names = EnumNames( "op::v4::Interpolate::NearestMode", - {{"round_prefer_floor", op::v4::Interpolate::NearestMode::round_prefer_floor}, - {"round_prefer_ceil", op::v4::Interpolate::NearestMode::round_prefer_ceil}, - {"floor", op::v4::Interpolate::NearestMode::floor}, - {"ceil", op::v4::Interpolate::NearestMode::ceil}, - {"simple", op::v4::Interpolate::NearestMode::simple}}); + {{"round_prefer_floor", op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR}, + {"round_prefer_ceil", op::v4::Interpolate::NearestMode::ROUND_PREFER_CEIL}, + {"floor", op::v4::Interpolate::NearestMode::FLOOR}, + {"ceil", op::v4::Interpolate::NearestMode::CEIL}, + {"simple", op::v4::Interpolate::NearestMode::SIMPLE}}); return enum_names; } diff --git a/ngraph/core/src/op/lstm_sequence.cpp b/ngraph/core/src/op/lstm_sequence.cpp index 6ef1c335aa8..5a1229986a6 100644 --- a/ngraph/core/src/op/lstm_sequence.cpp +++ b/ngraph/core/src/op/lstm_sequence.cpp @@ -16,13 +16,11 @@ using namespace ngraph; using namespace std; -NGRAPH_SUPPRESS_DEPRECATED_START - NGRAPH_RTTI_DEFINITION(op::v0::LSTMSequence, "LSTMSequence", 0); NGRAPH_RTTI_DEFINITION(op::v5::LSTMSequence, "LSTMSequence", 5); op::v0::LSTMSequence::LSTMSequence() - : FusedOp(), + : Op(), m_activations_alpha(), m_activations_beta(), m_activations(), @@ -48,7 +46,7 @@ op::v0::LSTMSequence::LSTMSequence(const Output& X, const std::vector activations, const float clip_threshold, const bool input_forget) - : FusedOp({X, initial_hidden_state, initial_cell_state, sequence_lengths, W, R, B, P}), + : Op({X, initial_hidden_state, initial_cell_state, sequence_lengths, W, R, B, P}), m_activations_alpha(activations_alpha), m_activations_beta(activations_beta), m_activations(activations), @@ -110,24 +108,6 @@ bool op::v0::LSTMSequence::visit_attributes(AttributeVisitor& visitor) { return true; } -OutputVector op::v0::LSTMSequence::decompose_op() const { - OutputVector results; - if (m_direction == direction::FORWARD || m_direction == direction::REVERSE) { - results = lstm_pass(m_direction == direction::REVERSE); - } - if (m_direction == direction::BIDIRECTIONAL) { - OutputVector fwd_results{lstm_pass()}; - OutputVector rev_results{lstm_pass(true)}; - - // Stack together respective outputs from both forward and reverse passess. - shared_ptr Y{make_shared(OutputVector{fwd_results.at(0), rev_results.at(0)}, 1)}; - shared_ptr Y_h{make_shared(OutputVector{fwd_results.at(1), rev_results.at(1)}, 1)}; - shared_ptr Y_c{make_shared(OutputVector{fwd_results.at(2), rev_results.at(2)}, 1)}; - results = OutputVector{Y, Y_h, Y_c}; - } - return results; -} - shared_ptr op::v0::LSTMSequence::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v0_LSTMSequence_clone_with_new_inputs); check_new_args_count(this, new_args); diff --git a/ngraph/core/src/op/max_pool.cpp b/ngraph/core/src/op/max_pool.cpp index d6438cc5078..5e5755fa485 100644 --- a/ngraph/core/src/op/max_pool.cpp +++ b/ngraph/core/src/op/max_pool.cpp @@ -171,13 +171,11 @@ op::v8::MaxPool::MaxPool(const Output& arg, const op::RoundingType rounding_type, const PadType auto_pad, const element::Type index_element_type, - const int64_t axis, - const float pads_value) + const int64_t axis) : op::util::MaxPoolBase(arg, strides, pads_begin, pads_end, kernel, rounding_type, auto_pad), m_dilations{dilations}, m_index_element_type{index_element_type}, - m_axis{axis}, - m_pads_value{pads_value} { + m_axis{axis} { constructor_validate_and_infer_types(); } @@ -192,7 +190,6 @@ bool ngraph::op::v8::MaxPool::visit_attributes(AttributeVisitor& visitor) { visitor.on_attribute("auto_pad", m_auto_pad); visitor.on_attribute("index_element_type", m_index_element_type); visitor.on_attribute("axis", m_axis); - visitor.on_attribute("pads_value", m_pads_value); return true; } @@ -224,6 +221,5 @@ shared_ptr op::v8::MaxPool::clone_with_new_inputs(const OutputVector& new_ m_rounding_type, m_auto_pad, m_index_element_type, - m_axis, - m_pads_value); + m_axis); } diff --git a/ngraph/core/src/op/mvn.cpp b/ngraph/core/src/op/mvn.cpp index 5d0b2887ebb..b70c944a692 100644 --- a/ngraph/core/src/op/mvn.cpp +++ b/ngraph/core/src/op/mvn.cpp @@ -7,36 +7,26 @@ #include #include "itt.hpp" -#include "ngraph/builder/autobroadcast.hpp" -#include "ngraph/builder/reduce_ops.hpp" -#include "ngraph/op/add.hpp" -#include "ngraph/op/broadcast.hpp" -#include "ngraph/op/constant.hpp" -#include "ngraph/op/divide.hpp" -#include "ngraph/op/sqrt.hpp" -#include "ngraph/op/subtract.hpp" using namespace std; using namespace ngraph; // ------------------------------ V0 ------------------------------ -NGRAPH_SUPPRESS_DEPRECATED_START - NGRAPH_RTTI_DEFINITION(op::v0::MVN, "MVN", 0); -op::MVN::MVN() : FusedOp(), m_across_channels(), m_normalize_variance(), m_reduction_axes() {} +op::v0::MVN::MVN() : Op(), m_across_channels(), m_normalize_variance(), m_reduction_axes() {} -op::MVN::MVN(const Output& data, bool across_channels, bool normalize_variance, double eps) - : FusedOp({data}), +op::v0::MVN::MVN(const Output& data, bool across_channels, bool normalize_variance, double eps) + : Op({data}), m_eps{eps}, m_across_channels{across_channels}, m_normalize_variance{normalize_variance} { constructor_validate_and_infer_types(); } -op::MVN::MVN(const Output& data, AxisSet reduction_axes, bool normalize_variance, double eps) - : FusedOp({data}), +op::v0::MVN::MVN(const Output& data, AxisSet reduction_axes, bool normalize_variance, double eps) + : Op({data}), m_eps{eps}, m_across_channels{false}, m_normalize_variance{normalize_variance}, @@ -46,10 +36,7 @@ op::MVN::MVN(const Output& data, AxisSet reduction_axes, bool normalize_va m_across_channels = (m_reduction_axes.count(chanelAxis) > 0); } -// decompose_op() relies on knowing the data type of input data which might -// not be available at shape inference time. So do direct shape inference -// instead of relying on op decomposition. -void op::MVN::validate_and_infer_types() { +void op::v0::MVN::validate_and_infer_types() { NGRAPH_OP_SCOPE(v0_MVN_validate_and_infer_types); // if m_across_channels is true we should calculate mean and variance per batch // else we calculate these per channel @@ -65,40 +52,16 @@ void op::MVN::validate_and_infer_types() { set_output_type(0, get_input_element_type(0), get_input_partial_shape(0)); } -OutputVector op::MVN::decompose_op() const { - auto data = input_value(0); - auto data_shape = data.get_shape(); // assume that data has n and c channels. - - // calculate mean normalization - auto mean = builder::opset1::mean(data, m_reduction_axes); - auto mean_normalization = - std::make_shared(data, builder::opset1::make_broadcast(mean, data_shape, m_reduction_axes)); - - if (!m_normalize_variance) { - return {mean_normalization}; - } else { - // calculate variance - auto variance = builder::opset1::variance(data, m_reduction_axes); - // add epsilon - auto eps_node = - op::Constant::create(data.get_element_type(), Output(variance).get_shape(), vector{m_eps}); - variance = std::make_shared(std::make_shared(variance, eps_node)); - return OutputVector{ - std::make_shared(mean_normalization, - builder::opset1::make_broadcast(variance, data_shape, m_reduction_axes))}; - } -} - -shared_ptr op::MVN::clone_with_new_inputs(const OutputVector& new_args) const { +shared_ptr op::v0::MVN::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v0_MVN_clone_with_new_inputs); NODE_VALIDATION_CHECK(this, new_args.size() == 1, "Expected 1 element in new_args for the MVN op but got ", new_args.size()); - return make_shared(new_args.at(0), m_reduction_axes, m_normalize_variance, m_eps); + return std::make_shared(new_args.at(0), m_reduction_axes, m_normalize_variance, m_eps); } -bool op::MVN::visit_attributes(AttributeVisitor& visitor) { +bool op::v0::MVN::visit_attributes(AttributeVisitor& visitor) { NGRAPH_OP_SCOPE(v0_MVN_visit_attributes); visitor.on_attribute("eps", m_eps); visitor.on_attribute("across_channels", m_across_channels); diff --git a/ngraph/core/src/op/reduce_l1.cpp b/ngraph/core/src/op/reduce_l1.cpp index 821baf61f12..c23b63173fc 100644 --- a/ngraph/core/src/op/reduce_l1.cpp +++ b/ngraph/core/src/op/reduce_l1.cpp @@ -23,9 +23,11 @@ op::v4::ReduceL1::ReduceL1(const Output& arg, const Output& reductio constructor_validate_and_infer_types(); } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v4::ReduceL1::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END shared_ptr op::v4::ReduceL1::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v4_ReduceL1_clone_with_new_inputs); diff --git a/ngraph/core/src/op/reduce_l2.cpp b/ngraph/core/src/op/reduce_l2.cpp index 64b26a22c99..396c365f30e 100644 --- a/ngraph/core/src/op/reduce_l2.cpp +++ b/ngraph/core/src/op/reduce_l2.cpp @@ -23,9 +23,11 @@ op::v4::ReduceL2::ReduceL2(const Output& arg, const Output& reductio constructor_validate_and_infer_types(); } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v4::ReduceL2::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END shared_ptr op::v4::ReduceL2::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v4_ReduceL2_clone_with_new_inputs); diff --git a/ngraph/core/src/op/reduce_prod.cpp b/ngraph/core/src/op/reduce_prod.cpp index 58840788fac..30bd01de272 100644 --- a/ngraph/core/src/op/reduce_prod.cpp +++ b/ngraph/core/src/op/reduce_prod.cpp @@ -23,9 +23,11 @@ op::v1::ReduceProd::ReduceProd(const Output& arg, const Output& redu constructor_validate_and_infer_types(); } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v1::ReduceProd::get_default_value() const { return ngraph::make_constant_from_string("1", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END shared_ptr op::v1::ReduceProd::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v1_ReduceProd_clone_with_new_inputs); diff --git a/ngraph/core/src/op/reduce_sum.cpp b/ngraph/core/src/op/reduce_sum.cpp index 51b4a3aa53d..ae0e9a60364 100644 --- a/ngraph/core/src/op/reduce_sum.cpp +++ b/ngraph/core/src/op/reduce_sum.cpp @@ -25,9 +25,11 @@ op::v1::ReduceSum::ReduceSum(const Output& arg, const Output& reduct constructor_validate_and_infer_types(); } +NGRAPH_SUPPRESS_DEPRECATED_START shared_ptr op::v1::ReduceSum::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); } +NGRAPH_SUPPRESS_DEPRECATED_END shared_ptr op::v1::ReduceSum::clone_with_new_inputs(const OutputVector& new_args) const { NGRAPH_OP_SCOPE(v1_ReduceSum_clone_with_new_inputs); diff --git a/ngraph/core/src/op/shape_of.cpp b/ngraph/core/src/op/shape_of.cpp index 3480ca5f0e3..69090af304a 100644 --- a/ngraph/core/src/op/shape_of.cpp +++ b/ngraph/core/src/op/shape_of.cpp @@ -173,7 +173,7 @@ bool op::v3::ShapeOf::evaluate_upper(const HostTensorVector& output_values) cons } bool op::v3::ShapeOf::constant_fold(OutputVector& output_values, const OutputVector& input_values) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "op::v3::ShapeOf::constant_fold"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "op::v3::ShapeOf::constant_fold"); if (get_rt_info().count("DISABLED_CONSTANT_FOLDING")) return false; return shape_of::constant_fold_shape_of(this, output_values[0], input_values[0]); @@ -232,7 +232,7 @@ bool op::v0::ShapeOf::has_evaluate() const { } bool op::v0::ShapeOf::constant_fold(OutputVector& output_values, const OutputVector& input_values) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "op::v0::ShapeOf::constant_fold"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "op::v0::ShapeOf::constant_fold"); if (get_rt_info().count("DISABLED_CONSTANT_FOLDING")) return false; return shape_of::constant_fold_shape_of(this, output_values[0], input_values[0]); diff --git a/ngraph/core/src/op/xor.cpp b/ngraph/core/src/op/xor.cpp index f0673dbd93f..00610fc9ceb 100644 --- a/ngraph/core/src/op/xor.cpp +++ b/ngraph/core/src/op/xor.cpp @@ -7,6 +7,7 @@ #include "itt.hpp" #include "ngraph/runtime/host_tensor.hpp" #include "ngraph/runtime/reference/xor.hpp" +#include "ngraph/validation_util.hpp" using namespace std; using namespace ngraph; @@ -26,12 +27,6 @@ shared_ptr op::v1::LogicalXor::clone_with_new_inputs(const OutputVector& n return make_shared(new_args.at(0), new_args.at(1), this->get_autob()); } -bool ngraph::op::v1::LogicalXor::visit_attributes(AttributeVisitor& visitor) { - NGRAPH_OP_SCOPE(v1_LogicalXor_visit_attributes); - BinaryElementwiseLogical::visit_attributes(visitor); - return true; -} - namespace logxor { template bool evaluate(const HostTensorPtr& arg0, @@ -55,22 +50,17 @@ bool evaluate_logxor(const HostTensorPtr& arg0, out->set_broadcast(broadcast_spec, arg0, arg1); switch (arg0->get_element_type()) { NGRAPH_TYPE_CASE(evaluate_logxor, boolean, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, i32, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, i64, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, u32, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, u64, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, f16, arg0, arg1, out, broadcast_spec); - NGRAPH_TYPE_CASE(evaluate_logxor, f32, arg0, arg1, out, broadcast_spec); default: rc = false; break; } return rc; -} +} // namespace logxor } // namespace logxor bool op::v1::LogicalXor::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { NGRAPH_OP_SCOPE(v1_LogicalXor_evaluate); + NGRAPH_CHECK(validate_host_tensor_vector(outputs, 1) && validate_host_tensor_vector(inputs, 2)); return logxor::evaluate_logxor(inputs[0], inputs[1], outputs[0], get_autob()); } @@ -78,12 +68,6 @@ bool op::v1::LogicalXor::has_evaluate() const { NGRAPH_OP_SCOPE(v1_LogicalXor_has_evaluate); switch (get_input_element_type(0)) { case ngraph::element::boolean: - case ngraph::element::i32: - case ngraph::element::i64: - case ngraph::element::u32: - case ngraph::element::u64: - case ngraph::element::f16: - case ngraph::element::f32: return true; default: break; @@ -113,12 +97,6 @@ bool op::v0::Xor::has_evaluate() const { NGRAPH_OP_SCOPE(v0_Xor_has_evaluate); switch (get_input_element_type(0)) { case ngraph::element::boolean: - case ngraph::element::i32: - case ngraph::element::i64: - case ngraph::element::u32: - case ngraph::element::u64: - case ngraph::element::f16: - case ngraph::element::f32: return true; default: break; diff --git a/ngraph/core/src/partial_shape.cpp b/ngraph/core/src/partial_shape.cpp index 28bd44767cf..9803d84e93b 100644 --- a/ngraph/core/src/partial_shape.cpp +++ b/ngraph/core/src/partial_shape.cpp @@ -107,7 +107,7 @@ Shape ngraph::PartialShape::get_shape() const { return shape; } -PartialShape ngraph::operator+(const PartialShape& s1, const PartialShape& s2) { +PartialShape ov::operator+(const PartialShape& s1, const PartialShape& s2) { if (s1.rank().is_dynamic() || s2.rank().is_dynamic()) { return PartialShape::dynamic(); } @@ -124,7 +124,7 @@ PartialShape ngraph::operator+(const PartialShape& s1, const PartialShape& s2) { return result; } -std::ostream& ngraph::operator<<(std::ostream& str, const PartialShape& shape) { +std::ostream& ov::operator<<(std::ostream& str, const PartialShape& shape) { if (shape.m_rank_is_static) { str << "{"; bool first = true; diff --git a/ngraph/core/src/pass/graph_rewrite.cpp b/ngraph/core/src/pass/graph_rewrite.cpp index c56c8e1f937..07e8472ce47 100644 --- a/ngraph/core/src/pass/graph_rewrite.cpp +++ b/ngraph/core/src/pass/graph_rewrite.cpp @@ -89,7 +89,7 @@ bool pass::GraphRewrite::run_on_function(std::shared_ptr f) { } bool pass::GraphRewrite::apply_matcher_passes(shared_ptr f, deque> nodes_to_run) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "pass::GraphRewrite::run_on_function"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "pass::GraphRewrite::run_on_function"); bool rewritten = false; const auto& pass_config = get_pass_config(); @@ -377,7 +377,7 @@ void ngraph::pass::MatcherPass::register_matcher(const std::shared_ptr node) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, pass::internal::perf_counters_graph_rewrite()[get_type_info()]); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, pass::internal::perf_counters_graph_rewrite()[get_type_info()]); m_new_nodes.clear(); if (m_handler) return m_handler(node); diff --git a/ngraph/core/src/pass/manager.cpp b/ngraph/core/src/pass/manager.cpp index 113e162ece5..5aeb9180670 100644 --- a/ngraph/core/src/pass/manager.cpp +++ b/ngraph/core/src/pass/manager.cpp @@ -46,7 +46,7 @@ pass::Manager::~Manager() {} pass::Manager::Manager(std::shared_ptr pass_config) : m_pass_config(std::move(pass_config)) {} void pass::Manager::run_passes(shared_ptr func) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "pass::Manager::run_passes"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "pass::Manager::run_passes"); static bool profile_enabled = getenv_bool("NGRAPH_PROFILE_PASS_ENABLE"); @@ -62,7 +62,7 @@ void pass::Manager::run_passes(shared_ptr func) { } OV_ITT_SCOPE(FIRST_INFERENCE, - itt::domains::nGraphPass_LT, + ov::itt::domains::nGraphPass_LT, pass::internal::perf_counters()[pass->get_type_info()]); pass_timer.start(); diff --git a/ngraph/core/src/pass/visualize_tree.cpp b/ngraph/core/src/pass/visualize_tree.cpp index b2235654659..ae0f30ba2d1 100644 --- a/ngraph/core/src/pass/visualize_tree.cpp +++ b/ngraph/core/src/pass/visualize_tree.cpp @@ -511,6 +511,7 @@ string pass::VisualizeTree::get_node_name(shared_ptr node) { } void pass::VisualizeTree::render() const { + NGRAPH_SUPPRESS_DEPRECATED_START string ext = file_util::get_file_ext(m_name); string output_format = ext.substr(1); string dot_file = m_name; @@ -536,4 +537,5 @@ void pass::VisualizeTree::render() const { #endif } } + NGRAPH_SUPPRESS_DEPRECATED_END } diff --git a/ngraph/core/src/pattern/matcher.cpp b/ngraph/core/src/pattern/matcher.cpp index 82b358846f9..9edc0df3309 100644 --- a/ngraph/core/src/pattern/matcher.cpp +++ b/ngraph/core/src/pattern/matcher.cpp @@ -85,6 +85,7 @@ void Matcher::capture(const std::set& static_nodes) { } } bool Matcher::is_contained_match(const NodeVector& exclusions, bool ignore_unused) { + NGRAPH_SUPPRESS_DEPRECATED_START if (exclusions.empty()) { NodeVector label_exclusions; for (auto entry : m_pattern_map) { @@ -97,6 +98,7 @@ bool Matcher::is_contained_match(const NodeVector& exclusions, bool ignore_unuse } return ngraph::get_subgraph_outputs(get_matched_nodes(), exclusions).size() < 2; + NGRAPH_SUPPRESS_DEPRECATED_END } bool Matcher::match_value(const ngraph::Output& pattern_value, const ngraph::Output& graph_value) { diff --git a/ngraph/core/src/specialize_function.cpp b/ngraph/core/src/specialize_function.cpp index 232eaf6edd2..418b3434129 100644 --- a/ngraph/core/src/specialize_function.cpp +++ b/ngraph/core/src/specialize_function.cpp @@ -18,7 +18,7 @@ std::shared_ptr ngraph::specialize_function(std::shared_ptr const std::vector& parameter_values) { - OV_ITT_SCOPED_TASK(itt::domains::nGraph, "specialize_function"); + OV_ITT_SCOPED_TASK(ov::itt::domains::nGraph, "specialize_function"); NGRAPH_CHECK(f->get_parameters().size() == parameter_shapes.size()); NGRAPH_CHECK(f->get_parameters().size() == parameter_element_types.size()); diff --git a/ngraph/core/src/type/element_type.cpp b/ngraph/core/src/type/element_type.cpp index 247928dfafd..cc5042a81d6 100644 --- a/ngraph/core/src/type/element_type.cpp +++ b/ngraph/core/src/type/element_type.cpp @@ -12,9 +12,8 @@ #include "ngraph/log.hpp" #include "ngraph/type/element_type_traits.hpp" -using namespace ngraph; +constexpr ngraph::DiscreteTypeInfo ngraph::AttributeAdapter::type_info; -constexpr DiscreteTypeInfo AttributeAdapter::type_info; namespace { class TypeInfo { public: @@ -40,73 +39,77 @@ public: struct ElementTypes { struct TypeHash { - size_t operator()(element::Type_t t) const { + size_t operator()(ov::element::Type_t t) const { return static_cast(t); } }; - using ElementsMap = std::unordered_map; + using ElementsMap = std::unordered_map; static const ElementsMap elements_map; }; const ElementTypes::ElementsMap ElementTypes::elements_map{ - {element::Type_t::undefined, + {ov::element::Type_t::undefined, TypeInfo(std::numeric_limits::max(), false, false, false, "undefined", "undefined")}, - {element::Type_t::dynamic, TypeInfo(0, false, false, false, "dynamic", "dynamic")}, - {element::Type_t::boolean, TypeInfo(8, false, true, false, "char", "boolean")}, - {element::Type_t::bf16, TypeInfo(16, true, true, false, "bfloat16", "bf16")}, - {element::Type_t::f16, TypeInfo(16, true, true, false, "float16", "f16")}, - {element::Type_t::f32, TypeInfo(32, true, true, false, "float", "f32")}, - {element::Type_t::f64, TypeInfo(64, true, true, false, "double", "f64")}, - {element::Type_t::i4, TypeInfo(4, false, true, true, "int4_t", "i4")}, - {element::Type_t::i8, TypeInfo(8, false, true, true, "int8_t", "i8")}, - {element::Type_t::i16, TypeInfo(16, false, true, false, "int16_t", "i16")}, - {element::Type_t::i32, TypeInfo(32, false, true, true, "int32_t", "i32")}, - {element::Type_t::i64, TypeInfo(64, false, true, false, "int64_t", "i64")}, - {element::Type_t::u1, TypeInfo(1, false, false, false, "uint1_t", "u1")}, - {element::Type_t::u4, TypeInfo(4, false, false, false, "uint4_t", "u4")}, - {element::Type_t::u8, TypeInfo(8, false, false, true, "uint8_t", "u8")}, - {element::Type_t::u16, TypeInfo(16, false, false, false, "uint16_t", "u16")}, - {element::Type_t::u32, TypeInfo(32, false, false, false, "uint32_t", "u32")}, - {element::Type_t::u64, TypeInfo(64, false, false, false, "uint64_t", "u64")}, + {ov::element::Type_t::dynamic, TypeInfo(0, false, false, false, "dynamic", "dynamic")}, + {ov::element::Type_t::boolean, TypeInfo(8, false, true, false, "char", "boolean")}, + {ov::element::Type_t::bf16, TypeInfo(16, true, true, false, "bfloat16", "bf16")}, + {ov::element::Type_t::f16, TypeInfo(16, true, true, false, "float16", "f16")}, + {ov::element::Type_t::f32, TypeInfo(32, true, true, false, "float", "f32")}, + {ov::element::Type_t::f64, TypeInfo(64, true, true, false, "double", "f64")}, + {ov::element::Type_t::i4, TypeInfo(4, false, true, true, "int4_t", "i4")}, + {ov::element::Type_t::i8, TypeInfo(8, false, true, true, "int8_t", "i8")}, + {ov::element::Type_t::i16, TypeInfo(16, false, true, false, "int16_t", "i16")}, + {ov::element::Type_t::i32, TypeInfo(32, false, true, true, "int32_t", "i32")}, + {ov::element::Type_t::i64, TypeInfo(64, false, true, false, "int64_t", "i64")}, + {ov::element::Type_t::u1, TypeInfo(1, false, false, false, "uint1_t", "u1")}, + {ov::element::Type_t::u4, TypeInfo(4, false, false, false, "uint4_t", "u4")}, + {ov::element::Type_t::u8, TypeInfo(8, false, false, true, "uint8_t", "u8")}, + {ov::element::Type_t::u16, TypeInfo(16, false, false, false, "uint16_t", "u16")}, + {ov::element::Type_t::u32, TypeInfo(32, false, false, false, "uint32_t", "u32")}, + {ov::element::Type_t::u64, TypeInfo(64, false, false, false, "uint64_t", "u64")}, }; const ElementTypes::ElementsMap& get_type_info_map() { return ElementTypes::elements_map; }; -const TypeInfo& get_type_info(element::Type_t type) { +const TypeInfo& get_type_info(ov::element::Type_t type) { const auto& tim = get_type_info_map(); const auto& found = tim.find(type); if (found == tim.end()) { - throw std::out_of_range{"element::Type_t not supported"}; + throw std::out_of_range{"ov::element::Type_t not supported"}; } return found->second; }; } // namespace -std::vector element::Type::get_known_types() { - std::vector rc = {&element::dynamic, - &element::boolean, - &element::bf16, - &element::f16, - &element::f32, - &element::f64, - &element::i4, - &element::i8, - &element::i16, - &element::i32, - &element::i64, - &element::u1, - &element::u4, - &element::u8, - &element::u16, - &element::u32, - &element::u64}; +std::vector ov::element::Type::get_known_types() { + std::vector rc = {&ov::element::dynamic, + &ov::element::boolean, + &ov::element::bf16, + &ov::element::f16, + &ov::element::f32, + &ov::element::f64, + &ov::element::i4, + &ov::element::i8, + &ov::element::i16, + &ov::element::i32, + &ov::element::i64, + &ov::element::u1, + &ov::element::u4, + &ov::element::u8, + &ov::element::u16, + &ov::element::u32, + &ov::element::u64}; return rc; } -element::Type::Type(size_t bitwidth, bool is_real, bool is_signed, bool is_quantized, const std::string& /* cname */) { +ov::element::Type::Type(size_t bitwidth, + bool is_real, + bool is_signed, + bool is_quantized, + const std::string& /* cname */) { for (const auto& t : get_type_info_map()) { const TypeInfo& info = t.second; if (bitwidth == info.m_bitwidth && is_real == info.m_is_real && is_signed == info.m_is_signed && @@ -117,23 +120,23 @@ element::Type::Type(size_t bitwidth, bool is_real, bool is_signed, bool is_quant } } -const std::string& element::Type::c_type_string() const { +const std::string& ov::element::Type::c_type_string() const { return get_type_info(m_type).m_cname; } -size_t element::Type::size() const { +size_t ov::element::Type::size() const { return std::ceil(static_cast(bitwidth()) / 8.0f); } -size_t element::Type::hash() const { +size_t ov::element::Type::hash() const { return static_cast(m_type); } -const std::string& element::Type::get_type_name() const { +const std::string& ov::element::Type::get_type_name() const { return get_type_info(m_type).m_type_name; } -namespace ngraph { +namespace ov { namespace element { template <> Type from() { @@ -192,17 +195,17 @@ Type from() { return Type_t::bf16; } } // namespace element -} // namespace ngraph +} // namespace ov -std::ostream& element::operator<<(std::ostream& out, const element::Type& obj) { +std::ostream& ov::element::operator<<(std::ostream& out, const ov::element::Type& obj) { return out << obj.get_type_name(); } -bool element::Type::compatible(const element::Type& t) const { +bool ov::element::Type::compatible(const ov::element::Type& t) const { return (is_dynamic() || t.is_dynamic() || *this == t); } -bool element::Type::merge(element::Type& dst, const element::Type& t1, const element::Type& t2) { +bool ov::element::Type::merge(ov::element::Type& dst, const ov::element::Type& t1, const ov::element::Type& t2) { if (t1.is_dynamic()) { dst = t2; return true; @@ -217,35 +220,35 @@ bool element::Type::merge(element::Type& dst, const element::Type& t1, const ele } } -bool element::Type::is_static() const { +bool ov::element::Type::is_static() const { return get_type_info(m_type).m_bitwidth != 0; } -bool element::Type::is_real() const { +bool ov::element::Type::is_real() const { return get_type_info(m_type).m_is_real; } -bool element::Type::is_integral_number() const { - return is_integral() && (m_type != element::boolean); +bool ov::element::Type::is_integral_number() const { + return is_integral() && (m_type != ov::element::boolean); } -bool element::Type::is_signed() const { +bool ov::element::Type::is_signed() const { return get_type_info(m_type).m_is_signed; } -bool element::Type::is_quantized() const { +bool ov::element::Type::is_quantized() const { return get_type_info(m_type).m_is_quantized; } -size_t element::Type::bitwidth() const { +size_t ov::element::Type::bitwidth() const { return get_type_info(m_type).m_bitwidth; } -size_t ngraph::compiler_byte_size(element::Type_t et) { +size_t compiler_byte_size(ov::element::Type_t et) { switch (et) { -#define ET_CASE(et) \ - case element::Type_t::et: \ - return sizeof(element_type_traits::value_type); +#define ET_CASE(et) \ + case ov::element::Type_t::et: \ + return sizeof(ov::element_type_traits::value_type); ET_CASE(boolean); ET_CASE(bf16); ET_CASE(f16); @@ -263,48 +266,48 @@ size_t ngraph::compiler_byte_size(element::Type_t et) { ET_CASE(u32); ET_CASE(u64); #undef ET_CASE - case element::Type_t::undefined: + case ov::element::Type_t::undefined: return 0; - case element::Type_t::dynamic: + case ov::element::Type_t::dynamic: return 0; } - throw ngraph_error("compiler_byte_size: Unsupported value of element::Type_t: " + - std::to_string(static_cast(et))); + throw ngraph::ngraph_error("compiler_byte_size: Unsupported value of ov::element::Type_t: " + + std::to_string(static_cast(et))); } namespace ngraph { template <> -NGRAPH_API EnumNames& EnumNames::get() { - static auto enum_names = EnumNames("element::Type_t", - {{"undefined", element::Type_t::undefined}, - {"dynamic", element::Type_t::dynamic}, - {"boolean", element::Type_t::boolean}, - {"bf16", element::Type_t::bf16}, - {"f16", element::Type_t::f16}, - {"f32", element::Type_t::f32}, - {"f64", element::Type_t::f64}, - {"i4", element::Type_t::i4}, - {"i8", element::Type_t::i8}, - {"i16", element::Type_t::i16}, - {"i32", element::Type_t::i32}, - {"i64", element::Type_t::i64}, - {"u1", element::Type_t::u1}, - {"u4", element::Type_t::u4}, - {"u8", element::Type_t::u8}, - {"u16", element::Type_t::u16}, - {"u32", element::Type_t::u32}, - {"u64", element::Type_t::u64}}); +NGRAPH_API EnumNames& EnumNames::get() { + static auto enum_names = EnumNames("ov::element::Type_t", + {{"undefined", ov::element::Type_t::undefined}, + {"dynamic", ov::element::Type_t::dynamic}, + {"boolean", ov::element::Type_t::boolean}, + {"bf16", ov::element::Type_t::bf16}, + {"f16", ov::element::Type_t::f16}, + {"f32", ov::element::Type_t::f32}, + {"f64", ov::element::Type_t::f64}, + {"i4", ov::element::Type_t::i4}, + {"i8", ov::element::Type_t::i8}, + {"i16", ov::element::Type_t::i16}, + {"i32", ov::element::Type_t::i32}, + {"i64", ov::element::Type_t::i64}, + {"u1", ov::element::Type_t::u1}, + {"u4", ov::element::Type_t::u4}, + {"u8", ov::element::Type_t::u8}, + {"u16", ov::element::Type_t::u16}, + {"u32", ov::element::Type_t::u32}, + {"u64", ov::element::Type_t::u64}}); return enum_names; } } // namespace ngraph -constexpr DiscreteTypeInfo AttributeAdapter::type_info; +constexpr ngraph::DiscreteTypeInfo ngraph::AttributeAdapter::type_info; -const std::string& AttributeAdapter::get() { - return as_string(static_cast(m_ref)); +const std::string& ngraph::AttributeAdapter::get() { + return as_string(static_cast(m_ref)); } -void AttributeAdapter::set(const std::string& value) { - m_ref = as_enum(value); +void ngraph::AttributeAdapter::set(const std::string& value) { + m_ref = as_enum(value); } diff --git a/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_manager.hpp b/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_manager.hpp index 3d406b6e3ec..5cc181935ef 100644 --- a/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_manager.hpp +++ b/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_manager.hpp @@ -93,6 +93,9 @@ struct FrontEndPluginInfo { }; } // namespace frontend +} // namespace ngraph + +namespace ov { template <> class FRONTEND_API VariantWrapper : public VariantImpl { @@ -116,4 +119,4 @@ public: }; #endif -} // namespace ngraph +} // namespace ov diff --git a/ngraph/frontend/frontend_manager/src/plugin_loader.cpp b/ngraph/frontend/frontend_manager/src/plugin_loader.cpp index f910b31610f..36100e89882 100644 --- a/ngraph/frontend/frontend_manager/src/plugin_loader.cpp +++ b/ngraph/frontend/frontend_manager/src/plugin_loader.cpp @@ -37,6 +37,7 @@ using namespace ngraph::frontend; // TODO: change to std::filesystem for C++17 static std::vector list_files(const std::string& path) { + NGRAPH_SUPPRESS_DEPRECATED_START std::vector res; try { ngraph::file_util::iterate_files( @@ -61,6 +62,7 @@ static std::vector list_files(const std::string& path) { // Ignore exceptions } return res; + NGRAPH_SUPPRESS_DEPRECATED_END } std::vector ngraph::frontend::load_plugins(const std::string& dir_name) { diff --git a/ngraph/frontend/onnx/frontend/src/core/graph.hpp b/ngraph/frontend/onnx/frontend/src/core/graph.hpp index 3db17899a72..ada3d2feca5 100644 --- a/ngraph/frontend/onnx/frontend/src/core/graph.hpp +++ b/ngraph/frontend/onnx/frontend/src/core/graph.hpp @@ -12,6 +12,7 @@ #include "core/graph_cache.hpp" #include "core/model.hpp" +#include "ngraph/function.hpp" #include "ngraph/op/parameter.hpp" #include "onnx_import/core/operator_set.hpp" diff --git a/ngraph/frontend/onnx/frontend/src/core/transform.cpp b/ngraph/frontend/onnx/frontend/src/core/transform.cpp index 141e7d3d6c0..758216fed4a 100644 --- a/ngraph/frontend/onnx/frontend/src/core/transform.cpp +++ b/ngraph/frontend/onnx/frontend/src/core/transform.cpp @@ -56,6 +56,7 @@ void ngraph::onnx_import::transform::expand_onnx_functions(ONNX_NAMESPACE::Model void ngraph::onnx_import::transform::update_external_data_paths(ONNX_NAMESPACE::ModelProto& model_proto, const std::string& model_path) { + NGRAPH_SUPPRESS_DEPRECATED_START if (model_path.empty()) { return; } @@ -78,6 +79,7 @@ void ngraph::onnx_import::transform::update_external_data_paths(ONNX_NAMESPACE:: initializer_tensor.mutable_external_data(location_key_value_index)->set_value(external_data_full_path); } } + NGRAPH_SUPPRESS_DEPRECATED_END } void ngraph::onnx_import::transform::fixup_legacy_operators(ONNX_NAMESPACE::ModelProto& model_proto) { diff --git a/ngraph/frontend/onnx/frontend/src/edge_mapper.cpp b/ngraph/frontend/onnx/frontend/src/edge_mapper.cpp index 8615469f10d..ee2bb58d5b6 100644 --- a/ngraph/frontend/onnx/frontend/src/edge_mapper.cpp +++ b/ngraph/frontend/onnx/frontend/src/edge_mapper.cpp @@ -72,25 +72,26 @@ int onnx_editor::EdgeMapper::get_node_output_idx(int node_index, const std::stri return (out_port_idx - std::begin(node_outputs)); } -int onnx_editor::EdgeMapper::get_node_input_idx(int node_index, const std::string& input_name) const { +std::vector onnx_editor::EdgeMapper::get_node_input_indexes(int node_index, const std::string& input_name) const { NGRAPH_CHECK(node_index >= 0 && node_index < static_cast(m_node_inputs.size()), "Node with index: ", std::to_string(node_index), "is out of scope outputs list"); const auto& node_inputs = m_node_inputs[node_index]; - const auto matched_inputs = std::count(std::begin(node_inputs), std::end(node_inputs), input_name); - if (matched_inputs == 0) { + std::vector node_inputs_indexes; + int index = 0; + for (const auto& in : node_inputs) { + if (in == input_name) { + node_inputs_indexes.push_back(index); + } + ++index; + } + if (node_inputs_indexes.size() == 0) { throw ngraph_error("Node with index: " + std::to_string(node_index) + " has not input with name: " + input_name); } - if (matched_inputs > 1) // more indexes with the same name - { - throw ngraph_error("Node with index: " + std::to_string(node_index) + " has more than one inputs with name: " + - input_name + ". You should use port indexes to distinguish them."); - } - const auto in_port_idx = std::find(std::begin(node_inputs), std::end(node_inputs), input_name); - return (in_port_idx - std::begin(node_inputs)); + return node_inputs_indexes; } InputEdge onnx_editor::EdgeMapper::find_input_edge(const EditorNode& node, const EditorInput& in) const { @@ -131,8 +132,14 @@ InputEdge onnx_editor::EdgeMapper::find_input_edge(const EditorNode& node, const return InputEdge{node_index, in.m_input_index, in.m_new_input_name}; } if (!in.m_input_name.empty()) { - const auto input_idx = get_node_input_idx(node_index, in.m_input_name); - return InputEdge{node_index, input_idx, in.m_new_input_name}; + const auto input_indexes = get_node_input_indexes(node_index, in.m_input_name); + if (input_indexes.size() > 1) // more indexes with the same name + { + throw ngraph_error("Node with index: " + std::to_string(node_index) + + " has more than one inputs with name: " + in.m_input_name + + ". You should use port indexes to distinguish them."); + } + return InputEdge{node_index, input_indexes[0], in.m_new_input_name}; } else { throw ngraph_error("Not enough information to determine input edge"); } @@ -186,14 +193,13 @@ OutputEdge onnx_editor::EdgeMapper::find_output_edge(const std::string& output_n std::vector onnx_editor::EdgeMapper::find_output_consumers(const std::string& output_name) const { const auto matched_nodes_range = m_output_consumers_index.equal_range(output_name); std::vector input_edges; - std::transform(matched_nodes_range.first, - matched_nodes_range.second, - std::back_inserter(input_edges), - [&output_name, this](const std::pair& iter) { - const auto node_idx = iter.second; - const auto port_idx = this->get_node_input_idx(node_idx, output_name); - return InputEdge{node_idx, port_idx}; - }); + for (auto it = matched_nodes_range.first; it != matched_nodes_range.second; ++it) { + const auto node_idx = it->second; + const auto port_indexes = get_node_input_indexes(node_idx, output_name); + for (const auto& idx : port_indexes) { + input_edges.push_back(InputEdge{node_idx, idx}); + } + } return input_edges; } @@ -211,7 +217,7 @@ bool onnx_editor::EdgeMapper::is_correct_tensor_name(const std::string& name) co return false; } -std::string onnx_editor::EdgeMapper::get_input_port_name(const InputEdge& edge) const { +std::string onnx_editor::EdgeMapper::get_source_tensor_name(const InputEdge& edge) const { if (edge.m_node_idx >= 0 && edge.m_node_idx < static_cast(m_node_inputs.size()) && edge.m_port_idx >= 0 && edge.m_port_idx < static_cast(m_node_inputs[edge.m_node_idx].size())) { return m_node_inputs[edge.m_node_idx][edge.m_port_idx]; @@ -219,7 +225,7 @@ std::string onnx_editor::EdgeMapper::get_input_port_name(const InputEdge& edge) return ""; } -std::string onnx_editor::EdgeMapper::get_output_port_name(const OutputEdge& edge) const { +std::string onnx_editor::EdgeMapper::get_target_tensor_name(const OutputEdge& edge) const { if (edge.m_node_idx >= 0 && edge.m_node_idx < static_cast(m_node_outputs.size()) && edge.m_port_idx >= 0 && edge.m_port_idx < static_cast(m_node_outputs[edge.m_node_idx].size())) { return m_node_outputs[edge.m_node_idx][edge.m_port_idx]; diff --git a/ngraph/frontend/onnx/frontend/src/edge_mapper.hpp b/ngraph/frontend/onnx/frontend/src/edge_mapper.hpp index 43911d6c2a6..df57fbe87b4 100644 --- a/ngraph/frontend/onnx/frontend/src/edge_mapper.hpp +++ b/ngraph/frontend/onnx/frontend/src/edge_mapper.hpp @@ -98,22 +98,23 @@ public: /// bool is_correct_tensor_name(const std::string& name) const; - /// \brief Get name of input port indicated by the input edge. + /// \brief Get name of the tensor which is the source of the input edge. /// - /// \note Empty string is returned if the port name is not found. + /// \note Empty string is returned if the tensor name is not found. /// - std::string get_input_port_name(const InputEdge& edge) const; + std::string get_source_tensor_name(const InputEdge& edge) const; - /// \brief Get name of output port indicated by the input edge. + /// \brief Get name of the tensor which is the target of the output edge. /// - /// \note Empty string is returned if the port name is not found. + /// \note Empty string is returned if the tensor name is not found. /// - std::string get_output_port_name(const OutputEdge& edge) const; + std::string get_target_tensor_name(const OutputEdge& edge) const; private: std::vector find_node_indexes(const std::string& node_name, const std::string& output_name) const; - int get_node_input_idx(int node_index, const std::string& input_name) const; + // note: a single node can have more than one inputs with the same name + std::vector get_node_input_indexes(int node_index, const std::string& input_name) const; int get_node_output_idx(int node_index, const std::string& output_name) const; std::vector> m_node_inputs; diff --git a/ngraph/frontend/onnx/frontend/src/editor.cpp b/ngraph/frontend/onnx/frontend/src/editor.cpp index 45efa1b87c5..ccbd18b0e1d 100644 --- a/ngraph/frontend/onnx/frontend/src/editor.cpp +++ b/ngraph/frontend/onnx/frontend/src/editor.cpp @@ -325,25 +325,33 @@ std::vector onnx_editor::ONNXModelEditor::model_outputs() const { return outputs; } -bool onnx_editor::ONNXModelEditor::is_input(const InputEdge& edge) const { +std::string onnx_editor::ONNXModelEditor::get_source_tensor_name(const InputEdge& edge) const { update_mapper_if_needed(); - const auto& port_name = m_pimpl->m_edge_mapper.get_input_port_name(edge); - if (port_name.empty()) { + return m_pimpl->m_edge_mapper.get_source_tensor_name(edge); +} + +bool onnx_editor::ONNXModelEditor::is_input(const InputEdge& edge) const { + const auto& tensor_name = get_source_tensor_name(edge); + if (tensor_name.empty()) { return false; } else { const auto& inputs = model_inputs(); - return std::count(std::begin(inputs), std::end(inputs), port_name) > 0; + return std::count(std::begin(inputs), std::end(inputs), tensor_name) > 0; } } -bool onnx_editor::ONNXModelEditor::is_output(const OutputEdge& edge) const { +std::string onnx_editor::ONNXModelEditor::get_target_tensor_name(const OutputEdge& edge) const { update_mapper_if_needed(); - const auto& port_name = m_pimpl->m_edge_mapper.get_output_port_name(edge); - if (port_name.empty()) { + return m_pimpl->m_edge_mapper.get_target_tensor_name(edge); +} + +bool onnx_editor::ONNXModelEditor::is_output(const OutputEdge& edge) const { + const auto& tensor_name = get_target_tensor_name(edge); + if (tensor_name.empty()) { return false; } else { const auto& outputs = model_outputs(); - return std::count(std::begin(outputs), std::end(outputs), port_name) > 0; + return std::count(std::begin(outputs), std::end(outputs), tensor_name) > 0; } } diff --git a/ngraph/frontend/onnx/frontend/src/editor.hpp b/ngraph/frontend/onnx/frontend/src/editor.hpp index b714c4174b2..bec2f1b47e1 100644 --- a/ngraph/frontend/onnx/frontend/src/editor.hpp +++ b/ngraph/frontend/onnx/frontend/src/editor.hpp @@ -100,9 +100,21 @@ public: /// instance of the model editor. std::vector model_outputs() const; + /// \brief Get name of the tensor which is the source of the input edge. + /// + /// \note Empty string is returned if the tensor name is not found. + /// + std::string get_source_tensor_name(const InputEdge& edge) const; + /// \brief Returns true if input edge is input of the model. Otherwise false. bool is_input(const InputEdge& edge) const; + /// \brief Get name of the tensor which is the target of the output edge. + /// + /// \note Empty string is returned if the tensor name is not found. + /// + std::string get_target_tensor_name(const OutputEdge& edge) const; + /// \brief Returns true if output edge is input of the model. Otherwise false. bool is_output(const OutputEdge& edge) const; diff --git a/ngraph/frontend/onnx/frontend/src/op/crop.cpp b/ngraph/frontend/onnx/frontend/src/op/crop.cpp new file mode 100644 index 00000000000..1acfecbdcc0 --- /dev/null +++ b/ngraph/frontend/onnx/frontend/src/op/crop.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "default_opset.hpp" +#include "exceptions.hpp" +#include "ngraph/builder/autobroadcast.hpp" +#include "ngraph/shape.hpp" + +namespace ngraph { +namespace onnx_import { +namespace op { +namespace set_1 { +OutputVector crop(const Node& node) { + // Crop is an obsolete experimental ONNX operation. + // Crops an image's spatial dimensions. + + const auto inputs = node.get_ng_inputs(); + const auto& input_data = inputs.at(0); + + // Border values: leftBorder, topBorder, rightBorder, bottomBorder. + const auto border = node.get_attribute_value>("border"); + + std::shared_ptr end; + + // Set slice begin values to border values (note order of indexes) + const auto begin = default_opset::Constant::create(ngraph::element::i64, + Shape{4}, + std::vector{0, 0, border[1], border[0]}); + + // If scale is given, then start crop at left/top `border` + // and end on left/top `border` + `scale`. + if (node.has_attribute("scale")) { + // List of ints height, width + const auto scale = node.get_attribute_value>("scale"); + + CHECK_VALID_NODE(node, + scale.size() == 2, + "ONNX Crop expects 2 values in 'scale' attribute, found: ", + scale.size()); + + // Set slice end values to topBorder+heightScale and leftBorder+widthScale + // Note that indexes don't match, e.g. border[0] + scale[1] + end = default_opset::Constant::create( + ngraph::element::i64, + Shape{4}, + std::vector{0, 0, border[1] + scale[0], border[0] + scale[1]}); + } + // If scale is not provided, crop the image by values provided in `border`. + else { + CHECK_VALID_NODE(node, + border.size() == 4, + "ONNX Crop expects 4 values in 'border' attribute, found: ", + border.size()); + + // Calculate ends as shape(input) - border[2:3] + const auto input_shape = std::make_shared(input_data); + const auto end_offset = + default_opset::Constant::create(ngraph::element::i64, + Shape{4}, + std::vector{0, 0, -border[3], -border[2]}); + end = std::make_shared(input_shape, end_offset); + } + + // Input data shape [N,C,H,W], slicing only along spatial dimensions + std::vector begin_mask{1, 1, 0, 0}; + std::vector end_mask{1, 1, 0, 0}; + + return {std::make_shared(input_data, begin, end, begin_mask, end_mask)}; +} + +} // namespace set_1 + +} // namespace op + +} // namespace onnx_import + +} // namespace ngraph diff --git a/ngraph/frontend/onnx/frontend/src/op/crop.hpp b/ngraph/frontend/onnx/frontend/src/op/crop.hpp new file mode 100644 index 00000000000..200bb08a93d --- /dev/null +++ b/ngraph/frontend/onnx/frontend/src/op/crop.hpp @@ -0,0 +1,22 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "ngraph/node.hpp" +#include "onnx_import/core/node.hpp" + +namespace ngraph { +namespace onnx_import { +namespace op { +namespace set_1 { +OutputVector crop(const Node& node); + +} // namespace set_1 + +} // namespace op + +} // namespace onnx_import + +} // namespace ngraph diff --git a/ngraph/frontend/onnx/frontend/src/op/resize.cpp b/ngraph/frontend/onnx/frontend/src/op/resize.cpp index 30bce624523..4f60a6f4eb5 100644 --- a/ngraph/frontend/onnx/frontend/src/op/resize.cpp +++ b/ngraph/frontend/onnx/frontend/src/op/resize.cpp @@ -24,24 +24,24 @@ static const std::unordered_set supported_transforms = {"half_pixel "tf_half_pixel_for_nn"}; using InterpolateMode = ngraph::op::v4::Interpolate::InterpolateMode; -static const std::map interp_mode_map = {{"nearest", static_cast(InterpolateMode::nearest)}, - {"linear", static_cast(InterpolateMode::linear_onnx)}, - {"cubic", static_cast(InterpolateMode::cubic)}}; +static const std::map interp_mode_map = {{"nearest", static_cast(InterpolateMode::NEAREST)}, + {"linear", static_cast(InterpolateMode::LINEAR_ONNX)}, + {"cubic", static_cast(InterpolateMode::CUBIC)}}; using Transform_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode; static const std::map transform_mode_map = { - {"half_pixel", static_cast(Transform_mode::half_pixel)}, - {"pytorch_half_pixel", static_cast(Transform_mode::pytorch_half_pixel)}, - {"align_corners", static_cast(Transform_mode::align_corners)}, - {"asymmetric", static_cast(Transform_mode::asymmetric)}, - {"tf_half_pixel_for_nn", static_cast(Transform_mode::tf_half_pixel_for_nn)}}; + {"half_pixel", static_cast(Transform_mode::HALF_PIXEL)}, + {"pytorch_half_pixel", static_cast(Transform_mode::PYTORCH_HALF_PIXEL)}, + {"align_corners", static_cast(Transform_mode::ALIGN_CORNERS)}, + {"asymmetric", static_cast(Transform_mode::ASYMMETRIC)}, + {"tf_half_pixel_for_nn", static_cast(Transform_mode::TF_HALF_PIXEL_FOR_NN)}}; using Nearest_mode = ngraph::op::v4::Interpolate::NearestMode; static const std::map nearest_mode_map = { - {"round_prefer_floor", static_cast(Nearest_mode::round_prefer_floor)}, - {"round_prefer_ceil", static_cast(Nearest_mode::round_prefer_ceil)}, - {"floor", static_cast(Nearest_mode::floor)}, - {"ceil", static_cast(Nearest_mode::ceil)}}; + {"round_prefer_floor", static_cast(Nearest_mode::ROUND_PREFER_FLOOR)}, + {"round_prefer_ceil", static_cast(Nearest_mode::ROUND_PREFER_CEIL)}, + {"floor", static_cast(Nearest_mode::FLOOR)}, + {"ceil", static_cast(Nearest_mode::CEIL)}}; static bool is_supported_str_value(const std::unordered_set& modes, const std::string& checked_mode) { return std::find(modes.begin(), modes.end(), checked_mode) != modes.end(); @@ -148,7 +148,7 @@ OutputVector resize(const onnx_import::Node& node) { if (inputs.size() == 4) // sizes input is provided { - attrs.shape_calculation_mode = default_opset::Interpolate::ShapeCalcMode::sizes; + attrs.shape_calculation_mode = default_opset::Interpolate::ShapeCalcMode::SIZES; const auto& sizes = inputs.at(3); const auto& sizes_shape = sizes.get_partial_shape(); @@ -161,7 +161,7 @@ OutputVector resize(const onnx_import::Node& node) { return {std::make_shared(data, sizes, scales, attrs)}; } - attrs.shape_calculation_mode = default_opset::Interpolate::ShapeCalcMode::scales; + attrs.shape_calculation_mode = default_opset::Interpolate::ShapeCalcMode::SCALES; const auto& scales = inputs.at(2); const auto& scales_shape = scales.get_partial_shape(); @@ -186,11 +186,11 @@ OutputVector resize(const onnx_import::Node& node) { auto attrs = get_resize_attrs(node); - if (attrs.mode == InterpolateMode::nearest) { - attrs.nearest_mode = Nearest_mode::floor; - attrs.coordinate_transformation_mode = Transform_mode::asymmetric; - } else if (attrs.mode == InterpolateMode::linear_onnx) { - attrs.coordinate_transformation_mode = Transform_mode::asymmetric; + if (attrs.mode == InterpolateMode::NEAREST) { + attrs.nearest_mode = Nearest_mode::FLOOR; + attrs.coordinate_transformation_mode = Transform_mode::ASYMMETRIC; + } else if (attrs.mode == InterpolateMode::LINEAR_ONNX) { + attrs.coordinate_transformation_mode = Transform_mode::ASYMMETRIC; } CHECK_VALID_NODE(node, @@ -202,9 +202,6 @@ OutputVector resize(const onnx_import::Node& node) { } } // namespace set_1 - } // namespace op - } // namespace onnx_import - } // namespace ngraph diff --git a/ngraph/frontend/onnx/frontend/src/op/upsample.cpp b/ngraph/frontend/onnx/frontend/src/op/upsample.cpp index aeb1ddd06c5..6dc776b2222 100644 --- a/ngraph/frontend/onnx/frontend/src/op/upsample.cpp +++ b/ngraph/frontend/onnx/frontend/src/op/upsample.cpp @@ -37,19 +37,19 @@ void check_mode_support(const onnx_import::Node& node, const std::string& mode, } } -default_opset::Interpolate::InterpolateAttrs get_attributes(std::string mode) { +default_opset::Interpolate::InterpolateAttrs get_attributes(const std::string& mode) { using InterpolateMode = default_opset::Interpolate::InterpolateMode; using Transform_mode = default_opset::Interpolate::CoordinateTransformMode; using ShapeCalcMode = default_opset::Interpolate::ShapeCalcMode; const auto interpolate_mode = - (mode == "linear" || mode == "bilinear" ? InterpolateMode::linear_onnx : InterpolateMode::nearest); + (mode == "linear" || mode == "bilinear" ? InterpolateMode::LINEAR_ONNX : InterpolateMode::NEAREST); std::vector pad{0}; - auto attrs = default_opset::Interpolate::InterpolateAttrs(interpolate_mode, ShapeCalcMode::scales, pad, pad); + auto attrs = default_opset::Interpolate::InterpolateAttrs(interpolate_mode, ShapeCalcMode::SCALES, pad, pad); - if (attrs.mode == InterpolateMode::linear_onnx) - attrs.coordinate_transformation_mode = Transform_mode::asymmetric; + if (attrs.mode == InterpolateMode::LINEAR_ONNX) + attrs.coordinate_transformation_mode = Transform_mode::ASYMMETRIC; return attrs; } @@ -134,9 +134,6 @@ OutputVector upsample(const onnx_import::Node& node) { } } // namespace set_9 - } // namespace op - } // namespace onnx_import - } // namespace ngraph diff --git a/ngraph/frontend/onnx/frontend/src/ops_bridge.cpp b/ngraph/frontend/onnx/frontend/src/ops_bridge.cpp index a3d29b595c2..bab0825909c 100644 --- a/ngraph/frontend/onnx/frontend/src/ops_bridge.cpp +++ b/ngraph/frontend/onnx/frontend/src/ops_bridge.cpp @@ -38,6 +38,7 @@ #include "op/conv_transpose.hpp" #include "op/cos.hpp" #include "op/cosh.hpp" +#include "op/crop.hpp" #include "op/cum_sum.hpp" #include "op/depth_to_space.hpp" #include "op/dequantize_linear.hpp" @@ -427,6 +428,7 @@ OperatorsBridge::OperatorsBridge() { // deprecated ops REGISTER_OPERATOR("Affine", 1, affine); + REGISTER_OPERATOR("Crop", 1, crop); REGISTER_OPERATOR("Scatter", 1, scatter_elements); REGISTER_OPERATOR("Upsample", 1, upsample); REGISTER_OPERATOR("Upsample", 7, upsample); diff --git a/ngraph/frontend/onnx/frontend/src/place.cpp b/ngraph/frontend/onnx/frontend/src/place.cpp index 8c18f644663..64c623c2957 100644 --- a/ngraph/frontend/onnx/frontend/src/place.cpp +++ b/ngraph/frontend/onnx/frontend/src/place.cpp @@ -34,6 +34,15 @@ bool PlaceInputEdgeONNX::is_equal(Place::Ptr another) const { return false; } +bool PlaceInputEdgeONNX::is_equal_data(Place::Ptr another) const { + return get_source_tensor()->is_equal_data(another); +} + +Place::Ptr PlaceInputEdgeONNX::get_source_tensor() const { + const auto tensor_name = m_editor->get_source_tensor_name(m_edge); + return std::make_shared(tensor_name, m_editor); +} + PlaceOutputEdgeONNX::PlaceOutputEdgeONNX(const onnx_editor::OutputEdge& edge, std::shared_ptr editor) : m_edge{edge}, @@ -59,6 +68,15 @@ bool PlaceOutputEdgeONNX::is_equal(Place::Ptr another) const { return false; } +bool PlaceOutputEdgeONNX::is_equal_data(Place::Ptr another) const { + return get_target_tensor()->is_equal_data(another); +} + +Place::Ptr PlaceOutputEdgeONNX::get_target_tensor() const { + const auto tensor_name = m_editor->get_target_tensor_name(m_edge); + return std::make_shared(tensor_name, m_editor); +} + PlaceTensorONNX::PlaceTensorONNX(const std::string& name, std::shared_ptr editor) : m_name(name), m_editor(editor) {} @@ -68,6 +86,8 @@ std::vector PlaceTensorONNX::get_names() const { } Place::Ptr PlaceTensorONNX::get_producing_port() const { + FRONT_END_GENERAL_CHECK(!is_input(), + "Tensor: " + m_name + " is an input of the model and doesn't have producing port."); return std::make_shared(m_editor->find_output_edge(m_name), m_editor); } @@ -102,3 +122,14 @@ bool PlaceTensorONNX::is_equal(Place::Ptr another) const { } return false; } + +bool PlaceTensorONNX::is_equal_data(Place::Ptr another) const { + const auto consuming_ports = get_consuming_ports(); + const auto eq_to_consuming_port = [&consuming_ports](const Ptr& another) { + return std::any_of(consuming_ports.begin(), consuming_ports.end(), [&another](const Ptr& place) { + return place->is_equal(another); + }); + }; + return is_equal(another) || (is_input() ? false : get_producing_port()->is_equal(another)) || + eq_to_consuming_port(another); +} diff --git a/ngraph/frontend/onnx/frontend/src/place.hpp b/ngraph/frontend/onnx/frontend/src/place.hpp index 20501f32f45..a236d8506e9 100644 --- a/ngraph/frontend/onnx/frontend/src/place.hpp +++ b/ngraph/frontend/onnx/frontend/src/place.hpp @@ -22,6 +22,10 @@ public: bool is_equal(Place::Ptr another) const override; + bool is_equal_data(Place::Ptr another) const override; + + Place::Ptr get_source_tensor() const override; + private: onnx_editor::InputEdge m_edge; const std::shared_ptr m_editor; @@ -39,6 +43,10 @@ public: bool is_equal(Place::Ptr another) const override; + bool is_equal_data(Place::Ptr another) const override; + + Place::Ptr get_target_tensor() const override; + private: onnx_editor::OutputEdge m_edge; std::shared_ptr m_editor; @@ -62,6 +70,8 @@ public: bool is_equal(Place::Ptr another) const override; + bool is_equal_data(Place::Ptr another) const override; + private: std::string m_name; std::shared_ptr m_editor; diff --git a/ngraph/frontend/onnx/frontend/src/utils/tensor_external_data.cpp b/ngraph/frontend/onnx/frontend/src/utils/tensor_external_data.cpp index 15e9b7ab4a4..e0bc8fd33fd 100644 --- a/ngraph/frontend/onnx/frontend/src/utils/tensor_external_data.cpp +++ b/ngraph/frontend/onnx/frontend/src/utils/tensor_external_data.cpp @@ -28,11 +28,13 @@ TensorExternalData::TensorExternalData(const ONNX_NAMESPACE::TensorProto& tensor } std::string TensorExternalData::load_external_data() const { + NGRAPH_SUPPRESS_DEPRECATED_START #if defined(ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32) std::wstring path = file_util::multi_byte_char_to_wstring(m_data_location.c_str()); #else std::string path = m_data_location; #endif + NGRAPH_SUPPRESS_DEPRECATED_END std::ifstream external_data_stream(path, std::ios::binary | std::ios::in | std::ios::ate); if (external_data_stream.fail()) throw error::invalid_external_data{*this}; diff --git a/ngraph/frontend/paddlepaddle/src/node_context.cpp b/ngraph/frontend/paddlepaddle/src/node_context.cpp index a941a688856..c702c52ce08 100644 --- a/ngraph/frontend/paddlepaddle/src/node_context.cpp +++ b/ngraph/frontend/paddlepaddle/src/node_context.cpp @@ -8,7 +8,7 @@ constexpr VariantTypeInfo VariantWrapper::type_info; \ template class ngraph::VariantImpl; -namespace ngraph { +namespace ov { NGRAPH_VARIANT_DEFINITION(int32_t) NGRAPH_VARIANT_DEFINITION(std::vector) NGRAPH_VARIANT_DEFINITION(float) @@ -16,5 +16,4 @@ NGRAPH_VARIANT_DEFINITION(std::vector) NGRAPH_VARIANT_DEFINITION(bool) NGRAPH_VARIANT_DEFINITION(ngraph::element::Type) NGRAPH_VARIANT_DEFINITION(std::vector) - -} // namespace ngraph \ No newline at end of file +} // namespace ov diff --git a/ngraph/frontend/paddlepaddle/src/node_context.hpp b/ngraph/frontend/paddlepaddle/src/node_context.hpp index ef079ea4f1e..cc1adc8cc67 100644 --- a/ngraph/frontend/paddlepaddle/src/node_context.hpp +++ b/ngraph/frontend/paddlepaddle/src/node_context.hpp @@ -18,7 +18,7 @@ VariantWrapper(const value_type& value) : VariantImpl(value) {} \ } -namespace ngraph { +namespace ov { NGRAPH_VARIANT_DECLARATION(int32_t, "Variant::int32"); NGRAPH_VARIANT_DECLARATION(std::vector, "Variant::int32_vector"); NGRAPH_VARIANT_DECLARATION(float, "Variant::float"); @@ -26,7 +26,9 @@ NGRAPH_VARIANT_DECLARATION(std::vector, "Variant::float_vector"); NGRAPH_VARIANT_DECLARATION(bool, "Variant::bool"); NGRAPH_VARIANT_DECLARATION(ngraph::element::Type, "Variant::element_type"); NGRAPH_VARIANT_DECLARATION(std::vector, "Variant::int64_vector"); +} // namespace ov +namespace ngraph { namespace frontend { namespace pdpd { using InPortName = std::string; diff --git a/ngraph/frontend/paddlepaddle/src/op/interp.cpp b/ngraph/frontend/paddlepaddle/src/op/interp.cpp index 46d9f18f742..94e586ef093 100644 --- a/ngraph/frontend/paddlepaddle/src/op/interp.cpp +++ b/ngraph/frontend/paddlepaddle/src/op/interp.cpp @@ -79,7 +79,7 @@ NamedOutputs interpolate(const NodeContext& node, const ngraph::opset6::Interpol Output target_spatial_shape; if (node.has_ng_input("OutSize")) { - attrs.shape_calculation_mode = ShapeCalcMode::sizes; + attrs.shape_calculation_mode = ShapeCalcMode::SIZES; auto hw_shape = node.get_ng_input("OutSize"); const auto shape_of_x = std::make_shared(x); auto shape_begin = opset6::Constant::create(element::i64, {1}, {0}); @@ -94,10 +94,10 @@ NamedOutputs interpolate(const NodeContext& node, const ngraph::opset6::Interpol 0); scales = calculate_scales_based_on_sizes(x, target_spatial_shape); } else if (out_w <= 0 || out_h <= 0) { - attrs.shape_calculation_mode = ShapeCalcMode::scales; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; target_spatial_shape = calculate_output_shape_based_on_scales(x, scale, scales); } else { - attrs.shape_calculation_mode = ShapeCalcMode::sizes; + attrs.shape_calculation_mode = ShapeCalcMode::SIZES; target_spatial_shape = extract_out_sizes(x, {out_h, out_w}); scales = calculate_scales_based_on_sizes(x, target_spatial_shape); } @@ -105,17 +105,17 @@ NamedOutputs interpolate(const NodeContext& node, const ngraph::opset6::Interpol bool align_corners = node.get_attribute("align_corners"); int32_t align_mode = node.get_attribute("align_mode"); - if (mode == InterpolateMode::nearest) { - attrs.coordinate_transformation_mode = CoordinateTransformMode::asymmetric; + if (mode == InterpolateMode::NEAREST) { + attrs.coordinate_transformation_mode = CoordinateTransformMode::ASYMMETRIC; } else if (!align_corners && align_mode == 1) { - attrs.coordinate_transformation_mode = CoordinateTransformMode::asymmetric; + attrs.coordinate_transformation_mode = CoordinateTransformMode::ASYMMETRIC; } else if (!align_corners && align_mode == 0) { - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; } else if (align_corners) { - attrs.coordinate_transformation_mode = CoordinateTransformMode::align_corners; + attrs.coordinate_transformation_mode = CoordinateTransformMode::ALIGN_CORNERS; } - attrs.nearest_mode = Nearest_mode::simple; + attrs.nearest_mode = Nearest_mode::SIMPLE; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -126,16 +126,16 @@ NamedOutputs interpolate(const NodeContext& node, const ngraph::opset6::Interpol } NamedOutputs bilinear_interp_v2(const NodeContext& node) { - auto mode = ngraph::opset6::Interpolate::InterpolateMode::linear_onnx; + auto mode = ngraph::opset6::Interpolate::InterpolateMode::LINEAR_ONNX; return interpolate(node, mode); } NamedOutputs nearest_interp_v2(const NodeContext& node) { - auto mode = ngraph::opset6::Interpolate::InterpolateMode::nearest; + auto mode = ngraph::opset6::Interpolate::InterpolateMode::NEAREST; return interpolate(node, mode); } } // namespace op } // namespace pdpd } // namespace frontend -} // namespace ngraph \ No newline at end of file +} // namespace ngraph diff --git a/ngraph/python/src/ngraph/opset8/__init__.py b/ngraph/python/src/ngraph/opset8/__init__.py index 0b089c345f3..d294788c282 100644 --- a/ngraph/python/src/ngraph/opset8/__init__.py +++ b/ngraph/python/src/ngraph/opset8/__init__.py @@ -53,7 +53,7 @@ from ngraph.opset1.ops import exp from ngraph.opset1.ops import fake_quantize from ngraph.opset1.ops import floor from ngraph.opset1.ops import floor_mod -from ngraph.opset7.ops import gather +from ngraph.opset8.ops import gather from ngraph.opset6.ops import gather_elements from ngraph.opset5.ops import gather_nd from ngraph.opset1.ops import gather_tree diff --git a/ngraph/python/src/ngraph/opset8/ops.py b/ngraph/python/src/ngraph/opset8/ops.py index a5496ab1e49..82e2a24446b 100644 --- a/ngraph/python/src/ngraph/opset8/ops.py +++ b/ngraph/python/src/ngraph/opset8/ops.py @@ -253,3 +253,26 @@ def matrix_nms( } return _get_node_factory_opset8().create("MatrixNms", inputs, attributes) + + +@nameable_op +def gather( + data: NodeInput, + indices: NodeInput, + axis: NodeInput, + batch_dims: Optional[int] = 0, +) -> Node: + """Return a node which performs Gather with support of negative indices. + + @param data: N-D tensor with data for gathering + @param indices: N-D tensor with indices by which data is gathered. Negative indices + indicate reverse indexing from the end + @param axis: axis along which elements are gathered + @param batch_dims: number of batch dimensions + @return: The new node which performs Gather + """ + inputs = as_nodes(data, indices, axis) + attributes = { + "batch_dims": batch_dims + } + return _get_node_factory_opset8().create("Gather", inputs, attributes) diff --git a/ngraph/python/src/pyngraph/dict_attribute_visitor.hpp b/ngraph/python/src/pyngraph/dict_attribute_visitor.hpp index 7905ff2eeb0..aa94e692a7f 100644 --- a/ngraph/python/src/pyngraph/dict_attribute_visitor.hpp +++ b/ngraph/python/src/pyngraph/dict_attribute_visitor.hpp @@ -9,6 +9,7 @@ #include #include "ngraph/attribute_visitor.hpp" +#include "ngraph/function.hpp" #include "ngraph/node.hpp" #include "ngraph/op/util/variable.hpp" @@ -127,4 +128,4 @@ namespace util protected: py::dict m_attributes; }; -} +} // namespace util diff --git a/ngraph/python/tests/__init__.py b/ngraph/python/tests/__init__.py index edcdb43a750..a132f6fad53 100644 --- a/ngraph/python/tests/__init__.py +++ b/ngraph/python/tests/__init__.py @@ -145,3 +145,5 @@ xfail_issue_52463 = xfail_test(reason="test_operator_add_size1_singleton_broadca xfail_issue_58033 = xfail_test(reason="Einsum operation misses support for complex ellipsis equations") xfail_issue_58676 = xfail_test(reason="AssertionError: Not equal to tolerance rtol=0.001, atol=1e-07") xfail_issue_onnx_models_140 = xfail_test(reason="https://github.com/onnx/models/issues/140") + +xfail_issue_54630 = xfail_test(reason="Gather with negative indices is not yet implemented on CPU") diff --git a/ngraph/python/tests/test_frontend/test_frontend_onnx_editor.py b/ngraph/python/tests/test_frontend/test_frontend_onnx_editor.py index ad5acbeb686..3542a20ef19 100644 --- a/ngraph/python/tests/test_frontend/test_frontend_onnx_editor.py +++ b/ngraph/python/tests/test_frontend/test_frontend_onnx_editor.py @@ -45,7 +45,8 @@ def create_test_onnx_models(): make_tensor_value_info("out4", onnx.TensorProto.FLOAT, (2, 2)), ] graph = make_graph([add, split, relu, mul], "test_graph", input_tensors, output_tensors) - models["input_model.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["input_model.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for extract_subgraph input_tensors = [ @@ -56,7 +57,8 @@ def create_test_onnx_models(): make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (2, 2)), ] graph = make_graph([add], "test_graph", input_tensors, output_tensors) - models["extract_subgraph.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["extract_subgraph.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for extract_subgraph 2 input_tensors = [ @@ -69,7 +71,8 @@ def create_test_onnx_models(): make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (2, 2)), ] graph = make_graph([add, relu], "test_graph", input_tensors, output_tensors) - models["extract_subgraph_2.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["extract_subgraph_2.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for extract_subgraph 3 input_tensors = [ @@ -82,7 +85,8 @@ def create_test_onnx_models(): expected_split = onnx.helper.make_node("Split", inputs=["out1/placeholder_port_0"], outputs=["out1", "out2"], name="split1", axis=0) graph = make_graph([expected_split], "test_graph", input_tensors, output_tensors) - models["extract_subgraph_3.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["extract_subgraph_3.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for extract_subgraph 4 input_tensors = [ @@ -100,7 +104,8 @@ def create_test_onnx_models(): expected_mul = onnx.helper.make_node("Mul", inputs=["out4/placeholder_port_0", "out4/placeholder_port_1"], outputs=["out4"]) graph = make_graph([expected_split, expected_mul], "test_graph", input_tensors, output_tensors) - models["extract_subgraph_4.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["extract_subgraph_4.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for test_override_all_outputs input_tensors = [ @@ -113,7 +118,8 @@ def create_test_onnx_models(): make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (2, 2)), ] graph = make_graph([add, relu], "test_graph", input_tensors, output_tensors) - models["test_override_all_outputs.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["test_override_all_outputs.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for test_override_all_outputs 2 input_tensors = [ @@ -124,7 +130,8 @@ def create_test_onnx_models(): make_tensor_value_info("out4", onnx.TensorProto.FLOAT, (2, 2)), ] graph = make_graph([add, mul], "test_graph", input_tensors, output_tensors) - models["test_override_all_outputs_2.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["test_override_all_outputs_2.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # Expected for test_override_all_inputs input_tensors = [ @@ -144,7 +151,8 @@ def create_test_onnx_models(): expected_mul = onnx.helper.make_node("Mul", inputs=["out4/placeholder_port_0", "out4/placeholder_port_1"], outputs=["out4"]) graph = make_graph([expected_split, relu, expected_mul], "test_graph", input_tensors, output_tensors) - models["test_override_all_inputs.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["test_override_all_inputs.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) # test partial shape input_tensors = [ @@ -159,7 +167,8 @@ def create_test_onnx_models(): make_tensor_value_info("out4", onnx.TensorProto.FLOAT, (8, 16)), ] graph = make_graph([add, split, relu, mul], "test_graph", input_tensors, output_tensors) - models["test_partial_shape.onnx"] = make_model(graph, producer_name="ONNX Importer") + models["test_partial_shape.onnx"] = make_model(graph, producer_name="ONNX Importer", + opset_imports=[onnx.helper.make_opsetid("", 13)]) return models @@ -530,6 +539,45 @@ def test_is_equal(): assert not place8.is_equal(place2) +def test_is_equal_data(): + skip_if_onnx_frontend_is_disabled() + fe = fem.load_by_framework(framework=ONNX_FRONTEND_NAME) + assert fe + + model = fe.load("input_model.onnx") + assert model + + place1 = model.get_place_by_tensor_name(tensorName="in1") + assert place1.is_equal_data(place1) + + place2 = model.get_place_by_tensor_name(tensorName="add_out") + assert place2.is_equal_data(place2) + + place3 = model.get_place_by_tensor_name(tensorName="in2") + assert not place1.is_equal_data(place3) + assert not place2.is_equal_data(place1) + + place4 = place2.get_producing_port() + assert place2.is_equal_data(place4) + + place5 = model.get_place_by_tensor_name(tensorName="out4").get_input_port(inputPortIndex=0) + assert place2.is_equal_data(place5) + assert place4.is_equal_data(place5) + + place6 = model.get_place_by_tensor_name(tensorName="out4").get_input_port(inputPortIndex=1) + assert place6.is_equal_data(place5) + + place7 = model.get_place_by_operation_name_and_input_port(operationName="split1", inputPortIndex=0) + assert place7.is_equal_data(place7) + + place8 = model.get_place_by_tensor_name(tensorName="out1") + place9 = model.get_place_by_tensor_name(tensorName="out2") + place10 = place8.get_producing_port() + assert not place8.is_equal_data(place9) + assert not place9.is_equal_data(place10) + assert place8.is_equal_data(place10) + + def test_get_place_by_tensor_name(): skip_if_onnx_frontend_is_disabled() fe = fem.load_by_framework(framework=ONNX_FRONTEND_NAME) diff --git a/ngraph/python/tests/test_ngraph/test_gather.py b/ngraph/python/tests/test_ngraph/test_gather.py index 08ff0893a8f..93714d6dcb4 100644 --- a/ngraph/python/tests/test_ngraph/test_gather.py +++ b/ngraph/python/tests/test_ngraph/test_gather.py @@ -4,6 +4,7 @@ import ngraph as ng import numpy as np +from tests import xfail_issue_54630 from tests.test_ngraph.util import run_op_node @@ -52,3 +53,37 @@ def test_gather_batch_dims_1(): result = run_op_node([input_data], ng.gather, input_indices, input_axis, batch_dims) assert np.allclose(result, expected) + + +@xfail_issue_54630 +def test_gather_negative_indices(): + input_data = np.array( + [1.0, 1.1, 1.2, 2.0, 2.1, 2.2, 3.0, 3.1, 3.2], np.float32 + ).reshape((3, 3)) + input_indices = np.array([0, -1], np.int32).reshape(1, 2) + input_axis = np.array([1], np.int32) + + expected = np.array([1.0, 1.2, 2.0, 2.2, 3.0, 3.2], dtype=np.float32).reshape( + (3, 1, 2) + ) + + result = run_op_node([input_data], ng.gather, input_indices, input_axis) + assert np.allclose(result, expected) + + +@xfail_issue_54630 +def test_gather_batch_dims_1_negative_indices(): + + input_data = np.array([[1, 2, 3, 4, 5], + [6, 7, 8, 9, 10]], np.float32) + + input_indices = np.array([[0, 1, -2], + [-2, 0, 0]], np.int32) + input_axis = np.array([1], np.int32) + batch_dims = 1 + + expected = np.array([[1, 2, 4], + [9, 6, 6]], np.float32) + + result = run_op_node([input_data], ng.gather, input_indices, input_axis, batch_dims) + assert np.allclose(result, expected) diff --git a/ngraph/python/tests/test_ngraph/util.py b/ngraph/python/tests/test_ngraph/util.py index da8e6dac6ec..18fe01fc18e 100644 --- a/ngraph/python/tests/test_ngraph/util.py +++ b/ngraph/python/tests/test_ngraph/util.py @@ -1,7 +1,7 @@ # Copyright (C) 2018-2021 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -from typing import Any, Callable, List +from typing import Any, Callable, List, Union import numpy as np @@ -16,7 +16,7 @@ def _get_numpy_dtype(scalar): def run_op_node(input_data, op_fun, *args): - # type: (NumericData, Callable, *Any) -> List[NumericData] + # type: (Union[NumericData, List[NumericData]], Callable, *Any) -> List[NumericData] """Run computation on node performing `op_fun`. `op_fun` has to accept a node as an argument. diff --git a/ngraph/python/tests/test_onnx/model_zoo_preprocess.sh b/ngraph/python/tests/test_onnx/model_zoo_preprocess.sh index 367b7eb70f0..dd35ed340eb 100755 --- a/ngraph/python/tests/test_onnx/model_zoo_preprocess.sh +++ b/ngraph/python/tests/test_onnx/model_zoo_preprocess.sh @@ -96,6 +96,7 @@ function update_onnx_models() { if [[ ! -d $ONNX_MODELS_DIR ]] ; then touch $MODEL_ZOO_DIR/executing_$ONNX_SHA + trap "rm -f $MODEL_ZOO_DIR/executing_$ONNX_SHA" EXIT INT TERM echo "The ONNX Model Zoo repository doesn't exist on your filesystem then will be cloned" git clone https://github.com/onnx/models.git "$ONNX_MODELS_DIR" cd "$ONNX_MODELS_DIR" diff --git a/ngraph/python/tox.ini b/ngraph/python/tox.ini index 62feca372fa..d19da1a3005 100644 --- a/ngraph/python/tox.ini +++ b/ngraph/python/tox.ini @@ -26,7 +26,7 @@ commands= commands= {envbindir}/python setup.py bdist_wheel {envbindir}/pip install --no-index --pre --find-links=dist/ ngraph-core - pytest --backend={env:NGRAPH_BACKEND} tests/test_onnx/test_zoo_models.py -v -n 4 -k 'not _cuda' --model_zoo_xfail + pytest --backend={env:NGRAPH_BACKEND} tests/test_onnx/test_zoo_models.py -v -n 4 --forked -k 'not _cuda' --model_zoo_xfail [testenv:devenv] envdir = devenv diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index d7957f89855..89197aee7ae 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -115,6 +115,7 @@ set(SRC type_prop/ctc_greedy_decoder.cpp type_prop/ctc_greedy_decoder_seq_len.cpp type_prop/ctc_loss.cpp + type_prop/cum_sum.cpp type_prop/deformable_convolution.cpp type_prop/deformable_convolution_opset8.cpp type_prop/deformable_psroi_pooling.cpp @@ -143,6 +144,7 @@ set(SRC type_prop/gather_elements.cpp type_prop/gather_nd.cpp type_prop/gather_tree.cpp + type_prop/gelu.cpp type_prop/grn.cpp type_prop/group_convolution.cpp type_prop/group_convolution_backprop_data.cpp @@ -155,6 +157,7 @@ set(SRC type_prop/interpolate.cpp type_prop/logical_and.cpp type_prop/logical_or.cpp + type_prop/logical_xor.cpp type_prop/lrn.cpp type_prop/lstm_cell.cpp type_prop/lstm_sequence.cpp @@ -458,7 +461,6 @@ set(MULTI_TEST_SRC backend/log.in.cpp backend/log_softmax.in.cpp backend/logical_not.in.cpp - backend/logical_xor.in.cpp backend/lrn.in.cpp backend/matmul.in.cpp backend/matrix_nms.in.cpp diff --git a/ngraph/test/backend/comparison.in.cpp b/ngraph/test/backend/comparison.in.cpp index f15890d9e67..dbe1247b896 100644 --- a/ngraph/test/backend/comparison.in.cpp +++ b/ngraph/test/backend/comparison.in.cpp @@ -45,63 +45,3 @@ NGRAPH_TEST(${BACKEND_NAME}, notequal) { handle->call_with_validate({result}, {a, b}); EXPECT_EQ((vector{0, 0, 1, 1, 1, 0, 0, 1}), read_vector(result)); } - -NGRAPH_TEST(${BACKEND_NAME}, greater) { - Shape shape{2, 2, 2}; - auto A = make_shared(element::f32, shape); - auto B = make_shared(element::f32, shape); - auto f = make_shared(make_shared(A, B), ParameterVector{A, B}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape); - copy_data(a, vector{1, 8, -8, 17, -0.5, 0.5, 2, 1}); - auto b = backend->create_tensor(element::f32, shape); - copy_data(b, vector{1, 2, 4, 8, 0, 0, 1, 1.5}); - auto result = backend->create_tensor(element::boolean, shape); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a, b}); - EXPECT_EQ((vector{0, 1, 0, 1, 0, 1, 1, 0}), read_vector(result)); -} - -NGRAPH_TEST(${BACKEND_NAME}, greater_int64) { - Shape shape{2, 2, 2}; - auto A = make_shared(element::i64, shape); - auto B = make_shared(element::i64, shape); - auto f = make_shared(make_shared(A, B), ParameterVector{A, B}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i64, shape); - copy_data(a, vector{0x4000000000000002, 0x4000000000000006, -8, 17, -5, 5, 2, 1}); - auto b = backend->create_tensor(element::i64, shape); - copy_data(b, vector{0x4000000000000001, 0x4000000000000002, 4, 8, 0, 0, 1, 2}); - auto result = backend->create_tensor(element::boolean, shape); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a, b}); - EXPECT_EQ((vector{1, 1, 0, 1, 0, 1, 1, 0}), read_vector(result)); -} - -NGRAPH_TEST(${BACKEND_NAME}, greatereq) { - Shape shape{2, 2, 2}; - auto A = make_shared(element::f32, shape); - auto B = make_shared(element::f32, shape); - auto f = make_shared(make_shared(A, B), ParameterVector{A, B}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape); - copy_data(a, vector{1, 8, -8, 17, -0.5, 0, 2, 1}); - auto b = backend->create_tensor(element::f32, shape); - copy_data(b, vector{1, 2, -8, 8, 0, 0, 0.5, 1.5}); - auto result = backend->create_tensor(element::boolean, shape); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a, b}); - EXPECT_EQ((vector{1, 1, 1, 1, 0, 1, 1, 0}), read_vector(result)); -} diff --git a/ngraph/test/backend/logical_xor.in.cpp b/ngraph/test/backend/logical_xor.in.cpp deleted file mode 100644 index 153b0e5cac8..00000000000 --- a/ngraph/test/backend/logical_xor.in.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "gtest/gtest.h" -#include "ngraph/ngraph.hpp" -#include "util/engine/test_engines.hpp" -#include "util/test_case.hpp" -#include "util/test_control.hpp" - -using namespace std; -using namespace ngraph; - -static string s_manifest = "${MANIFEST}"; -using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); - -NGRAPH_TEST(${BACKEND_NAME}, logical_xor) { - Shape shape{2, 2, 2}; - auto A = make_shared(element::boolean, shape); - auto B = make_shared(element::boolean, shape); - auto f = make_shared(make_shared(A, B), ParameterVector{A, B}); - - std::vector a{1, 0, 1, 1, 1, 0, 1, 0}; - std::vector b{0, 0, 1, 0, 0, 1, 1, 0}; - - auto test_case = test::TestCase(f); - test_case.add_multiple_inputs({a, b}); - test_case.add_expected_output(shape, {1, 0, 0, 1, 1, 1, 0, 0}); - test_case.run(); -} diff --git a/ngraph/test/file_util.cpp b/ngraph/test/file_util.cpp index 4b47aae404e..99296ea8a9e 100644 --- a/ngraph/test/file_util.cpp +++ b/ngraph/test/file_util.cpp @@ -11,6 +11,8 @@ #include "gtest/gtest.h" +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace std; using namespace ngraph; diff --git a/ngraph/test/frontend/frontend_manager.cpp b/ngraph/test/frontend/frontend_manager.cpp index ce8d8d67ed3..5be485bd0c6 100644 --- a/ngraph/test/frontend/frontend_manager.cpp +++ b/ngraph/test/frontend/frontend_manager.cpp @@ -49,6 +49,7 @@ TEST(FrontEndManagerTest, testAvailableFrontEnds) { } TEST(FrontEndManagerTest, testMockPluginFrontEnd) { + NGRAPH_SUPPRESS_DEPRECATED_START std::string fePath = ngraph::file_util::get_directory(ngraph::runtime::Backend::get_backend_shared_library_search_directory()); fePath = fePath + FrontEndPathSeparator + "someInvalidPath"; @@ -61,6 +62,7 @@ TEST(FrontEndManagerTest, testMockPluginFrontEnd) { ASSERT_NO_THROW(fe = fem.load_by_framework("mock1")); ASSERT_EQ(fe->get_name(), "mock1"); set_test_env("OV_FRONTEND_PATH", ""); + NGRAPH_SUPPRESS_DEPRECATED_END } TEST(FrontEndManagerTest, testDefaultFrontEnd) { diff --git a/ngraph/test/frontend/shared/include/utils.hpp b/ngraph/test/frontend/shared/include/utils.hpp index dc8db530f45..a335b0a0d97 100644 --- a/ngraph/test/frontend/shared/include/utils.hpp +++ b/ngraph/test/frontend/shared/include/utils.hpp @@ -52,9 +52,11 @@ inline int set_test_env(const char* name, const char* value) { } inline void setupTestEnv() { + NGRAPH_SUPPRESS_DEPRECATED_START std::string fePath = ngraph::file_util::get_directory(ngraph::runtime::Backend::get_backend_shared_library_search_directory()); set_test_env("OV_FRONTEND_PATH", fePath.c_str()); + NGRAPH_SUPPRESS_DEPRECATED_END } inline bool exists(const std::string& file) { @@ -65,4 +67,4 @@ inline bool exists(const std::string& file) { inline std::string make_model_path(const std::string& modelsRelativePath) { return CommonTestUtils::getModelFromTestModelZoo(modelsRelativePath); } -} // namespace FrontEndTestUtils \ No newline at end of file +} // namespace FrontEndTestUtils diff --git a/ngraph/test/models/onnx/crop.prototxt b/ngraph/test/models/onnx/crop.prototxt new file mode 100644 index 00000000000..c3ec30d4677 --- /dev/null +++ b/ngraph/test/models/onnx/crop.prototxt @@ -0,0 +1,65 @@ +ir_version: 3 +producer_name: "nGraph ONNX Importer" +graph { + node { + input: "x" + output: "y" + op_type: "Crop" + attribute { + name: "border" + ints: 1 + ints: 1 + ints: 1 + ints: 1 + type: INTS + } + } + name: "test_model" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 1 + } + dim { + dim_value: 4 + } + dim { + dim_value: 4 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 2 + } + } + } + } + } +} +opset_import { + version: 1 +} diff --git a/ngraph/test/models/onnx/crop_with_scale.prototxt b/ngraph/test/models/onnx/crop_with_scale.prototxt new file mode 100644 index 00000000000..a039c9e2a52 --- /dev/null +++ b/ngraph/test/models/onnx/crop_with_scale.prototxt @@ -0,0 +1,71 @@ +ir_version: 3 +producer_name: "nGraph ONNX Importer" +graph { + node { + input: "x" + output: "y" + op_type: "Crop" + attribute { + name: "border" + ints: 1 + ints: 1 + ints: 0 + ints: 0 + type: INTS + } + attribute { + name: "scale" + ints: 2 + ints: 3 + type: INTS + } + } + name: "test_model" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 1 + } + dim { + dim_value: 4 + } + dim { + dim_value: 4 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 1 +} diff --git a/ngraph/test/onnx/onnx_editor.cpp b/ngraph/test/onnx/onnx_editor.cpp index 3123ab21e34..1e7e36f5dc5 100644 --- a/ngraph/test/onnx/onnx_editor.cpp +++ b/ngraph/test/onnx/onnx_editor.cpp @@ -1019,6 +1019,16 @@ NGRAPH_TEST(onnx_editor, editor_api_find_output_consumers_empty_result) { EXPECT_EQ(output_consumers.size(), 0); } +NGRAPH_TEST(onnx_editor, editor_api_inputs_with_the_same_name) { + ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/add_ab.onnx")}; + + std::vector output_consumers = editor.find_output_consumers("X"); + EXPECT_EQ(output_consumers[0].m_node_idx, 1); + EXPECT_EQ(output_consumers[0].m_port_idx, 0); + EXPECT_EQ(output_consumers[1].m_node_idx, 1); + EXPECT_EQ(output_consumers[1].m_port_idx, 1); +} + NGRAPH_TEST(onnx_editor, editor_api_is_correct_and_unambiguous_node) { ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/subgraph_extraction_tests.onnx")}; @@ -1204,6 +1214,19 @@ NGRAPH_TEST(onnx_editor, cut_operator_with_no_schema) { EXPECT_TRUE(result.is_ok) << result.error_message; } +NGRAPH_TEST(onnx_editor, get_source_tensor_name) { + ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/subgraph_extraction_tests.onnx")}; + + EXPECT_EQ(editor.get_source_tensor_name(InputEdge{0, 0}), "in1"); + EXPECT_EQ(editor.get_source_tensor_name(InputEdge{1, 0}), "relu1"); + EXPECT_EQ(editor.get_source_tensor_name(InputEdge{1, 1}), "in2"); + const auto edge1 = editor.find_input_edge(EditorOutput{"conv1"}, 1); + EXPECT_EQ(editor.get_source_tensor_name(edge1), "in4"); + const auto edge2 = editor.find_input_edge(EditorOutput{"split2"}, 0); + EXPECT_EQ(editor.get_source_tensor_name(edge2), "add2"); + EXPECT_EQ(editor.get_source_tensor_name(InputEdge{999, 999}), ""); +} + NGRAPH_TEST(onnx_editor, is_model_input) { ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/subgraph_extraction_tests.onnx")}; @@ -1221,6 +1244,17 @@ NGRAPH_TEST(onnx_editor, is_model_input) { EXPECT_FALSE(editor.is_input(edge3)); } +NGRAPH_TEST(onnx_editor, get_target_tensor_name) { + ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/subgraph_extraction_tests.onnx")}; + + EXPECT_EQ(editor.get_target_tensor_name(OutputEdge{0, 0}), "relu1"); + EXPECT_EQ(editor.get_target_tensor_name(OutputEdge{1, 0}), "add1"); + EXPECT_EQ(editor.get_target_tensor_name(OutputEdge{4, 0}), "mul2"); + const auto edge1 = editor.find_output_edge("split1"); + EXPECT_EQ(editor.get_target_tensor_name(edge1), "split1"); + EXPECT_EQ(editor.get_target_tensor_name(OutputEdge{999, 999}), ""); +} + NGRAPH_TEST(onnx_editor, is_model_output) { ONNXModelEditor editor{file_util::path_join(SERIALIZED_ZOO, "onnx/model_editor/subgraph_extraction_tests.onnx")}; diff --git a/ngraph/test/onnx/onnx_import_const_folding.in.cpp b/ngraph/test/onnx/onnx_import_const_folding.in.cpp index 3151101a046..c6b9554af3f 100644 --- a/ngraph/test/onnx/onnx_import_const_folding.in.cpp +++ b/ngraph/test/onnx/onnx_import_const_folding.in.cpp @@ -15,6 +15,8 @@ #include "util/test_control.hpp" #include "util/type_prop.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace ngraph; using namespace ngraph::onnx_import; diff --git a/ngraph/test/onnx/onnx_import_deprecated.in.cpp b/ngraph/test/onnx/onnx_import_deprecated.in.cpp index 7247cb3a83d..cff0441e095 100644 --- a/ngraph/test/onnx/onnx_import_deprecated.in.cpp +++ b/ngraph/test/onnx/onnx_import_deprecated.in.cpp @@ -30,9 +30,6 @@ static std::string s_manifest = "${MANIFEST}"; using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); -using Inputs = std::vector>; -using Outputs = std::vector>; - NGRAPH_TEST(${BACKEND_NAME}, onnx_model_affine) { auto function = onnx_import::import_onnx_model(file_util::path_join(SERIALIZED_ZOO, "onnx/affine.onnx")); @@ -45,3 +42,41 @@ NGRAPH_TEST(${BACKEND_NAME}, onnx_model_affine) { test_case.add_expected_output(Shape{1, 3}, expected_output); test_case.run(); } + +NGRAPH_TEST(${BACKEND_NAME}, onnx_model_crop) { + auto function = onnx_import::import_onnx_model(file_util::path_join(SERIALIZED_ZOO, "onnx/crop.onnx")); + + // input shape (1, 1, 4, 4) + auto input = test::NDArray({{{{19.f, 20.f, 21.f, 22.f}, + {23.f, 24.f, 25.f, 26.f}, + {27.f, 28.f, 29.f, 30.f}, + {31.f, 32.f, 33.f, 34.f}}}}) + .get_vector(); + + // output shape (1, 1, 2, 2) + auto expected_output = test::NDArray{{{{24.f, 25.f}, {28.f, 29.f}}}}.get_vector(); + + auto test_case = test::TestCase(function); + test_case.add_input(Shape{1, 1, 4, 4}, input); + test_case.add_expected_output(Shape{1, 1, 2, 2}, expected_output); + test_case.run(); +} + +NGRAPH_TEST(${BACKEND_NAME}, onnx_model_crop_with_scale) { + auto function = onnx_import::import_onnx_model(file_util::path_join(SERIALIZED_ZOO, "onnx/crop_with_scale.onnx")); + + // input shape (1, 1, 4, 4) + auto input = test::NDArray({{{{19.f, 20.f, 21.f, 22.f}, + {23.f, 24.f, 25.f, 26.f}, + {27.f, 28.f, 29.f, 30.f}, + {31.f, 32.f, 33.f, 34.f}}}}) + .get_vector(); + + // output shape (1, 1, 2, 3) + auto expected_output = test::NDArray{{{{24.f, 25.f, 26.f}, {28.f, 29.f, 30.f}}}}.get_vector(); + + auto test_case = test::TestCase(function); + test_case.add_input(Shape{1, 1, 4, 4}, input); + test_case.add_expected_output(Shape{1, 1, 2, 3}, expected_output); + test_case.run(); +} diff --git a/ngraph/test/onnx/onnx_import_exceptions.cpp b/ngraph/test/onnx/onnx_import_exceptions.cpp index ee1e807eb06..89b821ec931 100644 --- a/ngraph/test/onnx/onnx_import_exceptions.cpp +++ b/ngraph/test/onnx/onnx_import_exceptions.cpp @@ -11,6 +11,8 @@ #include "onnx_import/onnx.hpp" #include "util/type_prop.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace ngraph; TEST(onnx_importer, exception_throws_ngraph_error) { diff --git a/ngraph/test/onnx/onnx_import_provenance.in.cpp b/ngraph/test/onnx/onnx_import_provenance.in.cpp index 5f05b7f04a4..10bb4f8eadc 100644 --- a/ngraph/test/onnx/onnx_import_provenance.in.cpp +++ b/ngraph/test/onnx/onnx_import_provenance.in.cpp @@ -12,6 +12,8 @@ #include "util/test_control.hpp" #include "util/type_prop.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace ngraph; using namespace ngraph::onnx_import; diff --git a/ngraph/test/op.cpp b/ngraph/test/op.cpp index 91b89a4192b..7529b586b32 100644 --- a/ngraph/test/op.cpp +++ b/ngraph/test/op.cpp @@ -83,7 +83,7 @@ struct Ship { int16_t y; }; -namespace ngraph { +namespace ov { template <> class VariantWrapper : public VariantImpl { public: @@ -95,7 +95,7 @@ public: }; constexpr VariantTypeInfo VariantWrapper::type_info; -} // namespace ngraph +} // namespace ov TEST(op, variant) { shared_ptr var_std_string = make_variant("My string"); diff --git a/ngraph/test/op_eval/if_eval.cpp b/ngraph/test/op_eval/if_eval.cpp new file mode 100644 index 00000000000..41a1cb9424f --- /dev/null +++ b/ngraph/test/op_eval/if_eval.cpp @@ -0,0 +1,368 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +#include "gtest/gtest.h" +#include "ngraph/opsets/opset1.hpp" +#include "ngraph/opsets/opset5.hpp" +#include "ngraph/opsets/opset8.hpp" +#include "ngraph/runtime/host_tensor.hpp" +#include "ngraph/validation_util.hpp" +#include "runtime/backend.hpp" +#include "util/test_tools.hpp" + +using namespace std; +using namespace ngraph; + +TEST(op_eval, if_condition_const) { + auto X = make_shared(element::f32, Shape{1, 2, 2}); + auto Y = make_shared(element::f32, Shape{1, 2, 2}); + auto cond = std::make_shared(element::boolean, Shape{1}, true); + auto cond2 = std::make_shared(element::boolean, Shape{1}, false); + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + auto then_op = std::make_shared(Xt, Yt); + auto res0 = make_shared(then_op); + auto res1 = make_shared(Xe); + auto then_body = make_shared(OutputVector{res0}, ParameterVector{Xt, Yt}); + auto else_body = make_shared(OutputVector{res1}, ParameterVector{Xe}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, nullptr); + if_op->set_output(res0, res1); + if_op->validate_and_infer_types(); + auto if_op2 = if_op->clone_with_new_inputs(OutputVector{cond2, X, Y}); + std::vector X_v{1.0, 1.0, 1.0, 1.0}; + std::vector Y_v{2.0, 2.0, 2.0, 2.0}; + auto fun = make_shared(OutputVector{if_op}, ParameterVector{X, Y}); + auto fun2 = make_shared(OutputVector{if_op2}, ParameterVector{X, Y}); + auto result = make_shared(); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result_data = read_vector(result); + std::vector expected_results{2.0, 2.0, 2.0, 2.0}; + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); + + auto result1 = make_shared(); + ASSERT_TRUE(fun2->evaluate({result1}, + {make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result1->get_element_type(), element::f32); + EXPECT_EQ(result1->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result_data1 = read_vector(result1); + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data1[i], X_v[i], 0.000001); +} + +TEST(op_eval, if_condition_non_const) { + auto X = make_shared(element::f32, Shape{1, 2, 2}); + auto Y = make_shared(element::f32, Shape{1, 2, 2}); + auto cond = make_shared(element::boolean, Shape{1}); + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto else_op = std::make_shared(Xe, Ye); + auto then_op_result = make_shared(then_op); + auto else_op_result = make_shared(else_op); + auto then_body = make_shared(OutputVector{then_op_result}, ParameterVector{Xt, Yt}); + auto else_body = make_shared(OutputVector{else_op_result}, ParameterVector{Xe, Ye}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + if_op->set_output(then_op_result, else_op_result); + if_op->validate_and_infer_types(); + std::vector X_v{1.0, 2.0, 3.0, 4.0}; + std::vector Y_v{2.0, 1.0, 2.0, 3.0}; + auto fun = make_shared(OutputVector{if_op}, ParameterVector{cond, X, Y}); + auto result = make_shared(); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {true}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result_data = read_vector(result); + std::vector expected_results{2.0, 2.0, 6.0, 12.0}; + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {false}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + result_data = read_vector(result); + expected_results = {3.0, 3.0, 5.0, 7.0}; + + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); +} + +TEST(op_eval, if_free_sample) { + auto cond = make_shared(element::boolean, Shape{1}); + auto A = std::make_shared(element::f32, Shape{1}, 8.0); + auto B = std::make_shared(element::f32, Shape{1}, 2.0); + auto A_res = std::make_shared(A); + auto B_res = std::make_shared(B); + auto then_body = make_shared(OutputVector{A_res}, ParameterVector{}); + auto else_body = make_shared(OutputVector{B_res}, ParameterVector{}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + auto res = if_op->set_output(A_res, B_res); + auto fun = make_shared(OutputVector{res}, ParameterVector{cond}); + fun->validate_nodes_and_infer_types(); + auto result1 = make_shared(), result2 = make_shared(); + ASSERT_TRUE(fun->evaluate({result1}, {make_host_tensor(Shape{1}, {true})})); + ASSERT_TRUE(fun->evaluate({result2}, {make_host_tensor(Shape{1}, {false})})); + auto result_data1 = read_vector(result1); + auto result_data2 = read_vector(result2); + EXPECT_EQ(result1->get_element_type(), element::f32); + EXPECT_EQ(result1->get_shape(), Shape{std::vector({1})}); + EXPECT_EQ(result2->get_element_type(), element::f32); + EXPECT_EQ(result2->get_shape(), Shape{std::vector({1})}); + EXPECT_NEAR(result_data1[0], 8.0, 0.000001); + EXPECT_NEAR(result_data2[0], 2.0, 0.000001); +} + +TEST(op_eval, if_constant_folding) { + auto cond = std::make_shared(element::boolean, Shape{1}, false); + auto A1 = std::make_shared(element::f32, Shape{1}, 37.0); + auto A2 = std::make_shared(element::f32, Shape{1}, 45.0); + auto B1 = std::make_shared(element::f32, Shape{1}, 10.0); + auto B2 = std::make_shared(element::f32, Shape{1}, 3.0); + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + auto a_add = std::make_shared(Xt, Yt); + auto b_pow = std::make_shared(Xe, Ye); + auto then_res = std::make_shared(a_add); + auto then_body = make_shared(OutputVector{then_res}, ParameterVector{Xt, Yt}); + auto else_res = std::make_shared(b_pow); + auto else_body = make_shared(OutputVector{else_res}, ParameterVector{Xe, Ye}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(A1, Xt, nullptr); + if_op->set_input(A2, Yt, nullptr); + if_op->set_input(B1, nullptr, Xe); + if_op->set_input(B2, nullptr, Ye); + if_op->set_output(then_res, else_res); + + auto fun = make_shared(OutputVector{if_op}, ParameterVector{}); + fun->validate_nodes_and_infer_types(); + ngraph::pass::ConstantFolding().run_on_function(fun); + auto results = fun->get_results(); + EXPECT_EQ(results.size(), 1); + auto result = results[0]; + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{1}); + const auto& cond_value = get_constant_from_source(result); + auto val = cond_value->cast_vector(); + EXPECT_NEAR(val[0], 1000.0, 0.000001); +} + +TEST(op_eval, if_dynamism) { + auto X = make_shared(element::f32, Shape{1, 2, 2}); + auto Y = make_shared(element::f32, Shape{4, 2, 2}); + auto Z = make_shared(element::f32, Shape{8, 8, 8}); + auto cond = make_shared(element::boolean, Shape{1}); + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ze = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Xt); + auto else_op = std::make_shared(Xe, Xe); + auto then_op_result1 = make_shared(then_op); + auto then_op_result2 = make_shared(Yt); + auto else_op_result1 = make_shared(else_op); + auto else_op_result2 = make_shared(Ze); + auto then_body = + make_shared(OutputVector{then_op_result1, then_op_result2}, ParameterVector{Xt, Yt}); + auto else_body = + make_shared(OutputVector{else_op_result1, else_op_result2}, ParameterVector{Xe, Ze}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, nullptr); + if_op->set_input(Z, nullptr, Ze); + auto res1 = if_op->set_output(then_op_result1, else_op_result1); + auto res2 = if_op->set_output(then_op_result2, else_op_result2); + auto result_if1 = make_shared(res1); + auto result_if2 = make_shared(res2); + if_op->validate_and_infer_types(); + std::vector X_v{1.0, 2.0, 3.0, 4.0}; + std::vector Y_v, Z_v; + for (auto c_ind = 0; c_ind < 4; ++c_ind) { + for (auto d_ind = 0; d_ind < 4; ++d_ind) { + Y_v.push_back(static_cast(c_ind * d_ind)); + } + } + for (auto c_ind = 0; c_ind < 8; ++c_ind) { + for (auto d_ind = 0; d_ind < 64; ++d_ind) { + Z_v.push_back(static_cast(c_ind * d_ind)); + } + } + auto fun = make_shared(OutputVector{result_if1, result_if2}, ParameterVector{cond, X, Y, Z}); + auto result1 = make_shared(); + auto result2 = make_shared(); + ASSERT_TRUE(fun->evaluate({result1, result2}, + {make_host_tensor(Shape{1}, {true}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{4, 2, 2}, Y_v), + make_host_tensor(Shape{8, 8, 8}, Z_v)})); + EXPECT_EQ(result1->get_element_type(), element::f32); + EXPECT_EQ(result1->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result1_data = read_vector(result1); + std::vector expected_results1{1.0, 4.0, 9.0, 16.0}; + for (auto i = 0; i < expected_results1.size(); i++) + EXPECT_NEAR(result1_data[i], expected_results1[i], 0.000001); + EXPECT_EQ(result2->get_element_type(), element::f32); + EXPECT_EQ(result2->get_shape(), Shape{std::vector({4, 2, 2})}); + auto result2_data = read_vector(result2); + for (auto i = 0; i < Y_v.size(); i++) + EXPECT_NEAR(result2_data[i], Y_v[i], 0.000001); + auto result3 = make_shared(); + auto result4 = make_shared(); + ASSERT_TRUE(fun->evaluate({result3, result4}, + {make_host_tensor(Shape{1}, {false}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{4, 2, 2}, Y_v), + make_host_tensor(Shape{8, 8, 8}, Z_v)})); + EXPECT_EQ(result3->get_element_type(), element::f32); + EXPECT_EQ(result3->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result3_data = read_vector(result3); + std::vector expected_results2{2.0, 4.0, 6.0, 8.0}; + for (auto i = 0; i < expected_results2.size(); i++) + EXPECT_NEAR(result3_data[i], expected_results2[i], 0.000001); + EXPECT_EQ(result4->get_element_type(), element::f32); + EXPECT_EQ(result4->get_shape(), Shape{std::vector({8, 8, 8})}); + auto result4_data = read_vector(result4); + for (auto i = 0; i < Z_v.size(); i++) + EXPECT_NEAR(result4_data[i], Z_v[i], 0.000001); +} + +TEST(op_eval, if_condition_non_const_scalar) { + auto X = make_shared(element::f32, Shape{1, 2, 2}); + auto Y = make_shared(element::f32, Shape{1, 2, 2}); + auto cond = make_shared(element::boolean, Shape{}); + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto else_op = std::make_shared(Xe, Ye); + auto then_op_result = make_shared(then_op); + auto else_op_result = make_shared(else_op); + auto then_body = make_shared(OutputVector{then_op_result}, ParameterVector{Xt, Yt}); + auto else_body = make_shared(OutputVector{else_op_result}, ParameterVector{Xe, Ye}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + if_op->set_output(then_op_result, else_op_result); + if_op->validate_and_infer_types(); + std::vector X_v{1.0, 2.0, 3.0, 4.0}; + std::vector Y_v{2.0, 1.0, 2.0, 3.0}; + auto fun = make_shared(OutputVector{if_op}, ParameterVector{cond, X, Y}); + auto result = make_shared(); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {true}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result_data = read_vector(result); + std::vector expected_results{2.0, 2.0, 6.0, 12.0}; + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {false}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + result_data = read_vector(result); + expected_results = {3.0, 3.0, 5.0, 7.0}; + + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); +} +TEST(op_eval, if_condition_is_dynamic) { + auto X = make_shared(element::f32, Shape{1, 2, 2}); + auto Y = make_shared(element::f32, Shape{1, 2, 2}); + auto cond = make_shared(element::boolean, PartialShape{Dimension::dynamic()}); + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto else_op = std::make_shared(Xe, Ye); + auto then_op_result = make_shared(then_op); + auto else_op_result = make_shared(else_op); + auto then_body = make_shared(OutputVector{then_op_result}, ParameterVector{Xt, Yt}); + auto else_body = make_shared(OutputVector{else_op_result}, ParameterVector{Xe, Ye}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + if_op->set_output(then_op_result, else_op_result); + if_op->validate_and_infer_types(); + std::vector X_v{1.0, 2.0, 3.0, 4.0}; + std::vector Y_v{2.0, 1.0, 2.0, 3.0}; + auto fun = make_shared(OutputVector{if_op}, ParameterVector{cond, X, Y}); + auto result = make_shared(); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {true}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + auto result_data = read_vector(result); + std::vector expected_results{2.0, 2.0, 6.0, 12.0}; + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); + ASSERT_TRUE(fun->evaluate({result}, + {make_host_tensor(Shape{1}, {false}), + make_host_tensor(Shape{1, 2, 2}, X_v), + make_host_tensor(Shape{1, 2, 2}, Y_v)})); + EXPECT_EQ(result->get_element_type(), element::f32); + EXPECT_EQ(result->get_shape(), Shape{std::vector({1, 2, 2})}); + result_data = read_vector(result); + expected_results = {3.0, 3.0, 5.0, 7.0}; + + for (auto i = 0; i < expected_results.size(); i++) + EXPECT_NEAR(result_data[i], expected_results[i], 0.000001); +} \ No newline at end of file diff --git a/ngraph/test/op_eval/interpolate.cpp b/ngraph/test/op_eval/interpolate.cpp index ad77bee3699..7ddb2c3b64e 100644 --- a/ngraph/test/op_eval/interpolate.cpp +++ b/ngraph/test/op_eval/interpolate.cpp @@ -41,45 +41,45 @@ TEST(op_eval, interpolate_v4_cubic) { ShapesAndAttrs{{3, 3}, Shape{1, 1, 3, 3}, {0.8f, 0.8f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_downsample_sizes_cubic: ShapesAndAttrs{{3, 3}, Shape{1, 1, 3, 3}, {0.75f, 0.75f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::sizes}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SIZES}, // resize_upsample_scales_cubic: ShapesAndAttrs{{8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_upsample_scales_cubic_asymmetric: ShapesAndAttrs{{8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::asymmetric, - ShapeCalcMode::scales}, + CoordinateTransformMode::ASYMMETRIC, + ShapeCalcMode::SCALES}, // resize_upsample_sizes_cubic: ShapesAndAttrs{{9, 10}, Shape{1, 1, 9, 10}, {2.25f, 2.5f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::sizes}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SIZES}, // resize_downsample_scales_cubic_align_corners: // (expected values from ONNX documentation are incorrect!) ShapesAndAttrs{{3, 3}, Shape{1, 1, 3, 3}, {0.8f, 0.8f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}, + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}, // resize_upsample_scales_cubic_align_corners: ShapesAndAttrs{{8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}}; + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}}; std::vector input_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; @@ -140,10 +140,10 @@ TEST(op_eval, interpolate_v4_cubic) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::cubic; + attrs.mode = InterpolateMode::CUBIC; attrs.shape_calculation_mode = s.shape_calculation_mode; attrs.coordinate_transformation_mode = s.transform_mode; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -180,65 +180,65 @@ TEST(op_eval, interpolate_v4_nearest) { {1, 2}, Shape{1, 1, 1, 2}, {0.6f, 0.6f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales, - Nearest_mode::round_prefer_floor}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES, + Nearest_mode::ROUND_PREFER_FLOOR}, // resize_downsample_sizes_nearest: ShapesAndAttrs{Shape{1, 1, 2, 4}, {1, 2}, Shape{1, 1, 1, 2}, {0.5f, 0.5f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::sizes, - Nearest_mode::round_prefer_floor}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SIZES, + Nearest_mode::ROUND_PREFER_FLOOR}, // resize_downsample_sizes_nearest_tf_half_pixel_for_nn: ShapesAndAttrs{Shape{1, 1, 4, 4}, {3, 2}, Shape{1, 1, 3, 2}, {0.75, 0.5}, - CoordinateTransformMode::tf_half_pixel_for_nn, - ShapeCalcMode::sizes, - Nearest_mode::round_prefer_floor}, + CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN, + ShapeCalcMode::SIZES, + Nearest_mode::ROUND_PREFER_FLOOR}, // resize_upsample_scales_nearest: ShapesAndAttrs{Shape{1, 1, 2, 2}, {4, 6}, Shape{1, 1, 4, 6}, {2.0f, 3.0f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales, - Nearest_mode::round_prefer_floor}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES, + Nearest_mode::ROUND_PREFER_FLOOR}, // resize_upsample_sizes_nearest: ShapesAndAttrs{Shape{1, 1, 2, 2}, {7, 8}, Shape{1, 1, 7, 8}, {3.5f, 4.0f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::sizes, - Nearest_mode::round_prefer_floor}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SIZES, + Nearest_mode::ROUND_PREFER_FLOOR}, // resize_upsample_sizes_nearest_ceil_half_pixel: ShapesAndAttrs{Shape{1, 1, 4, 4}, {8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::sizes, - Nearest_mode::ceil}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SIZES, + Nearest_mode::CEIL}, // resize_upsample_sizes_nearest_floor_align_corners: ShapesAndAttrs{Shape{1, 1, 4, 4}, {8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::sizes, - Nearest_mode::floor}, + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SIZES, + Nearest_mode::FLOOR}, // resize_upsample_sizes_nearest_round_prefer_ceil_asymmetric: ShapesAndAttrs{Shape{1, 1, 4, 4}, {8, 8}, Shape{1, 1, 8, 8}, {2.0f, 2.0f}, - CoordinateTransformMode::asymmetric, - ShapeCalcMode::sizes, - Nearest_mode::round_prefer_ceil}}; + CoordinateTransformMode::ASYMMETRIC, + ShapeCalcMode::SIZES, + Nearest_mode::ROUND_PREFER_CEIL}}; std::vector> input_data_list = { {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}, @@ -282,7 +282,7 @@ TEST(op_eval, interpolate_v4_nearest) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; + attrs.mode = InterpolateMode::NEAREST; attrs.shape_calculation_mode = s.shape_calculation_mode; attrs.coordinate_transformation_mode = s.transform_mode; attrs.nearest_mode = s.nearest_mode; @@ -322,37 +322,37 @@ TEST(op_eval, interpolate_v4_linear_onnx) { {1, 2}, Shape{1, 1, 1, 2}, {0.6f, 0.6f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_downsample_sizes_linear_pytorch_half_pixel ShapesAndAttrs{Shape{1, 1, 4, 4}, {3, 1}, Shape{1, 1, 3, 1}, {0.75f, 0.25f}, - CoordinateTransformMode::pytorch_half_pixel, - ShapeCalcMode::sizes}, + CoordinateTransformMode::PYTORCH_HALF_PIXEL, + ShapeCalcMode::SIZES}, // resize_upsample_scales_linear ShapesAndAttrs{Shape{1, 1, 2, 2}, {4, 4}, Shape{1, 1, 4, 4}, {2.0f, 2.0f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_upsample_scales_linear_align_corners ShapesAndAttrs{Shape{1, 1, 2, 2}, {4, 4}, Shape{1, 1, 4, 4}, {2.0f, 2.0f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}, + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}, // resize_downsample_scales_linear_align_corners: // (expected values from ONNX documentation are not correct!) ShapesAndAttrs{Shape{1, 1, 2, 4}, {1, 2}, Shape{1, 1, 1, 2}, {0.6f, 0.6f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}}; + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}}; std::vector> input_data_list = { {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f}, @@ -391,10 +391,10 @@ TEST(op_eval, interpolate_v4_linear_onnx) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::linear_onnx; + attrs.mode = InterpolateMode::LINEAR_ONNX; attrs.shape_calculation_mode = s.shape_calculation_mode; attrs.coordinate_transformation_mode = s.transform_mode; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -431,36 +431,36 @@ TEST(op_eval, interpolate_v4_linear_onnx5d) { {2, 1, 2}, Shape{1, 1, 2, 1, 2}, {0.8f, 0.6f, 0.6f}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_downsample_scales_linear_align_corners {Shape{1, 1, 3, 2, 4}, {2, 1, 2}, Shape{1, 1, 2, 1, 2}, {0.8f, 0.6f, 0.6f}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}, + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}, // resize_upsample_scales_linear {Shape{1, 1, 2, 2, 2}, {4, 4, 4}, Shape{1, 1, 4, 4, 4}, {2.0, 2.0, 2.0}, - CoordinateTransformMode::half_pixel, - ShapeCalcMode::scales}, + CoordinateTransformMode::HALF_PIXEL, + ShapeCalcMode::SCALES}, // resize_upsample_scales_linear_align_corners {Shape{1, 1, 2, 2, 2}, {4, 4, 4}, Shape{1, 1, 4, 4, 4}, {2.0, 2.0, 2.0}, - CoordinateTransformMode::align_corners, - ShapeCalcMode::scales}, + CoordinateTransformMode::ALIGN_CORNERS, + ShapeCalcMode::SCALES}, // resize_downsample_sizes_linear_pytorch_half_pixel {Shape{1, 1, 2, 4, 4}, {1, 3, 1}, Shape{1, 1, 1, 3, 1}, {0.5, 0.75, 0.25}, - CoordinateTransformMode::pytorch_half_pixel, - ShapeCalcMode::sizes}}; + CoordinateTransformMode::PYTORCH_HALF_PIXEL, + ShapeCalcMode::SIZES}}; std::vector> input_data_list = { // resize_downsample_scales_linear @@ -507,10 +507,10 @@ TEST(op_eval, interpolate_v4_linear_onnx5d) { auto axes = op::Constant::create(element::i64, Shape{3}, {2, 3, 4}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::linear_onnx; + attrs.mode = InterpolateMode::LINEAR_ONNX; attrs.shape_calculation_mode = s.shape_calculation_mode; attrs.coordinate_transformation_mode = s.transform_mode; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0, 0}; diff --git a/ngraph/test/provenance.cpp b/ngraph/test/provenance.cpp index 17c734dd29c..c66a4f249a5 100644 --- a/ngraph/test/provenance.cpp +++ b/ngraph/test/provenance.cpp @@ -17,6 +17,7 @@ #include "ngraph/pass/manager.hpp" #include "util/provenance_enabler.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START using namespace std; using namespace ngraph; using ::testing::Return; diff --git a/ngraph/test/runtime/backend.cpp b/ngraph/test/runtime/backend.cpp index 588ad48f640..d37799ca2d6 100644 --- a/ngraph/test/runtime/backend.cpp +++ b/ngraph/test/runtime/backend.cpp @@ -38,7 +38,9 @@ static string find_my_pathname() wstring ws(wpath); string path(ws.begin(), ws.end()); replace(path.begin(), path.end(), '\\', '/'); + NGRAPH_SUPPRESS_DEPRECATED_START path = file_util::get_directory(path); + NGRAPH_SUPPRESS_DEPRECATED_END path += "/"; return path; #elif defined(__linux) || defined(__APPLE__) diff --git a/ngraph/test/runtime/backend_manager.cpp b/ngraph/test/runtime/backend_manager.cpp index d31f22ea988..4d674d5d538 100644 --- a/ngraph/test/runtime/backend_manager.cpp +++ b/ngraph/test/runtime/backend_manager.cpp @@ -18,6 +18,8 @@ #include "ngraph/file_util.hpp" #include "ngraph/util.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START + using namespace std; using namespace ngraph; diff --git a/ngraph/test/runtime/ie/unit_test.manifest b/ngraph/test/runtime/ie/unit_test.manifest index a3a0d74ad1f..625da707551 100644 --- a/ngraph/test/runtime/ie/unit_test.manifest +++ b/ngraph/test/runtime/ie/unit_test.manifest @@ -418,8 +418,6 @@ grn_2d_with_bias erf divide_adjoint_stability notequal -greater -greatereq less sum_3d_to_scalar_int32 sum_2d_to_scalar_int8 @@ -459,7 +457,6 @@ gather_axis_0_int64 gather_axis_0_uint16 gather_axis_0_uint64 concat_matrix_int64 -greater_int64 broadcast_vector_rowwise_int64 broadcast_scalar_to_matrix_int64 abc_int64 @@ -479,8 +476,6 @@ IE_CPU.onnx_roi_align_f32 # [NOT_IMPLEMENTED] Input image format BOOL is not supported yet... not -logical_xor -logical_and gather_axis_0_bool auto_bcast_binary_elementwise auto_bcast_binary_elementwise_pdpd @@ -1569,7 +1564,17 @@ onnx_upsample6_dynamic # random values returned from the plugin: ticket 51762 onnx_model_deformable_conv_2d -# DeformableConvolution groups attribute: ticket 53312 +# DeformableConvolution groups attribute: ticket 53312 (fixed, but reproduced after v8->v1 conversion was enabled) +IE_CPU.deformable_convolution_opset8_2D_zeroed_offsets_groups_basic +IE_CPU.deformable_convolution_opset8_2D_zeroed_offsets_groups_complex +IE_CPU.deformable_convolution_opset8_2D_zeroed_offsets_groups_and_deforgroups +IE_CPU.deformable_convolution_opset8_2D_integral_offsets_groups_basic +IE_CPU.deformable_convolution_opset8_2D_integral_offsets_groups_complex +IE_CPU.deformable_convolution_opset8_2D_integral_offsets_groups_and_deforgroups +IE_CPU.deformable_convolution_opset8_2D_real_offsets_groups_basic +IE_CPU.deformable_convolution_opset8_2D_real_offsets_groups_complex +IE_CPU.deformable_convolution_opset8_2D_real_offsets_groups_and_deforgroups + IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_basic IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_complex IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_and_deforgroups diff --git a/ngraph/test/type_prop/cum_sum.cpp b/ngraph/test/type_prop/cum_sum.cpp new file mode 100644 index 00000000000..46df508b2da --- /dev/null +++ b/ngraph/test/type_prop/cum_sum.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "util/type_prop.hpp" + +using namespace ngraph; + +TEST(type_prop, cum_sum_op_default_attributes_no_axis_input) { + PartialShape data_shape{2, 4}; + auto A = std::make_shared(element::f32, data_shape); + auto cum_sum = std::make_shared(A); + + EXPECT_EQ(cum_sum->is_exclusive(), false); + EXPECT_EQ(cum_sum->is_reverse(), false); + EXPECT_EQ(cum_sum->get_input_size(), 2); + EXPECT_EQ(cum_sum->get_element_type(), element::f32); + EXPECT_EQ(cum_sum->get_output_partial_shape(0), data_shape); +} + +TEST(type_prop, cum_sum_op_default_attributes_with_axis_param) { + PartialShape data_shape{2, 4}; + auto A = std::make_shared(element::f32, data_shape); + auto axis = std::make_shared(element::i32, PartialShape{}); + auto cum_sum = std::make_shared(A, axis); + + EXPECT_EQ(cum_sum->is_exclusive(), false); + EXPECT_EQ(cum_sum->is_reverse(), false); + EXPECT_EQ(cum_sum->get_input_size(), 2); + EXPECT_EQ(cum_sum->get_element_type(), element::f32); + EXPECT_EQ(cum_sum->get_output_partial_shape(0), data_shape); +} + +TEST(type_prop, cum_sum_op_default_attributes_with_axis_const) { + PartialShape data_shape{2, 4}; + auto A = std::make_shared(element::f32, data_shape); + auto axis = op::Constant::create(element::i32, Shape{}, {1}); + auto cum_sum = std::make_shared(A, axis); + + EXPECT_EQ(cum_sum->is_exclusive(), false); + EXPECT_EQ(cum_sum->is_reverse(), false); + EXPECT_EQ(cum_sum->get_input_size(), 2); + EXPECT_EQ(cum_sum->get_element_type(), element::f32); + EXPECT_EQ(cum_sum->get_output_partial_shape(0), data_shape); +} + +TEST(type_prop, cum_sum_op_custom_attributes) { + PartialShape data_shape{2, 4}; + auto A = std::make_shared(element::f32, data_shape); + auto axis = std::make_shared(element::i32, PartialShape{}); + bool exclusive = true; + bool reverse = true; + auto cum_sum = std::make_shared(A, axis, exclusive, reverse); + + EXPECT_EQ(cum_sum->is_exclusive(), true); + EXPECT_EQ(cum_sum->is_reverse(), true); + EXPECT_EQ(cum_sum->get_input_size(), 2); + EXPECT_EQ(cum_sum->get_element_type(), element::f32); + EXPECT_EQ(cum_sum->get_output_partial_shape(0), data_shape); +} + +TEST(type_prop, cum_sum_op_data_shapes) { + std::vector input_shpes{{}, + {10}, + {3, 5}, + {2, 3, 5}, + {4, 16, 64, 32}, + {2, 4, 16, 64, 32}, + {2, Dimension(2, 4), Dimension()}, + PartialShape::dynamic()}; + + for (auto& shape : input_shpes) { + try { + auto axis = std::make_shared(element::i32, PartialShape{}); + auto A = std::make_shared(element::f32, shape); + auto cum_sum = std::make_shared(A, axis); + + EXPECT_EQ(cum_sum->get_output_partial_shape(0), shape); + } catch (...) { + FAIL() << "Data input shape validation check failed for unexpected reason"; + } + } +} + +TEST(type_prop, cum_sum_op_incorrect_axis_shapes) { + PartialShape data_shape{2, 4}; + std::vector incorrect_axis_shpes{{1}, {1, 1}, {2}}; + for (auto& shape : incorrect_axis_shpes) { + try { + auto axis = std::make_shared(element::i32, shape); + auto A = std::make_shared(element::f32, data_shape); + auto cum_sum = std::make_shared(A, axis); + } catch (...) { + FAIL() << "CumSum axis input shape validation shouldn't throw for backward compatibility"; + } + } +} + +TEST(type_prop, cum_sum_op_element_types) { + PartialShape data_shape{2, 4}; + std::vector element_types{element::u4, + element::u8, + element::u16, + element::u32, + element::i8, + element::i16, + element::i32, + element::i64, + element::f32, + element::f64, + element::u32, + element::boolean}; + + for (auto& et : element_types) { + try { + auto axis = std::make_shared(element::i32, PartialShape{}); + auto A = std::make_shared(et, data_shape); + + EXPECT_NO_THROW(std::make_shared(A, axis)); + } catch (...) { + FAIL() << "Data input element type validation check failed for unexpected reason"; + } + } +} + +TEST(type_prop, cum_sum_op_incorrect_axis_element_type) { + std::vector element_types{element::u32, element::f32, element::boolean, element::u32}; + + PartialShape data_shape{2, 4}; + + for (auto& et : element_types) { + try { + auto axis = std::make_shared(et, PartialShape{}); + auto A = std::make_shared(element::f32, data_shape); + auto cum_sum = std::make_shared(A, axis); + + FAIL() << "Invalid element type of axis input not detected"; + } catch (const NodeValidationFailure& error) { + EXPECT_HAS_SUBSTRING(error.what(), "axis element type must be either int64_t or int32_t"); + } catch (...) { + FAIL() << "Axis input element type validation check failed for unexpected reason"; + } + } +} diff --git a/ngraph/test/type_prop/gelu.cpp b/ngraph/test/type_prop/gelu.cpp index 28cf820616c..3ad9d37d340 100644 --- a/ngraph/test/type_prop/gelu.cpp +++ b/ngraph/test/type_prop/gelu.cpp @@ -9,8 +9,17 @@ using namespace std; using namespace ngraph; -TEST(type_prop, gelu_default_mode_inference_f32) -{ +// ------------------------------ V0 ------------------------------ +TEST(type_prop, gelu_v0) { + const PartialShape param_shape{64, Dimension::dynamic(), 256, Dimension(4, 8)}; + const auto param = std::make_shared(element::f32, param_shape); + const auto op = std::make_shared(param); + ASSERT_EQ(op->get_element_type(), element::f32); + ASSERT_EQ(op->get_output_partial_shape(0), param_shape); +} + +// ------------------------------ V7 ------------------------------ +TEST(type_prop, gelu_default_mode_inference_f32) { auto param = make_shared(element::f32, Shape{1, 32, 32}); auto gelu = make_shared(param); @@ -19,8 +28,7 @@ TEST(type_prop, gelu_default_mode_inference_f32) ASSERT_EQ(gelu->get_approximation_mode(), op::GeluApproximationMode::ERF); } -TEST(type_prop, gelu_default_mode_inference_f16) -{ +TEST(type_prop, gelu_default_mode_inference_f16) { auto param = make_shared(element::f16, Shape{1, 32, 32}); auto gelu = make_shared(param); @@ -29,8 +37,7 @@ TEST(type_prop, gelu_default_mode_inference_f16) ASSERT_EQ(gelu->get_approximation_mode(), op::GeluApproximationMode::ERF); } -TEST(type_prop, gelu_tanh_mode_inference_f32) -{ +TEST(type_prop, gelu_tanh_mode_inference_f32) { auto param = make_shared(element::f32, Shape{1, 32, 32}); auto gelu = make_shared(param, op::GeluApproximationMode::TANH); @@ -39,58 +46,50 @@ TEST(type_prop, gelu_tanh_mode_inference_f32) ASSERT_EQ(gelu->get_approximation_mode(), op::GeluApproximationMode::TANH); } -TEST(type_prop, gelu_tanh_mode_inference_f16) -{ +TEST(type_prop, gelu_tanh_mode_inference_f16) { auto param = make_shared(element::f16, Shape{1, 32, 32}); auto gelu = make_shared(param, op::GeluApproximationMode::TANH); ASSERT_EQ(gelu->get_element_type(), element::f16); ASSERT_EQ(gelu->get_shape(), (Shape{1, 32, 32})); ASSERT_EQ(gelu->get_approximation_mode(), op::GeluApproximationMode::TANH); -} +} -TEST(type_prop, gelu_incompatible_input_type_boolean) -{ +TEST(type_prop, gelu_incompatible_input_type_boolean) { auto param = make_shared(element::boolean, Shape{1, 32, 32}); ASSERT_THROW(std::make_shared(param), ngraph::NodeValidationFailure); } -TEST(type_prop, gelu_incompatible_input_type_u16) -{ +TEST(type_prop, gelu_incompatible_input_type_u16) { auto param = make_shared(element::u16, Shape{1, 32, 32}); ASSERT_THROW(std::make_shared(param), ngraph::NodeValidationFailure); } -TEST(type_prop, gelu_incompatible_input_type_i32) -{ +TEST(type_prop, gelu_incompatible_input_type_i32) { auto param = make_shared(element::i32, Shape{1, 32, 32}); ASSERT_THROW(std::make_shared(param), ngraph::NodeValidationFailure); } -TEST(type_prop, gelu_incompatible_input_type_i16) -{ +TEST(type_prop, gelu_incompatible_input_type_i16) { auto param = make_shared(element::i16, Shape{1, 32, 32}); ASSERT_THROW(std::make_shared(param), ngraph::NodeValidationFailure); } -TEST(type_prop, gelu_dynamic_rank_input_shape_2D) -{ +TEST(type_prop, gelu_dynamic_rank_input_shape_2D) { const PartialShape param_shape{Dimension::dynamic(), 10}; const auto param = std::make_shared(element::f32, param_shape); const auto op = std::make_shared(param); ASSERT_TRUE(op->get_output_partial_shape(0).same_scheme(PartialShape{Dimension(), 10})); } -TEST(type_prop, gelu_dynamic_rank_input_shape_3D) -{ +TEST(type_prop, gelu_dynamic_rank_input_shape_3D) { const PartialShape param_shape{100, Dimension::dynamic(), 58}; const auto param = std::make_shared(element::f32, param_shape); const auto op = std::make_shared(param); ASSERT_TRUE(op->get_output_partial_shape(0).same_scheme(PartialShape{100, Dimension(), 58})); } -TEST(type_prop, gelu_dynamic_rank_input_shape_full) -{ +TEST(type_prop, gelu_dynamic_rank_input_shape_full) { const auto param = std::make_shared(element::f32, PartialShape::dynamic()); const auto op = std::make_shared(param); ASSERT_TRUE(op->get_output_partial_shape(0).same_scheme(PartialShape::dynamic())); diff --git a/ngraph/test/type_prop/if.cpp b/ngraph/test/type_prop/if.cpp new file mode 100644 index 00000000000..d60d4890f1d --- /dev/null +++ b/ngraph/test/type_prop/if.cpp @@ -0,0 +1,278 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "gtest/gtest.h" +#include "ngraph/builder/reshape.hpp" +#include "ngraph/ngraph.hpp" +#include "ngraph/opsets/opset5.hpp" +#include "util/type_prop.hpp" + +using namespace std; +using namespace ngraph; + +TEST(type_prop, if_simple_test) { + // That which we iterate over + auto X = make_shared(element::f32, Shape{32, 40, 10}); + auto Y = make_shared(element::f32, Shape{32, 40, 10}); + auto cond = std::make_shared(ngraph::element::boolean, ngraph::Shape{1}, true); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_op_res = std::make_shared(then_op); + + auto then_body = make_shared(OutputVector{then_op_res}, ParameterVector{Xt, Yt}); + + auto else_op = std::make_shared(Xe, Ye); + auto else_op_res = std::make_shared(else_op); + auto else_body = make_shared(OutputVector{else_op_res}, ParameterVector{Xe, Ye}); + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res = if_op->set_output(then_op_res, else_op_res); + if_op->validate_and_infer_types(); + + auto result0 = make_shared(res); + Shape out0_shape{32, 40, 10}; + auto sh = result0->get_output_shape(0); + EXPECT_EQ(sh, out0_shape); +} + +TEST(type_prop, if_non_const_condition_test) { + // That which we iterate over + auto X = make_shared(element::f32, Shape{32, 40, 10}); + auto Y = make_shared(element::f32, Shape{32, 40, 10}); + auto cond = make_shared(element::boolean, Shape{1}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_body_res = make_shared(then_op); + auto then_body = make_shared(OutputVector{then_body_res}, ParameterVector{Xt, Yt}); + + auto else_op = std::make_shared(Xe, Ye); + auto else_body_res = make_shared(else_op); + auto else_body = make_shared(OutputVector{else_body_res}, ParameterVector{Xe, Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res = if_op->set_output(then_body_res, else_body_res); + if_op->validate_and_infer_types(); + auto result0 = make_shared(res); + Shape out0_shape{32, 40, 10}; + auto sh = result0->get_output_shape(0); + EXPECT_EQ(sh, out0_shape); +} + +TEST(type_prop, if_clone_test) { + auto X = make_shared(element::f32, Shape{32, 40, 10}); + auto Y = make_shared(element::f32, Shape{32, 40, 10}); + auto cond = make_shared(element::boolean, Shape{1}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + auto Xnew = make_shared(element::f32, PartialShape::dynamic()); + auto Ynew = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_body_res = make_shared(then_op); + auto then_body = make_shared(OutputVector{then_body_res}, ParameterVector{Xt, Yt}); + auto else_op = std::make_shared(Xe, Ye); + auto else_body_res = make_shared(else_op); + auto else_body = make_shared(OutputVector{else_body_res}, ParameterVector{Xe, Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res = if_op->set_output(then_body_res, else_body_res); + + auto new_if = std::dynamic_pointer_cast(if_op->clone_with_new_inputs(OutputVector{cond, Xnew, Ynew})); + EXPECT_EQ(true, true); +} + +TEST(type_prop, if_multiple_outputs) { + auto X = make_shared(element::f32, Shape{32, 40, 10}); + auto Y = make_shared(element::f32, Shape{32, 40, 10}); + auto cond = make_shared(element::boolean, Shape{1}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + auto Xnew = make_shared(element::f32, PartialShape::dynamic()); + auto Ynew = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_body_res_1 = make_shared(then_op); + auto then_body_res_2 = make_shared(Xt); + auto then_body = + make_shared(OutputVector{then_body_res_1, then_body_res_2}, ParameterVector{Xt, Yt}); + auto else_op = std::make_shared(Xe, Ye); + auto else_const = std::make_shared(ngraph::element::f32, + ngraph::Shape{1, 1, 1}, + std::vector{0.5f}); + auto else_body_res_1 = make_shared(else_op); + auto else_body_res_2 = make_shared(else_const); + auto else_body = + make_shared(OutputVector{else_body_res_1, else_body_res_2}, ParameterVector{Xe, Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res1 = if_op->set_output(then_body_res_1, else_body_res_1); + auto res2 = if_op->set_output(then_body_res_2, else_body_res_2); + if_op->validate_and_infer_types(); + auto result1 = make_shared(res1); + auto result2 = make_shared(res2); + Shape out0_shape{32, 40, 10}; + auto sh = result1->get_output_shape(0); + auto is_dynamic = result2->is_dynamic(); + EXPECT_EQ(out0_shape, sh); + EXPECT_EQ(is_dynamic, true); +} + +TEST(type_prop, if_scalar_condition) { + // That which we iterate over + auto X = make_shared(element::f32, Shape{32, 40, 10}); + auto Y = make_shared(element::f32, Shape{32, 40, 10}); + auto cond = make_shared(element::boolean, Shape{}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_body_res = make_shared(then_op); + auto then_body = make_shared(OutputVector{then_body_res}, ParameterVector{Xt, Yt}); + + auto else_op = std::make_shared(Xe, Ye); + auto else_body_res = make_shared(else_op); + auto else_body = make_shared(OutputVector{else_body_res}, ParameterVector{Xe, Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res = if_op->set_output(then_body_res, else_body_res); + if_op->validate_and_infer_types(); + auto result0 = make_shared(res); + Shape out0_shape{32, 40, 10}; + auto sh = result0->get_output_shape(0); + EXPECT_EQ(sh, out0_shape); +} + +TEST(type_prop, if_dynamic_output) { + // That which we iterate over + auto X_shape = Shape{1, 20, 5, 30}; + auto Y_shape = Shape{18, 16, 14, 12}; + auto X = make_shared(element::f32, X_shape); + auto Y = make_shared(element::f32, Y_shape); + auto cond = make_shared(element::boolean, Shape{1}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Xt); + auto then_body_res = make_shared(then_op); + auto then_body = make_shared(OutputVector{then_body_res}, ParameterVector{Xt}); + + auto else_op = std::make_shared(Ye, Ye); + auto else_body_res = make_shared(else_op); + auto else_body = make_shared(OutputVector{else_body_res}, ParameterVector{Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, nullptr); + if_op->set_input(Y, nullptr, Ye); + auto res = if_op->set_output(then_body_res, else_body_res); + if_op->validate_and_infer_types(); + auto result0 = make_shared(res); + auto dynamic_shape = result0->get_output_partial_shape(0); + + EXPECT_EQ(X_shape.size(), dynamic_shape.rank().get_length()); + for (auto shape_index = 0; shape_index < X_shape.size(); shape_index++) { + auto x_shape_it = X_shape.begin(); + auto y_shape_it = Y_shape.begin(); + auto res_it = dynamic_shape.begin(); + EXPECT_EQ(std::max(*x_shape_it, *y_shape_it), (*res_it).get_max_length()); + EXPECT_EQ(std::min(*x_shape_it, *y_shape_it), (*res_it).get_min_length()); + x_shape_it++; + y_shape_it++; + res_it++; + } +} + +TEST(type_prop, if_dynamic_inputs) { + // That which we iterate over + auto X_shape = PartialShape{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}; + auto Y_shape = PartialShape{Dimension::dynamic(), 20, 30}; + ; + auto X = make_shared(element::f32, X_shape); + auto Y = make_shared(element::f32, Y_shape); + auto cond = make_shared(element::boolean, Shape{1}); + + // Set up the cell body, a function from (Xi, Yi) -> (Zo) + // Body parameters + auto Xt = make_shared(element::f32, PartialShape::dynamic()); + auto Yt = make_shared(element::f32, PartialShape::dynamic()); + auto Xe = make_shared(element::f32, PartialShape::dynamic()); + auto Ye = make_shared(element::f32, PartialShape::dynamic()); + // Body + auto then_op = std::make_shared(Xt, Yt); + auto then_body_res = make_shared(then_op); + auto then_body = make_shared(OutputVector{then_body_res}, ParameterVector{Xt, Yt}); + + auto else_op = std::make_shared(Xe, Ye); + auto else_body_res = make_shared(else_op); + auto else_body = make_shared(OutputVector{else_body_res}, ParameterVector{Xe, Ye}); + + auto if_op = make_shared(cond); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + if_op->set_input(X, Xt, Xe); + if_op->set_input(Y, Yt, Ye); + auto res = if_op->set_output(then_body_res, else_body_res); + if_op->validate_and_infer_types(); + auto result0 = make_shared(res); + auto dynamic_shape = result0->get_output_partial_shape(0); + auto expected_result = PartialShape{Dimension::dynamic(), 20, 30}; + EXPECT_EQ(3, dynamic_shape.rank().get_length()); + for (auto dim_index = 0; dim_index < 3; dim_index++) { + auto exp_res_it = expected_result.begin(); + auto res_it = dynamic_shape.begin(); + EXPECT_EQ(*exp_res_it, *res_it); + } +} \ No newline at end of file diff --git a/ngraph/test/type_prop/interpolate.cpp b/ngraph/test/type_prop/interpolate.cpp index 350ba8e4aa5..70db74e2ff8 100644 --- a/ngraph/test/type_prop/interpolate.cpp +++ b/ngraph/test/type_prop/interpolate.cpp @@ -21,10 +21,10 @@ TEST(type_prop, interpolate_v4) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -43,10 +43,10 @@ TEST(type_prop, interpolate_v4_non_constant_axes_scales) { auto axes = std::make_shared(element::i32, PartialShape{2}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -67,10 +67,10 @@ TEST(type_prop, interpolate_v4_non_constant_axes_sizes) { auto axes = std::make_shared(element::i32, PartialShape{2}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::sizes; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SIZES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -92,10 +92,10 @@ TEST(type_prop, interpolate_v4_partial) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -120,10 +120,10 @@ TEST(type_prop, interpolate_v4_partial_static_rank) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -145,10 +145,10 @@ TEST(type_prop, interpolate_v4_partial_static_rank2) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -170,10 +170,10 @@ TEST(type_prop, interpolate_v4_partial_static_rank3) { auto axes = op::Constant::create(element::i64, Shape{2}, {2, 3}); InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0}; @@ -196,10 +196,10 @@ TEST(type_prop, interpolate_v4_interval_logic) { const auto out_shape = PartialShape{2, 2, Dimension(6, 400), Dimension(0, -1), Dimension(3, -1)}; InterpolateAttrs attrs; - attrs.mode = InterpolateMode::nearest; - attrs.shape_calculation_mode = ShapeCalcMode::scales; - attrs.coordinate_transformation_mode = CoordinateTransformMode::half_pixel; - attrs.nearest_mode = Nearest_mode::round_prefer_floor; + attrs.mode = InterpolateMode::NEAREST; + attrs.shape_calculation_mode = ShapeCalcMode::SCALES; + attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; + attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; attrs.pads_begin = {0, 0, 0, 0, 0}; attrs.pads_end = {0, 0, 0, 0, 0}; diff --git a/ngraph/test/type_prop/logical_xor.cpp b/ngraph/test/type_prop/logical_xor.cpp new file mode 100644 index 00000000000..7b951a74ca8 --- /dev/null +++ b/ngraph/test/type_prop/logical_xor.cpp @@ -0,0 +1,6 @@ +#include "logical_ops.hpp" +#include "util/type_prop.hpp" + +using Type = ::testing::Types>; + +INSTANTIATE_TYPED_TEST_SUITE_P(Type_prop_test, LogicalOperatorTypeProp, Type, LogicalOperatorTypeName); diff --git a/ngraph/test/type_prop/lstm_sequence.cpp b/ngraph/test/type_prop/lstm_sequence.cpp index a72ae47204d..320268864a8 100644 --- a/ngraph/test/type_prop/lstm_sequence.cpp +++ b/ngraph/test/type_prop/lstm_sequence.cpp @@ -7,9 +7,6 @@ #include "ngraph/opsets/opset5.hpp" #include "util/type_prop.hpp" -// suppress FusedOp deprecation warnings -NGRAPH_SUPPRESS_DEPRECATED_START - using namespace std; using namespace ngraph; diff --git a/ngraph/test/util.cpp b/ngraph/test/util.cpp index 9d11c61e727..d72563970b9 100644 --- a/ngraph/test/util.cpp +++ b/ngraph/test/util.cpp @@ -20,6 +20,7 @@ #include "util/all_close.hpp" #include "util/ndarray.hpp" +NGRAPH_SUPPRESS_DEPRECATED_START using namespace std; using namespace ngraph; diff --git a/ngraph/test/util/test_case.hpp b/ngraph/test/util/test_case.hpp index e59d3ce3f82..767f92e6164 100644 --- a/ngraph/test/util/test_case.hpp +++ b/ngraph/test/util/test_case.hpp @@ -80,15 +80,19 @@ namespace ngraph const std::string& basepath, const std::string& filename) { + NGRAPH_SUPPRESS_DEPRECATED_START const auto filepath = ngraph::file_util::path_join(basepath, filename); add_input_from_file(shape, filepath); + NGRAPH_SUPPRESS_DEPRECATED_END } template void add_input_from_file(const std::string& basepath, const std::string& filename) { + NGRAPH_SUPPRESS_DEPRECATED_START const auto filepath = ngraph::file_util::path_join(basepath, filename); add_input_from_file(filepath); + NGRAPH_SUPPRESS_DEPRECATED_END } template @@ -144,8 +148,10 @@ namespace ngraph const std::string& basepath, const std::string& filename) { + NGRAPH_SUPPRESS_DEPRECATED_START const auto filepath = ngraph::file_util::path_join(basepath, filename); add_expected_output_from_file(expected_shape, filepath); + NGRAPH_SUPPRESS_DEPRECATED_END } template diff --git a/ngraph/test/util/test_tools.hpp b/ngraph/test/util/test_tools.hpp index 67d1eb6df07..6f1260717d5 100644 --- a/ngraph/test/util/test_tools.hpp +++ b/ngraph/test/util/test_tools.hpp @@ -25,7 +25,6 @@ namespace ngraph { class Node; - class Function; class TestOpMultiOut : public op::Op { public: @@ -53,7 +52,7 @@ namespace ngraph bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; }; -} +} // namespace ngraph bool validate_list(const std::vector>& nodes); std::shared_ptr make_test_graph(); diff --git a/ngraph/test/visitors/op/cum_sum.cpp b/ngraph/test/visitors/op/cum_sum.cpp index af345720355..66ac11a8b8b 100644 --- a/ngraph/test/visitors/op/cum_sum.cpp +++ b/ngraph/test/visitors/op/cum_sum.cpp @@ -5,16 +5,29 @@ #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" #include "ngraph/op/util/attr_types.hpp" -#include "ngraph/opsets/opset1.hpp" #include "ngraph/opsets/opset3.hpp" -#include "ngraph/opsets/opset4.hpp" -#include "ngraph/opsets/opset5.hpp" #include "util/visitor.hpp" using namespace std; using namespace ngraph; using ngraph::test::NodeBuilder; -using ngraph::test::ValueMap; + +TEST(attributes, cum_sum_op_default_attributes_no_axis_input) { + NodeBuilder::get_ops().register_factory(); + + Shape shape{1, 4}; + auto A = make_shared(element::f32, shape); + auto cs = make_shared(A); + + NodeBuilder builder(cs); + auto g_cs = as_type_ptr(builder.create()); + + const auto expected_attr_count = 2; + EXPECT_EQ(builder.get_value_map_size(), expected_attr_count); + + EXPECT_EQ(g_cs->is_exclusive(), cs->is_exclusive()); + EXPECT_EQ(g_cs->is_reverse(), cs->is_reverse()); +} TEST(attributes, cum_sum_op_default_attributes) { NodeBuilder::get_ops().register_factory(); @@ -27,6 +40,9 @@ TEST(attributes, cum_sum_op_default_attributes) { NodeBuilder builder(cs); auto g_cs = as_type_ptr(builder.create()); + const auto expected_attr_count = 2; + EXPECT_EQ(builder.get_value_map_size(), expected_attr_count); + EXPECT_EQ(g_cs->is_exclusive(), cs->is_exclusive()); EXPECT_EQ(g_cs->is_reverse(), cs->is_reverse()); } @@ -44,6 +60,9 @@ TEST(attributes, cum_sum_op_custom_attributes) { NodeBuilder builder(cs); auto g_cs = as_type_ptr(builder.create()); + const auto expected_attr_count = 2; + EXPECT_EQ(builder.get_value_map_size(), expected_attr_count); + EXPECT_EQ(g_cs->is_exclusive(), cs->is_exclusive()); EXPECT_EQ(g_cs->is_reverse(), cs->is_reverse()); } diff --git a/tests/layer_tests/common/utils/common_utils.py b/tests/layer_tests/common/utils/common_utils.py index a487573afd8..f92daf51c26 100644 --- a/tests/layer_tests/common/utils/common_utils.py +++ b/tests/layer_tests/common/utils/common_utils.py @@ -31,7 +31,7 @@ def generate_ir(coverage=False, **kwargs): continue elif (isinstance(value, tuple) and value) or (isinstance(value, str)): params.extend(("--{}".format(key), str('"{}"'.format(value)))) - elif (key == "mean_values" and (' ' in value or '(' in value)): + elif key == "mean_values" and (' ' in value or '(' in value): params.extend(("--{}".format(key), str('"{}"'.format(value)))) else: params.extend(("--{}".format(key), str(value))) diff --git a/tests/layer_tests/onnx_tests/test_gather.py b/tests/layer_tests/onnx_tests/test_gather.py index c4c0ee9c12e..73781c354b8 100644 --- a/tests/layer_tests/onnx_tests/test_gather.py +++ b/tests/layer_tests/onnx_tests/test_gather.py @@ -215,31 +215,23 @@ class TestGather(OnnxRuntimeLayerTest): test_data_precommit = [ dict(shape=[6, 8, 10, 12], axis=2, indices=[[0, 2, 4], [5, 7, 9]], output_shape=[6, 8, 2, 3, 12]), dict(shape=[4, 6, 8, 10, 12], axis=1, indices=[2, 5], output_shape=[4, 2, 8, 10, 12]), - dict(shape=[4, 6, 8, 10, 12], axis=-1, indices=[5, 8], output_shape=[4, 6, 8, 10, 2])] + dict(shape=[4, 6, 8, 10, 12], axis=-1, indices=[5, 8], output_shape=[4, 6, 8, 10, 2]), + dict(shape=[6, 8, 10, 12], axis=-1, indices=[[[2, -1], [3, 2]], [[5, -1], [3, -2]]], output_shape=[6, 8, 10, 2, 2, 2]) + ] test_data = [dict(shape=[10, 12], axis=0, indices=[3, 6], output_shape=[2, 12]), - dict(shape=[10, 12], axis=1, indices=[4, 7], output_shape=[10, 2]), dict(shape=[10, 12], axis=-1, indices=[4, 7], output_shape=[10, 2]), dict(shape=[10, 12], axis=None, indices=[[0, 1, 3, 4], [5, 6, 8, 9]], output_shape=[2, 4, 12]), dict(shape=[10, 12], axis=1, indices=[[0, 1, 3, 4, 5], [6, 7, 9, 10, 11]], output_shape=[10, 2, 5]), dict(shape=[8, 10, 12], axis=0, indices=[3, 6], output_shape=[2, 10, 12]), - dict(shape=[8, 10, 12], axis=1, indices=[4, 7], output_shape=[8, 2, 12]), - dict(shape=[8, 10, 12], axis=2, indices=[5, 8], output_shape=[8, 10, 2]), dict(shape=[8, 10, 12], axis=-1, indices=[5, 8], output_shape=[8, 10, 2]), dict(shape=[8, 10, 12], axis=None, indices=[[0, 1], [3, 4], [6, 7]], output_shape=[3, 2, 10, 12]), dict(shape=[8, 10, 12], axis=1, indices=[[0, 2, 4], [5, 7, 9]], output_shape=[8, 2, 3, 12]), - dict(shape=[6, 8, 10, 12], axis=0, indices=[2, 5], output_shape=[2, 8, 10, 12]), - dict(shape=[6, 8, 10, 12], axis=1, indices=[3, 6], output_shape=[6, 2, 10, 12]), - dict(shape=[6, 8, 10, 12], axis=2, indices=[4, 7], output_shape=[6, 8, 2, 12]), - dict(shape=[6, 8, 10, 12], axis=3, indices=[5, 8], output_shape=[6, 8, 10, 2]), dict(shape=[6, 8, 10, 12], axis=-1, indices=[5, 8], output_shape=[6, 8, 10, 2]), dict(shape=[6, 8, 10, 12], axis=None, indices=[[0, 1, 2], [3, 4, 5]], output_shape=[2, 3, 8, 10, 12]), dict(shape=[6, 8, 10, 12], axis=2, indices=[[0, 2, 4], [5, 7, 9]], output_shape=[6, 8, 2, 3, 12]), dict(shape=[4, 6, 8, 10, 12], axis=0, indices=[1, 3], output_shape=[2, 6, 8, 10, 12]), dict(shape=[4, 6, 8, 10, 12], axis=1, indices=[2, 5], output_shape=[4, 2, 8, 10, 12]), - dict(shape=[4, 6, 8, 10, 12], axis=2, indices=[3, 6], output_shape=[4, 6, 2, 10, 12]), - dict(shape=[4, 6, 8, 10, 12], axis=3, indices=[4, 7], output_shape=[4, 6, 8, 2, 12]), - dict(shape=[4, 6, 8, 10, 12], axis=4, indices=[5, 8], output_shape=[4, 6, 8, 10, 2]), dict(shape=[4, 6, 8, 10, 12], axis=-1, indices=[5, 8], output_shape=[4, 6, 8, 10, 2])] @pytest.mark.parametrize("params", test_data_precommit) @@ -259,3 +251,18 @@ class TestGather(OnnxRuntimeLayerTest): def test_gather_const(self, params, ie_device, precision, ir_version, temp_dir): self._test(*self.create_net_const(**params, ir_version=ir_version), ie_device, precision, ir_version, temp_dir=temp_dir) + + test_data_negative_indices = [dict(shape=[10, 12], axis=0, indices=[3, -1, -4], output_shape=[3, 12]), + dict(shape=[6, 10, 14, 12], axis=1, indices=[[0, -1, 3, -4], [-5, 6, -7, 8]], + output_shape=[6, 2, 4, 14, 12]), + dict(shape=[8, 10, 14, 12], axis=1, indices=[[-2, 2, -4], [5, -7, 9]], + output_shape=[8, 2, 3, 14, 12]), + dict(shape=[6, 8, 10, 12], axis=-1, indices=[[[2, -1], [3, 2]], [[5, -1], [3, -2]]], + output_shape=[6, 8, 10, 2, 2, 2])] + + @pytest.mark.xfail(reason='negative indices are not yet implemented on CPU: xxx-54630') + @pytest.mark.parametrize("params", test_data_negative_indices) + @pytest.mark.nightly + def test_gather_nightly_negative_indices(self, params, ie_device, precision, ir_version, temp_dir): + self._test(*self.create_net(**params, ir_version=ir_version), + ie_device, precision, ir_version, temp_dir=temp_dir) diff --git a/tests/layer_tests/tensorflow_tests/test_tf_Gather.py b/tests/layer_tests/tensorflow_tests/test_tf_Gather.py new file mode 100644 index 00000000000..403b33ab1a3 --- /dev/null +++ b/tests/layer_tests/tensorflow_tests/test_tf_Gather.py @@ -0,0 +1,61 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import pytest + +from common.tf_layer_test_class import CommonTFLayerTest + + +class TestGather(CommonTFLayerTest): + + def create_indices_constant(self): + pass + + def create_gather_net(self, data_shape, indices, axis, batch_dims, **kwargs): + import tensorflow as tf + + tf.compat.v1.reset_default_graph() + + with tf.compat.v1.Session() as sess: + data = tf.compat.v1.placeholder(tf.float32, data_shape, 'data') + indices = tf.constant(indices, dtype=tf.int32) + gather = tf.gather(data, indices, axis=axis, batch_dims=batch_dims, name='gather_output') + + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph_def + + ref_net = None + + return tf_net, ref_net + + test_data_precommit = [ + dict(data_shape=[6, 8, 10, 12], indices=[[0, 2, 4], [5, 7, 9]], axis=2, batch_dims=0), + dict(data_shape=[4, 6, 8, 10, 12], indices=[2, 5], axis=1, batch_dims=0), + dict(data_shape=[4, 6, 8, 10, 12], indices=[2, 5], axis=-1, batch_dims=0) + ] + + @pytest.mark.parametrize("params", test_data_precommit) + @pytest.mark.precommit + def test_gather(self, params, ie_device, precision, ir_version, temp_dir): + self._test(*self.create_gather_net(**params, ir_version=ir_version), + ie_device, precision, ir_version, temp_dir=temp_dir) + + test_data_nightly = [ + dict(data_shape=[2, 3], axis=1, indices=[0, 2], batch_dims=0), + dict(data_shape=[10, 12], axis=0, indices=[3, 6], batch_dims=0), + dict(data_shape=[10, 12], axis=1, indices=[[0, 1, 3, 4, 5], [6, 7, 9, 10, 11]], batch_dims=0), + dict(data_shape=[8, 10, 12], axis=0, indices=[3, 6], batch_dims=0), + dict(data_shape=[8, 10, 12], axis=-1, indices=[5, 8], batch_dims=0), + dict(data_shape=[6, 8, 10, 12], axis=0, indices=[2, 5], batch_dims=0), + dict(data_shape=[6, 8, 10, 12], axis=-1, indices=[5, 8], batch_dims=0), + dict(data_shape=[6, 8, 10, 12], axis=2, indices=[[0, 2, 4], [5, 7, 9]], batch_dims=0), + dict(data_shape=[2, 14, 10, 12], axis=1, indices=[[0, 1, 3, 4, 5], [6, 7, 9, 10, 11]], batch_dims=1), + dict(data_shape=[4, 6, 8, 10, 12], axis=0, indices=[1, 3], batch_dims=0), + dict(data_shape=[4, 6, 8, 10, 12], axis=-1, indices=[5, 8], batch_dims=0), + ] + + @pytest.mark.parametrize("params", test_data_nightly) + @pytest.mark.nightly + def test_gather_nightly(self, params, ie_device, precision, ir_version, temp_dir): + self._test(*self.create_gather_net(**params), + ie_device, precision, ir_version, temp_dir=temp_dir) diff --git a/tests/stress_tests/README.md b/tests/stress_tests/README.md index a99146ad180..cc8a2911d16 100644 --- a/tests/stress_tests/README.md +++ b/tests/stress_tests/README.md @@ -12,8 +12,8 @@ when executing continuously. - StressUnitTests executing various Inference Engine use cases in parallel threads and processes. -Each test refers to configuration files located in `\local_configs` -folder. The configuration files are installed along with tests on build time. +Each test refers to configuration files located in `\.automation` +folder. ## Getting Started diff --git a/tests/stress_tests/memcheck_tests/CMakeLists.txt b/tests/stress_tests/memcheck_tests/CMakeLists.txt index 22661277511..7de857dd2a7 100644 --- a/tests/stress_tests/memcheck_tests/CMakeLists.txt +++ b/tests/stress_tests/memcheck_tests/CMakeLists.txt @@ -16,8 +16,3 @@ target_link_libraries(${TARGET_NAME} PRIVATE StressTestsCommon) install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL) -# Copy local configs to BIN_FOLDER -configure_file(local_configs/test_config.xml - ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/stress_tests_configs/memcheck_tests/test_config.xml COPYONLY) -configure_file(local_configs/references_config.xml - ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/stress_tests_configs/memcheck_tests/references_config.xml COPYONLY) diff --git a/tests/stress_tests/memcheck_tests/local_configs/references_config.xml b/tests/stress_tests/memcheck_tests/local_configs/references_config.xml deleted file mode 100644 index 3c2c5213ff1..00000000000 --- a/tests/stress_tests/memcheck_tests/local_configs/references_config.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/stress_tests/memcheck_tests/local_configs/test_config.xml b/tests/stress_tests/memcheck_tests/local_configs/test_config.xml deleted file mode 100644 index cbb163c0a48..00000000000 --- a/tests/stress_tests/memcheck_tests/local_configs/test_config.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - CPU - GPU - - - - - - - - - diff --git a/tests/stress_tests/memleaks_tests/CMakeLists.txt b/tests/stress_tests/memleaks_tests/CMakeLists.txt index da395c4d9fd..e62a9413110 100644 --- a/tests/stress_tests/memleaks_tests/CMakeLists.txt +++ b/tests/stress_tests/memleaks_tests/CMakeLists.txt @@ -15,6 +15,3 @@ target_link_libraries(${TARGET_NAME} PRIVATE StressTestsCommon) install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL) -# Copy local configs to BIN_FOLDER -configure_file(local_configs/test_config.xml - ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/stress_tests_configs/memleaks_tests/test_config.xml COPYONLY) diff --git a/tests/stress_tests/memleaks_tests/local_configs/test_config.xml b/tests/stress_tests/memleaks_tests/local_configs/test_config.xml deleted file mode 100644 index ce92ba10d50..00000000000 --- a/tests/stress_tests/memleaks_tests/local_configs/test_config.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - 1 - - - 1 - - - 30 - - - CPU - - - - - - diff --git a/tests/stress_tests/unittests/CMakeLists.txt b/tests/stress_tests/unittests/CMakeLists.txt index 3c6972f9c56..58474e6d832 100644 --- a/tests/stress_tests/unittests/CMakeLists.txt +++ b/tests/stress_tests/unittests/CMakeLists.txt @@ -14,7 +14,3 @@ target_link_libraries(${TARGET_NAME} PRIVATE StressTestsCommon) install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL) - -# Copy local configs to BIN_FOLDER -configure_file(local_configs/test_config.xml - ${OUTPUT_ROOT}/${BIN_FOLDER}/${CMAKE_BUILD_TYPE}/stress_tests_configs/unittests/test_config.xml COPYONLY) diff --git a/tests/stress_tests/unittests/local_configs/test_config.xml b/tests/stress_tests/unittests/local_configs/test_config.xml deleted file mode 100644 index aa988200a41..00000000000 --- a/tests/stress_tests/unittests/local_configs/test_config.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - 1 - - - 1 - - - 100 - - - CPU - GPU - - - - - diff --git a/thirdparty/itt_collector/sea_itt_lib/CMakeLists.txt b/thirdparty/itt_collector/sea_itt_lib/CMakeLists.txt index 30252f6fcc4..3618e8ae360 100644 --- a/thirdparty/itt_collector/sea_itt_lib/CMakeLists.txt +++ b/thirdparty/itt_collector/sea_itt_lib/CMakeLists.txt @@ -36,3 +36,6 @@ elseif(WIN32) endif() add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) + +install(TARGETS ${TARGET_NAME} + DESTINATION tests/sea_itt_lib COMPONENT itt_collector EXCLUDE_FROM_ALL)