diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ae1fbfb1b7..f9ac0862644 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ function(build_ngraph) ngraph_set(NGRAPH_UNIT_TEST_ENABLE FALSE) endif() - if(NOT (ANDROID OR WINDOWS_STORE)) + if(NOT (ANDROID OR WINDOWS_STORE OR (MSVC AND (ARM OR AARCH64)) )) ngraph_set(NGRAPH_ONNX_IMPORT_ENABLE TRUE) else() ngraph_set(NGRAPH_ONNX_IMPORT_ENABLE FALSE) diff --git a/build-instruction.md b/build-instruction.md index b17d51748d0..26651e94874 100644 --- a/build-instruction.md +++ b/build-instruction.md @@ -26,7 +26,7 @@ - [Build Steps](#build-steps-3) - [Use Custom OpenCV Builds for Inference Engine](#use-custom-opencv-builds-for-inference-engine) - [Add Inference Engine to Your Project](#add-inference-engine-to-your-project) -- [(Optional) Additional Installation Steps for the Intel® Movidius™ Neural Compute Stick and Neural Compute Stick 2](#optional-additional-installation-steps-for-the-intel-movidius-neural-compute-stick-and-neural-compute-stick-2) +- [(Optional) Additional Installation Steps for the Intel® Neural Compute Stick 2](#optional-additional-installation-steps-for-the-intel-movidius-neural-compute-stick-and-neural-compute-stick-2) - [For Linux, Raspbian Stretch* OS](#for-linux-raspbian-stretch-os) - [Next Steps](#next-steps) - [Additional Resources](#additional-resources) @@ -43,7 +43,7 @@ The open source version of Inference Engine includes the following plugins: | CPU plugin | Intel® Xeon® with Intel® AVX2 and AVX512, Intel® Core™ Processors with Intel® AVX2, Intel® Atom® Processors with Intel® SSE | | GPU plugin | Intel® Processor Graphics, including Intel® HD Graphics and Intel® Iris® Graphics | | GNA plugin | Intel® Speech Enabling Developer Kit, Amazon Alexa\* Premium Far-Field Developer Kit, Intel® Pentium® Silver processor J5005, Intel® Celeron® processor J4005, Intel® Core™ i3-8121U processor | -| MYRIAD plugin | Intel® Movidius™ Neural Compute Stick powered by the Intel® Movidius™ Myriad™ 2, Intel® Neural Compute Stick 2 powered by the Intel® Movidius™ Myriad™ X | +| MYRIAD plugin | Intel® Neural Compute Stick 2 powered by the Intel® Movidius™ Myriad™ X | | Heterogeneous plugin | Heterogeneous plugin enables computing for inference on one network on several Intel® devices. | ## Build on Linux\* Systems @@ -58,7 +58,7 @@ The software was validated on: - GCC\* 4.8 or higher to build the Inference Engine - Python 3.6 or higher for Inference Engine Python API wrapper - (Optional) [Install Intel® Graphics Compute Runtime for OpenCL™ Driver package 19.41.14441]. -> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. +> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. ### Build Steps 1. Clone submodules: @@ -129,7 +129,7 @@ You can use the following additional build options: 1. Install all additional packages listed in the `/inference-engine/ie_bridges/python/requirements.txt` file: ```sh - pip install -r requirements.txt + pip install -r requirements.txt ``` 2. Use the `-DENABLE_PYTHON=ON` option. To specify an exact Python version, use the following options: @@ -336,7 +336,7 @@ The software was validated on: - Microsoft\* Visual Studio 2017, 2019 - (Optional) Intel® Graphics Driver for Windows* (26.20) [driver package]. - Python 3.6 or higher for Inference Engine Python API wrapper -> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. +> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. ### Build Steps @@ -349,7 +349,7 @@ The software was validated on: the Intel® Graphics Driver for Windows (26.20) [driver package] before running the build. If you don't want to use the GPU plugin, use the `-DENABLE_CLDNN=OFF` CMake build option and skip the installation of the - Intel® Graphics Driver. + Intel® Graphics Driver. 3. Create build directory: ```sh mkdir build @@ -446,7 +446,7 @@ The software was validated on: - [CMake]\* 3.13 or higher - Clang\* compiler from Xcode\* 10.1 or higher - Python\* 3.6 or higher for the Inference Engine Python API wrapper -> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. +> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. ### Build Steps @@ -499,9 +499,9 @@ You can use the following additional build options: ```sh -DPYTHON_EXECUTABLE=/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/bin/python3.7m \ -DPYTHON_LIBRARY=/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib \ - -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/include/python3.7m + -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/include/python3.7m ``` - - If you installed Python another way, you can use the following commands to find where the `dylib` and `include_dir` are located, respectively: + - If you installed Python another way, you can use the following commands to find where the `dylib` and `include_dir` are located, respectively: ```sh find /usr/ -name 'libpython*m.dylib' find /usr/ -type d -name python3.7m @@ -518,7 +518,7 @@ This section describes how to build Inference Engine for Android x86 (64-bit) op - [CMake]\* 3.13 or higher - Android NDK (this guide has been validated with r20 release) -> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. +> **NOTE**: Building samples and demos from the Intel® Distribution of OpenVINO™ toolkit package requires CMake\* 3.10 or higher. ### Build Steps @@ -608,11 +608,11 @@ include_directories(${InferenceEngine_INCLUDE_DIRS}) target_link_libraries(${PROJECT_NAME} ${InferenceEngine_LIBRARIES} dl) ``` -## (Optional) Additional Installation Steps for the Intel® Movidius™ Neural Compute Stick and Neural Compute Stick 2 +## (Optional) Additional Installation Steps for the Intel® Neural Compute Stick 2 -> **NOTE**: These steps are only required if you want to perform inference on -Intel® Movidius™ Neural Compute Stick or the Intel® Neural Compute Stick 2 using -the Inference Engine MYRIAD Plugin. See also [Intel® Neural Compute Stick 2 Get Started]. +> **NOTE**: These steps are only required if you want to perform inference on the +Intel® Neural Compute Stick 2 using the Inference Engine MYRIAD Plugin. See also +[Intel® Neural Compute Stick 2 Get Started]. ### For Linux, Raspbian\* Stretch OS @@ -622,11 +622,10 @@ the Inference Engine MYRIAD Plugin. See also [Intel® Neural Compute Stick 2 Get sudo usermod -a -G users "$(whoami)" ``` -2. To perform inference on Intel® Movidius™ Neural Compute Stick and Intel® - Neural Compute Stick 2, install the USB rules as follows: +2. To perform inference on Intel® Neural Compute Stick 2, install the USB rules +as follows: ```sh cat < 97-myriad-usbboot.rules -SUBSYSTEM=="usb", ATTRS{idProduct}=="2150", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1" SUBSYSTEM=="usb", ATTRS{idProduct}=="2485", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1" SUBSYSTEM=="usb", ATTRS{idProduct}=="f63b", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1" EOF diff --git a/cmake/check_features.cmake b/cmake/check_features.cmake index 798d46b71f6..693227097ea 100644 --- a/cmake/check_features.cmake +++ b/cmake/check_features.cmake @@ -15,10 +15,6 @@ else() SET(ARCH_64 OFF) endif() -if (NOT ENABLE_MKL_DNN) - set(ENABLE_MKL OFF) -endif() - if(ENABLE_AVX512F) if ((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") AND (MSVC_VERSION VERSION_LESS 1920)) # 1920 version of MSVC 2019. In MSVC 2017 AVX512F not work diff --git a/cmake/developer_package.cmake b/cmake/developer_package.cmake index e8f69668568..cda7afd2940 100644 --- a/cmake/developer_package.cmake +++ b/cmake/developer_package.cmake @@ -4,10 +4,27 @@ cmake_minimum_required(VERSION 3.13) +# Detect target +include(target_flags) + +string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} ARCH_FOLDER) +if(X86_64) + set(ARCH_FOLDER intel64) +elseif(X86) + set(ARCH_FOLDER ia32) +elseif(MSVC AND ARM) + set(ARCH_FOLDER arm) +elseif(MSVC AND AARCH64) + set(ARCH_FOLDER arm64) +endif() + list(APPEND CMAKE_MODULE_PATH "${OpenVINO_MAIN_SOURCE_DIR}/cmake/download" - "${OpenVINO_MAIN_SOURCE_DIR}/cmake/cross_compile" - ) + "${OpenVINO_MAIN_SOURCE_DIR}/cmake/cross_compile") + +# +# CPack +# include(CPackComponent) unset(IE_CPACK_COMPONENTS_ALL CACHE) @@ -33,21 +50,14 @@ endif() # Set library directory for cpack # function(ie_cpack_set_library_dir) - string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} ARCH) - if(ARCH STREQUAL "x86_64" OR ARCH STREQUAL "amd64") # Windows detects Intel's 64-bit CPU as AMD64 - set(ARCH intel64) - elseif(ARCH STREQUAL "i386") - set(ARCH ia32) - endif() - if(WIN32) - set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) - set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) - set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) + set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) + set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/bin/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) + set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER}/${CMAKE_BUILD_TYPE} PARENT_SCOPE) else() - set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH} PARENT_SCOPE) - set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH} PARENT_SCOPE) - set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH} PARENT_SCOPE) + set(IE_CPACK_LIBRARY_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE) + set(IE_CPACK_RUNTIME_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE) + set(IE_CPACK_ARCHIVE_PATH ${IE_CPACK_IE_DIR}/lib/${ARCH_FOLDER} PARENT_SCOPE) endif() endfunction() @@ -109,28 +119,19 @@ function(set_temp_directory temp_variable source_tree_dir) endif() endfunction() +# +# Common scripts +# + include(coverage/coverage) include(shellcheck/shellcheck) # External dependencies find_package(Threads) -# Detect target -include(target_flags) - # printing debug messages include(debug) -# linking libraries without discarding symbols -include(whole_archive) - -string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} ARCH_FOLDER) -if(X86_64) - set(ARCH_FOLDER intel64) -elseif(X86) - set(ARCH_FOLDER ia32) -endif() - if(OS_FOLDER) message ("**** OS FOLDER IS: [${OS_FOLDER}]") if("${OS_FOLDER}" STREQUAL "ON") @@ -237,6 +238,7 @@ include(os_flags) include(sanitizer) include(cross_compiled_func) include(faster_build) +include(whole_archive) include(api_validator/api_validator) function(set_ci_build_number) diff --git a/cmake/features.cmake b/cmake/features.cmake index 91d30c4a6ac..e25d72f610e 100644 --- a/cmake/features.cmake +++ b/cmake/features.cmake @@ -17,11 +17,11 @@ ie_option (ENABLE_TESTS "unit, behavior and functional tests" OFF) ie_option (ENABLE_MKL_DNN "MKL-DNN plugin for inference engine" ${ENABLE_MKL_DNN_DEFAULT}) -ie_dependent_option (ENABLE_CLDNN "clDnn based plugin for inference engine" ON "WIN32 OR X86_64;NOT APPLE;NOT MINGW;NOT WINDOWS_STORE; NOT WINDOWS_PHONE" OFF) +ie_dependent_option (ENABLE_CLDNN "clDnn based plugin for inference engine" ON "X86_64;NOT APPLE;NOT MINGW;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" OFF) # FIXME: there are compiler failures with LTO and Cross-Compile toolchains. Disabling for now, but # this must be addressed in a proper way -ie_dependent_option (ENABLE_LTO "Enable Link Time Optimization" OFF "LINUX OR WIN32;NOT CMAKE_CROSSCOMPILING; CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9" OFF) +ie_dependent_option (ENABLE_LTO "Enable Link Time Optimization" OFF "LINUX;NOT CMAKE_CROSSCOMPILING; CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9" OFF) ie_option (OS_FOLDER "create OS dedicated folder in output" OFF) diff --git a/cmake/os_flags.cmake b/cmake/os_flags.cmake index c91aaa93358..09ae20a9a3e 100644 --- a/cmake/os_flags.cmake +++ b/cmake/os_flags.cmake @@ -127,8 +127,10 @@ function(ie_avx512_optimization_flags flags) endfunction() function(ie_arm_neon_optimization_flags flags) - if(WIN32 OR CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") message(WARNING "Unsupported CXX compiler ${CMAKE_CXX_COMPILER_ID}") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # nothing elseif(ANDROID) if(ANDROID_ABI STREQUAL "arm64-v8a") set(${flags} "-mfpu=neon" PARENT_SCOPE) diff --git a/cmake/target_flags.cmake b/cmake/target_flags.cmake index c51e0df8adb..030fcbfea96 100644 --- a/cmake/target_flags.cmake +++ b/cmake/target_flags.cmake @@ -16,10 +16,25 @@ if(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") endif() endif() +macro(_ie_process_msvc_generator_platform flag_name) + # if cmake -A is passed + if(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + set(AARCH64 ON) + elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") + set(ARM ON) + elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64") + set(X86_64 ON) + elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32") + set(X86 ON) + else() + set(${flag_name} ON) + endif() +endmacro() + if(MSVC64 OR MINGW64) - set(X86_64 ON) + _ie_process_msvc_generator_platform(X86_64) elseif(MINGW OR (MSVC AND NOT CMAKE_CROSSCOMPILING)) - set(X86 ON) + _ie_process_msvc_generator_platform(X86) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") set(X86_64 ON) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*") diff --git a/cmake/vs_version/vs_version.cmake b/cmake/vs_version/vs_version.cmake index 7b9f45f96db..d857e2e4bcc 100644 --- a/cmake/vs_version/vs_version.cmake +++ b/cmake/vs_version/vs_version.cmake @@ -7,15 +7,15 @@ macro(ie_parse_ci_build_number) set(IE_VERSION_MAJOR ${CMAKE_MATCH_1}) set(IE_VERSION_MINOR ${CMAKE_MATCH_2}) set(IE_VERSION_PATCH ${CMAKE_MATCH_3}) - set(IE_VS_VER_HAS_WELL_DEFINED_VERSION 1) + set(IE_VS_VER_HAS_VERSION 1) else() - set(IE_VS_VER_HAS_WELL_DEFINED_VERSION 0) + set(IE_VS_VER_HAS_VERSION 0) endif() endmacro() ie_parse_ci_build_number() -if(IE_VS_VER_HAS_WELL_DEFINED_VERSION) +if(IE_VS_VER_HAS_VERSION) set(IE_VS_VER_FILEVERSION_QUAD "${IE_VERSION_MAJOR},${IE_VERSION_MINOR},${IE_VERSION_PATCH},0") set(IE_VS_VER_PRODUCTVERSION_QUAD "${IE_VERSION_MAJOR},${IE_VERSION_MINOR},${IE_VERSION_PATCH},0") set(IE_VS_VER_FILEVERSION_STR "${IE_VERSION_MAJOR}.${IE_VERSION_MINOR}.${IE_VERSION_PATCH}.0") diff --git a/cmake/vs_version/vs_version.rc.in b/cmake/vs_version/vs_version.rc.in index 96b545fdb7b..037247e0061 100644 --- a/cmake/vs_version/vs_version.rc.in +++ b/cmake/vs_version/vs_version.rc.in @@ -1,7 +1,7 @@ #include VS_VERSION_INFO VERSIONINFO -#if IE_VS_VER_HAS_WELL_DEFINED_VERSION +#if @IE_VS_VER_HAS_VERSION@ FILEVERSION @IE_VS_VER_FILEVERSION_QUAD@ PRODUCTVERSION @IE_VS_VER_PRODUCTVERSION_QUAD@ #endif @@ -20,7 +20,7 @@ BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", "@IE_VS_VER_FILEDESCRIPTION_STR@\0" -#if IE_VS_VER_HAS_WELL_DEFINED_VERSION +#if @IE_VS_VER_HAS_VERSION@ VALUE "FileVersion", "@IE_VS_VER_FILEVERSION_STR@\0" #endif VALUE "InternalName", "@IE_VS_VER_INTERNALNAME_STR@\0" diff --git a/docs/IE_DG/Deep_Learning_Inference_Engine_DevGuide.md b/docs/IE_DG/Deep_Learning_Inference_Engine_DevGuide.md index 20f415a7317..25c14035144 100644 --- a/docs/IE_DG/Deep_Learning_Inference_Engine_DevGuide.md +++ b/docs/IE_DG/Deep_Learning_Inference_Engine_DevGuide.md @@ -10,7 +10,7 @@ and mixed-reality headsets. The OpenVINO™ toolkit: * Enables CNN-based deep learning inference on the edge -* Supports heterogeneous execution across an Intel® CPU, Intel® Integrated Graphics, Intel® Movidius™ Neural Compute Stick and Intel® Neural Compute Stick 2 +* Supports heterogeneous execution across an Intel® CPU, Intel® Integrated Graphics, Intel® Neural Compute Stick 2 * Speeds time-to-market via an easy-to-use library of computer vision functions and pre-optimized kernels * Includes optimized calls for computer vision standards including OpenCV\*, OpenCL™, and OpenVX\* @@ -35,7 +35,7 @@ optimized for running on Intel® hardware (CPU, GPU, IPU). This Guide provides overview of the Inference Engine describing the typical workflow for performing inference of a pre-trained and optimized deep learning model and a set of sample applications. -> **NOTES:** +> **NOTES:** > - Before you perform inference with the Inference Engine, your models should be converted to the Inference Engine format using the Model Optimizer or built directly in run-time using nGraph API. To learn about how to use Model Optimizer, refer to the [Model Optimizer Developer Guide](../MO_DG/Deep_Learning_Model_Optimizer_DevGuide.md). To learn about the pre-trained and optimized models delivered with the OpenVINO™ toolkit, refer to [Pre-Trained Models](@ref omz_models_intel_index). > - [Intel® System Studio](https://software.intel.com/en-us/system-studio) is an all-in-one, cross-platform tool suite, purpose-built to simplify system bring-up and improve system and IoT device application performance on Intel® platforms. If you are using the Intel® Distribution of OpenVINO™ with Intel® System Studio, go to [Get Started with Intel® System Studio](https://software.intel.com/en-us/articles/get-started-with-openvino-and-intel-system-studio-2019). diff --git a/docs/IE_DG/supported_plugins/MYRIAD.md b/docs/IE_DG/supported_plugins/MYRIAD.md index 3b1c3ec018c..df9c68da503 100644 --- a/docs/IE_DG/supported_plugins/MYRIAD.md +++ b/docs/IE_DG/supported_plugins/MYRIAD.md @@ -2,7 +2,7 @@ ## Introducing MYRIAD Plugin -The Inference Engine MYRIAD plugin is developed for inference of neural networks on Intel® Movidius™ Neural Compute Stick and Intel® Neural Compute Stick 2. +The Inference Engine MYRIAD plugin is developed for inference of neural networks on Intel® Neural Compute Stick 2. ## Installation on Linux* OS @@ -23,10 +23,10 @@ The Inference Engine MYRIAD plugin supports the following networks: * GoogleNet (Inception) v1, v2, v4 * VGG family (VGG16, VGG19) * SqueezeNet v1.0, v1.1 -* ResNet v1 family (18\*\* \*\*\*, 50, 101, 152) +* ResNet v1 family (18\*\*\*, 50, 101, 152) * MobileNet (mobilenet-v1-1.0-224, mobilenet-v2) * Inception ResNet v2 -* DenseNet family\*\* (121,161,169,201) +* DenseNet family (121,161,169,201) * SSD-300, SSD-512, SSD-MobileNet, SSD-GoogleNet, SSD-SqueezeNet **TensorFlow\***: @@ -45,7 +45,7 @@ The Inference Engine MYRIAD plugin supports the following networks: **MXNet\***: * AlexNet and CaffeNet -* DenseNet family\*\* (121,161,169,201) +* DenseNet family (121,161,169,201) * SqueezeNet v1.1 * MobileNet v1, v2 * NiN @@ -55,8 +55,6 @@ The Inference Engine MYRIAD plugin supports the following networks: * VGG family (VGG16, VGG19) * SSD-Inception-v3, SSD-MobileNet, SSD-ResNet-50, SSD-300 -\*\* Network is tested on Intel® Movidius™ Neural Compute Stick with BatchNormalization fusion optimization disabled during Model Optimizer import - \*\*\* Network is tested on Intel® Neural Compute Stick 2 with BatchNormalization fusion optimization disabled during Model Optimizer import ## Supported Configuration Parameters @@ -77,9 +75,9 @@ In addition to common parameters, the MYRIAD plugin accepts the following option ## Device allocation   Each `IExecutableNetwork` instance tries to allocate new device on `InferenceEngine::Core::LoadNetwork`, but if all available devices are already allocated it will use the one with the minimal number of uploaded networks. -The maximum number of networks single device can handle depends on device memory capacity and the size of the networks. +The maximum number of networks single device can handle depends on device memory capacity and the size of the networks. -If `KEY_VPU_MYRIAD_FORCE_RESET` option is set to `YES` the plugin will reset all VPU devices in the system. +If `KEY_VPU_MYRIAD_FORCE_RESET` option is set to `YES` the plugin will reset all VPU devices in the system. Single device cannot be shared across multiple processes. diff --git a/docs/MO_DG/prepare_model/convert_model/tf_specific/Convert_EfficientDet_Models.md b/docs/MO_DG/prepare_model/convert_model/tf_specific/Convert_EfficientDet_Models.md new file mode 100644 index 00000000000..c58de18d847 --- /dev/null +++ b/docs/MO_DG/prepare_model/convert_model/tf_specific/Convert_EfficientDet_Models.md @@ -0,0 +1,96 @@ +# Converting EfficientDet Models from TensorFlow {#openvino_docs_MO_DG_prepare_model_convert_model_tf_specific_Convert_EfficientDet_Models} + +This tutorial explains how to convert detection EfficientDet\* public models to the Intermediate Representation (IR). + +## Convert EfficientDet Model to IR + +On GitHub*, you can find several public versions of EfficientDet model implementation. This tutorial explains how to +convert models from the [https://github.com/google/automl/tree/master/efficientdet](https://github.com/google/automl/tree/master/efficientdet) +repository (commit 96e1fee) to IR. + +### Get Frozen TensorFlow\* Model + +Follow the instructions below to get frozen TensorFlow EfficientDet model. We use EfficientDet-D4 model as an example: + +1. Clone the repository:
+```sh +git clone https://github.com/google/automl +cd automl/efficientdet +``` +2. (Optional) Checkout to the commit that the conversion was tested on:
+```sh +git checkout 96e1fee +``` +3. Install required dependencies:
+```sh +python3 -m pip install --upgrade pip +python3 -m pip install -r automl/efficientdet/requirements.txt +``` +4. Download and extract the model checkpoint [efficientdet-d4.tar.gz](https://storage.googleapis.com/cloud-tpu-checkpoints/efficientdet/coco2/efficientdet-d4.tar.gz) +referenced in the "Pretrained EfficientDet Checkpoints" section of the model repository:
+```sh +wget https://storage.googleapis.com/cloud-tpu-checkpoints/efficientdet/coco2/efficientdet-d4.tar.gz +tar zxvf efficientdet-d4.tar.gz +``` +5. Freeze the model:
+```sh +python3 model_inspect.py --runmode=saved_model --model_name=efficientdet-d4 --ckpt_path=efficientdet-d4 --saved_model_dir=savedmodeldir +``` +As a result the frozen model file `savedmodeldir/efficientdet-d4_frozen.pb` will be generated. + +> **NOTE:** If you see an error `AttributeError: module 'tensorflow_core.python.keras.api._v2.keras.initializers' has no attribute 'variance_scaling'` apply the fix from the [patch](https://github.com/google/automl/pull/846). + +### Convert EfficientDet TensorFlow Model to the IR + +To generate the IR of the EfficientDet TensorFlow model, run:
+```sh +python3 $MO_ROOT/mo.py \ +--input_model savedmodeldir/efficientdet-d4_frozen.pb \ +--tensorflow_use_custom_operations_config $MO_ROOT/extensions/front/tf/automl_efficientdet.json \ +--input_shape [1,$IMAGE_SIZE,$IMAGE_SIZE,3] \ +--reverse_input_channels +``` + +Where `$IMAGE_SIZE` is the size that the input image of the original TensorFlow model will be resized to. Different +EfficientDet models were trained with different input image sizes. To determine the right one refer to the `efficientdet_model_param_dict` +dictionary in the [hparams_config.py](https://github.com/google/automl/blob/96e1fee/efficientdet/hparams_config.py#L304) file. +The attribute `image_size` specifies the shape to be specified for the model conversion. + +The `tensorflow_use_custom_operations_config` command line parameter specifies the configuration json file containing hints +to the Model Optimizer on how to convert the model and trigger transformations implemented in the +`$MO_ROOT/extensions/front/tf/AutomlEfficientDet.py`. The json file contains some parameters which must be changed if you +train the model yourself and modified the `hparams_config` file or the parameters are different from the ones used for EfficientDet-D4. +The attribute names are self-explanatory or match the name in the `hparams_config` file. + +> **NOTE:** The color channel order (RGB or BGR) of an input data should match the channel order of the model training dataset. If they are different, perform the `RGB<->BGR` conversion specifying the command-line parameter: `--reverse_input_channels`. Otherwise, inference results may be incorrect. For more information about the parameter, refer to **When to Reverse Input Channels** section of [Converting a Model Using General Conversion Parameters](../Converting_Model_General.md). + +OpenVINO™ toolkit provides samples that can be used to infer EfficientDet model. For more information, refer to +[Object Detection for SSD C++ Sample](@ref openvino_inference_engine_samples_object_detection_sample_ssd_README) and +[Object Detection for SSD Python Sample](@ref openvino_inference_engine_ie_bridges_python_sample_object_detection_sample_ssd_README). + +## Interpreting Results of the TensorFlow Model and the IR + +The TensorFlow model produces as output a list of 7-element tuples: `[image_id, y_min, x_min, y_max, x_max, confidence, class_id]`, where: +* `image_id` -- image batch index. +* `y_min` -- absolute `y` coordinate of the lower left corner of the detected object. +* `x_min` -- absolute `x` coordinate of the lower left corner of the detected object. +* `y_max` -- absolute `y` coordinate of the upper right corner of the detected object. +* `x_max` -- absolute `x` coordinate of the upper right corner of the detected object. +* `confidence` -- is the confidence of the detected object. +* `class_id` -- is the id of the detected object class counted from 1. + +The output of the IR is a list of 7-element tuples: `[image_id, class_id, confidence, x_min, y_min, x_max, y_max]`, where: +* `image_id` -- image batch index. +* `class_id` -- is the id of the detected object class counted from 0. +* `confidence` -- is the confidence of the detected object. +* `x_min` -- normalized `x` coordinate of the lower left corner of the detected object. +* `y_min` -- normalized `y` coordinate of the lower left corner of the detected object. +* `x_max` -- normalized `x` coordinate of the upper right corner of the detected object. +* `y_max` -- normalized `y` coordinate of the upper right corner of the detected object. + +The first element with `image_id = -1` means end of data. + +--- +## See Also + +* [Sub-Graph Replacement in Model Optimizer](../../customize_model_optimizer/Subgraph_Replacement_Model_Optimizer.md) diff --git a/docs/doxygen/ie_docs.xml b/docs/doxygen/ie_docs.xml index 40fd30de555..996a43c0c8b 100644 --- a/docs/doxygen/ie_docs.xml +++ b/docs/doxygen/ie_docs.xml @@ -22,6 +22,7 @@ + diff --git a/docs/install_guides/VisionAcceleratorFPGA_Configure_2018R5.md b/docs/install_guides/VisionAcceleratorFPGA_Configure_2018R5.md index 7f99be9a57e..1eecf13c6d8 100644 --- a/docs/install_guides/VisionAcceleratorFPGA_Configure_2018R5.md +++ b/docs/install_guides/VisionAcceleratorFPGA_Configure_2018R5.md @@ -22,12 +22,12 @@ A directory named `fpga_support_files` is created. ```sh cd fpga_support_files ``` - + 5. Source `setup_env.sh` to set your environment variables: ```sh source /home//Downloads/fpga_support_files/setup_env.sh ``` - + 6. Configure the FPGA Driver Blacklist: ```sh sudo mv config/blacklist-altera-cvp.conf /etc/modprobe.d @@ -37,41 +37,41 @@ sudo mv config/blacklist-altera-cvp.conf /etc/modprobe.d ```sh sudo su ``` - + 8. Use the `setup_env.sh` script from `fpga_support_files.tgz` to set your environment variables: ```sh source /home//Downloads/fpga_support_files/setup_env.sh ``` - + 9. Change directory to `Downloads/fpga_support_files/`: ```sh cd /home//Downloads/fpga_support_files/ ``` - + 10. Run the FPGA dependencies script, which allows OpenCL to support Ubuntu* and recent kernels: ```sh ./install_openvino_fpga_dependencies.sh ``` -11. When asked, select the FPGA card, Intel® GPU, and Intel® Movidius™ Neural Compute Stick, then you can install the correct dependencies. +11. When asked, select the FPGA card, Intel® GPU, and Intel® Neural Compute Stick 2, then you can install the correct dependencies. 12. If you installed the 4.14 kernel as part of the installation script, you will need to reboot the machine and select the new kernel in the Ubuntu (grub) boot menu. You will also need to rerun `setup_env.sh` to set up your environmental variables again. - + 13. Install OpenCL™ devices. Enter **Y** when prompted to install: ```sh aocl install ``` - + 14. Reboot the machine: ```sh reboot ``` - + 15. Use the `setup_env.sh` script from `fpga_support_files.tgz` to set your environment variables: ```sh source /home//Downloads/fpga_support_files/setup_env.sh ``` - + 16. Run `aocl diagnose`: ```sh aocl diagnose @@ -93,21 +93,21 @@ cd /home//Downloads/fpga_support_files/config/ ```sh sudo cp -rf a10_1150_sg1 /opt/altera/aocl-pro-rte/aclrte-linux64/board/ ``` - + 3. Convert the BSP files from DOS to UNIX: ```sh sudo chmod +x a10_1150_sg1 find a10_1150_sg1 -type f -print0 | xargs -0 dos2unix ``` - + 4. Set up the USB Blaster: - + 1. Connect the cable between the board and the host system. Use the letter codes in the diagram below for the connection points: - + 2. Connect the B end of the cable to point B on the board. 3. Connect the F end of the cable to point F on the FPGA download cable. - + 4. From point F end of the cable to point F on the FPGA download cable, the connection is as shown: ![](../img/VisionAcceleratorJTAG.png) @@ -115,17 +115,17 @@ find a10_1150_sg1 -type f -print0 | xargs -0 dos2unix ```sh source /home//Downloads/fpga_support_files/setup_env.sh ``` - -6. Update the Intel® FPGA Download Cable rules to program the board without root permissions and to flash the initialization bitstreams so that the Intel® FPGA Download Cable can communicate with the board: + +6. Update the Intel® FPGA Download Cable rules to program the board without root permissions and to flash the initialization bitstreams so that the Intel® FPGA Download Cable can communicate with the board: ```sh sudo cp config/51-usbblaster.rules /etc/udev/rules.d ``` - + 7. Load the USB rules: ```sh sudo udevadm control --reload-rules && udevadm trigger ``` - + 8. Unplug and re-plug the Intel® FPGA Download Cable to enable JTAG connection. 9. Run `jtagconfig` to ensure that your Intel FPGA Download Cable driver is ready to use: @@ -135,22 +135,22 @@ jtagconfig Your output is similar to: ```sh 1) USB-Blaster [1-6] -02E660DD 10AX115H1(.|E2|ES)/10AX115H2/.. +02E660DD 10AX115H1(.|E2|ES)/10AX115H2/.. ``` 10. Download [Intel® Quartus® Prime Software Lite Edition 17.1](http://fpgasoftware.intel.com/17.1/?edition=lite). Install the Intel® Quartus® Prime Software Lite to the `/home//intelFPGA/17.1` directory. > **NOTE**: You will need the complete the Intel® Quartus® Prime Software Lite version when you want to program the `boardtest_1ddr_top.aocx` into the flash for permanent availability. - + 11. Export the Intel® Quartus® Prime Software Lite environment variable: ```sh export QUARTUS_ROOTDIR=/home//intelFPGA/17.1/quartus ``` - + 12. Use `jtagconfig` to slow the clock: ```sh jtagconfig --setparam 1 JtagClock 6M ``` - + 13. (OPTIONAL) Confirm the clock is set to 6M: ```sh jtagconfig --getparam 1 JtagClock @@ -164,7 +164,7 @@ You should see the following: ```sh cd /opt/altera/aocl-pro-rte/aclrte-linux64/board/a10_1150_sg1/bringup ``` - + 15. Program the `boardtest_1ddr_top.aocx` file to the flash to be made permanently available even after power cycle: ```sh aocl flash acl0 boardtest_1ddr_top.aocx @@ -186,12 +186,12 @@ Your output is similar to: ```sh source /home//Downloads/fpga_support_file/setup_env.sh ``` - + 19. Uninstall the previous BSP before installing the OpenCL drivers for the R5 BSP: ```sh aocl uninstall /opt/altera/aocl-pro-rte/aclrte-linux64/board// ``` - + 20. Export and source the environment script: ```sh export AOCL_BOARD_PACKAGE_ROOT=/opt/altera/aocl-pro-rte/aclrte-linux64/board/a10_1150_sg1 @@ -204,13 +204,13 @@ source /opt/altera/aocl-pro-rte/aclrte-linux64/init_opencl.sh ```sh aocl install ``` - + 22. Run the `diagnose` command: ```sh aocl diagnose ``` You should see `DIAGNOSTIC_PASSED` before proceeding to the next steps. - + ## 3. Program a Bitstream The bitstream you program should correspond to the topology you want to deploy. In this section, you program a SqueezeNet bitstream and deploy the classification sample with a SqueezeNet model that you used the Model Optimizer to convert in the steps before. @@ -225,17 +225,17 @@ Depending on how many bitstreams you selected, there are different folders for e ```sh source /home//Downloads/fpga_support_files/setup_env.sh ``` - + 3. Change to your home directory: ```sh cd /home/ ``` - + 4. Program the bitstream for the Intel® Vision Accelerator Design with Intel® Arria® 10 FPGA: ```sh aocl program acl0 /opt/intel/openvino/bitstreams/a10_vision_design_bitstreams/5-0_PL1_FP11_SqueezeNet.aocx ``` - + ### Optional Steps to Flash the FPGA Card > **NOTE**: @@ -248,12 +248,12 @@ aocl program acl0 /opt/intel/openvino/bitstreams/a10_vision_design_bitstreams/5- ```sh jtagconfig ``` - + 3. Use `jtagconfig` to slow the clock: ```sh jtagconfig --setparam 1 JtagClock 6M ``` - + 4. Store the Intel® Vision Accelerator Design with Intel® Arria® 10 FPGA bistream on the board: ```sh aocl flash acl0 /opt/intel/openvino/bitstreams/a10_vision_design_bitstreams/5-0_PL1_FP11_SqueezeNet.aocx @@ -274,27 +274,27 @@ In this section, you will create an FP16 model suitable for hardware accelerator ```sh mkdir /home//squeezenet1.1_FP16 ``` - + 2. Go to `/home//squeezenet1.1_FP16`: ```sh cd /home//squeezenet1.1_FP16 ``` - + 3. Use the Model Optimizer to convert an FP16 SqueezeNet Caffe* model into an optimized Intermediate Representation (IR): ```sh python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo.py --input_model /home//openvino_models/FP32/classification/squeezenet/1.1/caffe/squeezenet1.1.caffemodel --data_type FP16 --output_dir . ``` - + 4. The `squeezenet1.1.labels` file contains the classes `ImageNet` uses. This file is included so that the inference results show text instead of classification numbers. Copy `squeezenet1.1.labels` to the your optimized model location: ```sh cp /home//openvino_models/ir/squeezenet1.1/FP32/squeezenet1.1.labels . ``` - + 5. Copy a sample image to the release directory. You will use this with your optimized model: ```sh sudo cp /opt/intel/openvino/deployment_tools/demo/car.png ~/inference_engine_samples/intel64/Release ``` - + ## 5. Run a Sample Application 1. Go to the samples directory diff --git a/docs/install_guides/installing-openvino-pip.md b/docs/install_guides/installing-openvino-pip.md index 58c71900210..1c7fd0cda26 100644 --- a/docs/install_guides/installing-openvino-pip.md +++ b/docs/install_guides/installing-openvino-pip.md @@ -13,55 +13,64 @@ This guide provides installation steps for the Intel® distribution of OpenVINO ## Install the Runtime Package Using the PyPI Repository -1. Set up and update pip to the highest version: - ```sh - python3 -m pip install --upgrade pip - ``` -2. Install the Intel® distribution of OpenVINO™ toolkit: +### Step 1. Set up and update pip to the highest version + +Run the command below: +```sh +python3 -m pip install --upgrade pip +``` + +### Step 2. Install the Intel® distribution of OpenVINO™ toolkit + +Run the command below: ```sh pip install openvino-python ``` -3. Add PATH to environment variables. - - Ubuntu* 18.04 and macOS*: - ```sh - export LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} - ``` - - Windows* 10: - ```sh - set PATH=;%PATH% - ``` - How to find `library_dir`: - - Ubuntu\*, macOS\*: - - Standard user: - ```sh - echo $(python3 -m site --user-base)/lib - ``` - - Root or sudo user: - ```sh - /usr/local/lib - ``` - - Virtual environments or custom Python installations (from sources or tarball): - ```sh - echo $(which python3)/../../lib - ``` - - Windows\*: - - Standard Python: - ```sh - python -c "import os, sys; print((os.path.dirname(sys.executable))+'\Library\\bin')" - ``` - - Virtual environments or custom Python installations (from sources or tarball): - ```sh - python -c "import os, sys; print((os.path.dirname(sys.executable))+'\..\Library\\bin')" - ``` -4. Verify that the package is installed: - ```sh - python3 -c "import openvino" - ``` +### Step 3. Add PATH to environment variables + +Run a command for your operating system: +- Ubuntu 18.04 and macOS: +```sh +export LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} +``` +- Windows* 10: +```sh +set PATH=;%PATH% +``` +To find `library_dir`: +**Ubuntu, macOS**: +- Standard user: +```sh +echo $(python3 -m site --user-base)/lib +``` +- Root or sudo user: +```sh +/usr/local/lib +``` +- Virtual environments or custom Python installations (from sources or tarball): +```sh +echo $(which python3)/../../lib +``` +**Windows**: +- Standard Python: +```sh +python -c "import os, sys; print((os.path.dirname(sys.executable))+'\Library\\bin')" +``` +- Virtual environments or custom Python installations (from sources or tarball): +```sh +python -c "import os, sys; print((os.path.dirname(sys.executable))+'\..\Library\\bin')" +``` + +### Step 4. Verify that the package is installed + +Run the command below: +```sh +python3 -c "import openvino" +``` Now you are ready to develop and run your application. - ## Additional Resources - [Intel® Distribution of OpenVINO™ toolkit](https://software.intel.com/en-us/openvino-toolkit). diff --git a/docs/template_plugin/tests/functional/shared_tests_instances/single_layer_tests/split.cpp b/docs/template_plugin/tests/functional/shared_tests_instances/single_layer_tests/split.cpp index 57485249ee3..fdb1901dbb3 100644 --- a/docs/template_plugin/tests/functional/shared_tests_instances/single_layer_tests/split.cpp +++ b/docs/template_plugin/tests/functional/shared_tests_instances/single_layer_tests/split.cpp @@ -20,7 +20,9 @@ INSTANTIATE_TEST_CASE_P(NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({})), ::testing::Values("TEMPLATE")), SplitLayerTest::getTestCaseName); + } // namespace diff --git a/inference-engine/cmake/dependencies.cmake b/inference-engine/cmake/dependencies.cmake index 216d943f9f9..f8637647dad 100644 --- a/inference-engine/cmake/dependencies.cmake +++ b/inference-engine/cmake/dependencies.cmake @@ -185,7 +185,7 @@ if (ENABLE_OPENCV) set(OPENCV_BUILD "36") set(OPENCV_BUILD_YOCTO "337") - if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + if (AARCH64) if(DEFINED ENV{THIRDPARTY_SERVER_PATH}) set(IE_PATH_TO_DEPS "$ENV{THIRDPARTY_SERVER_PATH}") elseif(DEFINED THIRDPARTY_SERVER_PATH) @@ -220,10 +220,10 @@ if (ENABLE_OPENCV) ENVIRONMENT "OpenCV_DIR" VERSION_REGEX ".*_([0-9]+.[0-9]+.[0-9]+).*") elseif(LINUX) - if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + if (AARCH64) set(OPENCV_SUFFIX "yocto_kmb") set(OPENCV_BUILD "${OPENCV_BUILD_YOCTO}") - elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") + elseif (ARM) set(OPENCV_SUFFIX "debian9arm") elseif (LINUX_OS_NAME STREQUAL "CentOS 7" OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9") set(OPENCV_SUFFIX "centos7") diff --git a/inference-engine/cmake/features_ie.cmake b/inference-engine/cmake/features_ie.cmake index ded5e71b66e..df4105ccf33 100644 --- a/inference-engine/cmake/features_ie.cmake +++ b/inference-engine/cmake/features_ie.cmake @@ -29,7 +29,7 @@ if (ENABLE_MKL_DNN) endif() # "MKL-DNN library based on OMP or TBB or Sequential implementation: TBB|OMP|SEQ" -if(ARM) +if(ARM OR (MSVC AND (ARM OR AARCH64)) ) set(THREADING_DEFAULT "SEQ") else() set(THREADING_DEFAULT "TBB") diff --git a/inference-engine/cmake/vpu_dependencies.cmake b/inference-engine/cmake/vpu_dependencies.cmake index 92ef842feff..d8eda8281f6 100644 --- a/inference-engine/cmake/vpu_dependencies.cmake +++ b/inference-engine/cmake/vpu_dependencies.cmake @@ -13,7 +13,7 @@ endif() include(dependency_solver) -set(VPU_SUPPORTED_FIRMWARES usb-ma2450 usb-ma2x8x pcie-ma248x) +set(VPU_SUPPORTED_FIRMWARES usb-ma2x8x pcie-ma248x) # # Default packages @@ -66,11 +66,11 @@ foreach(firmware_name IN LISTS VPU_SUPPORTED_FIRMWARES) string(TOUPPER "${firmware_name}" firmware_name_upper) set(var_name VPU_FIRMWARE_${firmware_name_upper}_FILE) - set(firmware_out_file "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${firmware_name}.mvcmd") + set(firmware_out_file "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${firmware_name}.mvcmd") # Handle PCIe elf firmware for Windows if (WIN32 AND "${firmware_name}" STREQUAL "pcie-ma248x") - set(firmware_out_file "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${firmware_name}.elf") + set(firmware_out_file "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${firmware_name}.elf") endif () list(APPEND all_firmware_files ${firmware_out_file}) @@ -79,7 +79,7 @@ foreach(firmware_name IN LISTS VPU_SUPPORTED_FIRMWARES) COMMAND ${CMAKE_COMMAND} -E copy ${${var_name}} ${firmware_out_file} MAIN_DEPENDENCY ${${var_name}} - COMMENT "[VPU] Copy ${${var_name}} to ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMENT "[VPU] Copy ${${var_name}} to ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}" VERBATIM) install(FILES ${${var_name}} diff --git a/inference-engine/ie_bridges/c/samples/object_detection_sample_ssd/c_w_dirent.h b/inference-engine/ie_bridges/c/samples/object_detection_sample_ssd/c_w_dirent.h index 35aa9d37e93..ae24b5c042c 100644 --- a/inference-engine/ie_bridges/c/samples/object_detection_sample_ssd/c_w_dirent.h +++ b/inference-engine/ie_bridges/c/samples/object_detection_sample_ssd/c_w_dirent.h @@ -24,6 +24,14 @@ # define _AMD64_ #endif +#if defined(_M_ARM) && !defined(_ARM_) && !defined(_ARM64_) +# define _ARM_ +#endif + +#if defined(_M_ARM64) && !defined(_ARM_) && !defined(_ARM64_) +# define _ARM64_ +#endif + #include #include #include diff --git a/inference-engine/samples/CMakeLists.txt b/inference-engine/samples/CMakeLists.txt index 94e19f29601..236c17e6af3 100644 --- a/inference-engine/samples/CMakeLists.txt +++ b/inference-engine/samples/CMakeLists.txt @@ -59,10 +59,6 @@ else () endif() if (WIN32) - if (NOT "${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - message(FATAL_ERROR "Only 64-bit supported on Windows") - endif() - set_property (DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_SCL_SECURE_NO_WARNINGS -DNOMINMAX") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") #no asynchronous structured exception handling diff --git a/inference-engine/samples/classification_sample_async/main.cpp b/inference-engine/samples/classification_sample_async/main.cpp index b8cf5a035d5..2a20eb56e26 100644 --- a/inference-engine/samples/classification_sample_async/main.cpp +++ b/inference-engine/samples/classification_sample_async/main.cpp @@ -98,6 +98,7 @@ int main(int argc, char *argv[]) { // ----------------------------------------------------------------------------------------------------- // --------------------------- 3. Configure input & output --------------------------------------------- + if (network.getOutputsInfo().size() != 1) throw std::logic_error("Sample supports topologies with 1 output only"); // --------------------------- Prepare input blobs ----------------------------------------------------- slog::info << "Preparing input blobs" << slog::endl; @@ -214,7 +215,6 @@ int main(int argc, char *argv[]) { // --------------------------- 8. Process output ------------------------------------------------------- slog::info << "Processing output blobs" << slog::endl; OutputsDataMap outputInfo(network.getOutputsInfo()); - if (outputInfo.size() != 1) throw std::logic_error("Sample supports topologies with 1 output only"); Blob::Ptr outputBlob = inferRequest.GetBlob(outputInfo.begin()->first); /** Validating -nt value **/ diff --git a/inference-engine/samples/common/os/windows/w_dirent.h b/inference-engine/samples/common/os/windows/w_dirent.h index 495c1d26cf0..928e19058c8 100644 --- a/inference-engine/samples/common/os/windows/w_dirent.h +++ b/inference-engine/samples/common/os/windows/w_dirent.h @@ -24,6 +24,14 @@ # define _AMD64_ #endif +#if defined(_M_ARM) && !defined(_ARM_) && !defined(_ARM64_) +# define _ARM_ +#endif + +#if defined(_M_ARM64) && !defined(_ARM_) && !defined(_ARM64_) +# define _ARM64_ +#endif + #include #include #include diff --git a/inference-engine/samples/hello_classification/main.cpp b/inference-engine/samples/hello_classification/main.cpp index 974aa0de754..048f3b0451b 100644 --- a/inference-engine/samples/hello_classification/main.cpp +++ b/inference-engine/samples/hello_classification/main.cpp @@ -86,6 +86,7 @@ int main(int argc, char *argv[]) { // 2. Read a model in OpenVINO Intermediate Representation (.xml and .bin files) or ONNX (.onnx file) format CNNNetwork network = ie.ReadNetwork(input_model); + if (network.getOutputsInfo().size() != 1) throw std::logic_error("Sample supports topologies with 1 output only"); network.setBatchSize(1); // ----------------------------------------------------------------------------------------------------- diff --git a/inference-engine/scripts/dependencies.bat b/inference-engine/scripts/dependencies.bat index 94860bf0747..345e0faf56a 100644 --- a/inference-engine/scripts/dependencies.bat +++ b/inference-engine/scripts/dependencies.bat @@ -11,7 +11,6 @@ for %%A in ("%GNA%") do set GNA_FILENAME=%%~nxA for %%A in ("%OPENCV%") do set OPENCV_FILENAME=%%~nxA for %%A in ("%MYRIAD%") do set MYRIAD_FILENAME=%%~nxA for %%A in ("%HDDL%") do set HDDL_FILENAME=%%~nxA -for %%A in ("%VPU_FIRMWARE_MA2450%") do set VPU_FIRMWARE_MA2450_FILENAME=%%~nxA for %%A in ("%VPU_FIRMWARE_MA2X8X%") do set VPU_FIRMWARE_MA2X8X_FILENAME=%%~nxA for %%A in ("%TBB%") do set TBB_FILENAME=%%~nxA @@ -86,16 +85,6 @@ if not "%HDDL%"=="" ( ) ) -if not "%VPU_FIRMWARE_MA2450%"=="" ( - if not exist "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME%" ( - mkdir "%DL_SDK_TEMP%\test_dependencies\VPU" - powershell -command "iwr -outf '%DL_SDK_TEMP%\test_dependencies\VPU\_%VPU_FIRMWARE_MA2450_FILENAME%' %VPU_FIRMWARE_MA2450%" - mkdir "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME%" - call "C:\Program Files\7-Zip\7z.exe" x -y %DL_SDK_TEMP%\test_dependencies\VPU\_%VPU_FIRMWARE_MA2450_FILENAME% -o%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME% - del "%DL_SDK_TEMP%\test_dependencies\VPU\_%VPU_FIRMWARE_MA2450_FILENAME%" /F /Q - ) -) - if not "%VPU_FIRMWARE_MA2X8X%"=="" ( if not exist "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2X8X_FILENAME%" ( mkdir "%DL_SDK_TEMP%\test_dependencies\VPU" @@ -131,7 +120,7 @@ if not "%MYRIAD%"=="" ( if exist "%DL_SDK_TEMP%\test_dependencies\MYRIAD\%MYRIAD_FILENAME%%MYRIAD%\mvnc" ( echo xcopy.exe "%DL_SDK_TEMP%\test_dependencies\MYRIAD\%MYRIAD_FILENAME%%MYRIAD%" intel64 /S /I /Y /R xcopy.exe "%DL_SDK_TEMP%\test_dependencies\MYRIAD\%MYRIAD_FILENAME%%MYRIAD%" intel64 /S /I /Y /R - ) + ) if exist "%DL_SDK_TEMP%\test_dependencies\MYRIAD\%MYRIAD_FILENAME%%MYRIAD%\..\bin\mvnc" ( echo xcopy.exe "%DL_SDK_TEMP%\test_dependencies\MYRIAD\%MYRIAD_FILENAME%%MYRIAD%\..\bin\*" intel64 /S /I /Y /R @@ -139,13 +128,6 @@ if not "%MYRIAD%"=="" ( ) ) -if not "%VPU_FIRMWARE_MA2450%"=="" ( - if exist "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME%" ( - echo xcopy.exe "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME%\*" intel64 /S /I /Y /R - xcopy.exe "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2450_FILENAME%\*" intel64 /S /I /Y /R - ) -) - if not "%VPU_FIRMWARE_MA2X8X%"=="" ( if exist "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2X8X_FILENAME%" ( echo xcopy.exe "%DL_SDK_TEMP%\test_dependencies\VPU\%VPU_FIRMWARE_MA2X8X_FILENAME%\*" intel64 /S /I /Y /R diff --git a/inference-engine/scripts/dependencies.sh b/inference-engine/scripts/dependencies.sh index 09051b7075a..f0228b898d5 100755 --- a/inference-engine/scripts/dependencies.sh +++ b/inference-engine/scripts/dependencies.sh @@ -37,7 +37,7 @@ add_path() { fi } -runtimes=(MKL CLDNN MYRIAD GNA DLIA OPENCV VPU_FIRMWARE_USB-MA2450 VPU_FIRMWARE_USB-MA2X8X HDDL OMP TBB AOCL_RTE LIBUSB) +runtimes=(MKL CLDNN MYRIAD GNA DLIA OPENCV VPU_FIRMWARE_USB-MA2X8X HDDL OMP TBB AOCL_RTE LIBUSB) export_library_path() { export LD_LIBRARY_PATH=$DL_SDK_TEMP/test_dependencies/$1:$LD_LIBRARY_PATH diff --git a/inference-engine/src/gna_plugin/backend/make_pwl.cpp b/inference-engine/src/gna_plugin/backend/make_pwl.cpp index 762ea97f562..f7f34d33270 100644 --- a/inference-engine/src/gna_plugin/backend/make_pwl.cpp +++ b/inference-engine/src/gna_plugin/backend/make_pwl.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -413,12 +414,12 @@ void make_gna_pwl(const DnnActivation fun, y_upper = tmp; } - int64_t x_lower_new = FLOAT_TO_INT32((x_lower / in_scale) / abs(pow_scale) * in_scale); - int64_t x_upper_new = FLOAT_TO_INT32((x_upper / in_scale) / abs(pow_scale) * in_scale); + int64_t x_lower_new = FLOAT_TO_INT32((x_lower / in_scale) / std::fabs(pow_scale) * in_scale); + int64_t x_upper_new = FLOAT_TO_INT32((x_upper / in_scale) / std::fabs(pow_scale) * in_scale); x_lower = static_cast(x_lower_new); x_upper = static_cast(x_upper_new); if (x_lower_new < INT32_MIN) { - int16_t offset_lower = abs(x_lower_new - INT32_MIN) / in_scale * out_scale; + int16_t offset_lower = std::abs(x_lower_new - INT32_MIN) / in_scale * out_scale; x_lower = INT32_MIN; y_lower = y_lower + offset_lower; } diff --git a/inference-engine/src/gna_plugin/gna_device.cpp b/inference-engine/src/gna_plugin/gna_device.cpp index 7cd9fc27127..963a1c37ced 100644 --- a/inference-engine/src/gna_plugin/gna_device.cpp +++ b/inference-engine/src/gna_plugin/gna_device.cpp @@ -132,6 +132,22 @@ uint32_t GNADeviceHelper::createRequestConfig(const uint32_t model_id) { return reqConfId; } +uint32_t GNADeviceHelper::getNumberOfGnaDevices() { + std::unique_lock lockGnaCalls{ acrossPluginsSync }; + uint32_t numberOfGnaDevices = 0; + auto status = Gna2DeviceGetCount(&numberOfGnaDevices); + checkGna2Status(status); + return numberOfGnaDevices; +} + +uint32_t GNADeviceHelper::selectGnaDevice() { + const auto deviceCount = getNumberOfGnaDevices(); + if (deviceCount != 1) { + THROW_GNA_EXCEPTION << "Unsupported number of GNA devices detected = " << deviceCount; + } + return 0; +} + void GNADeviceHelper::checkGna2Status(Gna2Status status, const Gna2Model& gnaModel) { if (!Gna2StatusIsSuccessful(status)) { std::vector gna2StatusBuffer(1024); diff --git a/inference-engine/src/gna_plugin/gna_device.hpp b/inference-engine/src/gna_plugin/gna_device.hpp index d067ce9f410..596ba8f53e0 100644 --- a/inference-engine/src/gna_plugin/gna_device.hpp +++ b/inference-engine/src/gna_plugin/gna_device.hpp @@ -69,12 +69,13 @@ public: bool isPerformanceMeasuring = false) : isPerformanceMeasuring(isPerformanceMeasuring) { #else - explicit GNADeviceHelper(Gna2DeviceVersion gna2HwConsistency = Gna2DeviceVersionSoftwareEmulation, + explicit GNADeviceHelper(Gna2DeviceVersion gna2HwConsistency = Gna2DeviceVersionSoftwareEmulation, uint8_t lib_async_n_threads = 1, bool use_openmp = false, bool isPerformanceMeasuring = false) : gna2HwConsistency(gna2HwConsistency), - isPerformanceMeasuring(isPerformanceMeasuring) { + isPerformanceMeasuring(isPerformanceMeasuring), + nGnaDeviceIndex{selectGnaDevice()} { #endif open(lib_async_n_threads); initGnaPerfCounters(); @@ -116,6 +117,8 @@ public: #endif void releaseModel(const uint32_t model_id); uint32_t createRequestConfig(const uint32_t model_id); + static uint32_t getNumberOfGnaDevices(); + static uint32_t selectGnaDevice(); bool hasGnaHw() const { return Gna2DeviceVersionSoftwareEmulation != detectedGnaDevVersion; } diff --git a/inference-engine/src/gna_plugin/gna_model_serial.cpp b/inference-engine/src/gna_plugin/gna_model_serial.cpp index c74d1c7e27f..b36e4b61c1a 100644 --- a/inference-engine/src/gna_plugin/gna_model_serial.cpp +++ b/inference-engine/src/gna_plugin/gna_model_serial.cpp @@ -107,9 +107,10 @@ GNAPluginNS::HeaderLatest::ModelHeader GNAModelSerial::ReadHeader(std::istream & switch (header.version.minor) { case 1: readBits(tempHeader2dot1, is); - header = Header2dot2::ModelHeader(tempHeader2dot1); + header = Header2dot3::ModelHeader(tempHeader2dot1); break; case 2: + case 3: readBits(header, is); break; default: @@ -166,7 +167,30 @@ void GNAModelSerial::Import(void *basePointer, InferenceEngine::OutputsDataMap& outputsDataMap) { is.exceptions(std::istream::failbit); + if (modelHeader.version.major == 2) { + if (modelHeader.version.minor >= 3) { + for (auto inputIndex = 0; inputIndex < modelHeader.nInputs; inputIndex++) { + uint32_t nameSize = 0; + readNBits<32>(nameSize, is); + std::string inName("", nameSize); + readNBytes(&inName[0], nameSize, is); + inputNames.push_back(inName.substr(0, nameSize - 1)); + } + } + } ImportInputs(is, basePointer, inputsDesc, inputsDataMap); + + if (modelHeader.version.major == 2) { + if (modelHeader.version.minor >= 3) { + for (auto inputIndex = 0; inputIndex < modelHeader.nOutputs; inputIndex++) { + uint32_t nameSize = 0; + readNBits<32>(nameSize, is); + std::string outName("", nameSize); + readNBytes(&outName[0], nameSize, is); + outputNames.push_back(outName.substr(0, nameSize - 1)); + } + } + } ImportOutputs(is, basePointer, desc, outputsDataMap); for (auto operation = gna2Model->Operations; operation != gna2Model->Operations + gna2Model->NumberOfOperations; ++operation) { @@ -311,9 +335,19 @@ void GNAModelSerial::Export(void * basePointer, size_t gnaGraphSize, std::ostrea writeBits(header, os); + for (auto &name : inputNames) { + const auto nameSize = strlen(name.c_str()) + 1; + writeBits(static_cast(nameSize), os); + writeNBytes(name.c_str(), nameSize , os); + } for (const auto &input : inputs) { writeBits(convert_to_serial(input), os); } + for (auto &name : outputNames) { + const auto nameSize = strlen(name.c_str()) + 1; + writeBits(static_cast(nameSize), os); + writeNBytes(name.c_str(), nameSize, os); + } for (const auto &output : outputs) { writeBits(convert_to_serial(output), os); } @@ -691,7 +725,8 @@ void GNAModelSerial::ImportInputs(std::istream &is, dataMap.clear(); for (auto inputIndex = 0; inputIndex < modelHeader.nInputs; inputIndex++) { - std::string name = "input" + std::to_string(inputIndex); + const std::string& name = (modelHeader.version.major == 2 && modelHeader.version.minor >= 3) + ? inputNames.at(inputIndex) : std::string("input" + std::to_string(inputIndex)); HeaderLatest::RuntimeEndPoint input; is.read(reinterpret_cast(&input), sizeof(input)); inputsDesc->getPtrInputsGlobal(name).push_back(reinterpret_cast(reinterpret_cast (basePtr) + input.descriptor_offset)); @@ -719,7 +754,8 @@ void GNAModelSerial::ImportOutputs(std::istream &is, desc.resize(modelHeader.nOutputs); for (auto outputIndex = 0; outputIndex < modelHeader.nOutputs; outputIndex++) { - std::string name = "output" + std::to_string(outputIndex); + const std::string& name = (modelHeader.version.major == 2 && modelHeader.version.minor >= 3) + ? outputNames.at(outputIndex) : std::string("input" + std::to_string(outputIndex)); HeaderLatest::RuntimeEndPoint output; is.read(reinterpret_cast(&output), sizeof(output)); OutputDesc description; diff --git a/inference-engine/src/gna_plugin/gna_model_serial.hpp b/inference-engine/src/gna_plugin/gna_model_serial.hpp index 1db971d164c..807c4c4ea97 100644 --- a/inference-engine/src/gna_plugin/gna_model_serial.hpp +++ b/inference-engine/src/gna_plugin/gna_model_serial.hpp @@ -32,6 +32,8 @@ private: #endif std::vector inputs; std::vector outputs; + std::vector inputNames; + std::vector outputNames; uint32_t nRotateRows = 0; uint32_t nRotateColumns = 0; bool doRotateInput = false; @@ -63,6 +65,13 @@ private: const InferenceEngine::OutputsDataMap& outputsDataMap) : gna2Model(model), inputs(serializeInputs(inputsDataMap, inputDesc)), outputs(serializeOutputs(outputsDataMap, outputsDesc)) { + for (auto const& input : inputsDataMap) { + inputNames.push_back(input.first); + } + + for (auto const& input : outputsDataMap) { + outputNames.push_back(input.first); + } } #else diff --git a/inference-engine/src/gna_plugin/gna_plugin_query_api.cpp b/inference-engine/src/gna_plugin/gna_plugin_query_api.cpp index c078675f1fa..53e573d90d2 100644 --- a/inference-engine/src/gna_plugin/gna_plugin_query_api.cpp +++ b/inference-engine/src/gna_plugin/gna_plugin_query_api.cpp @@ -36,8 +36,8 @@ Parameter GNAPlugin::GetMetric(const std::string& name, const std::map(pLayers->front()); for (auto & l : *pLayers) { for (auto && prev : getCandidatesForIdentityInsertion(l)) { + // Do an upstream search until Functional layer is found + auto original_prev_layer = prev; + auto true_layer = l; + while (LayerInfo(prev).isNonFunctional()) { + if (CNNNetHasPrevLayer(prev.get()) && prev->outData.size() == 1) { + true_layer = prev; + prev = CNNNetPrevLayer(prev); + } else { + gnawarn() << "Could not find Functional parent for " << original_prev_layer->name << ", using original layer"; + prev = original_prev_layer; + true_layer = l; + break; + } + } int numOfIdentityLayers = this->getPassManager()->getIntVar(identityLayersCounterName)++; // actual insertion auto activationName = std::string("identity_") + std::to_string(numOfIdentityLayers); - gnalog() << "Inserted "<< activationName << " between: " << prev->name << " and " << l->name << "\n" << std::flush; + gnalog() << "Inserted "<< activationName << " between: " << prev->name << " and " << true_layer->name << "\n" << std::flush; CNNLayerPtr activationLayer = std::make_shared(LayerParams({activationName, "identity", Precision::FP32})); @@ -643,17 +657,17 @@ void InsertIdentityLayerPass::run() { // TODO: why index is 0 ? - better use direct indexing in getCandidateFunction // detecting ins-data-idx size_t insDataIdx = std::numeric_limits::max(); - for (size_t i = 0; i != l->insData.size(); i++) { - if (getCreatorLayer(l->insData[i].lock()).lock() == prev) { + for (size_t i = 0; i != true_layer->insData.size(); i++) { + if (getCreatorLayer(true_layer->insData[i].lock()).lock() == prev) { insDataIdx = i; break; } } if (insDataIdx == std::numeric_limits::max()) { - THROW_GNA_EXCEPTION << "cannot insert identity layer after" << prev->name << " and before " << l->name; + THROW_GNA_EXCEPTION << "cannot insert identity layer after" << prev->name << " and before " << true_layer->name; } - auto inputData = l->insData[insDataIdx].lock(); + auto inputData = true_layer->insData[insDataIdx].lock(); auto dataPtr = std::make_shared("identity_data_" + std::to_string(numOfIdentityLayers), inputData->getTensorDesc()); auto activationLayerWithQuant = quantized ? @@ -681,7 +695,7 @@ void InsertIdentityLayerPass::run() { activationLayerWithQuant->params["original_num_rows"] = prev->params["original_num_rows"]; } - CNNNetworkInsertLayer(prev, notAll ? l : CNNLayerPtr(nullptr), activationLayerWithQuant); + CNNNetworkInsertLayer(prev, notAll ? true_layer : CNNLayerPtr(nullptr), activationLayerWithQuant); } } } diff --git a/inference-engine/src/gna_plugin/round_float_define.hpp b/inference-engine/src/gna_plugin/round_float_define.hpp index f17259b847b..d11dd1e0ece 100644 --- a/inference-engine/src/gna_plugin/round_float_define.hpp +++ b/inference-engine/src/gna_plugin/round_float_define.hpp @@ -7,5 +7,5 @@ #include -#define FLOAT_TO_INT16(a) static_cast(((a) < 0)?((a) - 0.5):((a) + 0.5)) -#define FLOAT_TO_INT32(a) static_cast(((a) < 0)?((a)-0.5):((a)+0.5)) +#define FLOAT_TO_INT16(a) static_cast(((a) < 0)?((a) - 0.5f):((a) + 0.5f)) +#define FLOAT_TO_INT32(a) static_cast(((a) < 0)?((a)-0.5f):((a)+0.5f)) diff --git a/inference-engine/src/gna_plugin/serial/headers/2dot3/gna_model_header.hpp b/inference-engine/src/gna_plugin/serial/headers/2dot3/gna_model_header.hpp new file mode 100644 index 00000000000..e95f5c81c46 --- /dev/null +++ b/inference-engine/src/gna_plugin/serial/headers/2dot3/gna_model_header.hpp @@ -0,0 +1,122 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include "backend/dnn_types.h" +#include "serial/headers/2dot1/gna_model_header.hpp" + +#pragma pack(push, 1) + + +namespace GNAPluginNS { +namespace Header2dot3 { + + +/** + * @brief Header version 2.3 + */ +struct ModelHeader { + /** + *@brief MagicNumber – GNAM in ascii table, equals to hex 0x474e414d + */ + char gnam[4] = {}; + /** + * @brief if header size is not equal to sizeof ModelHeader - some reserved data append in the end of header + * usually it is an indicator of working with version of model different that is current export function produce + */ + uint32_t headerSize = 0u; + struct Version { + /** + * @details Version of format Major – unsigned int, ex: 0x0001 + * every change in the header or in the layers definition should be reflected in version change + * for backward compatibility new parsers can read old versions of model with certain restrictions + */ + uint16_t major = 2u; + /** + * @details Version of Format Minor – unsigned int, corresponding to build revision for example + * changes in minor version are not affected layout of model + */ + uint32_t minor = 3u; + } version; + /** + * @brief Memory required to be allocated using GNAAlloc() + */ + uint64_t gnaMemSize = 0ull; + /** + * @brief Number of GNA Layers + */ + uint64_t layersCount = 0ull; + /** + * @brief Grouping level + */ + uint32_t nGroup = 0u; + /** + * Convolution related setting - they are affecting input transformation + */ + uint32_t nRotateRows = 0u; + uint32_t nRotateColumns = 0u; + bool doRotateInput = false; + + uint32_t nInputs = 0u; + uint32_t nOutputs = 0u; + + /** + * Reserved Data might be here + */ + ModelHeader() = default; + ModelHeader(GNAPluginNS::Header2dot1::ModelHeader const &old) { + gnaMemSize = old.gnaMemSize; + layersCount = old.layersCount; + nGroup = old.nGroup; + nRotateRows = old.nRotateRows; + nRotateColumns = old.nRotateColumns; + nInputs = old.nInputs; + nOutputs = old.nOutputs; + } +}; +#pragma pack(pop) + +/* + * In runtime endpoint mostly same as in serial version, except of descriptor field + */ +struct RuntimeEndPoint { + /** + * if scale factor is different then pased into infer , network might need to be requantized + */ + float scaleFactor = 0; + /** + * Pointer descriptor + */ + void* descriptor_ptr = nullptr; + /** + * Endpoint resolution in bytes. + */ + uint32_t element_size = 0; + /** + * Number of elements + */ + uint32_t elements_count = 0; + /** + * Offset in bytes of pointer descriptor + */ + uint64_t descriptor_offset = 0ull; + + intel_dnn_orientation_t orientation = kDnnUnknownOrientation; + + RuntimeEndPoint() = default; + RuntimeEndPoint(double scaleFactor, + void* descriptor_ptr, + uint32_t element_size, + uint32_t elements_count, + intel_dnn_orientation_t orientation) : scaleFactor(scaleFactor), + descriptor_ptr(descriptor_ptr), + element_size(element_size), + elements_count(elements_count), + orientation(orientation) { + } +}; +} // namespace Header2dot3 +} // namespace GNAPluginNS diff --git a/inference-engine/src/gna_plugin/serial/headers/latest/gna_model_header.hpp b/inference-engine/src/gna_plugin/serial/headers/latest/gna_model_header.hpp index c5fc1256e30..716e17227d8 100644 --- a/inference-engine/src/gna_plugin/serial/headers/latest/gna_model_header.hpp +++ b/inference-engine/src/gna_plugin/serial/headers/latest/gna_model_header.hpp @@ -4,11 +4,11 @@ #pragma once -#include "serial/headers/2dot2/gna_model_header.hpp" +#include "serial/headers/2dot3/gna_model_header.hpp" namespace GNAPluginNS { namespace HeaderLatest { -using ModelHeader = GNAPluginNS::Header2dot2::ModelHeader; -using RuntimeEndPoint = GNAPluginNS::Header2dot2::RuntimeEndPoint; +using ModelHeader = GNAPluginNS::Header2dot3::ModelHeader; +using RuntimeEndPoint = GNAPluginNS::Header2dot3::RuntimeEndPoint; } } diff --git a/inference-engine/src/inference_engine/CMakeLists.txt b/inference-engine/src/inference_engine/CMakeLists.txt index 97eba73f331..fa7b03201d3 100644 --- a/inference-engine/src/inference_engine/CMakeLists.txt +++ b/inference-engine/src/inference_engine/CMakeLists.txt @@ -12,7 +12,7 @@ file (GLOB LIBRARY_SRC # TODO: WA for OneHot pass usage in reshape set(LEGACY_SRC_ROOT "${IE_MAIN_SOURCE_DIR}/src/legacy_api/src/") -list(APPEND LIBRARY_SRC +set(LEGACY_LIBRARY_SHARED_SRCS "${LEGACY_SRC_ROOT}/transformations/convert_opset1_to_legacy/convert_one_hot_to_one_hot_ie.cpp" "${LEGACY_SRC_ROOT}/ngraph_ops/onehot_ie.cpp") @@ -125,6 +125,7 @@ add_cpplint_target(${TARGET_NAME}_cpplint FOR_TARGETS ${TARGET_NAME}_obj) add_library(${TARGET_NAME} SHARED ${IE_STATIC_DEPENDENT_FILES} + ${LEGACY_LIBRARY_SHARED_SRCS} ${vs_version_file} $) @@ -137,7 +138,8 @@ target_link_libraries(${TARGET_NAME} PRIVATE pugixml openvino::itt ${CMAKE_DL_LI ${NGRAPH_LIBRARIES} inference_engine_transformations) target_include_directories(${TARGET_NAME} INTERFACE ${PUBLIC_HEADERS_DIR} - PRIVATE $) + PRIVATE $ + $) if(WIN32) set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME}) diff --git a/inference-engine/src/legacy_api/include/legacy/graph_tools.hpp b/inference-engine/src/legacy_api/include/legacy/graph_tools.hpp index b364e0d17b2..c03f4096f71 100644 --- a/inference-engine/src/legacy_api/include/legacy/graph_tools.hpp +++ b/inference-engine/src/legacy_api/include/legacy/graph_tools.hpp @@ -371,19 +371,42 @@ inline CNNLayerSet CNNNetGetAllInputLayers(const ICNNNetwork& network) { InputsDataMap inputs; network.getInputsInfo(inputs); + OutputsDataMap outputs; + network.getOutputsInfo(outputs); + + std::vector entryDataSet; + entryDataSet.reserve(inputs.size() + outputs.size()); + for (const auto &kvp : inputs) + entryDataSet.push_back(kvp.second->getInputData()); + for (const auto &kvp : outputs) + entryDataSet.push_back(kvp.second); + CNNLayerSet inputLayers; std::unordered_set allLayers; - if (inputs.empty()) return inputLayers; + if (entryDataSet.empty()) return inputLayers; - for (const auto& input : inputs) { - auto& secondLayers = getInputTo(input.second->getInputData()); + // define any layer connected to provided Data object (consumer or creator) + auto findConnectedLayer = [] (const DataPtr& data) -> CNNLayerPtr { + auto consumerLayers = getInputTo(data); + if (!consumerLayers.empty()) + return consumerLayers.begin()->second; - if (secondLayers.empty()) continue; + auto creator = getCreatorLayer(data).lock(); + if (creator != nullptr) + return creator; + + return nullptr; + }; + + for (const auto& data : entryDataSet) { + auto entryLayer = findConnectedLayer(data); + + if (entryLayer == nullptr) continue; details::UnorderedDFS( - allLayers, secondLayers.begin()->second, - [&](CNNLayerPtr layer) { + allLayers, entryLayer, + [&inputLayers](const CNNLayerPtr& layer) { if (layer->insData.empty()) { inputLayers.insert(layer); } diff --git a/inference-engine/src/legacy_api/src/ie_cnn_layer_builder_ngraph.cpp b/inference-engine/src/legacy_api/src/ie_cnn_layer_builder_ngraph.cpp index 4fc0dd6ce5a..50c68108e39 100644 --- a/inference-engine/src/legacy_api/src/ie_cnn_layer_builder_ngraph.cpp +++ b/inference-engine/src/legacy_api/src/ie_cnn_layer_builder_ngraph.cpp @@ -132,13 +132,6 @@ CNNLayer::Ptr createSubGraphLayer(const std::shared_ptr& layer) { THROW_IE_EXCEPTION << "Cannot cast layer to TensorIterator."; } - std::map>> ngraph_parameter_id_to_ie_layer_port; - std::map, uint64_t> ie_layer_port_to_tensor_iterator_input_id; - - // inputs/outputs of TensorIterator body (ie) - std::map in_info_map; - std::map out_info_map; - // inputs/outputs of TensorIterator (ngraph representation) auto parameters = tensor_iterator->get_function()->get_parameters(); auto results = tensor_iterator->get_function()->get_results(); @@ -148,10 +141,7 @@ CNNLayer::Ptr createSubGraphLayer(const std::shared_ptr& layer) { // IE TensorIterator doesn't include such nodes so we create CNNNetwork in a separate scope // to call the destructor and delete these "Input"/data nodes. - // These layers will hold the necessary subnet after destruction of CNNNetwork. - std::set body_input_layers; - // This map will save information about data nodes - std::map> layer_name_to_tensor_desc; + TensorIterator::Body body; { CNNNetwork body_net(tensor_iterator->get_function()); CNNNetwork net(InferenceEngine::details::convertFunctionToICNNNetwork(body_net.getFunction(), body_net)); @@ -163,73 +153,102 @@ CNNLayer::Ptr createSubGraphLayer(const std::shared_ptr& layer) { } // Get inputs/outputs of cnn network - InputsDataMap in_info_map_with_parameters; - in_info_map_with_parameters = net.getInputsInfo(); - out_info_map = net.getOutputsInfo(); + auto in_info_map_with_parameters = net.getInputsInfo(); + auto out_info_map = net.getOutputsInfo(); - // Fill the map to get layer and port of the body by the parameter index. + IE_ASSERT(in_info_map_with_parameters.size() == parameters.size()); + IE_ASSERT(out_info_map.size() == results.size()); + + InferenceEngine::TensorIterator::Body temp_body; + temp_body.inputs.resize(in_info_map_with_parameters.size()); + temp_body.outputs.resize(out_info_map.size()); + + // Fill inputs/outs in order aligned with ng representation uint64_t counter = 0; for (const auto& param : parameters) { auto info = in_info_map_with_parameters.at(param->get_friendly_name()); - auto data_ptr = info->getInputData(); - auto input_to = getInputTo(data_ptr); - for (const auto& next_layer : input_to) { - auto port_idx = find_input_idx(next_layer.second, data_ptr); - ngraph_parameter_id_to_ie_layer_port[counter].push_back({next_layer.first, port_idx}); + temp_body.inputs[counter++] = info->getInputData(); + } + + auto map_ng_result_to_ie_name = [] (std::shared_ptr res_op) { + auto result = res_op->input(0).get_source_output(); + + std::string name = result.get_node()->get_friendly_name(); + if (result.get_node()->get_output_size() > 1) { + name += "." + std::to_string(result.get_index()); } - counter++; - } + return name; + }; - // Temporary body to call deep copy - InferenceEngine::TensorIterator::Body temp_body; - for (const auto& in : in_info_map_with_parameters) { - temp_body.inputs.emplace_back(in.second->getInputData()); - } - - for (const auto& out : out_info_map) { - temp_body.outputs.emplace_back(out.second); + counter = 0; + for (const auto& result : results) { + auto data = out_info_map.at(map_ng_result_to_ie_name(result)); + temp_body.outputs[counter++] = data; } // This deep copy will hold all unreachable constants. See the comment in CopyTIBody function. - auto deep_cp_body = InferenceEngine::NetPass::CopyTIBody(temp_body); - for (const auto& data_ptr : deep_cp_body.inputs) { - auto input_to = getInputTo(data_ptr); - for (const auto& node : input_to) { - // Make it compatible with ir v7: delete Input layers in body - if (node.second->type != "Input") { - body_input_layers.emplace(node.second); - // Save information about data nodes to re-create them with correct names. - for (const auto& data : node.second->insData) { - layer_name_to_tensor_desc[node.second->name].emplace_back(data.lock()->getTensorDesc()); - } - } + body = InferenceEngine::NetPass::CopyTIBody(temp_body); + + // Check if data is really const layer holder + auto is_constant_holder = [] (const DataPtr data) { + return data->getPrecision() == Precision::UNSPECIFIED; + }; + + // Strip unreached node holder from Inputs node. + auto holder = body.inputs.back(); + if (is_constant_holder(holder)) { + auto& holder_map = getInputTo(holder); + // remove_if + for( auto it = holder_map.begin(); it != holder_map.end(); ) { + if( it->second->type == "Input") + it = holder_map.erase(it); + else + ++it; } } - for (const auto& data_ptr : deep_cp_body.outputs) { - out_info_map[data_ptr->getName()] = data_ptr; - } - } + // TODO: Disable this WA after total switch onto Ngraph + // WA: Some plugins (like GPU) require matching of Data object name and producer Layer name. + // Data name is expected in format "[layer_name]" or "[layer_name].[port_idx]" in case + // of multiple inputs. We have to restore it if possible and ignore original names of + // Ngraph parameter and result ops. + // Will not change data name if: + // - data has several consumer layers + // - data has no consumer (example if data is straight used as output) + // + for (auto &in : body.inputs) { + if (is_constant_holder(in)) + continue; - auto holder = std::make_shared("const_holder", Precision::UNSPECIFIED); - for (const auto& input_layer : body_input_layers) { - // Save all constants to the holder so that they are not deleted. - if (input_layer->insData.empty()) { - getInputTo(holder)[input_layer->name] = input_layer; - continue; + const auto input_to = getInputTo(in); + if (input_to.size() != 1) + continue; + + const auto consumer_layer = input_to.begin()->second; + const auto consumer_in_port_set = consumer_layer->insData; + const auto found = std::find_if(consumer_in_port_set.begin(), consumer_in_port_set.end(), + [&in] (const DataWeakPtr &wptr) { return wptr.lock() == in; }); + IE_ASSERT(found != consumer_in_port_set.end()); + const auto consumer_port_idx = std::distance(consumer_in_port_set.begin(), found); + + auto new_name = consumer_layer->name; + if (consumer_in_port_set.size() > 1) { + new_name += '.' + std::to_string(consumer_port_idx); + } + in->setName(new_name); } - // Re-create the data nodes with the correct names and fill inputs of TensorIterator (ie) - for (size_t i = 0; i < input_layer->insData.size(); i++) { - if (!input_layer->insData[i].lock()) { - std::string data_name = (input_layer->insData.size() == 1) - ? input_layer->name - : input_layer->name + "." + std::to_string(i); - - DataPtr data(new Data(data_name, layer_name_to_tensor_desc[input_layer->name][i])); - input_layer->insData[i] = data; - getInputTo(data)[input_layer->name] = input_layer; - in_info_map[data_name] = data; + // TODO: this WA restore original precisions of outputs. + // convertFunctionToICNNNetwork has internal fallback policy for unsupported + // precisions for inputs/outputs ports. Particular for U8 will be translated + // to FP32. However Loop body has strong requirements for continue_condition + // port, it should be BOOL(U8). + // + for (int i = 0; i < results.size(); i++) { + auto result = results[i]; + auto output = body.outputs[i]; + if (result->get_element_type() == ngraph::element::u8) { + output->setPrecision(InferenceEngine::Precision::U8); } } } @@ -238,44 +257,11 @@ CNNLayer::Ptr createSubGraphLayer(const std::shared_ptr& layer) { LayerParams params = {layer->get_friendly_name(), "TensorIterator", details::convertPrecision(layer->get_output_element_type(0))}; auto res = std::make_shared(params); - - // Body: inputs - uint64_t counter = 0; - for (const auto& in : in_info_map) { - res->body.inputs.emplace_back(in.second); - - // Fill the map to get the input index by layer and port of the body. - auto input_to = getInputTo(in.second); - for (const auto& next_layer : input_to) { - auto port_idx = find_input_idx(next_layer.second, in.second); - ie_layer_port_to_tensor_iterator_input_id[{next_layer.first, port_idx}] = counter; - } - counter++; - } - // the holder should be the last input element. - res->body.inputs.emplace_back(holder); - - // Body: outputs - for (const auto& out : out_info_map) { - res->body.outputs.emplace_back(out.second); - } + res->body = body; // Port map: outputs for (const auto& desc : tensor_iterator->get_output_descriptions()) { - auto result = results[desc->m_body_value_index]->input(0).get_source_output(); - - std::string name = result.get_node()->get_friendly_name(); - if (result.get_node()->get_output_size() > 1) { - name += "." + std::to_string(result.get_index()); - } - auto output_layer = out_info_map.at(name); - - // Find index in outputs of the IE TensorIterator body - auto it = std::find(res->body.outputs.begin(), res->body.outputs.end(), output_layer); - if (it == res->body.outputs.end()) { - THROW_IE_EXCEPTION << "Output layer not found."; - } - auto body_output_idx = it - res->body.outputs.begin(); + auto body_output_idx = desc->m_body_value_index; std::string type_name = desc->get_type_info().name; if (type_name == "ConcatOutputDescription") { @@ -301,56 +287,44 @@ CNNLayer::Ptr createSubGraphLayer(const std::shared_ptr& layer) { // Port map : inputs and back edges for (const auto& desc : tensor_iterator->get_input_descriptions()) { - for (const auto& mapping : ngraph_parameter_id_to_ie_layer_port[desc->m_body_parameter_index]) { - auto body_input_index = ie_layer_port_to_tensor_iterator_input_id.at(mapping); - std::string type_name = desc->get_type_info().name; + auto body_input_index = desc->m_body_parameter_index; - if (type_name == "SliceInputDescription") { - auto input_desc = ::ngraph::as_type_ptr(desc); - IE_ASSERT(input_desc != nullptr); + if (const auto slice_desc = std::dynamic_pointer_cast(desc)) { + res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { + static_cast(slice_desc->m_input_index), static_cast(body_input_index), + static_cast(slice_desc->m_axis), static_cast(slice_desc->m_stride), + static_cast(slice_desc->m_start), static_cast(slice_desc->m_end), + static_cast(slice_desc->m_part_size)}); + } else if (const auto merge_desc = std::dynamic_pointer_cast(desc)) { + res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { + static_cast(merge_desc->m_input_index), static_cast(body_input_index), -1, 1, 0, -1, 1}); - res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { - static_cast(input_desc->m_input_index), static_cast(body_input_index), - static_cast(input_desc->m_axis), static_cast(input_desc->m_stride), - static_cast(input_desc->m_start), static_cast(input_desc->m_end), - static_cast(input_desc->m_part_size)}); - } else if (type_name == "MergedInputDescription") { - auto input_desc = ::ngraph::as_type_ptr(desc); - IE_ASSERT(input_desc != nullptr); + auto body_output_idx = merge_desc->m_body_value_index; - res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { - static_cast(input_desc->m_input_index), static_cast(body_input_index), -1, 1, 0, -1, 1}); - - auto result = results[input_desc->m_body_value_index]->inputs()[0].get_source_output(); - - // Create correct name for output. - std::string output_name = result.get_node()->get_friendly_name(); - if (result.get_node()->get_output_size() > 1) { - output_name += "." + std::to_string(result.get_index()); - } - - auto output_layer = out_info_map.at(output_name); - // Find index in outputs of the IE TensorIterator body - auto it = std::find(res->body.outputs.begin(), res->body.outputs.end(), output_layer); - if (it == res->body.outputs.end()) { - THROW_IE_EXCEPTION << "Output layer not found."; - } - auto body_output_idx = it - res->body.outputs.begin(); - - res->back_edges.emplace_back(InferenceEngine::TensorIterator::PortMap { - static_cast(body_output_idx), static_cast(body_input_index), -1, 1, 0, -1, 1}); - } else if (type_name == "InvariantInputDescription") { - auto input_desc = ::ngraph::as_type_ptr(desc); - IE_ASSERT(input_desc != nullptr); - - res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { - static_cast(input_desc->m_input_index), static_cast(body_input_index), -1, 1, 0, -1, 1}); - } else { - THROW_IE_EXCEPTION << "Incorrect type of the input description."; - } + res->back_edges.emplace_back(InferenceEngine::TensorIterator::PortMap { + static_cast(body_output_idx), static_cast(body_input_index), -1, 1, 0, -1, 1}); + } else if (const auto inv_desc = std::dynamic_pointer_cast(desc)) { + res->input_port_map.emplace_back(InferenceEngine::TensorIterator::PortMap { + static_cast(inv_desc->m_input_index), static_cast(body_input_index), -1, 1, 0, -1, 1}); + } else { + THROW_IE_EXCEPTION << "Incorrect type of the input description."; } } + if (const auto loop_op = std::dynamic_pointer_cast(layer)) { + auto spec_port = loop_op->get_special_body_ports(); + if (spec_port.current_iteration_input_idx != -1) { + auto ie_port_idx = spec_port.current_iteration_input_idx; + res->params["loop_body_current_iteration_idx"] = std::to_string(ie_port_idx); + } + if (spec_port.body_condition_output_idx != -1) { + auto body_output_idx = spec_port.body_condition_output_idx; + res->params["loop_body_condition_output_idx"] = std::to_string(body_output_idx); + } + res->params["loop_trip_count_idx"] = "0"; + res->params["loop_execution_condition_idx"] = "1"; + } + return res; } @@ -1173,14 +1147,6 @@ CNNLayer::Ptr NodeConverter::createLayer(const std: return res; } -template <> -CNNLayer::Ptr NodeConverter::createLayer(const std::shared_ptr& layer) const { - LayerParams params = {layer->get_friendly_name(), "Reshape", - details::convertPrecision(layer->get_output_element_type(0))}; - auto res = std::make_shared(params); - return res; -} - template <> CNNLayer::Ptr NodeConverter::createLayer(const std::shared_ptr& layer) const { LayerParams params = {layer->get_friendly_name(), "ShapeOf", diff --git a/inference-engine/src/legacy_api/src/net_pass.cpp b/inference-engine/src/legacy_api/src/net_pass.cpp index dafe806700d..e2c34de2fcb 100644 --- a/inference-engine/src/legacy_api/src/net_pass.cpp +++ b/inference-engine/src/legacy_api/src/net_pass.cpp @@ -46,15 +46,28 @@ static std::vector getAllInputs(const std::vector& heads) { CNNLayerSet inputLayers; std::unordered_set allLayers; + // define any layer connected to provided Data object (consumer or creator) + auto findConnectedLayer = [] (const DataPtr& data) -> CNNLayerPtr { + auto consumerLayers = getInputTo(data); + if (!consumerLayers.empty()) + return consumerLayers.begin()->second; + + auto creator = getCreatorLayer(data).lock(); + if (creator != nullptr) + return creator; + + return nullptr; + }; + // Define all start layers for (const auto& data : heads) { - auto& secondLayers = getInputTo(data); + auto entryLayer = findConnectedLayer(data); - if (secondLayers.empty()) continue; + if (entryLayer == nullptr) continue; details::UnorderedDFS( - allLayers, secondLayers.begin()->second, - [&](CNNLayerPtr layer) { + allLayers, entryLayer, + [&inputLayers](const CNNLayerPtr &layer) { if (layer->insData.empty()) { inputLayers.insert(layer); } @@ -77,10 +90,17 @@ static std::vector getAllInputs(const std::vector& heads) { std::vector TIBodySortTopologically(const TensorIterator::Body& body) { std::vector all_layers; - auto all_input_layers = getAllInputs(body.inputs); + // In case of graph with several connected component + // total entry point is a union of [inputs]U[outputs] + // All internal nodes are achievable starting from this. + auto total_entry_point = body.inputs; + total_entry_point.insert(total_entry_point.end(), + body.outputs.begin(), body.outputs.end()); + + auto all_input_layers = getAllInputs(total_entry_point); CNNNetForestDFS( all_input_layers, - [&](CNNLayerPtr current) { + [&all_layers](const CNNLayerPtr ¤t) { all_layers.push_back(current); }, false); @@ -143,9 +163,17 @@ TensorIterator::Body CopyTIBody(const TensorIterator::Body& body, std::string su } TensorIterator::Body res; - for (auto& in : body.inputs) res.inputs.emplace_back(old2new_d[in.get()]); + for (auto& in : body.inputs) { + auto found = old2new_d.find(in.get()); + IE_ASSERT(found != old2new_d.end()); + res.inputs.emplace_back(found->second); + } - for (auto& out : body.outputs) res.outputs.emplace_back(old2new_d[out.get()]); + for (auto& out : body.outputs) { + auto found = old2new_d.find(out.get()); + IE_ASSERT(found != old2new_d.end()); + res.outputs.emplace_back(found->second); + } // Fake holder. // The graph itself is a shared_ptr set where parent holds child. diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_graph.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_graph.cpp index b6019c50b30..d6d1f483c85 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_graph.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_graph.cpp @@ -110,64 +110,73 @@ void MKLDNNGraph::Replicate(const TensorIterator::Body &subgraph, const MKLDNNEx this->_name = "subgraph"; this->reuse_io_tensors = false; - std::unordered_map layer2node; - std::unordered_set unused_data; // nodes which has no consumers (output or just unused) + // Map data object onto producer layer(node) + std::unordered_map> data2node; - auto _parent_port = [] (const DataPtr &data) -> int { - auto parent = getCreatorLayer(data).lock(); - for (int i = 0; parent->outData.size(); i++) - if (data == parent->outData[i]) - return i; - return -1; - }; + // nodes which has no consumers (output or just unused). But doesn't marked as graph output. + // Will be stored as fake output separately. + std::unordered_set unused_data; - auto _child_port = [] (const DataPtr &data, const CNNLayerPtr &layer) -> int { - for (int i = 0; layer->insData.size(); i++) - if (data == layer->insData[i].lock()) - return i; - return -1; - }; + // Step 1. Replicate input nodes + for (const auto &input : subgraph.inputs) { + if (input->getPrecision() == Precision::UNSPECIFIED) continue; // const node holder + auto creator = getCreatorLayer(input).lock(); + if (creator == nullptr) { + creator.reset(new CNNLayer({input->getName(), "Input", input->getTensorDesc().getPrecision()})); + creator->outData.push_back(input); + } - // Replicate All Nodes in topological order - for (const auto layer : NetPass::TIBodySortTopologically(subgraph)) { - CNNLayerPtr _layer = layer; + const MKLDNNNodePtr node(MKLDNNNode::factory().create(creator, getEngine(), extMgr, weightsCache)); + data2node[input.get()] = {node, 0}; - const MKLDNNNodePtr node(MKLDNNNode::factory().create(_layer, getEngine(), extMgr, weightsCache)); graphNodes.push_back(node); - layer2node[layer] = node; + inputNodes[input->getName()] = node; + + if (getInputTo(input).empty()) { + unused_data.insert(input); + } + } + + // Step 2. Replicate all internal nodes. + for (const auto layer : NetPass::TIBodySortTopologically(subgraph)) { + const MKLDNNNodePtr node {MKLDNNNode::factory().create(layer, getEngine(), extMgr, weightsCache)}; + graphNodes.push_back(node); for (int port = 0; port < layer->insData.size(); port++) { auto data = layer->insData[port].lock(); - auto parent_layer = getCreatorLayer(data).lock(); - if (!parent_layer) continue; // no parent means that it is input data node (or memory/const layer) - auto parent_node = layer2node[parent_layer]; + auto port_info = data2node[data.get()]; + auto parent_node = port_info.first; + auto parent_port_idx = port_info.second; - MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, _parent_port(data), port)); + MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, parent_port_idx, port)); node->addEdge(edge); graphEdges.push_back(edge); } + int out_port_idx = 0; for (auto &out_data : layer->outData) { + data2node[out_data.get()] = {node, out_port_idx++}; if (getInputTo(out_data).empty()) { unused_data.insert(out_data); } } } + // Step 3. Add output nodes and output stubs for unused data objects. for (const auto &output : subgraph.outputs) { - auto parent_layer = getCreatorLayer(output).lock(); - auto parent_node = layer2node[parent_layer]; + auto port_info = data2node[output.get()]; + auto parent_node = port_info.first; + auto parent_port_idx = port_info.second; CNNLayerPtr layer(new CNNLayer({"out_" + output->getName(), "Output", output->getTensorDesc().getPrecision()})); layer->insData.push_back(output); - const MKLDNNNodePtr node(MKLDNNNode::factory().create(layer, getEngine(), extMgr, weightsCache)); + const MKLDNNNodePtr node {MKLDNNNode::factory().create(layer, getEngine(), extMgr, weightsCache)}; - MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, _parent_port(output), 0)); + MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, parent_port_idx, 0)); node->addEdge(edge); graphEdges.push_back(edge); - graphNodes.push_back(node); outputNodes.push_back(node); @@ -176,39 +185,20 @@ void MKLDNNGraph::Replicate(const TensorIterator::Body &subgraph, const MKLDNNEx // Add stub output node for unused data for (auto to_stub_data : unused_data) { - auto parent_layer = getCreatorLayer(to_stub_data).lock(); - auto parent_node = layer2node[parent_layer]; + auto port_info = data2node[to_stub_data.get()]; + auto parent_node = port_info.first; + auto parent_port_idx = port_info.second; - CNNLayerPtr layer(new CNNLayer({"stub_" + parent_layer->name, "Output", to_stub_data->getTensorDesc().getPrecision()})); + CNNLayerPtr layer(new CNNLayer({"stub_" + to_stub_data->getName(), "Output", to_stub_data->getTensorDesc().getPrecision()})); layer->insData.push_back(to_stub_data); const MKLDNNNodePtr node(MKLDNNNode::factory().create(layer, getEngine(), extMgr, weightsCache)); - MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, _parent_port(to_stub_data), 0)); + MKLDNNEdgePtr edge(new MKLDNNEdge(parent_node, node, parent_port_idx, 0)); node->addEdge(edge); graphEdges.push_back(edge); graphNodes.push_back(node); } - - // Replicate input nodes - for (const auto &input : subgraph.inputs) { - if (input->getName() == "const_holder") continue; - - CNNLayerPtr layer(new CNNLayer({"in_" + input->getName(), "Input", input->getTensorDesc().getPrecision()})); - layer->outData.push_back(input); - - const MKLDNNNodePtr node(MKLDNNNode::factory().create(layer, getEngine(), extMgr, weightsCache)); - - for (auto p : getInputTo(input)) { - auto consumer = p.second; - MKLDNNEdgePtr edge(new MKLDNNEdge(node, layer2node[consumer], 0, _child_port(input, consumer))); - node->addEdge(edge); - graphEdges.push_back(edge); - } - - graphNodes.push_back(node); - inputNodes[input->getName()] = node; - } } void MKLDNNGraph::Replicate(const ICNNNetwork &network, const MKLDNNExtensionManager::Ptr& extMgr) { diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_graph.h b/inference-engine/src/mkldnn_plugin/mkldnn_graph.h index a758145ae64..ca092386447 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_graph.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_graph.h @@ -76,6 +76,11 @@ public: return outputNodes; } + std::map& GetInputNodes() { + return inputNodes; + } + + mkldnn::engine getEngine() const { return eng; } diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp index ccdef345d19..8c2236b05c0 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp @@ -600,7 +600,8 @@ void MKLDNNGraphOptimizer::FuseConvolutionAndActivation(MKLDNNGraph &graph) { return eltwiseNode && (eltwiseNode->getOpType() == Relu || (conv->getCnnLayer()->precision == Precision::FP32 && - IsOneOf(eltwiseNode->getOpType(), {Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid}))); + IsOneOf(eltwiseNode->getOpType(), {Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid, + Round}))); }; for (int i = 0; i < graphNodes.size(); i++) { @@ -678,7 +679,8 @@ void MKLDNNGraphOptimizer::FuseFullyConnectedAndSimpleOperation(MKLDNNGraph &gra if (eltwiseNode == nullptr) THROW_IE_EXCEPTION << "Cannot get Eltwise node " << childNode->getName(); - if (IsOneOf(eltwiseNode->getOpType(), {Relu, Gelu, Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid})) { + if (IsOneOf(eltwiseNode->getOpType(), {Relu, Gelu, Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, + Hsigmoid, Round})) { return true; } else if (IsOneOf(eltwiseNode->getOpType(), {MulAdd, Prelu})) { if (eltwiseNode->getOpType() == MulAdd && eltwiseNode->getCnnLayer()->blobs.size() != 2) @@ -1044,7 +1046,8 @@ void MKLDNNGraphOptimizer::FuseConvolutionAndSimpleOperation(MKLDNNGraph &graph) return ((eltwiseNode->getOpType() == MulAdd && node->getCnnLayer()->blobs.size() == 2) || (eltwiseNode->getOpType() == Prelu) || - IsOneOf(eltwiseNode->getOpType(), {Relu, Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid})); + IsOneOf(eltwiseNode->getOpType(), {Relu, Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, + Hsigmoid, Round})); } return false; @@ -1258,7 +1261,8 @@ void MKLDNNGraphOptimizer::FuseConvolutionSumAndConvolutionSumActivation(MKLDNNG return eltwiseNode && (eltwiseNode->getOpType() == Relu || (conv->getCnnLayer()->precision == Precision::FP32 && - IsOneOf(eltwiseNode->getOpType(), {Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid}))); + IsOneOf(eltwiseNode->getOpType(), {Elu, Logistic, BoundedRelu, Clamp, Swish, Hswish, Mish, Hsigmoid, + Round}))); }; for (auto &graphNode : graphNodes) { @@ -1611,7 +1615,7 @@ void MKLDNNGraphOptimizer::FuseNormalizeAndSimpleOperation(MKLDNNGraph &graph) { if (eltwiseNode == nullptr) THROW_IE_EXCEPTION << "Cannot get Eltwise node " << node->getName(); return IsOneOf(eltwiseNode->getOpType(), {Relu, Gelu, Elu, Logistic, BoundedRelu, Clamp, Tanh, Swish, - Hswish, Mish, Hsigmoid, Linear, Abs, Square, Sqrt}) || + Hswish, Mish, Hsigmoid, Round, Linear, Abs, Square, Sqrt}) || ((eltwiseNode->getOpType() == MulAdd && eltwiseNode->getCnnLayer()->blobs.size() == 2) || (eltwiseNode->getOpType() == Prelu)); } diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp index ff96a750a48..a4bfc1163a6 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp @@ -75,6 +75,7 @@ static const InferenceEngine::details::caseless_unordered_map { "HSwish", Eltwise }, { "Mish", Eltwise }, { "HSigmoid", Eltwise }, + { "Round", Eltwise }, { "ScaleShift", Eltwise }, { "PReLU", Eltwise }, { "Norm", Lrn }, @@ -112,6 +113,7 @@ static const InferenceEngine::details::caseless_unordered_map { "BinaryConvolution", BinaryConvolution }, { "DeformableConvolution", DeformableConvolution }, { "TensorIterator", TensorIterator }, + { "Loop", TensorIterator }, { "MemoryInput", MemoryInput}, // for construction from name ctor, arbitrary name is used { "Memory", MemoryOutput }, // for construction from layer ctor { "Convert", Convert }, diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp index 2c0fc6f88e4..2bffe173695 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp @@ -312,7 +312,8 @@ private: auto& eltwiseNode = dynamic_cast(node); switch (eltwiseNode.getOpType()) { case Relu: case Gelu: case Elu: case Tanh: case Logistic: case Square: case Abs: case Sqrt: - case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: case Mish: case Hsigmoid: + case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: + case Mish: case Hsigmoid: case Round: return jit_mkldnn_emitter::get_supported_precisions(); case Add: return jit_add_emitter::get_supported_precisions(); case MulAdd: return jit_mul_add_emitter::get_supported_precisions(); @@ -345,7 +346,8 @@ private: auto& eltwiseNode = dynamic_cast(node); switch (eltwiseNode.getOpType()) { case Relu: case Gelu: case Elu: case Tanh: case Logistic: case Square: case Abs: case Sqrt: - case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: case Mish: case Hsigmoid: + case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: + case Mish: case Hsigmoid: case Round: return std::make_shared(this, isa, eltwiseNode, exec_prec); case Add: return std::make_shared(this, isa, eltwiseNode, exec_prec); case MulAdd: return std::make_shared(this, isa, eltwiseNode, exec_prec); @@ -764,6 +766,18 @@ MKLDNNEltwiseNode::initializers = { opType = Hsigmoid; algorithm = mkldnn::eltwise_hsigmoid; }}, + {"round", [](GenericLayer* activationLayer, EltwiseOpType& opType, mkldnn::algorithm& algorithm, float& alpha, float& beta) { + alpha = 0.0f; + beta = 0.0f; + opType = Round; + std::string mode = activationLayer->GetParamAsString("mode", "half_to_even"); + if (mode == "half_to_even") + algorithm = mkldnn::eltwise_round_half_to_even; + else if (mode == "half_away_from_zero") + algorithm = mkldnn::eltwise_round_half_away_from_zero; + else + THROW_IE_EXCEPTION << "Round layer with name " << activationLayer->name << " doesn't support mode " << mode; + }}, }; void MKLDNNEltwiseNode::init() { @@ -833,7 +847,8 @@ void MKLDNNEltwiseNode::init() { comparator(layerType, "swish") || comparator(layerType, "hswish") || comparator(layerType, "mish") || - comparator(layerType, "hsigmoid")) { + comparator(layerType, "hsigmoid") || + comparator(layerType, "round")) { initializers[layerType](getCnnLayer().get(), eltwiseOp, eltwiseAlgorithm, alpha, beta); } else { THROW_IE_EXCEPTION << "Unsupported algorithm for Eltwise node with name `" << getName() << "`."; @@ -843,7 +858,8 @@ void MKLDNNEltwiseNode::init() { size_t MKLDNNEltwiseNode::getOpInputsNum() const { switch (getOpType()) { case Relu: case Gelu: case Elu: case Tanh: case Logistic: case Square: case Abs: case Sqrt: case PowerStatic: - case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: case Mish: case Hsigmoid: + case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: + case Mish: case Hsigmoid: case Round: case LogicalNot: return 1; case Add: case Subtract: case Multiply: case Divide: case FloorMod: case Mod: case Maximum: case Minimum: case SquaredDifference: @@ -1469,7 +1485,8 @@ void MKLDNNEltwiseNode::executeReference(const std::vector& src switch (getOpType()) { case Relu: case Gelu: case Elu: case Tanh: case Logistic: case Square: case Abs: case Sqrt: - case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: case Mish: case Hsigmoid: + case Linear: case BoundedRelu: case SoftRelu: case Relu6: case Exp: case Clamp: case Swish: case Hswish: + case Mish: case Hsigmoid: case Round: *dst_ptr_f = ref_eltwise_injector->compute_scalar(src_f[0]); break; case Add: *dst_ptr_f = src_f[0] + src_f[1]; break; case MulAdd: *dst_ptr_f = src_f[0] * src_f[1] + src_f[2]; break; @@ -1570,6 +1587,8 @@ void MKLDNNEltwiseNode::appendPostOps(mkldnn::post_ops& ops) { case mkldnn::eltwise_hswish: case mkldnn::eltwise_mish: case mkldnn::eltwise_hsigmoid: + case mkldnn::eltwise_round_half_to_even: + case mkldnn::eltwise_round_half_away_from_zero: ops.append_eltwise(1.0, getAlgorithm(), getAlpha(), getBeta()); break; case mkldnn::depthwise_scale_shift: diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h index 9b003ca1bb1..1590d378e32 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h @@ -59,7 +59,8 @@ enum EltwiseOpType { Prelu, Mish, Hswish, - Hsigmoid + Hsigmoid, + Round }; struct jit_eltwise_params { diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp index de76d7d3aa3..799f2da3dc6 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp @@ -2123,7 +2123,7 @@ bool MKLDNNInterpolateNode::canFuse(const MKLDNNNodePtr& node) const { if (eltwiseNode == nullptr) THROW_IE_EXCEPTION << "Cannot get eltwise node " << node->getName(); return isOneOf(eltwiseNode->getOpType(), {MulAdd, Prelu, Relu, Gelu, Elu, Logistic, BoundedRelu, Clamp, - Tanh, Swish, Hswish, Mish, Hsigmoid, Linear, Abs, Square, Sqrt}); + Tanh, Swish, Hswish, Mish, Hsigmoid, Round, Linear, Abs, Square, Sqrt}); } return false; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.cpp index db88b0c2d28..b299e14733f 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.cpp @@ -11,7 +11,6 @@ #include #include #include -#include using namespace mkldnn; using namespace MKLDNNPlugin; @@ -50,96 +49,137 @@ static InferenceEngine::LayerConfig make_plain_config(const InferenceEngine::CNN class PortIteratorHelper : public PortMapHelper { public: - PortIteratorHelper(const MKLDNNMemoryPtr &from, const MKLDNNMemoryPtr &to, - bool as_input, const InferenceEngine::TensorIterator::PortMap &port_map, const mkldnn::engine& eng, int n_iter) : as_input(as_input) { - const auto &full_blob = as_input ? from : to; - const auto &part_blob = !as_input ? from : to; + PortIteratorHelper(const MKLDNNMemoryPtr &from, const MKLDNNMemoryPtr &to, bool sliced_src, + const InferenceEngine::TensorIterator::PortMap &slice_rule, const mkldnn::engine& eng) { + const auto &full_blob = sliced_src ? from : to; + const auto &part_blob = !sliced_src ? from : to; - auto axis = port_map.axis; - auto stride = port_map.stride; + auto axis = slice_rule.axis; + auto stride = slice_rule.stride; auto full_dims = full_blob->GetDims(); auto part_dims = part_blob->GetDims(); - if (port_map.axis == -1) { - // simple copy mode. No iteration through this tensor - reorders.emplace_back(from->GetPrimitive(), to->GetPrimitive()); - iter_count = n_iter; + auto abs_stride = std::abs(stride); + auto sign_of_stride = stride < 0.0f ? -1 : 1; + + iter_count = full_dims[axis] / abs_stride; + + full_dims[axis] = abs_stride; + IE_ASSERT(full_dims == part_dims) << "Shape mismatch for tensor iterator port"; + + // make chunk view + auto chunk_desc = full_blob->GetDescriptor(); + chunk_desc.data.dims[axis] = abs_stride; + chunk_desc.data.layout_desc.blocking.padding_dims[axis] = abs_stride; // TODO: asamption that plain tensor + + mem_holder.push_back(full_blob->GetPrimitive()); + auto full_mem_handler = full_blob->GetPrimitive().get_data_handle(); + mem_holder.emplace_back(mkldnn::memory::primitive_desc(chunk_desc, eng), full_mem_handler); + auto &chunk_mem_prim = mem_holder.back(); + + auto elem_size = MKLDNNExtensionUtils::sizeOfDataType(mkldnn::memory::data_type(chunk_desc.data.data_type)); + + chunk_stride_in_byte = chunk_desc.data.layout_desc.blocking.strides[0][axis] * elem_size * abs_stride; + chunk_offset_in_byte = sign_of_stride < 0 ? (iter_count - 1) * chunk_stride_in_byte : 0; + chunk_stride_in_byte *= sign_of_stride; + + if (sliced_src) { + reorders.emplace_back(chunk_mem_prim, to->GetPrimitive()); } else { - auto abs_stride = std::abs(stride); - auto sign_of_stride = stride < 0.0f ? -1 : 1; - - IE_ASSERT(n_iter == full_dims[axis] / abs_stride) << "Shape mismatch for tensor iterator port"; - - full_dims[axis] = abs_stride; - IE_ASSERT(full_dims == part_dims) << "Shape mismatch for tensor iterator port"; - - iter_count = n_iter; - - // make chunk view - auto chunk_desc = full_blob->GetDescriptor(); - chunk_desc.data.dims[axis] = abs_stride; - chunk_desc.data.layout_desc.blocking.padding_dims[axis] = abs_stride; // TODO: asamption that plain tensor - - mem_holder.push_back(full_blob->GetPrimitive()); - auto full_mem_handler = full_blob->GetPrimitive().get_data_handle(); - mem_holder.emplace_back(mkldnn::memory::primitive_desc(chunk_desc, eng), full_mem_handler); - auto &chunk_mem_prim = mem_holder.back(); - - auto elem_size = MKLDNNExtensionUtils::sizeOfDataType(mkldnn::memory::data_type(chunk_desc.data.data_type)); - - chunk_stride_in_byte = chunk_desc.data.layout_desc.blocking.strides[0][axis] * elem_size * abs_stride; - chunk_offset_in_byte = sign_of_stride < 0 ? (iter_count - 1) * chunk_stride_in_byte : 0; - chunk_stride_in_byte *= sign_of_stride; - - if (as_input) { - reorders.emplace_back(chunk_mem_prim, to->GetPrimitive()); - } else { - reorders.emplace_back(from->GetPrimitive(), chunk_mem_prim); - } + reorders.emplace_back(from->GetPrimitive(), chunk_mem_prim); } } - void execute(int n_iter, mkldnn::stream strm) override { - if (chunk_stride_in_byte != 0) { - IE_ASSERT(n_iter < iter_count); + void execute(mkldnn::stream strm, int iter) override { + IE_ASSERT(iter >= 0 && iter < iter_count); - auto full_mem = mem_holder[FULL_DATA]; - auto chunk_mem = mem_holder[CHUNK_DATA]; + auto full_mem = mem_holder[FULL_DATA]; + auto chunk_mem = mem_holder[CHUNK_DATA]; - chunk_mem.set_data_handle(static_cast(full_mem.get_data_handle()) + - chunk_offset_in_byte + chunk_stride_in_byte * n_iter); + chunk_mem.set_data_handle(static_cast(full_mem.get_data_handle()) + + chunk_offset_in_byte + chunk_stride_in_byte * iter); - strm.submit({reorders.begin(), reorders.end()}); - } else { - if (as_input ? n_iter == 0 : n_iter == (iter_count - 1)) - strm.submit({reorders.begin(), reorders.end()}); - } - }; + strm.submit({reorders.begin(), reorders.end()}); + } private: - bool as_input; ptrdiff_t chunk_stride_in_byte = 0; ptrdiff_t chunk_offset_in_byte = 0; const int FULL_DATA = 0; const int CHUNK_DATA = 1; + int iter_count; }; class BackEdgePortHelper : public PortMapHelper { public: - BackEdgePortHelper(const MKLDNNMemoryPtr &from, const MKLDNNMemoryPtr &to, const mkldnn::engine& eng, int n_iter) { - auto mem_desc = from->GetDescriptor(); - mem_holder.emplace_back(mkldnn::memory::primitive_desc(mem_desc, eng)); + BackEdgePortHelper(const MKLDNNMemoryPtr &from, const MKLDNNMemoryPtr &to, const mkldnn::engine& eng) { reorders.emplace_back(from->GetPrimitive(), to->GetPrimitive()); - iter_count = n_iter; } - void execute(int n_iter, mkldnn::stream strm) override { - if (n_iter < iter_count - 1) { + void execute(mkldnn::stream strm, int iter) override { + if (iter != 0) { strm.submit({reorders.begin(), reorders.end()}); } - }; + } +}; + +class IterCountPortHelper : public PortMapHelper { +public: + IterCountPortHelper(const MKLDNNMemoryPtr &to, const mkldnn::engine& eng) { + // Only scalar I32 tensor is supported + IE_ASSERT(to->GetDataType() == memory::s32); + IE_ASSERT(to->GetDims() == memory::dims{1}); + mem_holder.push_back(to->GetPrimitive()); + } + + void execute(mkldnn::stream strm, int n_iter) override { + auto mem = mem_holder[0]; + auto data_ptr = static_cast(mem.get_data_handle()); + *data_ptr = n_iter; + } +}; + +class asBoolCheck : public PortChecker { +public: + asBoolCheck(const MKLDNNMemoryPtr &mem) { + IE_ASSERT(mem->GetDataType() == memory::u8); + IE_ASSERT(mem->GetDims() == memory::dims{1}); + mem_holder.push_back(mem->GetPrimitive()); + } + + int getStatus() override { + auto mem = mem_holder[0]; + auto data_ptr = static_cast(mem.get_data_handle()); + return *data_ptr == static_cast(0) ? 0 : 1; + } +}; + +class asIntCheck : public PortChecker { +public: + asIntCheck(const MKLDNNMemoryPtr &mem) { + IE_ASSERT(mem->GetDataType() == memory::s32); + IE_ASSERT(mem->GetDims() == memory::dims{1}); + mem_holder.push_back(mem->GetPrimitive()); + } + + int getStatus() override { + auto mem = mem_holder[0]; + auto data_ptr = static_cast(mem.get_data_handle()); + return *data_ptr; + } +}; + +class staticValueCheck : public PortChecker { +public: + staticValueCheck(const int &value) : value(value) {} + + int getStatus() override { + return value; + } +private: + int value; }; } // namespace MKLDNNPlugin @@ -157,25 +197,19 @@ void MKLDNNTensorIteratorNode::getSupportedDescriptors() { sub_graph.CreateGraph(ti->body, ext_mng, weightCache); // Try to detect inputs and outputs by indexes - std::map in_map, out_map; - for (auto node : sub_graph.GetNodes()) - if (node->getType() == Input) // filter by type Input - in_map[node->getName().substr(3)] = node; // remove "in_" prefix - - for (auto node : sub_graph.GetOutputNodes()) - out_map[node->getName().substr(4)] = node; // remove "out_" prefix - + const auto &in_map = sub_graph.GetInputNodes(); for (const auto &in_data : ti->body.inputs) { if (in_data->getName() == "const_holder") continue; - auto &in_node = in_map[in_data->getName()]; + auto &in_node = in_map.at(in_data->getName()); auto in_mem = in_node->getChildEdgeAt(0)->getMemoryPtr(); input_mem.push_back(in_mem); } - for (const auto &out_data : ti->body.outputs) { - auto &out_node = out_map[out_data->getName()]; - auto out_mem = out_node->getParentEdgeAt(0)->getMemoryPtr(); + // Assume that order of outputs in original TI and produces sub_graph is same + const auto &out_vec = sub_graph.GetOutputNodes(); + for (size_t i = 0; i < out_vec.size(); i++) { + auto out_mem = out_vec[i]->getParentEdgeAt(0)->getMemoryPtr(); output_mem.push_back(out_mem); } } @@ -194,52 +228,99 @@ void MKLDNNTensorIteratorNode::createPrimitive() { if (ti == nullptr) THROW_IE_EXCEPTION << "Cannot convert to TensorIterator layer."; + const auto &eng = getEngine(); + for (auto map_rule : ti->input_port_map) { - auto &extr_mem = getParentEdgesAtPort(map_rule.from)[0]->getMemoryPtr(); - auto &intr_mem = input_mem[map_rule.to]; + auto &from_mem = getParentEdgesAtPort(map_rule.from)[0]->getMemoryPtr(); + auto &to_mem = input_mem[map_rule.to]; - auto mapper = std::shared_ptr( - new PortIteratorHelper (extr_mem, intr_mem, true, map_rule, getEngine(), n_iter)); - - in_port_mappers.push_back(mapper); + if (map_rule.axis == -1) + first_mappers.emplace_back(new BackEdgePortHelper(from_mem, to_mem, eng)); + else + before_mappers.emplace_back(new PortIteratorHelper(from_mem, to_mem, true, map_rule, eng)); } for (auto map_rule : ti->output_port_map) { - auto &extr_mem = getChildEdgesAtPort(map_rule.from)[0]->getMemoryPtr(); - auto &intr_mem = output_mem[map_rule.to]; + auto &to_mem = getChildEdgesAtPort(map_rule.from)[0]->getMemoryPtr(); + auto &from_mem = output_mem[map_rule.to]; - auto mapper = std::shared_ptr( - new PortIteratorHelper (intr_mem, extr_mem, false, map_rule, getEngine(), n_iter)); - - out_port_mappers.push_back(mapper); + if (map_rule.axis == -1) + last_mappers.emplace_back(new BackEdgePortHelper(from_mem, to_mem, eng)); + else + after_mappers.emplace_back(new PortIteratorHelper(from_mem, to_mem, false, map_rule, eng)); } for (auto map_rule : ti->back_edges) { auto from_mem = output_mem[map_rule.from]; auto to_mem = input_mem[map_rule.to]; - auto mapper = std::shared_ptr( - new BackEdgePortHelper(from_mem, to_mem, getEngine(), n_iter)); + before_mappers.emplace_back(new BackEdgePortHelper(from_mem, to_mem, eng)); + } - out_port_mappers.push_back(mapper); + // special purpose ports + constexpr auto key_cur_iter_port = "loop_body_current_iteration_idx"; + constexpr auto key_cond_port = "loop_body_condition_output_idx"; + constexpr auto key_trip_count_port = "loop_trip_count_idx"; + constexpr auto key_init_cond_port = "loop_execution_condition_idx"; + + auto iter_idx_ports = ti->GetParamAsInts(key_cur_iter_port, {}); + for (auto idx : iter_idx_ports) { + auto to_mem = input_mem[idx]; + before_mappers.emplace_back(new IterCountPortHelper(to_mem, eng)); + } + + auto condition_port_idx = ti->GetParamAsInt(key_cond_port, -1); + if (condition_port_idx == -1) { + continue_cond_check.reset(new staticValueCheck(true)); // always true + } else { + auto mem = output_mem[condition_port_idx]; + continue_cond_check.reset(new asBoolCheck(mem)); + } + + auto trip_count_port_idx = ti->GetParamAsInt(key_trip_count_port, -1); + if (trip_count_port_idx == -1) { + trip_count_check.reset(new staticValueCheck(n_iter)); // use statically calculated num of iteration + } else { + auto mem = getParentEdgesAtPort(trip_count_port_idx)[0]->getMemoryPtr(); + trip_count_check.reset(new asIntCheck(mem)); + } + + auto init_cond_port_idx = ti->GetParamAsInt(key_init_cond_port, -1); + if (init_cond_port_idx == -1) { + initial_cond_check.reset(new staticValueCheck(true)); + } else { + auto mem = getParentEdgesAtPort(init_cond_port_idx)[0]->getMemoryPtr(); + initial_cond_check.reset(new asBoolCheck(mem)); } } void MKLDNNTensorIteratorNode::execute(mkldnn::stream strm) { sub_graph.ResetInferCount(); - for (int i = 0; i < n_iter; i++) { + bool continue_cond = initial_cond_check->getStatus(); + int max_num_iter = trip_count_check->getStatus(); + + for (auto &mapper : first_mappers) + mapper->execute(strm); + + // use "i != max_num_iter" only to allow "-1" works like infinite loop + for (int i = 0; i != max_num_iter && continue_cond; i++) { // copy data to subgraph iteration - for (auto &mapper : in_port_mappers) - mapper->execute(i, strm); + for (auto &mapper : before_mappers) + mapper->execute(strm, i); sub_graph.Infer(); + continue_cond = continue_cond_check->getStatus(); + // copy data from subgraph iteration to outputs - // or next iteration inputs - for (auto &mapper : out_port_mappers) - mapper->execute(i, strm); + // or to next iteration inputs + for (auto &mapper : after_mappers) + mapper->execute(strm, i); } + + for (auto &mapper : last_mappers) + mapper->execute(strm); } bool MKLDNNTensorIteratorNode::created() const { diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.h index f7c6bffe289..3d32adf3f80 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_tensoriterator_node.h @@ -13,16 +13,35 @@ namespace MKLDNNPlugin { +/** + * Functor interface to perform some action with pointed tensors (captured in constructor) + * Generally it's read, write or move data from specified tensors. + * Action may depends on iteration index. + */ class PortMapHelper { public: virtual ~PortMapHelper() = default; - virtual void execute(int n_iter, mkldnn::stream strm) = 0; + virtual void execute(mkldnn::stream strm, int n_iter = -1) = 0; protected: std::vector reorders; std::vector mem_holder; - int iter_count; }; + +/** + * Functor interface to perform check of data tensor (captured in constructor) + * Information extracted as int. Meaning of returned value is specific for + * particular type of checker. + */ +class PortChecker { +public: + virtual ~PortChecker() = default; + virtual int getStatus() = 0; +protected: + std::vector mem_holder; +}; + + class MKLDNNTensorIteratorNode : public MKLDNNNode { public: MKLDNNTensorIteratorNode(InferenceEngine::CNNLayerPtr layer, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache); @@ -35,6 +54,7 @@ public: void execute(mkldnn::stream strm) override; void setExtManager(const MKLDNNExtensionManager::Ptr& extMgr) { ext_mng = extMgr; } + private: int n_iter = 0; @@ -42,7 +62,16 @@ private: MKLDNNGraph sub_graph; std::vector input_mem, output_mem; - std::vector> in_port_mappers, out_port_mappers; + std::vector> + first_mappers, /// < Applied once before loop + last_mappers, /// < Applied once after loop + before_mappers, /// < Applied before each iteration + after_mappers; /// < Applied after each iteration + + std::shared_ptr + trip_count_check, /// < Perform check of trip count value. value >= -1 + initial_cond_check, /// < Perform check of initial continue condition value. value [0, 1] + continue_cond_check; /// < Perform check of continue condition value of body. value [0, 1] }; } // namespace MKLDNNPlugin diff --git a/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp b/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp index 4da31e8bfa2..0514b741b61 100644 --- a/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp +++ b/inference-engine/src/transformations/src/transformations/common_optimizations/nop_elimination.cpp @@ -332,18 +332,12 @@ static bool eliminate_squeeze(const std::shared_ptr& node) { return false; } -static bool eliminate_stop_gradient(const std::shared_ptr& node) { - replace_output_update_name(node->output(0), node->input_value(0)); - return true; -} - bool pass::NopElimination::run_on_function(std::shared_ptr function) { static const std::unordered_map&)>> dispatcher{{TI(opset3::Pad), &eliminate_nop}, {TI(op::v0::Sum), &eliminate_sum}, {TI(opset3::Convert), &eliminate_convert}, {TI(op::v0::Slice), &eliminate_nop}, - {TI(op::v0::StopGradient), &eliminate_stop_gradient}, {TI(opset3::Reshape), &eliminate_reshape_v1}, {TI(opset3::Concat), &eliminate_concat}, {TI(opset3::Squeeze), &eliminate_squeeze}, diff --git a/inference-engine/src/vpu/common/CMakeLists.txt b/inference-engine/src/vpu/common/CMakeLists.txt index d0cd7c00952..35a7a61437b 100644 --- a/inference-engine/src/vpu/common/CMakeLists.txt +++ b/inference-engine/src/vpu/common/CMakeLists.txt @@ -39,8 +39,6 @@ function(add_common_target TARGET_NAME STATIC_IE) $) if(WIN32) - target_compile_definitions(${TARGET_NAME} PRIVATE NOMINMAX) - set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME}) endif() @@ -54,6 +52,10 @@ function(add_common_target TARGET_NAME STATIC_IE) target_link_libraries(${TARGET_NAME} PUBLIC ${NGRAPH_LIBRARIES} inference_engine_transformations PRIVATE openvino::itt) + + if(NOT STATIC_IE) + target_link_libraries(${TARGET_NAME} PUBLIC inference_engine_legacy) + endif() endfunction() add_common_target("vpu_common_lib" FALSE) diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/convert_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/convert_tests.cpp new file mode 100644 index 00000000000..d614c62c5ab --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/convert_tests.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadConvertNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 3 + 4 + + + + + + + + 1 + 3 + 4 + + + + + 1 + 3 + 4 + + + + + + + 1 + 3 + 4 + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 3 + 4 + + + + + + + + 1 + 3 + 4 + + + + + 1 + 3 + 4 + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 0); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/depth_to_space_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/depth_to_space_tests.cpp new file mode 100644 index 00000000000..858d3e626cb --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/depth_to_space_tests.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2019-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadDepthToSpaceNetwork) { + std::string model = R"V0G0N( + + + + + + + 5 + 4 + 28 + 2 + + + + + + + + 5 + 4 + 28 + 2 + + + + + 5 + 1 + 56 + 4 + + + + + + + 5 + 1 + 56 + 4 + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 5 + 4 + 28 + 2 + + + + + + + 6 + + + + + + + + + + + 5 + 4 + 28 + 2 + + + 6 + + + + + 5 + 2 + 2 + 1 + 28 + 2 + + + + + + + + 5 + 2 + 2 + 1 + 28 + 2 + + + + + 5 + 1 + 28 + 2 + 2 + 2 + + + + + + + 4 + + + + + + + + + + + 5 + 1 + 28 + 2 + 2 + 2 + + + 4 + + + + + 5 + 1 + 56 + 4 + + + + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 80, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 0; + buffer[1] = 2; + buffer[2] = 2; + buffer[3] = 1; + buffer[4] = 28; + buffer[5] = 2; + buffer[7] = 0; + buffer[7] = 1; + buffer[8] = 56; + buffer[9] = 4; + }); +} diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/floor_mod_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/floor_mod_tests.cpp new file mode 100644 index 00000000000..60fb41b9ae6 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/floor_mod_tests.cpp @@ -0,0 +1,179 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadFloorModNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 1 + 4 + + + + + + + + 1 + + + + + + + + 3 + + + + + + + + 1 + + + 3 + + + + + 1 + 1 + 1 + + + + + + + 1 + 1 + 4 + + + 1 + 1 + 1 + + + + + 1 + 1 + 4 + + + + + + + 1 + 1 + 4 + + + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 1 + 4 + + + + + + + 1 + + + + + + + 3 + + + + + + + + + + + 1 + + + 3 + + + + + 1 + 1 + 1 + + + + + + + + 1 + 1 + 4 + + + 1 + 1 + 1 + + + + + 1 + 1 + 4 + + + + + + + + + + + +)V0G0N"; + // compareIRs(model, modelV7, 0); + compareIRs(model, modelV7, 40, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 1; + buffer[1] = 1; + buffer[2] = 1; + }); +} diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/gather_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/gather_tests.cpp new file mode 100644 index 00000000000..86c1a7b6010 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/gather_tests.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadGatherNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 3 + 4 + + + + + + + + 1 + + + + + + + + + + + + + 1 + 3 + 4 + + + 1 + + + + + + 1 + 3 + 4 + + + + + + + 1 + 3 + 4 + + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 3 + 4 + + + + + + + 1 + + + + + + + + 1 + 3 + 4 + + + 1 + + + + + 1 + 3 + 4 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 16, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 0; + }); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/minimum_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/minimum_tests.cpp new file mode 100644 index 00000000000..fe6efe7afcd --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/minimum_tests.cpp @@ -0,0 +1,190 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadMinimumNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 1 + 27 + 27 + + + + + + + + 1 + 1 + 27 + 27 + + + + + + + 1 + 1 + 27 + 27 + + + 1 + 1 + 27 + 27 + + + + + 1 + 1 + 27 + 27 + + + + + + + 1 + 1 + 27 + 27 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 1 + 27 + 27 + + + + + + + + 1 + 1 + 27 + 27 + + + + + 1 + 1 + 27 + 27 + + + + + + + 1 + 1 + 27 + 27 + + + + + + + + 1 + 1 + 27 + 27 + + + + + 1 + 1 + 27 + 27 + + + + + + + + 1 + 1 + 27 + 27 + + + 1 + 1 + 27 + 27 + + + + + 1 + 1 + 27 + 27 + + + + + + + + 1 + 1 + 27 + 27 + + + + + 1 + 1 + 27 + 27 + + + + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 0); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/multiply_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/multiply_tests.cpp new file mode 100644 index 00000000000..470e58c136b --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/multiply_tests.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadMultiplyNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 4 + + + + + + + + 1 + 4 + + + + + + + 1 + 4 + + + 1 + 4 + + + + + 1 + 4 + + + + + + + 1 + 4 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 4 + + + + + + + 1 + 4 + + + + + + + + 1 + 4 + + + 1 + 4 + + + + + 1 + 4 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 0); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/normalize_l2_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/normalize_l2_tests.cpp new file mode 100644 index 00000000000..ba5397d33af --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/normalize_l2_tests.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2019-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadNormalizeL2Network) { + std::string model = R"V0G0N( + + + + + + + 6 + 24 + 12 + 10 + + + + + + + + 1 + + + + + + + + 6 + 24 + 12 + 10 + + + 1 + + + + + 6 + 24 + 12 + 10 + + + + + + + + 1 + + + + + + + 6 + 24 + 12 + 10 + + + 1 + + + + + 6 + 24 + 12 + 10 + + + + + + + 6 + 24 + 12 + 10 + + + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 6 + 24 + 12 + 10 + + + + + + + + 6 + 24 + 12 + 10 + + + + + 6 + 24 + 12 + 10 + + + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 100, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 1; + buffer[1] = 32831; + }); +} diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/not_equal_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/not_equal_tests.cpp new file mode 100644 index 00000000000..7a2e114a7bb --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/not_equal_tests.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +//) +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadNotEqualNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 4 + + + + + + + + 1 + 4 + + + + + + + 1 + 4 + + + 1 + 4 + + + + + 1 + 4 + + + + + + + 1 + 4 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 4 + + + + + + + 1 + 4 + + + + + + + + 1 + 4 + + + 1 + 4 + + + + + 1 + 4 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 0); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_min_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_min_tests.cpp new file mode 100644 index 00000000000..e73a529c6f0 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_min_tests.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2019-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadReduceMinNetwork) { + std::string model = R"V0G0N( + + + + + + + 3 + 2 + 2 + + + + + + + + 3 + + + + + + + + 3 + 2 + 2 + + + 3 + + + + + 1 + 1 + 1 + + + + + + + 1 + 1 + 1 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 3 + 2 + 2 + + + + + + + 3 + + + + + + + + + + + 3 + 2 + 2 + + + 3 + + + + + 1 + 1 + 1 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 100, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 0; + buffer[1] = 1; + buffer[2] = 2; + }); +} diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_prod_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_prod_tests.cpp new file mode 100644 index 00000000000..7065eeb4855 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/reduce_prod_tests.cpp @@ -0,0 +1,115 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadReduceProdNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 1 + 4 + + + + + + + + 1 + + + + + + + + 1 + 1 + 4 + + + 1 + + + + + 1 + 4 + + + + + + + 1 + 4 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 1 + 4 + + + + + + + 1 + + + + + + + + + + + 1 + 1 + 4 + + + 1 + + + + + 1 + 4 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 16, [](Blob::Ptr& weights) { + auto *buffer = weights->buffer().as(); + buffer[0] = 1; + }); +} diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/space_to_depth_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/space_to_depth_tests.cpp new file mode 100644 index 00000000000..013edcaf097 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/space_to_depth_tests.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2019-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadSpaceToDepthNetwork) { + std::string model = R"V0G0N( + + + + + + + 6 + 5 + 4 + 4 + + + + + + + + 6 + 5 + 4 + 4 + + + + + 6 + 20 + 2 + 2 + + + + + + + 6 + 20 + 2 + 2 + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 6 + 5 + 4 + 4 + + + + + + + 6 + + + + + + + + + + + 6 + 5 + 4 + 4 + + + 6 + + + + + 6 + 5 + 2 + 2 + 2 + 2 + + + + + + + + 6 + 5 + 2 + 2 + 2 + 2 + + + + + 6 + 2 + 2 + 5 + 2 + 2 + + + + + + + 4 + + + + + + + + + + + 6 + 2 + 2 + 5 + 2 + 2 + + + 4 + + + + + 6 + 20 + 2 + 2 + + + + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 80, [](Blob::Ptr& weights) { + auto* buffer = weights->buffer().as(); + buffer[0] = 6; + buffer[1] = 5; + buffer[2] = 2; + buffer[3] = 2; + buffer[4] = 2; + buffer[5] = 2; + buffer[7] = 6; + buffer[7] = 14; + buffer[8] = 2; + buffer[9] = 2; + }); +} \ No newline at end of file diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/subtract_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/subtract_tests.cpp new file mode 100644 index 00000000000..6230c0252b7 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/subtract_tests.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "ngraph_reader_tests.hpp" +TEST_F(NGraphReaderTests, ReadSubtractNetwork) { + std::string model = R"V0G0N( + + + + + + + 3 + 4 + 5 + + + + + + + + 3 + 4 + 5 + + + + + + + 3 + 4 + 5 + + + 3 + 4 + 5 + + + + + 3 + 4 + 5 + + + + + + + 3 + 4 + 5 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 3 + 4 + 5 + + + + + + + 3 + 4 + 5 + + + + + + + + 3 + 4 + 5 + + + + + 3 + 4 + 5 + + + + + + + + 3 + 4 + 5 + + + 3 + 4 + 5 + + + + + 3 + 4 + 5 + + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7, 0); +} diff --git a/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp b/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp index 7056b31d43a..b0a0e3b5728 100644 --- a/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp +++ b/inference-engine/tests/functional/inference_engine/transformations/nop_elimination.cpp @@ -97,19 +97,6 @@ TEST(nop_elimination, eliminate_broadcast) { ASSERT_EQ(count_ops_of_type(f), 0); } -TEST(nop_elimination, eliminate_stop_gradient) { - Shape shape{}; - auto A = make_shared(element::f32, shape); - auto s = make_shared(A); - auto f = make_shared(make_shared(s), ParameterVector{A}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); -} - TEST(nop_elimination, pass_property) { auto pass = std::make_shared(); ASSERT_FALSE(pass->get_property(pass::PassProperty::CHANGE_DYNAMIC_STATE)); diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp index fc50b3b78f2..c011eb31327 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/activation.cpp @@ -23,34 +23,36 @@ const std::vector netPrecisions = { }; const std::map>> activationTypes = { - {Sigmoid, {}}, - {Tanh, {}}, - {Relu, {}}, - {Exp, {}}, - {Log, {}}, - {Sign, {}}, - {Abs, {}}, - {Clamp, {{-2.0f, 2.0f}}}, - {Negative, {}}, - {Acos, {}}, - {Asin, {}}, - {Atan, {}}, - {Cos, {}}, - {Cosh, {}}, - {Floor, {}}, - {Sin, {}}, - {Sinh, {}}, - {Sqrt, {}}, - {Tan, {}}, - {Elu, {{0.1f}}}, - {Erf, {}}, - {HardSigmoid, {{0.2f, 0.5f}}}, - {Selu, {{1.6732f, 1.0507f}}}, - {Ceiling, {}}, - {Mish, {}}, - {HSwish, {}}, - {SoftPlus, {}}, - {HSigmoid, {}} + {Sigmoid, {}}, + {Tanh, {}}, + {Relu, {}}, + {Exp, {}}, + {Log, {}}, + {Sign, {}}, + {Abs, {}}, + {Clamp, {{-2.0f, 2.0f}}}, + {Negative, {}}, + {Acos, {}}, + {Asin, {}}, + {Atan, {}}, + {Cos, {}}, + {Cosh, {}}, + {Floor, {}}, + {Sin, {}}, + {Sinh, {}}, + {Sqrt, {}}, + {Tan, {}}, + {Elu, {{0.1f}}}, + {Erf, {}}, + {HardSigmoid, {{0.2f, 0.5f}}}, + {Selu, {{1.6732f, 1.0507f}}}, + {Ceiling, {}}, + {Mish, {}}, + {HSwish, {}}, + {SoftPlus, {}}, + {HSigmoid, {}}, + {RoundHalfToEven, {}}, + {RoundHalfAwayFromZero, {}} }; const std::map>> activationParamTypes = { diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp index 1b1fe9d8285..c4ae2bbaeff 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp @@ -3,7 +3,6 @@ // #include -#include #include "single_layer_tests/loop.hpp" #include "common_test_utils/test_constants.hpp" @@ -12,9 +11,9 @@ using namespace LayerTestsDefinitions; namespace { // without clip values increase rapidly, so use only seq_lenghts = 2 std::vector execute_first_iteration{true}; - std::vector is_body_condition_const{true, false}; - std::vector body_condition{true, false}; // works only if is_body_condition_const == true - std::vector trip_count{1, 10, -1}; // -1 means infinity + std::vector is_body_condition_const{true/*, false*/}; + std::vector body_condition{true/*, false*/}; // works only if is_body_condition_const == true + std::vector trip_count{1, 10/*, -1*/}; // -1 means infinity std::vector, LOOP_IN_TYPE>>> inputs = { {{{32, 1, 10}, LOOP_IN_TYPE::INVARIANT}, {{32, 1, 10}, LOOP_IN_TYPE::INVARIANT}, {{32, 1, 10}, LOOP_IN_TYPE::MERGED}}, }; @@ -31,4 +30,37 @@ namespace { ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), LoopTest::getTestCaseName); + + static const std::vector> static_loop_types { + // GCC4.8 limitation: have to specify type of each element in list + // static_trip_count | max | dynamic_exit | axis + std::tuple{ true , 5, -1, -1 }, // n_iter 5, no dynamic exit + std::tuple{ true , 5, 3, -1 }, // n_iter 3, dynamic exit on 3 + std::tuple{ true , 5, 7, -1 }, // n_iter 5, dynamic exit not reached + std::tuple{ true , -1, 5, -1 }, // n_iter 5, inf loop with dynamic exit on 5 + std::tuple{ true , 5, -1, 1 }, // n_iter 5, const for loop with auto concatenated out + std::tuple{ false , 5, -1, -1 }, // | + std::tuple{ false , 5, 3, -1 }, // | same with dynamic trip count + std::tuple{ false , 5, 7, -1 }, // | + std::tuple{ false , -1, 5, -1 } // | + }; + + using namespace testing; + using namespace InferenceEngine; + + INSTANTIATE_TEST_CASE_P(smoke_StaticShapeLoop, StaticShapeLoopTest, + Combine( + Values(true), + ValuesIn(static_loop_types), + Values(7), + Values({2, 1, 4}), + Values(Precision::FP32, Precision::I32), + Values(CommonTestUtils::DEVICE_CPU))); + using namespace testing; + INSTANTIATE_TEST_CASE_P(smoke_TrivialLoop, TrivialLoopTest, + Combine( + Values(Precision::FP32, Precision::I32), + Values({2, 3, 4}), + Values(CommonTestUtils::DEVICE_CPU))); + } // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/split.cpp index 76cb74a1dc5..e29eef1ef01 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/split.cpp @@ -25,7 +25,22 @@ INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + SplitLayerTest::getTestCaseName); + +INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, SplitLayerTest, + ::testing::Combine( + ::testing::Values(5), + ::testing::Values(0), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({0, 3})), ::testing::Values(CommonTestUtils::DEVICE_CPU)), SplitLayerTest::getTestCaseName); } // namespace 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 052527c6a05..eff5c10d824 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 @@ -53,8 +53,6 @@ std::vector disabledTestPatterns() { // TODO: Issue: 38841 R"(.*TopKLayerTest.*k=10.*mode=min.*sort=index.*)", R"(.*TopKLayerTest.*k=5.*sort=(none|index).*)", - // TODO: not supported yet, ticket 37690 - R"(.*Loop.*)", // TODO: Issue: 41694 R"(.*smoke_Set2.*CTCLossLayerTest.*)", }; diff --git a/inference-engine/tests/functional/plugin/gna/import_export_network.cpp b/inference-engine/tests/functional/plugin/gna/import_export_network.cpp index 01b18a72457..9c0313ffef7 100644 --- a/inference-engine/tests/functional/plugin/gna/import_export_network.cpp +++ b/inference-engine/tests/functional/plugin/gna/import_export_network.cpp @@ -70,7 +70,14 @@ class ImportNetworkTest : public testing::WithParamInterfaceImportNetwork(inputStream, targetDevice, configuration); + for (const auto& next_input : importedNetwork.GetInputsInfo()) { + ASSERT_NO_THROW(executableNetwork.GetInputsInfo()[next_input.first]); + } + for (const auto& next_output : importedNetwork.GetOutputsInfo()) { + ASSERT_NO_THROW(executableNetwork.GetOutputsInfo()[next_output.first]); + } + auto importedOutputs = CalculateImportedNetwork(importedNetwork); Compare(importedOutputs, actualOutputs); } @@ -107,9 +114,7 @@ class ImportNetworkTest : public testing::WithParamInterface exportConfiguration; std::map importConfiguration; - std::vector> CalculateImportedNetwork(std::istream& networkModel) { - auto importedNetwork = core->ImportNetwork(networkModel, targetDevice, configuration); - + std::vector> CalculateImportedNetwork(InferenceEngine::ExecutableNetwork& importedNetwork) { auto refInferRequest = importedNetwork.CreateInferRequest(); std::vector refInfos; for (const auto& input : importedNetwork.GetInputsInfo()) { diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/split.cpp index 65e0a2550fc..dcaa8d5d991 100644 --- a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/split.cpp @@ -26,6 +26,7 @@ INSTANTIATE_TEST_CASE_P(DISABLED_smoke_NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(std::vector({30, 30})), + ::testing::Values(std::vector({})), ::testing::Values(CommonTestUtils::DEVICE_GNA)), SplitLayerTest::getTestCaseName); diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/memory_eltwise_reshape_concat.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/memory_eltwise_reshape_concat.cpp new file mode 100644 index 00000000000..102bec2ca9d --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/memory_eltwise_reshape_concat.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +#include +#include "common_test_utils/test_constants.hpp" + +namespace SubgraphTestsDefinitions { +namespace { +std::vector input_multiples = { + 1, + 7, + 5, + 8 +}; + +std::vector concat_sizes = { + 32, + 64 +}; + +std::map additional_config = { + {"GNA_COMPACT_MODE", "NO"}, + {"GNA_DEVICE_MODE", "GNA_SW_FP32"}, + {"GNA_SCALE_FACTOR_0", "1638.4"}, +}; +} // namespace + +INSTANTIATE_TEST_CASE_P(smoke_MemoryEltwiseReshapeConcatTest, MemoryEltwiseReshapeConcatTest, + ::testing::Combine( + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::Values(InferenceEngine::Precision::FP32), + ::testing::ValuesIn(input_multiples), + ::testing::ValuesIn(concat_sizes), + ::testing::Values(additional_config)), + MemoryEltwiseReshapeConcatTest::getTestCaseName); +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/split.cpp index bcbd26b4f44..bf70bcebe03 100644 --- a/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/gpu/shared_tests_instances/single_layer_tests/split.cpp @@ -26,8 +26,22 @@ INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({})), ::testing::Values(CommonTestUtils::DEVICE_GPU)), SplitLayerTest::getTestCaseName); +INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, SplitLayerTest, + ::testing::Combine( + ::testing::Values(5), + ::testing::Values(0), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({0, 3})), + ::testing::Values(CommonTestUtils::DEVICE_GPU)), + SplitLayerTest::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp index 8ec930ec296..2f0903066c5 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp @@ -16,7 +16,7 @@ const std::vector netPrecisions = { INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, SplitLayerTest, ::testing::Combine( - ::testing::Values(1), + ::testing::Values(5), // TODO: 0-axis excluded // Check (status == ie::StatusCode::OK) failed: Failed to reshape Network: // Failed to infer shapes for Split layer (Split_2) with error: @@ -28,10 +28,11 @@ INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({})), ::testing::Values(CommonTestUtils::DEVICE_MYRIAD)), SplitLayerTest::getTestCaseName); -INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, splitWithUnusedOutputsTest, +INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, SplitLayerTest, ::testing::Combine( ::testing::Values(5), // TODO: 0-axis excluded @@ -49,5 +50,5 @@ INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, splitWithUnusedOutputs std::vector({0, 4}), std::vector({2, 3})), ::testing::Values(CommonTestUtils::DEVICE_MYRIAD)), - splitWithUnusedOutputsTest::getTestCaseName); + SplitLayerTest::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp index bf3b005fdec..6d87854dbbd 100644 --- a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp @@ -29,7 +29,7 @@ using LoopParams = typename std::tuple< std::string>; // Device name class LoopTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon { + virtual public LayerTestsUtils::LayerTestsCommon { public: static std::string getTestCaseName(const testing::TestParamInfo &obj); @@ -37,4 +37,108 @@ protected: void SetUp() override; }; + +using StaticShapeLoopParams = typename std::tuple< + bool, + std::tuple< + bool, + int64_t, + int64_t, + int64_t + >, + int64_t, + InferenceEngine::SizeVector, + InferenceEngine::Precision, + std::string + >; + +/** + * Test case with static SHAPE version of loop operation. + * Total iteration count is dynamic. + */ +class StaticShapeLoopTest : 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; + std::vector> CalculateRefs() override; + +private: + bool static_iter_num; // trip count provided by constant node + bool static_continue_cond; // initial_cond provided by constant node + int64_t max_iter_num; // -1 means infinity loop (expected dynamic exit condition in body) + int64_t dynamic_exit; // -1 means always true + int64_t axis; // -1 means no auto concatenation + int64_t start_value; + InferenceEngine::SizeVector data_shape; + InferenceEngine::Precision data_prc; + + int64_t actual_n_iter(); + +protected: + void SetUp() override; +}; + + +class TrivialLoopTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon { +protected: + using RefBlobGenerator = std::function; + std::map inputGens, outputGens; + + InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo &info) const override { + auto found = inputGens.find(info.name()); + if (found != inputGens.end()) { + return found->second(info.getTensorDesc()); + } + + found = inputGens.find(""); + if (found != inputGens.end()) { + return found->second(info.getTensorDesc()); + } + + return LayerTestsCommon::GenerateInput(info); + } + + std::vector> CalculateRefs() override { + if (outputGens.empty()) + return LayerTestsCommon::CalculateRefs(); + + const auto results = function->get_results(); + const auto outs_info = cnnNetwork.getOutputsInfo(); + const auto num_out_blob = results.size(); + + std::vector> res_collection(num_out_blob); + + for (int i = 0; i < num_out_blob; i++) { + // TODO: name of original NG result doesn't match with outs after conversion. + // Expected : auto name = results[i]->get_friendly_name(); + auto name = results[i]->get_input_node_ptr(0)->get_friendly_name(); + auto data = outs_info.at(name); + IE_ASSERT(data != nullptr); + + RefBlobGenerator generator; + auto found = outputGens.find(name); + if (found != outputGens.end()) { + generator = found->second; + } else { + found = outputGens.find(""); + if (found != outputGens.end()) { + generator = found->second; + } + } + + IE_ASSERT(generator != nullptr) << "Test output generator is not specified"; + auto blob = generator(data->getTensorDesc()); + auto blob_size = blob->byteSize(); + auto blob_ptr = blob->buffer().as(); + + auto &res = res_collection[i]; + res.resize(blob_size); + std::copy(blob_ptr, blob_ptr + blob_size, res.begin()); + } + return res_collection; + } +}; + } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp index 65f0d4a7d4e..2bc03006cb0 100644 --- a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp @@ -23,6 +23,7 @@ typedef std::tuple< InferenceEngine::Layout, // Input layout InferenceEngine::Layout, // Output layout std::vector, // Input shapes + std::vector, // Used outputs indices std::string // Target device name > splitParams; @@ -35,26 +36,4 @@ protected: void SetUp() override; }; -typedef std::tuple< - size_t, // Num splits - size_t, // Axis - InferenceEngine::Precision, // Net precision - InferenceEngine::Precision, // Input precision - InferenceEngine::Precision, // Output precision - InferenceEngine::Layout, // Input layout - InferenceEngine::Layout, // Output layout - std::vector, // Input shapes - std::vector, // Used outputs indices - std::string // Target device name -> splitWithUnusedOutputsParams; - -class splitWithUnusedOutputsTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon { -public: - static std::string getTestCaseName(testing::TestParamInfo obj); - -protected: - void SetUp() override; -}; - } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/memory_eltwise_reshape_concat.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/memory_eltwise_reshape_concat.hpp new file mode 100644 index 00000000000..e49b57f7879 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/memory_eltwise_reshape_concat.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include "common_test_utils/test_common.hpp" +#include "functional_test_utils/layer_test_utils.hpp" +#include + +namespace SubgraphTestsDefinitions { +typedef std::tuple< + std::string, // Target device name + InferenceEngine::Precision, // Network precision + size_t, // Mutiples of concat size to be used as input size + size_t, // Concat size + std::map // Configuration +> memoryEltwiseReshapeConcatParams; + +class MemoryEltwiseReshapeConcatTest : public LayerTestsUtils::LayerTestsCommon, + public testing::WithParamInterface { +private: + void initTestModel(); + // you have to replace memory layers since ngraph does not support them + void initNgraphFriendlyModel(); + + // since we switching models we need to generate and save these values in SetUp + size_t inputSize; + size_t concatSize; + ngraph::element::Type ngPrc; + std::vector memory_init; + std::vector concat_vals; +protected: + void SetUp() override; + void Run() override; +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); +}; +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp index b1043a09ca6..d519cef4160 100644 --- a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp @@ -46,7 +46,9 @@ namespace LayerTestsDefinitions { result << "types=" << CommonTestUtils::vec2str(types_separate) << "_"; result << "netPRC=" << netPrecision.name() << "_"; result << "targetDevice=" << targetDevice << "_"; - return result.str(); + auto res_str = result.str(); + std::replace(res_str.begin(), res_str.end(), '-', '_'); + return res_str; } void LoopTest::SetUp() { @@ -155,5 +157,227 @@ namespace LayerTestsDefinitions { TEST_P(LoopTest, CompareWithRefs) { Run(); - }; + } + + void StaticShapeLoopTest::SetUp() { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + SetRefMode(LayerTestsUtils::IE); + + auto args_papck = std::tie(static_iter_num, max_iter_num, dynamic_exit, axis); + std::tie( + static_continue_cond, + args_papck, + start_value, + data_shape, + data_prc, + targetDevice) = GetParam(); + + const auto prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(data_prc); + const auto ngShape = ngraph::Shape{data_shape}; + const auto scalarShape = ngraph::Shape{}; + + ngraph::ParameterVector params{}; + auto cond_input_create = [¶ms] (ngraph::element::Type prc, const ngraph::Shape &shape, int value = 0, bool is_static = false) + -> std::shared_ptr { + if (is_static) + return std::make_shared(prc, shape, value); + + auto input = std::make_shared(prc, shape); + params.push_back(input); + return input; + }; + + auto start = cond_input_create(prc, ngShape); + auto count = cond_input_create(ngraph::element::i64, scalarShape, max_iter_num, static_iter_num); + auto skip = cond_input_create(ngraph::element::boolean, scalarShape, true, static_continue_cond); + + // + // count skip start count skip start + // / / + // ___*___*____ __________*___*____ | idx | data | out | + // | idx in | | ex_val idx in | | 0 | 7 | 7 | + // | | / | | | / | / | | 1 | 7 | 8 | + // | add | | less add | | 2 | 8 | 10 | + // | | true | | | | | | 3 | 10 | 13 | + // | | | | | | | | ~~~~~ * * * ~~~~~ + // | out cnd | | cnd out | + // |___*____*___| |____*_____*________| + // Full loop Dynamic exit loop + // n_iter = count n_iter = ex_val + // + auto b_indx = std::make_shared(ngraph::element::i64, ngraph::Shape{}); + auto b_data = std::make_shared(prc, ngShape); + auto b_indx_cast = std::make_shared(b_indx, prc); + auto b_add = std::make_shared(b_data, b_indx_cast, ngraph::op::AutoBroadcastSpec::NUMPY); + + std::shared_ptr b_cond; + if (dynamic_exit == -1) { + b_cond = std::make_shared(ngraph::element::boolean, ngraph::Shape{}, true); + } else { + auto b_exit_value = std::make_shared(ngraph::element::i64, scalarShape, dynamic_exit); + b_cond = std::make_shared(b_indx, b_exit_value); + } + + auto body = std::make_shared( + ngraph::OutputVector {b_cond, b_add}, // TODO: check with reverse + ngraph::ParameterVector {b_indx, b_data}); // TODO: check with reverse + + auto loop = std::make_shared(count, skip); + loop->set_function(body); + loop->set_special_body_ports({0, 0}); + loop->set_merged_input(b_data, start, b_add); + if (axis == -1) + loop->get_iter_value(b_add, -1); + else + loop->get_concatenated_slices(b_add, 0, 1, 1, -1, axis); + + function = std::make_shared( + ngraph::OutputVector {loop}, + params); + } + + InferenceEngine::Blob::Ptr StaticShapeLoopTest::GenerateInput(const InferenceEngine::InputInfo &info) const { + auto tdesc = info.getTensorDesc(); + auto blob = make_blob_with_precision(tdesc); + blob->allocate(); + + if (tdesc.getLayout() == InferenceEngine::SCALAR) { + auto scalar_1d = CommonTestUtils::make_reshape_view(blob, {1}); + CommonTestUtils::fill_data_with_broadcast(scalar_1d, 0, {static_cast(max_iter_num)}); + } else { + CommonTestUtils::fill_data_with_broadcast(blob, 0, {static_cast(start_value)}); + } + + return blob; + } + + int64_t StaticShapeLoopTest::actual_n_iter() { + constexpr auto INF_N_ITER = std::numeric_limits::max(); + IE_ASSERT(dynamic_exit != -1 || max_iter_num != -1); + + // dynamic_exit + 1 - because loop body looks like do-while loop with post condition check. + return std::min(dynamic_exit == -1 ? INF_N_ITER : dynamic_exit + 1, + max_iter_num == -1 ? INF_N_ITER : max_iter_num); + } + + // Predefined ref output + std::vector> StaticShapeLoopTest::CalculateRefs() { + bool auto_concat_out = (axis != -1); + const auto n_iter = actual_n_iter(); + + auto ref_shape = data_shape; + if (auto_concat_out) + ref_shape[axis] *= n_iter; + + using namespace CommonTestUtils; + InferenceEngine::TensorDesc tdesc {data_prc, ref_shape, InferenceEngine::TensorDesc::getLayoutByDims(ref_shape)}; + std::vector res(byte_size(tdesc)); + auto out = make_blob_with_precision(tdesc, res.data()); + + std::vector vals(n_iter); + float val = start_value; + for (int i = 0; i < n_iter; i++) { + val += i; + vals[i] = val; + } + + if (auto_concat_out) + fill_data_with_broadcast(out, axis, vals); + else + fill_data_with_broadcast(out, 0, {val}); // broadcast scalar data + + return {res}; + } + + TEST_P(StaticShapeLoopTest, CompareWithRefs) { + Run(); + } + + TEST_P(TrivialLoopTest, PassThroughBody) { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + InferenceEngine::Precision iePrc; + InferenceEngine::SizeVector ieShape; + std::tie(iePrc, ieShape, targetDevice) = GetParam(); + + const auto prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(iePrc); + const auto shape = ngraph::Shape{ieShape}; + const auto scalarShape = ngraph::Shape{}; + + auto start = std::make_shared(prc, shape); + auto count = std::make_shared(ngraph::element::i64, scalarShape, 5); + auto icond = std::make_shared(ngraph::element::boolean, scalarShape, true); + + // Loop body + auto b_data = std::make_shared(prc, shape); + auto b_cond = std::make_shared(ngraph::element::boolean, scalarShape); + + auto body = std::make_shared( + ngraph::OutputVector {b_cond, b_data}, // | passthrough body, no data changes + ngraph::ParameterVector {b_cond, b_data}); // | input -> output + + auto loop = std::make_shared(count, icond); + loop->set_function(body); + loop->set_special_body_ports({-1, 0}); + loop->set_invariant_input(b_cond, icond); + loop->set_invariant_input(b_data, start); + loop->get_iter_value(b_data, -1); + + function = std::make_shared( + ngraph::OutputVector {loop}, + ngraph::ParameterVector {start}); + + // Precalculated ref blobs + auto blob = make_blob_with_precision({iePrc, ieShape, InferenceEngine::TensorDesc::getLayoutByDims(ieShape)}); + blob->allocate(); + CommonTestUtils::fill_data_with_broadcast(blob, 0, {10}); + + inputGens[""] = [&] (InferenceEngine::TensorDesc tdesc) { return blob; }; + outputGens[""] = [&] (InferenceEngine::TensorDesc tdesc) { return blob; }; + + Run(); + } + + TEST_P(TrivialLoopTest, UnusedInputBody) { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + InferenceEngine::Precision iePrc; + InferenceEngine::SizeVector ieShape; + std::tie(iePrc, ieShape, targetDevice) = GetParam(); + + const auto prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(iePrc); + const auto shape = ngraph::Shape{ieShape}; + const auto scalarShape = ngraph::Shape{}; + + auto start = std::make_shared(prc, shape); + auto count = std::make_shared(ngraph::element::i64, scalarShape, 5); + auto icond = std::make_shared(ngraph::element::boolean, scalarShape, true); + + // Loop body + auto b_data = std::make_shared(prc, shape); + auto b_cond = std::make_shared(ngraph::element::boolean, scalarShape, true); + auto b_iter = std::make_shared(ngraph::element::i64, scalarShape); + + auto body = std::make_shared( + ngraph::OutputVector {b_cond, b_data}, + ngraph::ParameterVector {b_data, b_iter}); + + auto loop = std::make_shared(count, icond); + loop->set_function(body); + loop->set_special_body_ports({1, 0}); + loop->set_invariant_input(b_data, start); + loop->get_iter_value(b_data, -1); + + function = std::make_shared( + ngraph::OutputVector {loop}, + ngraph::ParameterVector {start}); + + // Precalculated ref blobs + auto blob = make_blob_with_precision({iePrc, ieShape, InferenceEngine::TensorDesc::getLayoutByDims(ieShape)}); + blob->allocate(); + CommonTestUtils::fill_data_with_broadcast(blob, 0, {10}); + + inputGens[""] = [&] (InferenceEngine::TensorDesc tdesc) { return blob; }; + outputGens[""] = [&] (InferenceEngine::TensorDesc tdesc) { return blob; }; + + Run(); + } } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp index 0add873c3b5..2731afaa62d 100644 --- a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp @@ -26,13 +26,16 @@ std::string SplitLayerTest::getTestCaseName(testing::TestParamInfo InferenceEngine::Precision netPrecision; InferenceEngine::Precision inPrc, outPrc; InferenceEngine::Layout inLayout, outLayout; - InferenceEngine::SizeVector inputShapes; + InferenceEngine::SizeVector inputShapes, outIndices; std::string targetDevice; - std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, targetDevice) = obj.param; + std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, outIndices, targetDevice) = obj.param; std::ostringstream result; result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; result << "numSplits=" << numSplits << "_"; result << "axis=" << axis << "_"; + if (!outIndices.empty()) { + result << "outIndices" << CommonTestUtils::vec2str(outIndices) << "_"; + } result << "IS"; result << "netPRC=" << netPrecision.name() << "_"; result << "inPRC=" << inPrc.name() << "_"; @@ -46,57 +49,14 @@ std::string SplitLayerTest::getTestCaseName(testing::TestParamInfo void SplitLayerTest::SetUp() { SetRefMode(LayerTestsUtils::RefMode::CONSTANT_FOLDING); size_t axis, numSplits; - std::vector inputShape; + std::vector inputShape, outIndices; InferenceEngine::Precision netPrecision; - std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, targetDevice) = this->GetParam(); - auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); - auto paramOuts = ngraph::helpers::convert2OutputVector( - ngraph::helpers::castOps2Nodes(params)); - auto split = std::dynamic_pointer_cast(ngraph::builder::makeSplit(paramOuts[0], - ngPrc, numSplits, axis)); - ngraph::ResultVector results; - for (int i = 0; i < numSplits; i++) { - results.push_back(std::make_shared(split->output(i))); - } - function = std::make_shared(results, params, "split"); -} - -TEST_P(SplitLayerTest, CompareWithRefs) { - Run(); -}; - -std::string splitWithUnusedOutputsTest::getTestCaseName(testing::TestParamInfo obj) { - size_t numSplits, axis; - InferenceEngine::Precision netPrecision; - InferenceEngine::Precision inPrc, outPrc; - InferenceEngine::Layout inLayout, outLayout; - InferenceEngine::SizeVector inputShapes; - std::vector outIndices; - std::string targetDevice; - std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, outIndices, targetDevice) = obj.param; - std::ostringstream result; - result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; - result << "numSplits=" << numSplits << "_"; - result << "axis=" << axis << "_"; - result << "outIndices" << CommonTestUtils::vec2str(outIndices) << "_"; - result << "IS"; - result << "netPRC=" << netPrecision.name() << "_"; - result << "inPRC=" << inPrc.name() << "_"; - result << "outPRC=" << outPrc.name() << "_"; - result << "inL=" << inLayout << "_"; - result << "outL=" << outLayout << "_"; - result << "trgDev=" << targetDevice; - return result.str(); -} - -void splitWithUnusedOutputsTest::SetUp() { - SetRefMode(LayerTestsUtils::RefMode::CONSTANT_FOLDING); - size_t axis, numSplits; - std::vector inputShape; - InferenceEngine::Precision netPrecision; - std::vector outIndices; std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, outIndices, targetDevice) = this->GetParam(); + if (outIndices.empty()) { + for (int i = 0; i < numSplits; ++i) { + outIndices.push_back(i); + } + } auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); auto paramOuts = ngraph::helpers::convert2OutputVector( @@ -110,7 +70,7 @@ void splitWithUnusedOutputsTest::SetUp() { function = std::make_shared(results, params, "split"); } -TEST_P(splitWithUnusedOutputsTest, CompareWithRefs) { +TEST_P(SplitLayerTest, CompareWithRefs) { Run(); }; diff --git a/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/memory_eltwise_reshape_concat.cpp b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/memory_eltwise_reshape_concat.cpp new file mode 100644 index 00000000000..7b9a13f0b67 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/memory_eltwise_reshape_concat.cpp @@ -0,0 +1,150 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include +#include + +#include "ie_core.hpp" + +#include "common_test_utils/common_utils.hpp" +#include "functional_test_utils/blob_utils.hpp" +#include "functional_test_utils/precision_utils.hpp" +#include "functional_test_utils/plugin_cache.hpp" +#include "functional_test_utils/skip_tests_config.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" +#include "ngraph_functions/builders.hpp" + +#include +#include "subgraph_tests/memory_eltwise_reshape_concat.hpp" + +namespace SubgraphTestsDefinitions { + +std::string MemoryEltwiseReshapeConcatTest::getTestCaseName(const testing::TestParamInfo &obj) { + std::string targetDevice; + InferenceEngine::Precision netPrecision; + size_t inputSize; + size_t concatSize; + std::map config; + std::tie(targetDevice, netPrecision, inputSize, concatSize, config) = obj.param; + std::ostringstream result; + + result << "netPrecision=" << netPrecision.name() << "_"; + result << "IS=" << inputSize << "_"; + result << "CS=" << concatSize << "_"; + result << "targetDevice=" << targetDevice; + return result.str(); +} + +void MemoryEltwiseReshapeConcatTest::SetUp() { + InferenceEngine::Precision netPrecision; + std::map config; + std::tie(targetDevice, netPrecision, inputSize, concatSize, config) = this->GetParam(); + configuration.insert(config.begin(), config.end()); + ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + + const int seed = 0; + std::mt19937 gen(static_cast(seed)); + + auto generateFloatNumbers = [gen](std::size_t vec_len, float min, float max) mutable { + std::vector res; + + std::uniform_real_distribution dist(min, max); + for (int i = 0; i < vec_len; i++) + res.emplace_back(static_cast(dist(gen))); + + return res; + }; + + memory_init = generateFloatNumbers(inputSize * concatSize, -1.0f, 1.0f); + concat_vals = generateFloatNumbers(concatSize, 12.0f, 14.0f); +} + +void MemoryEltwiseReshapeConcatTest::initTestModel() { + InferenceEngine::SizeVector input_dims = {1, inputSize * concatSize}; + auto input_parameter = ngraph::builder::makeParams(ngPrc, {input_dims}); + + auto memory_constant = ngraph::builder::makeConstant(ngPrc, input_dims, memory_init); + memory_constant->set_friendly_name("memory_constant"); + auto memory_read = std::make_shared(memory_constant, "memory"); + memory_read->set_friendly_name("memory_read"); + + auto mul = ngraph::builder::makeEltwise(input_parameter[0], memory_read, ngraph::helpers::EltwiseTypes::MULTIPLY); + mul->set_friendly_name("multiplication"); + + auto memory_write = std::make_shared(mul, "memory"); + memory_write->set_friendly_name("memory_write"); + + auto reshape_1_pattern = std::make_shared(ngraph::element::i64, ngraph::Shape{2}, std::vector({inputSize, concatSize})); + reshape_1_pattern->set_friendly_name("reshape_pattern"); + auto reshape_1 = std::make_shared(mul, reshape_1_pattern, false); + reshape_1->set_friendly_name("reshape"); + + auto concat_constant = ngraph::builder::makeConstant(ngPrc, {1, concatSize}, concat_vals); + concat_constant->set_friendly_name("concat_constant"); + + auto concat = ngraph::builder::makeConcat({concat_constant, reshape_1}, 0); + + memory_write->add_control_dependency(memory_read); + concat->add_control_dependency(memory_write); + + auto final_reshape_pattern = std::make_shared(ngraph::element::i64, ngraph::Shape{4}, + std::vector({1, 1, inputSize + 1, concatSize})); + auto final_reshape = std::make_shared(concat, final_reshape_pattern, false); + + function = std::make_shared(final_reshape, input_parameter, "memory_multiply_reshape_concat"); +} + +void MemoryEltwiseReshapeConcatTest::initNgraphFriendlyModel() { + InferenceEngine::SizeVector input_dims = {1, inputSize * concatSize}; + auto input_parameter = ngraph::builder::makeParams(ngPrc, {input_dims}); + + auto memory_constant = ngraph::builder::makeConstant(ngPrc, input_dims, memory_init); + memory_constant->set_friendly_name("memory_constant"); + + auto mul = ngraph::builder::makeEltwise(input_parameter[0], memory_constant, ngraph::helpers::EltwiseTypes::MULTIPLY); + mul->set_friendly_name("multiplication"); + + auto reshape_pattern = std::make_shared(ngraph::element::i64, ngraph::Shape{3}, std::vector({1, inputSize, concatSize})); + reshape_pattern->set_friendly_name("reshape_pattern"); + auto reshape = std::make_shared(mul, reshape_pattern, false); + reshape->set_friendly_name("reshape"); + + auto squeeze_const = std::make_shared(ngraph::element::i64, ngraph::Shape{1}, 0); + squeeze_const->set_friendly_name("squeeze_const"); + auto squeeze = std::make_shared(reshape, squeeze_const); + squeeze->set_friendly_name("squeeze"); + + auto concat_constant = ngraph::builder::makeConstant(ngPrc, {1, concatSize}, concat_vals); + concat_constant->set_friendly_name("concat_constant"); + + auto concat = ngraph::builder::makeConcat({concat_constant, squeeze}, 0); + + function = std::make_shared(concat, input_parameter, "memory_multiply_reshape_concat"); +} + +void MemoryEltwiseReshapeConcatTest::Run() { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + initTestModel(); + LoadNetwork(); + + InferenceEngine::TensorDesc state_description(InferenceEngine::Precision::FP32, + InferenceEngine::SizeVector({1, inputSize * concatSize}), + InferenceEngine::Layout::NC); + + auto states = executableNetwork.QueryState(); + auto state_values_blob = FuncTestUtils::createAndFillBlobWithFloatArray(state_description, + memory_init.data(), memory_init.size()); + states[0].SetState(state_values_blob); + Infer(); + initNgraphFriendlyModel(); + Validate(); +} + +TEST_P(MemoryEltwiseReshapeConcatTest, CompareWithRefs) { + Run(); +}; +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.cpp b/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.cpp index 12ae4eebc53..4867d8d1746 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.cpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.cpp @@ -104,6 +104,10 @@ void fill_data_with_broadcast(InferenceEngine::Blob::Ptr& blob, InferenceEngine: auto src_ptr = get_data(values); switch (blob->getTensorDesc().getPrecision()) { + case InferenceEngine::Precision::U64: + case InferenceEngine::Precision::I64: + copy_7D(src_ptr, src_strides, dst_ptr, dst_strides, dst_dims); + break; case InferenceEngine::Precision::FP32: case InferenceEngine::Precision::I32: copy_7D(src_ptr, src_strides, dst_ptr, dst_strides, dst_dims); @@ -189,6 +193,12 @@ InferenceEngine::Blob::Ptr make_reshape_view(const InferenceEngine::Blob::Ptr &b return new_blob; } +size_t byte_size(const InferenceEngine::TensorDesc &tdesc) { + auto prc = tdesc.getPrecision(); + auto dims = tdesc.getDims(); + return prc.size() * std::accumulate(std::begin(dims), std::end(dims), (size_t)1, std::multiplies()); +} + /** * repeated filling tensor with data. * diff --git a/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.hpp b/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.hpp index c6eeab1fb1e..8d46d855d3b 100644 --- a/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.hpp +++ b/inference-engine/tests/ie_test_utils/common_test_utils/data_utils.hpp @@ -72,6 +72,14 @@ InferenceEngine::Blob::Ptr make_reshape_view(const InferenceEngine::Blob::Ptr &b */ void fill_data_const(InferenceEngine::Blob::Ptr& blob, float val); + +/** + * Calculate size of buffer required for provided tensor descriptor. + * @param tdesc provided tensor descriptor + * @return size in bytes + */ +size_t byte_size(const InferenceEngine::TensorDesc &tdesc); + static void fill_data_bbox(float *data, size_t size, int height, int width, float omega) { float center_h = (height - 1.0f) / 2; float center_w = (width - 1.0f) / 2; diff --git a/inference-engine/tests/unit/gna/gna_api_stub.cpp b/inference-engine/tests/unit/gna/gna_api_stub.cpp index d109f4912f5..fb35cf82ef4 100644 --- a/inference-engine/tests/unit/gna/gna_api_stub.cpp +++ b/inference-engine/tests/unit/gna/gna_api_stub.cpp @@ -60,6 +60,14 @@ GNA2_API Gna2Status Gna2DeviceClose( return Gna2StatusSuccess; } +GNA2_API Gna2Status Gna2DeviceGetCount( + uint32_t* numberOfDevices) { + if (numberOfDevices != nullptr) { + *numberOfDevices = 1; + } + return Gna2StatusSuccess; +} + GNA2_API enum Gna2Status Gna2MemoryFree( void * memory) { return Gna2StatusSuccess; diff --git a/inference-engine/tests_deprecated/unit/engines/gna/gna_api_stub.cpp b/inference-engine/tests_deprecated/unit/engines/gna/gna_api_stub.cpp index be48e980a6f..1502f8f6141 100644 --- a/inference-engine/tests_deprecated/unit/engines/gna/gna_api_stub.cpp +++ b/inference-engine/tests_deprecated/unit/engines/gna/gna_api_stub.cpp @@ -69,6 +69,14 @@ GNA2_API Gna2Status Gna2DeviceClose( return Gna2StatusSuccess; } +GNA2_API Gna2Status Gna2DeviceGetCount( + uint32_t * numberOfDevices) { + if (numberOfDevices != nullptr) { + *numberOfDevices = 1; + } + return Gna2StatusSuccess; +} + GNA2_API enum Gna2Status Gna2MemoryFree( void * memory) { if (current != nullptr) { diff --git a/inference-engine/tests_deprecated/unit/engines/gna/gna_matcher.cpp b/inference-engine/tests_deprecated/unit/engines/gna/gna_matcher.cpp index ed787e50bce..0e8443df233 100644 --- a/inference-engine/tests_deprecated/unit/engines/gna/gna_matcher.cpp +++ b/inference-engine/tests_deprecated/unit/engines/gna/gna_matcher.cpp @@ -60,10 +60,10 @@ public: void * alloc(size_t size) noexcept override { return ptr; } - virtual bool free(void* handle) noexcept { + bool free(void* handle) noexcept override { return true; } - virtual void Release() noexcept { + void Release() noexcept override { delete this; } }; diff --git a/inference-engine/tests_deprecated/unit/engines/gna/gna_mock_api.hpp b/inference-engine/tests_deprecated/unit/engines/gna/gna_mock_api.hpp index f93effcbad9..7b3fb2d533b 100644 --- a/inference-engine/tests_deprecated/unit/engines/gna/gna_mock_api.hpp +++ b/inference-engine/tests_deprecated/unit/engines/gna/gna_mock_api.hpp @@ -102,6 +102,9 @@ class GNACppApi { MOCK_METHOD1(Gna2DeviceClose, Gna2Status ( uint32_t deviceIndex)); + MOCK_METHOD1(Gna2DeviceGetCount, Gna2Status ( + uint32_t * numberOfDevices)); + MOCK_METHOD1(Gna2MemoryFree, Gna2Status ( void * memory)); diff --git a/inference-engine/thirdparty/clDNN/api/resample.hpp b/inference-engine/thirdparty/clDNN/api/resample.hpp index add63e47a6a..e48d7e117fe 100644 --- a/inference-engine/thirdparty/clDNN/api/resample.hpp +++ b/inference-engine/thirdparty/clDNN/api/resample.hpp @@ -100,24 +100,23 @@ struct resample : public primitive_base { /// @param scale Resample scale. /// @param num_filter Input filter. Only used by bilinear sample_type. /// @param sample_type Resample method (nearest neighbor/bilinear/caffe bilinear). - /// @param with_activation Enables Relu activation. - /// @param activation_slp Relu activation slope. resample(const primitive_id& id, const primitive_id& input, tensor output_size, uint32_t num_filter, resample_type operation_type = resample_type::nearest, - bool with_activation = false, - float activation_slp = 0.0f, const padding& output_padding = padding()) : primitive_base(id, {input}, output_padding), output_size(output_size), num_filter(num_filter), + axesAndScales({}), + pads_begin({}), + pads_end({}), align_corners(1), operation_type(operation_type), shape_calc_mode(shape_calculation_mode::sizes), - with_activation(with_activation), - activation_negative_slope(activation_slp), + antialias(0), + cube_coeff(0.0f), coord_trans_mode(coordinate_transformation_mode::asymmetric), round_mode(nearest_mode::floor) { if (operation_type == resample_type::caffe_bilinear) { @@ -132,8 +131,6 @@ struct resample : public primitive_base { /// @param pads_end Optional end padding for input. /// @param align_corners Align corner pixels of the input and output tensors. /// @param resample_type Resample bilinear method. - /// @param with_activation Enables Relu activation. - /// @param activation_slp Relu activation slope. resample(const primitive_id& id, const primitive_id& input, tensor output_size, @@ -141,19 +138,18 @@ struct resample : public primitive_base { std::vector pads_end = {}, int32_t align_corners = 1, resample_type operation_type = resample_type::bilinear, - bool with_activation = false, - float activation_slp = 0.0f, const padding& output_padding = padding()) : primitive_base(id, {input}, output_padding), output_size(output_size), num_filter(0), + axesAndScales({}), pads_begin(pads_begin), pads_end(pads_end), align_corners(align_corners), operation_type(operation_type), shape_calc_mode(shape_calculation_mode::sizes), - with_activation(with_activation), - activation_negative_slope(activation_slp), + antialias(0), + cube_coeff(0.0f), coord_trans_mode(coordinate_transformation_mode::asymmetric), round_mode(nearest_mode::floor) {} @@ -170,19 +166,20 @@ struct resample : public primitive_base { std::vector pads_end = {}, int32_t antialias = 0, float cube_coeff = -0.75f, - resample_type mode = resample_type::caffe_bilinear, + resample_type operation_type = resample_type::caffe_bilinear, shape_calculation_mode shape_calc_mode = shape_calculation_mode::sizes, coordinate_transformation_mode ctm = coordinate_transformation_mode::half_pixel, nearest_mode nm = nearest_mode::round_prefer_floor, const padding& output_padding = padding()) : primitive_base(id, {input}, output_padding), output_size(output_size), + num_filter(0), axesAndScales(axesAndScales), pads_begin(pads_begin), pads_end(pads_end), - operation_type(mode), + align_corners(1), + operation_type(operation_type), shape_calc_mode(shape_calc_mode), - with_activation(false), antialias(antialias), cube_coeff(cube_coeff), coord_trans_mode(ctm), @@ -200,21 +197,17 @@ struct resample : public primitive_base { std::vector pads_end; /// @param align_corners corner pixels of the input and output tensors int32_t align_corners; - /// @param sample_type Resample method (nearest neighbor/bilinear/caffe bilinear). + /// @param operation_type Resample method (nearest neighbor/bilinear/caffe bilinear). resample_type operation_type; /// @param shape_calc_mode Specifies which input, sizes or scales, is used to calculate an output shape. shape_calculation_mode shape_calc_mode; - /// @brief Enables Relu activation. - bool with_activation; - /// @brief Relu activation slope. - float activation_negative_slope; /// @param antialias is a flag that specifies whether to perform anti-aliasing. int32_t antialias; /// @param cube_coeff specifies the parameter a for cubic interpolation. cube_coeff is used only when mode == cubic. float cube_coeff; - /// @param specifies how to transform the coordinate in the resized tensor to the coordinate in the original tensor + /// @param coord_trans_mode specifies how to transform the coordinate in the resized tensor to the coordinate in the original tensor coordinate_transformation_mode coord_trans_mode; - /// @param specifies round mode when mode == nearest and is used only when mode == nearest. + /// @param round_mode specifies round mode when mode == nearest and is used only when mode == nearest. nearest_mode round_mode; }; /// @} diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/eltwise/eltwise_kernel_ref.h b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/eltwise/eltwise_kernel_ref.h index 8039afad3b4..de96ee7ee57 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/eltwise/eltwise_kernel_ref.h +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/eltwise/eltwise_kernel_ref.h @@ -34,7 +34,7 @@ public: }; } - JitConstants GetJitConstants(const eltwise_params& params) const; + JitConstants GetJitConstants(const eltwise_params& params) const override; protected: bool Validate(const Params& p, const optional_params& o) const override; diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_b_fs_yx_fsv16.h b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_b_fs_yx_fsv16.h index edc68af6703..a4d1b0dd106 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_b_fs_yx_fsv16.h +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_b_fs_yx_fsv16.h @@ -24,7 +24,7 @@ class ReduceKernel_b_fs_yx_fsv16 : public ReduceKernelBase { public: ReduceKernel_b_fs_yx_fsv16() : ReduceKernelBase("reduce_gpu_b_fs_yx_fsv16") {} virtual ~ReduceKernel_b_fs_yx_fsv16() {} - virtual CommonDispatchData SetDefault(const reduce_params& params, const optional_params&) const; + CommonDispatchData SetDefault(const reduce_params& params, const optional_params&) const override; JitConstants GetJitConstants(const reduce_params& params) const override; KernelsData GetKernelsData(const Params& params, const optional_params& options) const override; ParamsKey GetSupportedKey() const override; diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_ref.h b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_ref.h index f54af534eaa..494bcc154b6 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_ref.h +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/reduce/reduce_kernel_ref.h @@ -24,7 +24,7 @@ class ReduceKernelRef : public ReduceKernelBase { public: ReduceKernelRef() : ReduceKernelBase("reduce_ref") {} virtual ~ReduceKernelRef() {} - virtual CommonDispatchData SetDefault(const reduce_params& params, const optional_params&) const; + CommonDispatchData SetDefault(const reduce_params& params, const optional_params&) const override; KernelsData GetKernelsData(const Params& params, const optional_params& options) const override; ParamsKey GetSupportedKey() const override; JitConstants GetJitConstants(const reduce_params& params) const override; diff --git a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/space_to_depth/space_to_depth_kernel_ref.h b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/space_to_depth/space_to_depth_kernel_ref.h index ec86b548ec6..14d00a48642 100644 --- a/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/space_to_depth/space_to_depth_kernel_ref.h +++ b/inference-engine/thirdparty/clDNN/kernel_selector/core/actual_kernels/space_to_depth/space_to_depth_kernel_ref.h @@ -50,7 +50,7 @@ public: protected: virtual CommonDispatchData SetDefault(const space_to_depth_params& params, const optional_params&) const; virtual JitConstants GetJitConstants(const space_to_depth_params& params) const; - virtual bool Validate(const Params& p, const optional_params& o) const; + bool Validate(const Params& p, const optional_params& o) const override; std::vector GetSupportedFusedOps() const override { return { FusedOpType::ELTWISE, FusedOpType::QUANTIZE, diff --git a/inference-engine/thirdparty/clDNN/src/gpu/ocl_base_event.h b/inference-engine/thirdparty/clDNN/src/gpu/ocl_base_event.h index e449661e629..c9b1fd163ff 100644 --- a/inference-engine/thirdparty/clDNN/src/gpu/ocl_base_event.h +++ b/inference-engine/thirdparty/clDNN/src/gpu/ocl_base_event.h @@ -55,7 +55,7 @@ public: } std::shared_ptr get_context() const { return _ctx; } - cl::Event get() { return _event; } + cl::Event get() override { return _event; } private: std::shared_ptr _ctx; @@ -91,7 +91,7 @@ public: _attached = true; } - cl::Event get() { return _last_ocl_event; } + cl::Event get() override { return _last_ocl_event; } std::shared_ptr get_context() const { return _ctx; } private: diff --git a/inference-engine/thirdparty/clDNN/src/gpu/resample_gpu.cpp b/inference-engine/thirdparty/clDNN/src/gpu/resample_gpu.cpp index be26f9cc6ff..7607232ed06 100644 --- a/inference-engine/thirdparty/clDNN/src/gpu/resample_gpu.cpp +++ b/inference-engine/thirdparty/clDNN/src/gpu/resample_gpu.cpp @@ -118,9 +118,6 @@ struct resample_gpu : typed_primitive_gpu_impl { get_default_optional_params(arg.get_program()); const auto& primitive = arg.get_primitive(); - if (primitive->with_activation) - convert_activation_func_params(primitive, us_params.activations); - size_t dimsNum = arg.get_output_layout().format.dimension(); us_params.resampleType = convert_to_sample_type(primitive->operation_type); us_params.nearestMode = convert_to_nearest_mode(primitive->round_mode); diff --git a/inference-engine/thirdparty/clDNN/src/resample.cpp b/inference-engine/thirdparty/clDNN/src/resample.cpp index f62612034a9..91cc57a1a9e 100644 --- a/inference-engine/thirdparty/clDNN/src/resample.cpp +++ b/inference-engine/thirdparty/clDNN/src/resample.cpp @@ -118,7 +118,6 @@ std::string resample_inst::to_string(resample_node const& node) { resample_info.add("nearest_mode:", "simple"); resample_info.add("output_size", desc->output_size); - resample_info.add("with activation", desc->with_activation); resample_info.add("output padding lower size", desc->output_padding.lower_size()); resample_info.add("output padding upper size", desc->output_padding.upper_size()); diff --git a/inference-engine/thirdparty/mkl-dnn b/inference-engine/thirdparty/mkl-dnn index d7d8ed46078..5ef085d5af6 160000 --- a/inference-engine/thirdparty/mkl-dnn +++ b/inference-engine/thirdparty/mkl-dnn @@ -1 +1 @@ -Subproject commit d7d8ed46078b637794bc91215e1a982bb0f1683a +Subproject commit 5ef085d5af65e8966e03cdfcbaa65761d61a5c9a diff --git a/model-optimizer/automation/package_BOM.txt b/model-optimizer/automation/package_BOM.txt index a58cf4ded64..847f3bd456e 100644 --- a/model-optimizer/automation/package_BOM.txt +++ b/model-optimizer/automation/package_BOM.txt @@ -343,6 +343,8 @@ extensions/front/tf/__init__.py extensions/front/tf/activation_ext.py extensions/front/tf/argmax_ext.py extensions/front/tf/assign_elimination.py +extensions/front/tf/automl_efficientdet.json +extensions/front/tf/AutomlEfficientDet.py extensions/front/tf/basic_lstm_cell.py extensions/front/tf/batch_to_space_ext.py extensions/front/tf/BatchMatMul_ext.py diff --git a/model-optimizer/extensions/front/Pack.py b/model-optimizer/extensions/front/Pack.py index 9c285b43c82..4070ec44e4f 100644 --- a/model-optimizer/extensions/front/Pack.py +++ b/model-optimizer/extensions/front/Pack.py @@ -15,9 +15,10 @@ """ from mo.front.common.partial_infer.utils import int64_array from mo.front.common.replacement import FrontReplacementOp -from mo.graph.graph import Node, Graph +from mo.front.tf.graph_utils import create_op_with_const_inputs +from mo.graph.graph import Node, Graph, rename_nodes from mo.ops.concat import Concat -from mo.ops.expand_dims import ExpandDims +from mo.ops.unsqueeze import Unsqueeze class Pack(FrontReplacementOp): @@ -25,15 +26,15 @@ class Pack(FrontReplacementOp): enabled = True def replace_op(self, graph: Graph, node: Node): - out_node = Concat(graph, {'axis': node.axis, 'in_ports_count': len(node.in_ports()), - 'name': node.name + '/Concat_', }).create_node() + out_node = Concat(graph, {'axis': node.axis, 'in_ports_count': len(node.in_ports())}).create_node() + pack_name = node.soft_get('name', node.id) for ind in node.in_ports(): - expand_dims_node = ExpandDims(graph, {'expand_axis': int64_array([node.axis]), - 'name': node.name + '/ExpandDims_'}).create_node() - node.in_port(ind).get_connection().set_destination(expand_dims_node.in_port(0)) - expand_dims_node.out_port(0).connect(out_node.in_port(ind)) - # Replace edge from out port 0 of the matched node with a edge from node out_node.id with port 0. - # The "explicit" version of the return value is: [(out_node.id, 0)]) + unsqueeze_node = create_op_with_const_inputs(graph, Unsqueeze, {1: int64_array([node.axis])}, + {'name': node.soft_get('name', node.id) + '/Unsqueeze'}) + node.in_port(ind).get_connection().set_destination(unsqueeze_node.in_port(0)) + unsqueeze_node.out_port(0).connect(out_node.in_port(ind)) + + rename_nodes([(node, pack_name + '/TBR'), (out_node, pack_name)]) return [out_node.id] diff --git a/model-optimizer/extensions/front/Pack_test.py b/model-optimizer/extensions/front/Pack_test.py index 663d1ce9255..7471b8e1a97 100644 --- a/model-optimizer/extensions/front/Pack_test.py +++ b/model-optimizer/extensions/front/Pack_test.py @@ -20,6 +20,7 @@ import numpy as np from generator import generator, generate from extensions.front.Pack import Pack +from mo.front.common.partial_infer.utils import int64_array from mo.utils.ir_engine.compare_graphs import compare_graphs from mo.utils.unittest.graph import build_graph @@ -32,12 +33,16 @@ nodes_attributes = { 'pack': {'axis': None, 'type': None, 'kind': 'op', 'op': 'Pack'}, # Test operation 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None}, - # ExpandDims, Concat and Const operations + # Unsqueeze, Concat and Const operations 'const_1': {'value': None, 'type': None, 'kind': 'op', 'op': 'Const'}, - 'ExpandDims_0': {'expand_axis': None, 'type': None, 'kind': 'op', 'op': 'ExpandDims'}, - 'ExpandDims_1': {'expand_axis': None, 'type': None, 'kind': 'op', 'op': 'ExpandDims'}, - 'ExpandDims_2': {'expand_axis': None, 'type': None, 'kind': 'op', 'op': 'ExpandDims'}, - 'ExpandDims_3': {'expand_axis': None, 'type': None, 'kind': 'op', 'op': 'ExpandDims'}, + 'Unsqueeze_0': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'}, + 'Unsqueeze_1': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'}, + 'Unsqueeze_2': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'}, + 'Unsqueeze_3': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'}, + 'Unsqueeze_0_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None}, + 'Unsqueeze_1_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None}, + 'Unsqueeze_2_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None}, + 'Unsqueeze_3_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None}, 'concat_1': {'axis': None, 'type': 'Concat', 'kind': 'op', 'op': 'Concat'}, } @@ -65,15 +70,17 @@ class PackTest(unittest.TestCase): graph_ref_edges = [] for i in range(num_inputs - num_placeholders + 1): for j in range(num_placeholders): - graph_ref_edges.append(('placeholder_{}'.format(j), 'ExpandDims_{}'.format(i + j))) - graph_ref_edges.append(('ExpandDims_{}'.format(i + j), 'concat_1')) + graph_ref_edges.append(('placeholder_{}'.format(j), 'Unsqueeze_{}'.format(i + j))) + graph_ref_edges.append(('Unsqueeze_{}'.format(i + j), 'concat_1')) graph_ref_edges.append(('concat_1', 'last')) update_graph_ref_attributes = {} for i in range(num_placeholders): update_graph_ref_attributes['placeholder_{}'.format(i)] = {'shape': np.array([1, 227, 227, 3])} for i in range(num_inputs): - update_graph_ref_attributes['ExpandDims_{}'.format(i)] = {'expand_axis': np.array([axis])} + graph_ref_edges.append(('Unsqueeze_{}_axis'.format(i), 'Unsqueeze_{}'.format(i))) + update_graph_ref_attributes['Unsqueeze_{}_axis'.format(i)] = {'shape': int64_array([1]), + 'value': int64_array([axis])} update_graph_ref_attributes['concat_1'] = {'axis': axis} graph_ref = build_graph(nodes_attributes, graph_ref_edges, update_graph_ref_attributes, diff --git a/model-optimizer/extensions/front/tf/AutomlEfficientDet.py b/model-optimizer/extensions/front/tf/AutomlEfficientDet.py new file mode 100644 index 00000000000..f9af87247c6 --- /dev/null +++ b/model-optimizer/extensions/front/tf/AutomlEfficientDet.py @@ -0,0 +1,140 @@ +""" + Copyright (C) 2018-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import numpy as np + +from extensions.front.Pack import Pack +from extensions.front.TransposeOrderNormalizer import TransposeOrderNormalizer +from extensions.front.eltwise_n import EltwiseNReplacement +from extensions.front.tf.pad_tf_to_pad import PadTFToPad +from extensions.ops.DetectionOutput import DetectionOutput +from extensions.ops.activation_ops import Sigmoid +from extensions.ops.priorbox_clustered import PriorBoxClusteredOp +from mo.front.common.partial_infer.utils import int64_array +from mo.front.tf.replacement import FrontReplacementFromConfigFileGeneral +from mo.graph.graph import Graph, Node +from mo.middle.passes.convert_data_type import data_type_str_to_np +from mo.ops.concat import Concat +from mo.ops.const import Const +from mo.ops.reshape import Reshape +from mo.ops.result import Result + + +class EfficientDet(FrontReplacementFromConfigFileGeneral): + replacement_id = 'AutomlEfficientDet' + + def run_before(self): + from extensions.front.ExpandDimsToUnsqueeze import ExpandDimsToUnsqueeze + return [ExpandDimsToUnsqueeze, Pack, TransposeOrderNormalizer, PadTFToPad, EltwiseNReplacement] + + class AnchorGenerator: + def __init__(self, min_level, aspect_ratios, num_scales, anchor_scale): + self.min_level = min_level + self.aspect_ratios = aspect_ratios + self.anchor_scale = anchor_scale + self.scales = [2 ** (float(s) / num_scales) for s in range(num_scales)] + + def get(self, layer_id): + widths = [] + heights = [] + for s in self.scales: + for a in self.aspect_ratios: + base_anchor_size = 2 ** (self.min_level + layer_id) * self.anchor_scale + heights.append(base_anchor_size * s * a[1]) + widths.append(base_anchor_size * s * a[0]) + return widths, heights + + def transform_graph(self, graph: Graph, replacement_descriptions: dict): + parameter_node = graph.get_op_nodes(op='Parameter')[0] + parameter_node['data_type'] = data_type_str_to_np(parameter_node.graph.graph['cmd_params'].data_type) + parameter_node.out_port(0).disconnect() + + # remove existing Result operations to remove unsupported sub-graph + graph.remove_nodes_from([node.id for node in graph.get_op_nodes(op='Result')] + ['detections']) + + # determine if the op which is a input/final result of mean value and scale applying to the input tensor + # then connect it to the input of the first convolution of the model, so we remove the image pre-processing + # which includes padding and resizing from the model + preprocessing_input_node_id = replacement_descriptions['preprocessing_input_node'] + assert preprocessing_input_node_id in graph.nodes, 'The node with name "{}" is not found in the graph. This ' \ + 'node should provide scaled image output and is specified' \ + ' in the json file.'.format(preprocessing_input_node_id) + preprocessing_input_node = Node(graph, preprocessing_input_node_id) + preprocessing_input_node.in_port(0).get_connection().set_source(parameter_node.out_port(0)) + + preprocessing_output_node_id = replacement_descriptions['preprocessing_output_node'] + assert preprocessing_output_node_id in graph.nodes, 'The node with name "{}" is not found in the graph. This ' \ + 'node should provide scaled image output and is specified' \ + ' in the json file.'.format(preprocessing_output_node_id) + preprocessing_output_node = Node(graph, preprocessing_output_node_id) + preprocessing_output_node.out_port(0).disconnect() + + convolution_nodes = [n for n in graph.pseudo_topological_sort() if n.soft_get('type') == 'Convolution'] + convolution_nodes[0].in_port(0).get_connection().set_source(preprocessing_output_node.out_port(0)) + + # create prior boxes (anchors) generator + aspect_ratios = replacement_descriptions['aspect_ratios'] + assert len(aspect_ratios) % 2 == 0 + aspect_ratios = list(zip(aspect_ratios[::2], aspect_ratios[1::2])) + priors_generator = self.AnchorGenerator(min_level=int(replacement_descriptions['min_level']), + aspect_ratios=aspect_ratios, + num_scales=int(replacement_descriptions['num_scales']), + anchor_scale=replacement_descriptions['anchor_scale']) + + prior_boxes = [] + for i in range(100): + inp_name = 'box_net/box-predict{}/BiasAdd'.format('_%d' % i if i else '') + if inp_name not in graph: + break + widths, heights = priors_generator.get(i) + prior_box_op = PriorBoxClusteredOp(graph, {'width': np.array(widths), + 'height': np.array(heights), + 'clip': 0, 'flip': 0, + 'variance': replacement_descriptions['variance'], + 'offset': 0.5}) + prior_boxes.append(prior_box_op.create_node([Node(graph, inp_name), parameter_node])) + + # concatenate prior box operations + concat_prior_boxes = Concat(graph, {'axis': -1}).create_node() + for idx, node in enumerate(prior_boxes): + concat_prior_boxes.add_input_port(idx) + concat_prior_boxes.in_port(idx).connect(node.out_port(0)) + + conf = Sigmoid(graph, dict(name='concat/sigmoid')).create_node([Node(graph, 'concat')]) + reshape_size_node = Const(graph, {'value': int64_array([0, -1])}).create_node([]) + logits = Reshape(graph, dict(name=conf.name + '/Flatten')).create_node([conf, reshape_size_node]) + deltas = Reshape(graph, dict(name='concat_1/Flatten')).create_node([Node(graph, 'concat_1'), reshape_size_node]) + + # revert convolution boxes prediction weights from yxYX to xyXY (convolutions share weights and bias) + weights = Node(graph, 'box_net/box-predict/pointwise_kernel') + weights.value = weights.value.reshape(-1, 4)[:, [1, 0, 3, 2]].reshape(weights.shape) + bias = Node(graph, 'box_net/box-predict/bias') + bias.value = bias.value.reshape(-1, 4)[:, [1, 0, 3, 2]].reshape(bias.shape) + + detection_output_node = DetectionOutput(graph, dict( + name='detections', + num_classes=int(replacement_descriptions['num_classes']), + share_location=1, + background_label_id=int(replacement_descriptions['num_classes']) + 1, + nms_threshold=replacement_descriptions['nms_threshold'], + confidence_threshold=replacement_descriptions['confidence_threshold'], + top_k=100, + keep_top_k=100, + code_type='caffe.PriorBoxParameter.CENTER_SIZE', + )).create_node([deltas, logits, concat_prior_boxes]) + + output_op = Result(graph, dict(name='output')) + output_op.create_node([detection_output_node]) diff --git a/model-optimizer/extensions/front/tf/automl_efficientdet.json b/model-optimizer/extensions/front/tf/automl_efficientdet.json new file mode 100644 index 00000000000..19eb1122f0c --- /dev/null +++ b/model-optimizer/extensions/front/tf/automl_efficientdet.json @@ -0,0 +1,18 @@ +[ + { + "id": "AutomlEfficientDet", + "custom_attributes": { + "preprocessing_input_node": "convert_image", + "preprocessing_output_node": "truediv", + "aspect_ratios": [1.0, 1.0, 1.4, 0.7, 0.7, 1.4], + "variance": [1.0, 1.0, 1.0, 1.0], + "min_level": 3, + "num_scales": 3, + "anchor_scale": 4.0, + "num_classes": 90, + "nms_threshold": 0.6, + "confidence_threshold": 0.2 + }, + "match_kind": "general" + } +] diff --git a/model-optimizer/mo/ops/unsqueeze.py b/model-optimizer/mo/ops/unsqueeze.py index 946dc7b5a39..6ac1ed7e5ec 100644 --- a/model-optimizer/mo/ops/unsqueeze.py +++ b/model-optimizer/mo/ops/unsqueeze.py @@ -32,14 +32,14 @@ class Unsqueeze(Op): def __init__(self, graph, attrs: dict): super().__init__(graph, { - 'op': __class__.op, - 'type': __class__.op, + 'op': self.op, + 'type': self.op, 'version': 'opset1', 'unsqueeze_dims': None, 'reinterp_shape': True, 'in_ports_count': 2, 'out_ports_count': 1, - 'infer': __class__.infer + 'infer': self.infer }, attrs) @staticmethod diff --git a/ngraph/core/builder/include/ngraph/builder/reshape.hpp b/ngraph/core/builder/include/ngraph/builder/reshape.hpp index 58330fe5590..c4e7f0d22e8 100644 --- a/ngraph/core/builder/include/ngraph/builder/reshape.hpp +++ b/ngraph/core/builder/include/ngraph/builder/reshape.hpp @@ -46,7 +46,7 @@ namespace ngraph std::shared_ptr reorder_axes(const Output& value, std::vector axes_order = {}); - /// \brief Return transposed vlaue (with axes in reversed order). + /// \brief Return transposed value (with axes in reversed order). /// /// \param Value to transpose. /// diff --git a/ngraph/core/builder/src/builder/autobroadcast.cpp b/ngraph/core/builder/src/builder/autobroadcast.cpp index 3a74ec53af7..9ac059f47c7 100644 --- a/ngraph/core/builder/src/builder/autobroadcast.cpp +++ b/ngraph/core/builder/src/builder/autobroadcast.cpp @@ -233,8 +233,7 @@ namespace ngraph auto trimmed_value = value; if (value_shape != trimmed_value_shape) { - trimmed_value = make_shared( - value, get_default_order(value_shape), trimmed_value_shape); + trimmed_value = builder::opset1::reshape(value, trimmed_value_shape); } auto shape_const = diff --git a/ngraph/core/builder/src/builder/matmul_factory.cpp b/ngraph/core/builder/src/builder/matmul_factory.cpp index 753287cccda..92df40a9210 100644 --- a/ngraph/core/builder/src/builder/matmul_factory.cpp +++ b/ngraph/core/builder/src/builder/matmul_factory.cpp @@ -149,8 +149,7 @@ OutputVector builder::MatmulFactory::make_matmul_op() Shape result_shape(next(begin(shape)), end(shape)); result_shape.insert( begin(result_shape), begin(left_shape), next(begin(left_shape), left_shape.size() - 2)); - return {make_shared(result, get_default_order(shape.size()), result_shape) - ->add_provenance_group_members_above(m_inputs)}; + return {builder::opset1::reshape(result, result_shape)}; } } diff --git a/ngraph/core/include/ngraph/op/op_version_tbl.hpp b/ngraph/core/include/ngraph/op/op_version_tbl.hpp index f68e4a36c59..aa5a4af17a9 100644 --- a/ngraph/core/include/ngraph/op/op_version_tbl.hpp +++ b/ngraph/core/include/ngraph/op/op_version_tbl.hpp @@ -145,7 +145,6 @@ NGRAPH_OP(ReduceSum, ngraph::op::v1, 1) NGRAPH_OP(RegionYolo, ngraph::op::v0, 0) NGRAPH_OP(Relu, ngraph::op::v0, 0) NGRAPH_OP(ReorgYolo, ngraph::op::v0, 0) -NGRAPH_OP(Reshape, ngraph::op::v0, 0) NGRAPH_OP(Reshape, ngraph::op::v1, 1) NGRAPH_OP(Result, ngraph::op::v0, 0) NGRAPH_OP(Reverse, ngraph::op::v1, 1) @@ -174,7 +173,6 @@ NGRAPH_OP(Split, ngraph::op::v0, 0) NGRAPH_OP(Sqrt, ngraph::op::v0, 0) NGRAPH_OP(SquaredDifference, ngraph::op::v0, 0) NGRAPH_OP(Squeeze, ngraph::op::v0, 0) -NGRAPH_OP(StopGradient, ngraph::op::v0, 0) NGRAPH_OP(StridedSlice, ngraph::op::v1, 1) NGRAPH_OP(Subtract, ngraph::op::v0, 0) NGRAPH_OP(Subtract, ngraph::op::v1, 1) diff --git a/ngraph/core/include/ngraph/op/reshape.hpp b/ngraph/core/include/ngraph/op/reshape.hpp index 049dde988c4..b24a8713f80 100644 --- a/ngraph/core/include/ngraph/op/reshape.hpp +++ b/ngraph/core/include/ngraph/op/reshape.hpp @@ -25,96 +25,6 @@ namespace ngraph { namespace op { - namespace v0 - { - // clang-format off - /// \brief Tensor reshape operation. - /// - /// "Converts" an input tensor into a new shape with the same number of elements. - /// - /// Given that the input tensor has shape \f$[d_1,\dots,d_n]\f$, the output may have any - /// shape \f$[d'_1,\dots,d'_m]\f$ such that - /// \f$\Pi_{0 \leq i \lt n}(d_i) = \Pi_{0 \leq i \lt m}(d'_i)\f$. For example, a - /// \f$3\times{}4\f$ matrix can be reshaped into a 3-tensor of shape - /// \f$3\times{}2\times{}2\f$, a matrix of shape \f$6\times{}2\f$, or a vector of size - /// \f$12\f$, but not, for example, a matrix of size \f$4\times{}4\f$. - /// - /// The parameter `input_order` indicates the order in which to "walk" over the input axes. - /// Given a tensor of shape \f$(d_1,\dots,d_n)\f$, an input order of - /// \f$(a_0, a_1, \dots, a_{n-1})\f$ results in the coordinate for axis \f$a_{n-1}\f$ being - /// varied most frequently, followed by axis \f$a-2\f$, and so on down to \f$a_0\f$. - /// - /// (TODO: example.) - /// - /// ## Parameters - /// - /// | | Description | - /// | -------------- | ---------------------------------------------------------- | - /// | `input_order` | The order in which to walk over the input axes. | - /// | `output_shape` | The shape \f$[d'_1,\dots,d'_m]\f$ for the reshaped tensor. | - /// - /// ## Inputs - /// - /// | | Type | Description | - /// | ----- | --------------------------------- | ------------------------------------------------------------------------------------------------------------ | - /// | `arg` | \f$E[d_1,\dots,d_n]~(n \geq 0)\f$ | An input tensor of any type and shape, as long as the product of \f$d_i\f$ equals the product of \f$d'_i\f$. | - /// - /// ## Output - /// - /// | Type | Description | - /// | ------------------------ | ------------------------------------------------------------------------------------------------------ | - /// | \f$E[d'_1,\dots,d'_m]\f$ | The tensor \f$T\f$, where \f$T\f$ is the input tensor with its elements rearranged as described above. | - // clang-format on - class NGRAPH_DEPRECATED( - "This operation is deprecated and will be removed soon. " - "Use v1::Reshape instead of it.") NGRAPH_API Reshape : public Op - { - NGRAPH_SUPPRESS_DEPRECATED_START - public: - static constexpr NodeTypeInfo type_info{"Reshape", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - /// \brief Constructs a reshape operation. - Reshape() = default; - /// \brief Constructs a reshape operation. - /// - /// \param arg The tensor to be reshaped. - /// \param input_order The order in which to iterate over input axes. This must be a - /// permutation of the sequence \f$(0,\dots,n-1)\f$ where \f$n\f$ - /// is - /// the rank of the input tensor. - /// \param output_shape The output shape. If the input shape is - /// \f$(a_0,\dots,a_{k-1})\f$ then the output shape must - /// be of the form \f$(b_0,\dots,b_{j-1})\f$ where - /// \f$\Pi(a_i) = \Pi(b_i)\f$. - Reshape(const Output& arg, - const AxisVector& input_order, - const Shape& output_shape); - - void validate_and_infer_types() override; - - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - bool visit_attributes(AttributeVisitor& visitor) override; - - /// \return The order in which to iterate over input axes. - const AxisVector& get_input_order() const { return m_input_order; } - void set_input_order(const AxisVector& input_order) { m_input_order = input_order; } - /// \return The shape of the output tensor. - const Shape& get_reshape_output_shape() const { return m_output_shape; } - void set_output_shape(const Shape& output_shape) { m_output_shape = output_shape; } - bool get_is_transpose() const { return m_is_transpose; } - void set_is_transpose(bool is_transpose) { m_is_transpose = is_transpose; } - bool evaluate(const HostTensorVector& outputs, - const HostTensorVector& inputs) const override; - - protected: - AxisVector m_input_order; - Shape m_output_shape; - bool m_is_transpose{false}; - NGRAPH_SUPPRESS_DEPRECATED_END - }; - } - namespace v1 { /// \brief Tensor dynamic reshape operation. @@ -131,16 +41,19 @@ namespace ngraph /// transpose. /// /// \param arg The tensor to be reshaped. - /// \param pattern The node that defines output shape pattern. + /// \param shape_pattern The node that defines output shape shape_pattern. /// If the input shape is \f$(a_0,\dots,a_{k-1})\f$ then the output shape /// must /// be of the form \f$(b_0,\dots,b_{j-1})\f$ where \f$\Pi(a_i) = \Pi(b_i)\f$. /// A value of -1 is allowed for at most one dimension, in which case the /// dimension size is inferred based on element count of input tensor. - /// \param special_zero Treats zeros in `pattern` as wildcard flags indicating a + /// \param special_zero Treats zeros in `shape_pattern` as wildcard flags indicating + /// a /// copy from input shape at the same index. /// - Reshape(const Output& arg, const Output& pattern, bool special_zero); + Reshape(const Output& arg, + const Output& shape_pattern, + bool special_zero); bool visit_attributes(AttributeVisitor& visitor) override; void validate_and_infer_types() override; @@ -160,8 +73,5 @@ namespace ngraph bool m_special_zero; }; } - NGRAPH_SUPPRESS_DEPRECATED_START - using v0::Reshape; - NGRAPH_SUPPRESS_DEPRECATED_END } } diff --git a/ngraph/core/include/ngraph/op/stop_gradient.hpp b/ngraph/core/include/ngraph/op/stop_gradient.hpp deleted file mode 100644 index 057aa9aff08..00000000000 --- a/ngraph/core/include/ngraph/op/stop_gradient.hpp +++ /dev/null @@ -1,51 +0,0 @@ -//***************************************************************************** -// Copyright 2017-2020 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#pragma once - -#include "ngraph/op/util/unary_elementwise_arithmetic.hpp" - -namespace ngraph -{ - namespace op - { - namespace v0 - { - /// \brief create StopGrdient op - class NGRAPH_DEPRECATED( - "This operation is deprecated and will be removed soon. Please do not use it.") - NGRAPH_API StopGradient : public util::UnaryElementwiseArithmetic - { - NGRAPH_SUPPRESS_DEPRECATED_START - public: - static constexpr NodeTypeInfo type_info{"StopGradient", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - /// \brief Constructs StopGradient - /// - /// \param arg Node that produces the input tensor. - StopGradient(const Output& arg); - StopGradient() = default; - - virtual std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; - NGRAPH_SUPPRESS_DEPRECATED_END - }; - } - NGRAPH_SUPPRESS_DEPRECATED_START - using v0::StopGradient; - NGRAPH_SUPPRESS_DEPRECATED_END - } -} diff --git a/ngraph/core/include/ngraph/ops.hpp b/ngraph/core/include/ngraph/ops.hpp index 07c63a276aa..90b2e683ff2 100644 --- a/ngraph/core/include/ngraph/ops.hpp +++ b/ngraph/core/include/ngraph/ops.hpp @@ -155,7 +155,6 @@ #include "ngraph/op/sqrt.hpp" #include "ngraph/op/squared_difference.hpp" #include "ngraph/op/squeeze.hpp" -#include "ngraph/op/stop_gradient.hpp" #include "ngraph/op/strided_slice.hpp" #include "ngraph/op/subtract.hpp" #include "ngraph/op/sum.hpp" diff --git a/ngraph/core/src/op/dot.cpp b/ngraph/core/src/op/dot.cpp index fa2e1cde348..825aed116fa 100644 --- a/ngraph/core/src/op/dot.cpp +++ b/ngraph/core/src/op/dot.cpp @@ -157,28 +157,6 @@ void op::Dot::validate_and_infer_types() set_output_type(0, result_et, result_shape); } -shared_ptr make_reshape_axes_to_front(const Output& n, - const Shape& front_shape, - const Shape& back_shape) -{ - AxisVector input_order; - Shape output_shape; - - for (size_t i = 0; i < back_shape.size(); i++) - { - input_order.push_back(front_shape.size() + i); - output_shape.push_back(back_shape[i]); - } - - for (size_t i = 0; i < front_shape.size(); i++) - { - input_order.push_back(i); - output_shape.push_back(front_shape[i]); - } - - return make_shared(n, input_order, output_shape); -} - shared_ptr op::Dot::get_default_value() const { return ngraph::make_constant_from_string("0", get_element_type(), get_shape()); diff --git a/ngraph/core/src/op/reshape.cpp b/ngraph/core/src/op/reshape.cpp index 9368020bad4..ff8e580c98b 100644 --- a/ngraph/core/src/op/reshape.cpp +++ b/ngraph/core/src/op/reshape.cpp @@ -24,8 +24,6 @@ #include "ngraph/runtime/opt_kernel/reshape.hpp" #include "ngraph/runtime/reference/reshape.hpp" -NGRAPH_SUPPRESS_DEPRECATED_START - using namespace std; using namespace ngraph; @@ -45,126 +43,23 @@ namespace } template - void compute_output_shape(const HostTensorPtr& pattern, Shape& output_shape) + void compute_output_shape(const HostTensorPtr& shape_pattern, + std::vector& output_shape) { using T = typename element_type_traits::value_type; - T* pattern_ptr = pattern->get_data_ptr(); - size_t output_rank = pattern->get_shape()[0]; + T* shape_pattern_ptr = shape_pattern->get_data_ptr(); + size_t output_rank = shape_pattern->get_shape()[0]; for (int i = 0; i < output_rank; i++) { - output_shape.push_back(pattern_ptr[i]); + output_shape.push_back(shape_pattern_ptr[i]); } } } -constexpr NodeTypeInfo op::Reshape::type_info; - -op::Reshape::Reshape(const Output& arg, - const AxisVector& input_order, - const Shape& output_shape) - : Op({arg}) - , m_input_order(input_order) - , m_output_shape(output_shape) -{ - constructor_validate_and_infer_types(); -} - -void op::Reshape::validate_and_infer_types() -{ - auto& input_shape = get_input_partial_shape(0); - auto input_rank = input_shape.rank(); - - // Check that the input axis order is a permutation of (0,...,n-1) for some n. - for (size_t i = 0; i < m_input_order.size(); i++) - { - NODE_VALIDATION_CHECK( - this, - find(begin(m_input_order), end(m_input_order), i) != end(m_input_order), - "Input axis order is not a permutation of argument's axis indices (axis order: ", - m_input_order, - ", argument shape: ", - input_shape, - ")."); - } - - // TODO(amprocte): should be possible to move around unknown dims in the input shape. - if (input_rank.is_static()) - { - NODE_VALIDATION_CHECK( - this, - m_input_order.size() == input_rank.get_length(), - "Input axis order is not a permutation of argument's axis indices (axis order: ", - m_input_order, - ", argument shape: ", - input_shape, - ")."); - - for (size_t i = 0; i < input_rank.get_length(); i++) - { - auto it = find(begin(m_input_order), end(m_input_order), i); - NODE_VALIDATION_CHECK( - this, - it != end(m_input_order), - "Input axis order is not a permutation of argument's axis indices (axis order: ", - m_input_order, - ", argument shape: ", - input_shape, - ")."); - } - - // TODO(amprocte): make a partial_shape_size() analogous to shape_size(). - Dimension input_shape_product = 1; - for (size_t i = 0; i < input_rank.get_length(); i++) - { - input_shape_product *= input_shape[i]; - } - - if (input_shape_product.is_static()) - { - NODE_VALIDATION_CHECK( - this, - input_shape_product.get_length() == shape_size(m_output_shape), - "Product of output shape dimensions does not match product of argument shape " - "dimensions ", - "(output shape: ", - m_output_shape, - ", argument shape: ", - input_shape, - ")."); - } - } - - if (!std::is_sorted(m_input_order.begin(), m_input_order.end())) - { - m_is_transpose = true; - } - set_output_type(0, get_input_element_type(0), m_output_shape); -} - -shared_ptr op::Reshape::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(new_args.at(0), m_input_order, m_output_shape); -} - -bool op::Reshape::visit_attributes(AttributeVisitor& visitor) -{ - visitor.on_attribute("input_order", m_input_order); - visitor.on_attribute("output_shape", m_output_shape); - return true; -} - -bool op::v0::Reshape::evaluate(const HostTensorVector& outputs, - const HostTensorVector& inputs) const -{ - OV_ITT_SCOPED_TASK(itt::domains::nGraphOp, "op::v0::Reshape::evaluate"); - return evaluate_reshape(inputs[0], outputs[0], get_input_order()); -} - NGRAPH_RTTI_DEFINITION(op::v1::Reshape, "Reshape", 1); -op::v1::Reshape::Reshape(const Output& arg, const Output& pattern, bool zero_flag) - : Op({arg, pattern}) +op::v1::Reshape::Reshape(const Output& arg, const Output& shape_pattern, bool zero_flag) + : Op({arg, shape_pattern}) , m_special_zero(zero_flag) { constructor_validate_and_infer_types(); @@ -178,20 +73,21 @@ bool op::v1::Reshape::visit_attributes(AttributeVisitor& visitor) void op::v1::Reshape::validate_and_infer_types() { - auto pattern_et = get_input_element_type(1); + auto shape_pattern_et = get_input_element_type(1); // check data types NODE_VALIDATION_CHECK( - this, pattern_et.is_integral_number(), "Pattern must be an integral number."); + this, shape_pattern_et.is_integral_number(), "Shape pattern must be an integral number."); // check shapes const PartialShape& input_pshape = get_input_partial_shape(0); - const PartialShape& pattern_shape = get_input_partial_shape(1); + const PartialShape& shape_pattern_shape = get_input_partial_shape(1); NODE_VALIDATION_CHECK(this, - pattern_shape.rank().compatible(1), + shape_pattern_shape.rank().compatible(1), "Pattern shape must have rank 1, got ", - pattern_shape.rank(), + shape_pattern_shape.rank(), "."); - Rank output_rank = pattern_shape.rank().is_dynamic() ? Rank::dynamic() : pattern_shape[0]; + Rank output_rank = + shape_pattern_shape.rank().is_dynamic() ? Rank::dynamic() : shape_pattern_shape[0]; set_input_is_relevant_to_shape(1); @@ -339,7 +235,7 @@ bool op::v1::Reshape::evaluate(const HostTensorVector& outputs, // infer and set output shape if the output shape contain -1 // and zero value dimension size_t output_rank = inputs[1]->get_shape()[0]; - Shape out_shape_val; + std::vector out_shape_val; switch (inputs[1]->get_element_type()) { @@ -367,7 +263,7 @@ bool op::v1::Reshape::evaluate(const HostTensorVector& outputs, case element::Type_t::u64: compute_output_shape(inputs[1], out_shape_val); break; - default: throw ngraph_error("pattern element type is not integral data type"); + default: throw ngraph_error("shape_pattern element type is not integral data type"); } NODE_VALIDATION_CHECK( @@ -382,9 +278,10 @@ bool op::v1::Reshape::evaluate(const HostTensorVector& outputs, NODE_VALIDATION_CHECK( this, negative_dims <= 1, "More than one dimension has size of -1 (", negative_dims, ")"); + Shape output_shape; + std::copy(out_shape_val.begin(), out_shape_val.end(), std::back_inserter(output_shape)); if (!(zero_dims && m_special_zero) && !negative_dims) { - auto output_shape = out_shape_val; if (get_input_partial_shape(0).is_static()) { NODE_VALIDATION_CHECK(this, @@ -398,7 +295,6 @@ bool op::v1::Reshape::evaluate(const HostTensorVector& outputs, } else { - Shape output_shape = out_shape_val; size_t output_elements = 1; int negative_dim = -1; @@ -482,4 +378,4 @@ bool op::v1::Reshape::constant_fold(OutputVector& output_values, const OutputVec return true; } return false; -} \ No newline at end of file +} diff --git a/ngraph/core/src/op/squeeze.cpp b/ngraph/core/src/op/squeeze.cpp index 821a168e73f..7adfe93ce7a 100644 --- a/ngraph/core/src/op/squeeze.cpp +++ b/ngraph/core/src/op/squeeze.cpp @@ -19,6 +19,7 @@ #include #include "itt.hpp" +#include "ngraph/builder/reshape.hpp" #include "ngraph/op/constant.hpp" #include "ngraph/op/reshape.hpp" #include "ngraph/op/squeeze.hpp" @@ -122,10 +123,11 @@ OutputVector op::Squeeze::decompose_op() const (get_output_partial_shape(0).is_static()), "output shape was not calculated during pre_validate_and_infer_types. Can not decompose."); auto data = input_value(0); - auto data_shape = data.get_shape(); auto output_data_shape = get_output_shape(0); - AxisVector input_order{get_default_order(data_shape.size())}; - return {make_shared(data, input_order, output_data_shape)}; + return {make_shared( + data, + op::Constant::create(element::u64, {output_data_shape.size()}, output_data_shape), + false)}; } shared_ptr op::Squeeze::clone_with_new_inputs(const OutputVector& new_args) const @@ -241,4 +243,4 @@ bool op::v0::Squeeze::constant_fold(OutputVector& output_values, const OutputVec return true; } return false; -} \ No newline at end of file +} diff --git a/ngraph/core/src/op/stop_gradient.cpp b/ngraph/core/src/op/stop_gradient.cpp deleted file mode 100644 index ca8a8f26adb..00000000000 --- a/ngraph/core/src/op/stop_gradient.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//***************************************************************************** -// Copyright 2017-2020 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include "ngraph/op/stop_gradient.hpp" -#include "ngraph/op/broadcast.hpp" - -NGRAPH_SUPPRESS_DEPRECATED_START - -using namespace std; -using namespace ngraph; - -constexpr NodeTypeInfo op::StopGradient::type_info; - -op::StopGradient::StopGradient(const Output& arg) - : UnaryElementwiseArithmetic(arg) -{ - constructor_validate_and_infer_types(); -} - -shared_ptr op::StopGradient::clone_with_new_inputs(const OutputVector& new_args) const -{ - check_new_args_count(this, new_args); - return make_shared(new_args.at(0)); -} diff --git a/ngraph/core/src/op/unsqueeze.cpp b/ngraph/core/src/op/unsqueeze.cpp index b033bb2c9c5..03a59630bd3 100644 --- a/ngraph/core/src/op/unsqueeze.cpp +++ b/ngraph/core/src/op/unsqueeze.cpp @@ -18,6 +18,7 @@ #include #include "itt.hpp" +#include "ngraph/builder/reshape.hpp" #include "ngraph/op/constant.hpp" #include "ngraph/op/reshape.hpp" #include "ngraph/op/unsqueeze.hpp" @@ -87,8 +88,7 @@ OutputVector op::Unsqueeze::decompose_op() const auto data = input_value(0); auto data_shape = data.get_shape(); auto output_shape = get_output_shape(0); - AxisVector input_order{ngraph::get_default_order(data_shape.size())}; - return {make_shared(data, input_order, output_shape)}; + return {builder::opset1::reshape(data, output_shape)}; } bool ngraph::op::v0::Unsqueeze::visit_attributes(AttributeVisitor& visitor) @@ -203,4 +203,4 @@ bool op::v0::Unsqueeze::constant_fold(OutputVector& output_values, return true; } return false; -} \ No newline at end of file +} diff --git a/ngraph/core/src/pass/constant_folding_scatter.cpp b/ngraph/core/src/pass/constant_folding_scatter.cpp index f79b38863a1..3b4bd5fe278 100644 --- a/ngraph/core/src/pass/constant_folding_scatter.cpp +++ b/ngraph/core/src/pass/constant_folding_scatter.cpp @@ -101,13 +101,13 @@ static shared_ptr case element::Type_t::f32: case element::Type_t::f64: case element::Type_t::u1: - default: - NGRAPH_CHECK(false, - "Encountered unsupported axis element type in " - "constant_scatter_elem_updt_callback: ", - axis_type); - break; + default: break; } + + NGRAPH_CHECK( + false, + "Encountered unsupported axis element type in constant_scatter_elem_updt_callback: ", + axis_type); } template @@ -152,13 +152,13 @@ static shared_ptr dispatch_const_fold_data(const shared_ptr x_new_shape = make_shared(x); auto axes = op::Constant::create(element::i64, {}, {0}); x_new_shape = make_shared(x_new_shape, axes); - x_new_shape = make_shared(x_new_shape, AxisVector{}, Shape{1}); + x_new_shape = make_shared( + x_new_shape, op::Constant::create(element::u64, {1}, Shape{1}), false); auto x_reshaped = make_shared(x, x_new_shape, true); @@ -298,3 +299,30 @@ NGRAPH_TEST(${BACKEND_NAME}, dynamic_reverse_shape) Shape{8, 2, 8, 2}, Shape{2, 3, 4, 5, 2}}); } + +NGRAPH_TEST(${BACKEND_NAME}, dynamic_transpose) +{ + auto arg = std::make_shared(element::i32, PartialShape::dynamic()); + auto input_order = make_shared(element::i32, PartialShape::dynamic()); + auto transpose = std::make_shared(arg, input_order); + + auto f = std::make_shared(NodeVector{transpose}, ParameterVector{arg, input_order}); + + auto backend = runtime::Backend::create("${BACKEND_NAME}", true); + auto ex = backend->compile(f); + + auto arg_data = vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + auto input_order_data = vector{2, 0, 1}; + + auto arg_tensor = backend->create_tensor(element::i32, Shape{2, 2, 3}); + auto input_order_tensor = backend->create_tensor(element::i32, Shape{input_order_data.size()}); + copy_data(arg_tensor, arg_data); + copy_data(input_order_tensor, input_order_data); + + auto output = backend->create_dynamic_tensor(element::i32, PartialShape::dynamic()); + ex->call_with_validate({output}, {arg_tensor, input_order_tensor}); + + ASSERT_EQ(output->get_element_type(), element::i32); + EXPECT_EQ(read_vector(output), + vector({1, 4, 7, 10, 2, 5, 8, 11, 3, 6, 9, 12})); +} diff --git a/ngraph/test/backend/gather.in.cpp b/ngraph/test/backend/gather.in.cpp index 0b28d840ece..0f60ed9c1f7 100644 --- a/ngraph/test/backend/gather.in.cpp +++ b/ngraph/test/backend/gather.in.cpp @@ -23,15 +23,9 @@ #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" -#include "ngraph/runtime/tensor.hpp" -#include "runtime/backend.hpp" -#include "util/all_close.hpp" -#include "util/all_close_f.hpp" -#include "util/ndarray.hpp" -#include "util/random.hpp" +#include "util/engine/test_engines.hpp" #include "util/test_case.hpp" #include "util/test_control.hpp" -#include "util/test_tools.hpp" NGRAPH_SUPPRESS_DEPRECATED_START @@ -39,530 +33,375 @@ using namespace std; using namespace ngraph; static string s_manifest = "${MANIFEST}"; +using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); NGRAPH_TEST(${BACKEND_NAME}, gather_4d_indices_axis_0_uint8) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2, 3, 4}; Shape out_shape{2, 2, 3, 4, 2}; - auto P = make_shared(element::u8, params_shape); + auto P = make_shared(element::u8, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::u8, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, - 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, - 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); - auto result = backend->create_tensor(element::u8, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close( - (vector{10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, - 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, - 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, - 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, - 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, - 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, + 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, + 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); + test_case.add_expected_output( + out_shape, {10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, + 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, + 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, + 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, + 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, gather_4d_indices_axis_0_2d_input) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2, 3, 4}; Shape out_shape{2, 2, 3, 4, 2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, - 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, - 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, - 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, - 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, - 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.add_input({0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, + 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, + 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); + test_case.add_expected_output( + out_shape, + {1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, + 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, + 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, + 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, + 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, + 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, + 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_3d_indices_axis_0_2d_input) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 3, 4}; Shape out_shape{2, 3, 4, 2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data( - i, vector{0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, - 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, - 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.add_input( + {0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2}); + test_case.add_expected_output( + out_shape, {1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, + 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, + 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, + 2.0f, 2.1f, 3.0f, 3.1f, 1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_2d_indices_axis_0_2d_input) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f((vector{1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, + {1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_2d_negative_and_positive_indices_axis_0_2d_input) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, -2, 1, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f((vector{1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.add_input({0, -2, 1, 2}); + test_case.add_expected_output(out_shape, + {1.0f, 1.1f, 2.0f, 2.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_1d_indices_axis_0_1d_input) { - Shape params_shape{3}; + Shape data_shape{3}; Shape indices_shape{2}; Shape out_shape{2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 2.0f, 3.0f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{1, 0}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{2.0f, 1.0f}), read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 2.0f, 3.0f}); + test_case.add_input({1, 0}); + test_case.add_expected_output(out_shape, {2.0f, 1.0f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_scalar_indices_axis_0_2d_input) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{}; Shape out_shape{2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{1}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{2.0f, 2.1f}), read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f}); + test_case.add_input({1}); + test_case.add_expected_output(out_shape, {2.0f, 2.1f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_2d_indices_axis_1_2d_input) { - Shape params_shape{3, 3}; + Shape data_shape{3, 3}; Shape indices_shape{1, 2}; Shape out_shape{3, 1, 2}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {1}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f((vector{1.0f, 1.2f, 2.0f, 2.2f, 3.0f, 3.2f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); + test_case.add_input({0, 2}); + test_case.add_expected_output(out_shape, {1.0f, 1.2f, 2.0f, 2.2f, 3.0f, 3.2f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_1d_indices_axis_2_4d_input) { - Shape params_shape{2, 2, 3, 3}; + Shape data_shape{2, 2, 3, 3}; Shape indices_shape{2}; Shape out_shape{2, 2, 2, 3}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {2}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, - 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, - 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, - 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 2}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, - 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, + 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, + 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f, + 1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); + test_case.add_input({0, 2}); + test_case.add_expected_output( + out_shape, {1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, + 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f, 1.0f, 1.1f, 1.2f, 3.0f, 3.1f, 3.2f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_scalar_indices_axis_1_2d_input) { - Shape params_shape{3, 3}; + Shape data_shape{3, 3}; Shape indices_shape{}; Shape out_shape{3}; - auto P = make_shared(element::f32, params_shape); + auto P = make_shared(element::f32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {1}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::f32, params_shape); - copy_data(p, vector{1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0}); - auto result = backend->create_tensor(element::f32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close_f( - (vector{1.0f, 2.0f, 3.0f}), read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); + auto test_case = test::TestCase(f); + test_case.add_input({1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}); + test_case.add_input({0}); + test_case.add_expected_output(out_shape, {1.0f, 2.0f, 3.0f}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_int8) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::i8, params_shape); + auto P = make_shared(element::i8, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::i8, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::i8, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_int16) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::i16, params_shape); + auto P = make_shared(element::i16, data_shape); auto I = make_shared(element::i64, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::i16, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i64, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::i16, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_int32) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::i32, params_shape); + auto P = make_shared(element::i32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::i32, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::i32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_int64) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::i64, params_shape); + auto P = make_shared(element::i64, data_shape); auto I = make_shared(element::i64, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::i64, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i64, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::i64, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_uint8) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::u8, params_shape); + auto P = make_shared(element::u8, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::u8, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::u8, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_uint16) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::u16, params_shape); + auto P = make_shared(element::u16, data_shape); auto I = make_shared(element::i64, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::u16, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i64, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::u16, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_uint32) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::u32, params_shape); + auto P = make_shared(element::u32, data_shape); auto I = make_shared(element::i32, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::u32, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i32, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::u32, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_uint64) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::u64, params_shape); + auto P = make_shared(element::u64, data_shape); auto I = make_shared(element::i64, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::u64, params_shape); - copy_data(p, vector{10, 11, 20, 21, 30, 31}); - auto i = backend->create_tensor(element::i64, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::u64, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{10, 11, 20, 21, 20, 21, 30, 31}), - read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({10, 11, 20, 21, 30, 31}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {10, 11, 20, 21, 20, 21, 30, 31}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_bool) { - Shape params_shape{3, 2}; + Shape data_shape{3, 2}; Shape indices_shape{2, 2}; Shape out_shape{2, 2, 2}; - auto P = make_shared(element::boolean, params_shape); + auto P = make_shared(element::boolean, data_shape); auto I = make_shared(element::i64, indices_shape); auto A = op::Constant::create(element::i64, Shape{}, {0}); auto G = make_shared(P, I, A); auto f = make_shared(G, ParameterVector{P, I}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto p = backend->create_tensor(element::boolean, params_shape); - copy_data(p, vector{1, 1, 1, 0, 0, 1}); - auto i = backend->create_tensor(element::i64, indices_shape); - copy_data(i, vector{0, 1, 1, 2}); - auto result = backend->create_tensor(element::boolean, out_shape); - - auto c = backend->compile(f); - c->call_with_validate({result}, {p, i}); - EXPECT_TRUE(test::all_close((vector{1, 1, 1, 0, 1, 0, 0, 1}), read_vector(result))); + auto test_case = test::TestCase(f); + test_case.add_input({1, 1, 1, 0, 0, 1}); + test_case.add_input({0, 1, 1, 2}); + test_case.add_expected_output(out_shape, {1, 1, 1, 0, 1, 0, 0, 1}); + test_case.run(MIN_FLOAT_TOLERANCE_BITS); } diff --git a/ngraph/test/backend/numeric.in.cpp b/ngraph/test/backend/numeric.in.cpp index 1977a4d4a76..63f444b646d 100644 --- a/ngraph/test/backend/numeric.in.cpp +++ b/ngraph/test/backend/numeric.in.cpp @@ -16,13 +16,9 @@ #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" -#include "ngraph/runtime/tensor.hpp" -#include "runtime/backend.hpp" -#include "util/all_close.hpp" -#include "util/all_close_f.hpp" -#include "util/ndarray.hpp" +#include "util/engine/test_engines.hpp" +#include "util/test_case.hpp" #include "util/test_control.hpp" -#include "util/test_tools.hpp" NGRAPH_SUPPRESS_DEPRECATED_START @@ -30,6 +26,7 @@ using namespace std; using namespace ngraph; static string s_manifest = "${MANIFEST}"; +using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); NGRAPH_TEST(${BACKEND_NAME}, numeric_float_nan) { @@ -38,13 +35,9 @@ NGRAPH_TEST(${BACKEND_NAME}, numeric_float_nan) auto B = op::Constant::create(element::f32, shape, {10.0f, 5.0f, 2.25f, 10.0f, NAN}); auto f = make_shared(make_shared(A, B), ParameterVector{}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto result = backend->create_tensor(element::boolean, shape); - auto handle = backend->compile(f); - handle->call_with_validate({result}, {}); - EXPECT_EQ((vector{false, false, true, false, false}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_expected_output(shape, {false, false, true, false, false}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, numeric_double_nan) @@ -54,13 +47,9 @@ NGRAPH_TEST(${BACKEND_NAME}, numeric_double_nan) auto B = op::Constant::create(element::f64, shape, {10.0f, 5.0f, 2.25f, 10.0f, NAN}); auto f = make_shared(make_shared(A, B), ParameterVector{}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto result = backend->create_tensor(element::boolean, shape); - auto handle = backend->compile(f); - handle->call_with_validate({result}, {}); - EXPECT_EQ((vector{false, false, true, false, false}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_expected_output(shape, {false, false, true, false, false}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, numeric_float_inf) @@ -70,13 +59,9 @@ NGRAPH_TEST(${BACKEND_NAME}, numeric_float_inf) auto B = op::Constant::create(element::f32, shape, {10.0f, 5.0f, 2.25f, 10.0f, -INFINITY}); auto f = make_shared(make_shared(A, B), ParameterVector{}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto result = backend->create_tensor(element::boolean, shape); - auto handle = backend->compile(f); - handle->call_with_validate({result}, {}); - EXPECT_EQ((vector{false, false, true, false, false}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_expected_output(shape, {false, false, true, false, false}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, numeric_double_inf) @@ -86,11 +71,7 @@ NGRAPH_TEST(${BACKEND_NAME}, numeric_double_inf) auto B = op::Constant::create(element::f64, shape, {10.0f, 5.0f, 2.25f, 10.0f, -INFINITY}); auto f = make_shared(make_shared(A, B), ParameterVector{}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto result = backend->create_tensor(element::boolean, shape); - auto handle = backend->compile(f); - handle->call_with_validate({result}, {}); - EXPECT_EQ((vector{false, false, true, false, false}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_expected_output(shape, {false, false, true, false, false}); + test_case.run(); } diff --git a/ngraph/test/backend/one_hot.in.cpp b/ngraph/test/backend/one_hot.in.cpp index 3e322b48cbf..47192df718f 100644 --- a/ngraph/test/backend/one_hot.in.cpp +++ b/ngraph/test/backend/one_hot.in.cpp @@ -23,18 +23,15 @@ #include "gtest/gtest.h" #include "ngraph/ngraph.hpp" -#include "ngraph/runtime/tensor.hpp" -#include "runtime/backend.hpp" -#include "util/all_close.hpp" -#include "util/all_close_f.hpp" -#include "util/ndarray.hpp" +#include "util/engine/test_engines.hpp" +#include "util/test_case.hpp" #include "util/test_control.hpp" -#include "util/test_tools.hpp" using namespace std; using namespace ngraph; static string s_manifest = "${MANIFEST}"; +using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_2_in_3) { @@ -48,16 +45,10 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_2_in_3) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{2}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ((vector{0, 0, 1}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({2}); + test_case.add_expected_output(shape_r, {0, 0, 1}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_1_in_3) @@ -72,16 +63,10 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_1_in_3) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{1}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ((vector{0, 1, 0}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({1}); + test_case.add_expected_output(shape_r, {0, 1, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_0_in_3) @@ -96,16 +81,10 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_0_in_3) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{0}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ((vector{1, 0, 0}), read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({0}); + test_case.add_expected_output(shape_r, {1, 0, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_0) @@ -120,18 +99,11 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_0) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{2, 1, 0, 0, 2, 2, 1, 0}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ( - (vector{0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0}), - read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({2, 1, 0, 0, 2, 2, 1, 0}); + test_case.add_expected_output( + shape_r, {0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1) @@ -146,18 +118,11 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{2, 1, 0, 0, 2, 2, 1, 0}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ( - (vector{0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}), - read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({2, 1, 0, 0, 2, 2, 1, 0}); + test_case.add_expected_output( + shape_r, {0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_barely_oob) @@ -172,49 +137,12 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_barely_oob) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, vector{2, 1, 0, 0, 3, 2, 1, 0}); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - vector rv = read_vector(result); - - EXPECT_EQ(rv[0], 0); - EXPECT_EQ(rv[1], 0); - EXPECT_EQ(rv[2], 1); - - EXPECT_EQ(rv[3], 0); - EXPECT_EQ(rv[4], 1); - EXPECT_EQ(rv[5], 0); - - EXPECT_EQ(rv[6], 1); - EXPECT_EQ(rv[7], 0); - EXPECT_EQ(rv[8], 0); - - EXPECT_EQ(rv[9], 1); - EXPECT_EQ(rv[10], 0); - EXPECT_EQ(rv[11], 0); - - // These are undefined since value is out of bounds - // EXPECT_EQ(rv[12], 0); - // EXPECT_EQ(rv[13], 0); - // EXPECT_EQ(rv[14], 0); - - EXPECT_EQ(rv[15], 0); - EXPECT_EQ(rv[16], 0); - EXPECT_EQ(rv[17], 1); - - EXPECT_EQ(rv[18], 0); - EXPECT_EQ(rv[19], 1); - EXPECT_EQ(rv[20], 0); - - EXPECT_EQ(rv[21], 1); - EXPECT_EQ(rv[22], 0); - EXPECT_EQ(rv[23], 0); + auto test_case = test::TestCase(f); + test_case.add_input({2, 1, 0, 0, 3, 2, 1, 0}); + // elements 12, 13, 14 are zeroed as out of bound + test_case.add_expected_output( + shape_r, {0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_matrix_0) @@ -229,30 +157,17 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_matrix_0) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - copy_data(a, - vector{ - 0, 1, 1, 2, 1, 0, 0, 2, 1, - }); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_EQ((vector{1, 0, 0, 0, 0, 1, 1, 0, 0, - - 0, 1, 1, 0, 1, 0, 0, 0, 1, - - 0, 0, 0, 1, 0, 0, 0, 1, 0}), - read_vector(result)); + auto test_case = test::TestCase(f); + test_case.add_input({0, 1, 1, 2, 1, 0, 0, 2, 1}); + test_case.add_expected_output( + shape_r, {1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0}); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_many_categories) { // Imagenet has roughly 20,000 categories - uint32_t category_count = 20000; + constexpr uint32_t category_count = 20000; Shape shape_a{6}; auto A = make_shared(element::i32, shape_a); Shape shape_r{6, category_count}; @@ -263,27 +178,17 @@ NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_many_categories) auto r = make_shared(A, depth, on_value, off_value, axis); auto f = make_shared(r, ParameterVector{A}); - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::i32, shape_a); - vector input_data{0, 11, 101, 1001, 10001, static_cast(category_count - 1)}; - copy_data(a, input_data); - auto result = backend->create_tensor(element::i32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - vector data = read_vector(result); - - vector bit_positions; - for (size_t i = 0; i < shape_size(shape_r); ++i) + vector input{0, 11, 101, 1001, 10001, static_cast(category_count - 1)}; + vector output(shape_size(shape_r), 0); + for (size_t i = 0; i < input.size(); ++i) { - if (data[i] == 1) - { - bit_positions.push_back(i % category_count); - } + output[i * category_count + input[i]] = 1; } - EXPECT_EQ(bit_positions, input_data); + + auto test_case = test::TestCase(f); + test_case.add_input(input); + test_case.add_expected_output(shape_r, output); + test_case.run(); } NGRAPH_TEST(${BACKEND_NAME}, one_hot_on_off_float) diff --git a/ngraph/test/backend/reshape.in.cpp b/ngraph/test/backend/reshape.in.cpp index 3e703d2cdda..130629430b5 100644 --- a/ngraph/test/backend/reshape.in.cpp +++ b/ngraph/test/backend/reshape.in.cpp @@ -49,7 +49,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_t2v_012) Shape shape_a{2, 2, 3}; auto A = make_shared(element::f32, shape_a); Shape shape_r{12}; - auto r = make_shared(A, AxisVector{0, 1, 2}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -71,7 +72,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_t2s_012) Shape shape_a{1, 1, 1}; auto A = make_shared(element::f32, shape_a); Shape shape_r{}; - auto r = make_shared(A, AxisVector{0, 1, 2}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -92,7 +94,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_t2s_120) Shape shape_a{1, 1, 1}; auto A = make_shared(element::f32, shape_a); Shape shape_r{}; - auto r = make_shared(A, AxisVector{1, 2, 0}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -113,7 +116,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_s2t) Shape shape_a{}; auto A = make_shared(element::f32, shape_a); Shape shape_r{1, 1, 1, 1, 1, 1}; - auto r = make_shared(A, AxisVector{}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -134,7 +138,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_s2t1) Shape shape_a{}; auto A = make_shared(element::boolean, shape_a); Shape shape_r{1}; - auto r = make_shared(A, AxisVector{}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -154,7 +159,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_v2m_col) Shape shape_a{3}; auto A = make_shared(element::f32, shape_a); Shape shape_r{3, 1}; - auto r = make_shared(A, AxisVector{0}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -175,7 +181,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_v2m_row) Shape shape_a{3}; auto A = make_shared(element::f32, shape_a); Shape shape_r{1, 3}; - auto r = make_shared(A, AxisVector{0}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -196,7 +203,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_v2t_middle) Shape shape_a{3}; auto A = make_shared(element::f32, shape_a); Shape shape_r{1, 3, 1}; - auto r = make_shared(A, AxisVector{0}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -217,7 +225,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_m2m_same) Shape shape_a{3, 3}; auto A = make_shared(element::f32, shape_a); Shape shape_r{3, 3}; - auto r = make_shared(A, AxisVector{0, 1}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -234,217 +243,13 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_m2m_same) MIN_FLOAT_TOLERANCE_BITS)); } -NGRAPH_TEST(${BACKEND_NAME}, reshape_m2m_transpose) -{ - Shape shape_a{3, 3}; - auto A = make_shared(element::f32, shape_a); - Shape shape_r{3, 3}; - auto r = make_shared(A, AxisVector{1, 0}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, vector{1, 2, 3, 4, 5, 6, 7, 8, 9}); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 4, 7, 2, 5, 8, 3, 6, 9}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_m2m_dim_change_transpose) -{ - Shape shape_a{3, 2}; - auto A = make_shared(element::f32, shape_a); - Shape shape_r{2, 3}; - auto r = make_shared(A, AxisVector{1, 0}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, vector{1, 2, 3, 4, 5, 6}); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f( - (vector{1, 3, 5, 2, 4, 6}), read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_3d_transpose_021) -{ - Shape shape_a{2, 3, 4}; - Shape shape_r{2, 4, 3}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{0, 2, 1}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12, - 13, 17, 21, 14, 18, 22, 15, 19, 23, 16, 20, 24}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_3d_transpose_210) -{ - Shape shape_a{2, 3, 4}; - Shape shape_r{4, 3, 2}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{2, 1, 0}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 13, 5, 17, 9, 21, 2, 14, 6, 18, 10, 22, - 3, 15, 7, 19, 11, 23, 4, 16, 8, 20, 12, 24}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_3d_transpose_201) -{ - Shape shape_a{2, 3, 4}; - Shape shape_r{4, 2, 3}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{2, 0, 1}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, - 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_3d_transpose_102) -{ - Shape shape_a{2, 3, 4}; - Shape shape_r{3, 2, 4}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{1, 0, 2}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 2, 3, 4, 13, 14, 15, 16, 5, 6, 7, 8, - 17, 18, 19, 20, 9, 10, 11, 12, 21, 22, 23, 24}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_3d_transpose_120) -{ - Shape shape_a{2, 3, 4}; - Shape shape_r{3, 4, 2}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{1, 2, 0}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 13, 2, 14, 3, 15, 4, 16, 5, 17, 6, 18, - 7, 19, 8, 20, 9, 21, 10, 22, 11, 23, 12, 24}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_4d_transpose) +NGRAPH_TEST(${BACKEND_NAME}, reshape_special_zero) { Shape shape_a{2, 2, 5, 5}; Shape shape_r{2, 5, 5, 2}; auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{0, 2, 3, 1}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - vector a_data(shape_size(shape_a)); - iota(a_data.begin(), a_data.end(), 1.f); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, a_data); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f( - (vector{1., 26., 2., 27., 3., 28., 4., 29., 5., 30., 6., 31., 7., 32., 8., - 33., 9., 34., 10., 35., 11., 36., 12., 37., 13., 38., 14., 39., 15., 40., - 16., 41., 17., 42., 18., 43., 19., 44., 20., 45., 21., 46., 22., 47., 23., - 48., 24., 49., 25., 50., 51., 76., 52., 77., 53., 78., 54., 79., 55., 80., - 56., 81., 57., 82., 58., 83., 59., 84., 60., 85., 61., 86., 62., 87., 63., - 88., 64., 89., 65., 90., 66., 91., 67., 92., 68., 93., 69., 94., 70., 95., - 71., 96., 72., 97., 73., 98., 74., 99., 75., 100.}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - -NGRAPH_TEST(${BACKEND_NAME}, reshape_4d_no_transpose) -{ - Shape shape_a{2, 2, 5, 5}; - Shape shape_r{2, 5, 5, 2}; - auto A = make_shared(element::f32, shape_a); - auto r = make_shared(A, AxisVector{0, 1, 2, 3}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {4}, Shape{0, 5, 0, 2}), true); auto f = make_shared(r, ParameterVector{A}); vector a_data(shape_size(shape_a)); @@ -462,28 +267,6 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_4d_no_transpose) EXPECT_TRUE(test::all_close_f(a_data, read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); } -NGRAPH_TEST(${BACKEND_NAME}, reshape_transposed_shape_change) -{ - Shape shape_a{2, 6}; - auto A = make_shared(element::f32, shape_a); - Shape shape_r{12}; - auto r = make_shared(A, AxisVector{1, 0}, shape_r); - auto f = make_shared(r, ParameterVector{A}); - - auto backend = runtime::Backend::create("${BACKEND_NAME}"); - - // Create some tensors for input/output - auto a = backend->create_tensor(element::f32, shape_a); - copy_data(a, vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}); - auto result = backend->create_tensor(element::f32, shape_r); - - auto handle = backend->compile(f); - handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f((vector{1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); -} - // // Numpy: // @@ -534,7 +317,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_6d) vector a_data(shape_size(shape_a)); iota(a_data.begin(), a_data.end(), 1.f); - auto r = make_shared(A, AxisVector{2, 4, 0, 5, 3, 1}, shape_r); + auto r = make_shared( + A, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r, ParameterVector{A}); auto backend = runtime::Backend::create("${BACKEND_NAME}"); @@ -547,31 +331,8 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_6d) auto handle = backend->compile(f); handle->call_with_validate({result}, {a}); - EXPECT_TRUE(test::all_close_f( - (vector{ - 1., 73., 9., 81., 17., 89., 2., 74., 10., 82., 18., 90., 3., 75., - 11., 83., 19., 91., 4., 76., 12., 84., 20., 92., 145., 217., 153., 225., - 161., 233., 146., 218., 154., 226., 162., 234., 147., 219., 155., 227., 163., 235., - 148., 220., 156., 228., 164., 236., 5., 77., 13., 85., 21., 93., 6., 78., - 14., 86., 22., 94., 7., 79., 15., 87., 23., 95., 8., 80., 16., 88., - 24., 96., 149., 221., 157., 229., 165., 237., 150., 222., 158., 230., 166., 238., - 151., 223., 159., 231., 167., 239., 152., 224., 160., 232., 168., 240., 25., 97., - 33., 105., 41., 113., 26., 98., 34., 106., 42., 114., 27., 99., 35., 107., - 43., 115., 28., 100., 36., 108., 44., 116., 169., 241., 177., 249., 185., 257., - 170., 242., 178., 250., 186., 258., 171., 243., 179., 251., 187., 259., 172., 244., - 180., 252., 188., 260., 29., 101., 37., 109., 45., 117., 30., 102., 38., 110., - 46., 118., 31., 103., 39., 111., 47., 119., 32., 104., 40., 112., 48., 120., - 173., 245., 181., 253., 189., 261., 174., 246., 182., 254., 190., 262., 175., 247., - 183., 255., 191., 263., 176., 248., 184., 256., 192., 264., 49., 121., 57., 129., - 65., 137., 50., 122., 58., 130., 66., 138., 51., 123., 59., 131., 67., 139., - 52., 124., 60., 132., 68., 140., 193., 265., 201., 273., 209., 281., 194., 266., - 202., 274., 210., 282., 195., 267., 203., 275., 211., 283., 196., 268., 204., 276., - 212., 284., 53., 125., 61., 133., 69., 141., 54., 126., 62., 134., 70., 142., - 55., 127., 63., 135., 71., 143., 56., 128., 64., 136., 72., 144., 197., 269., - 205., 277., 213., 285., 198., 270., 206., 278., 214., 286., 199., 271., 207., 279., - 215., 287., 200., 272., 208., 280., 216., 288.}), - read_vector(result), - MIN_FLOAT_TOLERANCE_BITS)); + EXPECT_TRUE(test::all_close_f(a_data, read_vector(result), MIN_FLOAT_TOLERANCE_BITS)); + EXPECT_EQ(r->get_output_shape(0), shape_r); } NGRAPH_TEST(${BACKEND_NAME}, builder_reshape_1D_to_scalar) @@ -619,9 +380,12 @@ NGRAPH_TEST(${BACKEND_NAME}, reshape_shufflenet_5d) vector a_data(shape_size(shape_a)); iota(a_data.begin(), a_data.end(), 1.f); - auto r0 = make_shared(A, AxisVector{0, 1, 2, 3}, shape_b); - auto r1 = make_shared(r0, AxisVector{0, 2, 1, 3, 4}, shape_c); - auto r2 = make_shared(r1, AxisVector{0, 1, 2, 3, 4}, shape_r); + auto r0 = make_shared( + A, op::Constant::create(element::u64, {shape_b.size()}, shape_b), false); + auto r1 = make_shared( + r0, op::Constant::create(element::u64, {shape_c.size()}, shape_c), false); + auto r2 = make_shared( + r1, op::Constant::create(element::u64, {shape_r.size()}, shape_r), false); auto f = make_shared(r2, ParameterVector{A}); auto ref_func = clone_function(*f); diff --git a/ngraph/test/backend/slice.in.cpp b/ngraph/test/backend/slice.in.cpp index cbbb4cb001b..dcdb3fb955c 100644 --- a/ngraph/test/backend/slice.in.cpp +++ b/ngraph/test/backend/slice.in.cpp @@ -15,6 +15,7 @@ //***************************************************************************** #include "gtest/gtest.h" +#include "ngraph/builder/reshape.hpp" #include "ngraph/ngraph.hpp" #include "ngraph/runtime/tensor.hpp" #include "runtime/backend.hpp" @@ -197,15 +198,15 @@ NGRAPH_TEST(${BACKEND_NAME}, slice_matrix_axis_0_in_place_twice_overlap) MIN_FLOAT_TOLERANCE_BITS)); } -NGRAPH_TEST(${BACKEND_NAME}, slice_matrix_axis_0_in_place_with_reshape) +NGRAPH_TEST(${BACKEND_NAME}, slice_matrix_axis_0_in_place_with_transpose) { Shape shape_a{4, 5}; auto A = make_shared(element::f32, shape_a); Shape shape_r{2, 4}; auto B = make_shared(A, Coordinate{1, 0}, Coordinate{4, 5}); - auto C = make_shared(B, AxisVector{1, 0}, Shape{5, 3}); + auto C = builder::opset1::transpose(B); auto D = make_shared(C, Coordinate{1, 0}, Coordinate{5, 3}); - auto E = make_shared(D, AxisVector{1, 0}, Shape{3, 4}); + auto E = builder::opset1::transpose(D); auto r = make_shared(E, Coordinate{1, 0}, Coordinate{3, 4}); auto f = make_shared(r, ParameterVector{A}); diff --git a/ngraph/test/constant_folding.cpp b/ngraph/test/constant_folding.cpp index 60915c057db..dfe150c5acd 100644 --- a/ngraph/test/constant_folding.cpp +++ b/ngraph/test/constant_folding.cpp @@ -210,61 +210,6 @@ TEST(constant_folding, constant_unsqueeze) ASSERT_TRUE(test::all_close_f(values_in, values_out, MIN_FLOAT_TOLERANCE_BITS)); } -TEST(constant_folding, constant_reshape) -{ - Shape shape_in{2, 4}; - Shape shape_out{2, 4, 1}; - - vector values_in{0, 1, 2, 3, 4, 5, 6, 7}; - auto constant = make_shared(element::f32, shape_in, values_in); - auto reshape = make_shared(constant, AxisVector{0, 1}, shape_out); - reshape->set_friendly_name("test"); - auto f = make_shared(reshape, ParameterVector{}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto new_const = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - ASSERT_TRUE(new_const); - ASSERT_EQ(new_const->get_friendly_name(), "test"); - auto values_out = new_const->get_vector(); - - ASSERT_TRUE(test::all_close_f(values_in, values_out, MIN_FLOAT_TOLERANCE_BITS)); -} - -TEST(constant_folding, DISABLED_constant_reshape_permute) -{ - Shape shape_in{2, 4}; - Shape shape_out{4, 2}; - - vector values_in{0, 1, 2, 3, 4, 5, 6, 7}; - auto constant = make_shared(element::f64, shape_in, values_in); - auto reshape = make_shared(constant, AxisVector{1, 0}, shape_out); - reshape->set_friendly_name("test"); - auto f = make_shared(reshape, ParameterVector{}); - - pass::Manager pass_manager; - pass_manager.register_pass(); - pass_manager.run_passes(f); - - ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); - - auto new_const = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); - ASSERT_TRUE(new_const); - ASSERT_EQ(new_const->get_friendly_name(), "test"); - auto values_out = new_const->get_vector(); - - vector values_permute{0, 4, 1, 5, 2, 6, 3, 7}; - ASSERT_TRUE(test::all_close_f(values_permute, values_out, MIN_FLOAT_TOLERANCE_BITS)); -} - TEST(constant_folding, constant_broadcast_v1) { vector values_in{0, 1}; diff --git a/ngraph/test/copy.cpp b/ngraph/test/copy.cpp index d7c51ab1a21..0c563c6d2e7 100644 --- a/ngraph/test/copy.cpp +++ b/ngraph/test/copy.cpp @@ -271,20 +271,20 @@ TEST(copy, power) TEST(copy, reshape) { Shape shape_in{2, 3, 4}; - AxisVector axes{0, 1, 2}; Shape shape_out{6, 4}; auto arg0 = make_shared(element::f32, shape_in); - OutputVector new_args{make_shared(element::f32, shape_in)}; + OutputVector new_args{make_shared(element::f32, shape_in), + op::Constant::create(element::u64, {shape_out.size()}, shape_out)}; - auto node = make_shared(arg0, axes, shape_out); + auto shape_pattern = op::Constant::create(element::u64, {shape_out.size()}, shape_out); + auto node = make_shared(arg0, shape_pattern, false); auto new_node = node->clone_with_new_inputs(new_args); - auto node_cast = as_type_ptr(new_node); + auto node_cast = as_type_ptr(new_node); ASSERT_NE(node_cast, nullptr); ASSERT_TRUE(nullptr != new_node); ASSERT_TRUE(new_args == new_node->input_values()); - ASSERT_TRUE(axes == node_cast->get_input_order()); ASSERT_TRUE(shape_out == node_cast->get_output_shape(0)); } diff --git a/ngraph/test/dyn_elimination.cpp b/ngraph/test/dyn_elimination.cpp index f882564fc1f..a3474cabccb 100644 --- a/ngraph/test/dyn_elimination.cpp +++ b/ngraph/test/dyn_elimination.cpp @@ -44,10 +44,10 @@ TEST(dyn_elimination, transpose) pass_manager.run_passes(f); ASSERT_EQ(count_ops_of_type(f), 0); - ASSERT_EQ(count_ops_of_type(f), 1); + ASSERT_EQ(count_ops_of_type(f), 1); auto new_reshape = - as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); + as_type_ptr(f->get_results().at(0)->input_value(0).get_node_shared_ptr()); ASSERT_TRUE(new_reshape); ASSERT_EQ(new_reshape->get_input_order(), (AxisVector{2, 3, 1, 0})); diff --git a/ngraph/test/eval.cpp b/ngraph/test/eval.cpp index 7640986a963..926d6e0e355 100644 --- a/ngraph/test/eval.cpp +++ b/ngraph/test/eval.cpp @@ -62,7 +62,6 @@ #include "ngraph/op/sinh.hpp" #include "ngraph/op/sqrt.hpp" #include "ngraph/op/squeeze.hpp" -#include "ngraph/op/stop_gradient.hpp" #include "ngraph/op/tan.hpp" #include "ngraph/op/tanh.hpp" #include "ngraph/op/topk.hpp" diff --git a/ngraph/test/op_is.cpp b/ngraph/test/op_is.cpp index 981dae7c65d..ab28ada18f0 100644 --- a/ngraph/test/op_is.cpp +++ b/ngraph/test/op_is.cpp @@ -643,7 +643,7 @@ namespace void op_is_Reshape() { - op::Reshape node; + op::v1::Reshape node; EXPECT_FALSE(op::is_unary_elementwise_arithmetic(&node)); EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); @@ -830,15 +830,6 @@ namespace EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); } - void op_is_StopGradient() - { - op::StopGradient node; - EXPECT_TRUE(op::is_unary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_arithmetic(&node)); - EXPECT_FALSE(op::is_binary_elementwise_comparison(&node)); - EXPECT_FALSE(op::is_binary_elementwise_logical(&node)); - } - void op_is_Subtract() { op::Subtract node; diff --git a/ngraph/test/runtime/dynamic/dynamic_backend.cpp b/ngraph/test/runtime/dynamic/dynamic_backend.cpp index fd60a7611fc..e7b6a48701e 100644 --- a/ngraph/test/runtime/dynamic/dynamic_backend.cpp +++ b/ngraph/test/runtime/dynamic/dynamic_backend.cpp @@ -89,8 +89,8 @@ runtime::dynamic::DynamicExecutable::DynamicExecutable(shared_ptr wrap // count_dyn_nodes. bool is_dynamic_op(const std::shared_ptr& op) { - return is_type(op) || is_type(op) || is_type(op) || - is_type(op) || is_type(op); + return is_type(op) || is_type(op) || + is_type(op); } // Helper for a vile hack in DynamicExecutable::call. See body of that function for details. diff --git a/ngraph/test/runtime/ie/unit_test.manifest b/ngraph/test/runtime/ie/unit_test.manifest index 38911a86930..9f511562bb8 100644 --- a/ngraph/test/runtime/ie/unit_test.manifest +++ b/ngraph/test/runtime/ie/unit_test.manifest @@ -914,6 +914,9 @@ broadcast_algo_matrix_stride_1 broadcast_algo_matrix_stride_2 broadcast_algo_matrix_stride_3 +# Cannot find blob with name: Parameter_1 +dynamic_transpose + # Failing from new reason after unblocking more Blob types gather_2d_negative_and_positive_indices_axis_0_2d_input gather_axis_0_int8 diff --git a/ngraph/test/runtime/interpreter/int_executable.hpp b/ngraph/test/runtime/interpreter/int_executable.hpp index c70d68667e8..b29834ab83c 100644 --- a/ngraph/test/runtime/interpreter/int_executable.hpp +++ b/ngraph/test/runtime/interpreter/int_executable.hpp @@ -1430,7 +1430,6 @@ protected: case OP_TYPEID::SpaceToDepth: case OP_TYPEID::Split: case OP_TYPEID::SquaredDifference: - case OP_TYPEID::StopGradient: case OP_TYPEID::TensorIterator: case OP_TYPEID::Tile: case OP_TYPEID::UnknownOp: @@ -1458,7 +1457,7 @@ protected: case OP_TYPEID::NotEqual: case OP_TYPEID::Power: case OP_TYPEID::Range: - case OP_TYPEID::Reshape: + case OP_TYPEID::Reshape_v1: case OP_TYPEID::Result: case OP_TYPEID::Reverse_v1: case OP_TYPEID::Round_v5: diff --git a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp index 0c85a46b1c8..9c7711bbcf8 100644 --- a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp +++ b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp @@ -34,6 +34,7 @@ NGRAPH_OP(LogicalXor, op::v1) NGRAPH_OP(LogicalNot, op::v1) NGRAPH_OP(GatherTree, op::v1) NGRAPH_OP(OneHot, op::v1) +NGRAPH_OP(Reshape, op::v1) NGRAPH_OP(Reverse, op::v1) #undef ID_SUFFIX diff --git a/ngraph/test/runtime/op/group_conv.cpp b/ngraph/test/runtime/op/group_conv.cpp index cd14a8c8470..587a0018641 100644 --- a/ngraph/test/runtime/op/group_conv.cpp +++ b/ngraph/test/runtime/op/group_conv.cpp @@ -23,7 +23,6 @@ #include "ngraph/builder/split.hpp" #include "ngraph/op/concat.hpp" #include "ngraph/op/convolution.hpp" -#include "ngraph/op/reshape.hpp" #include "ngraph/op/slice.hpp" #include "ngraph/validation_util.hpp" @@ -203,16 +202,14 @@ OutputVector op::v0::GroupConvolution::decompose_op() const auto sliced_data = builder::split(data, get_groups(), 1); // slice filters auto sliced_filters = builder::split(filters, get_groups(), 0); + auto shape = Shape(std::next(std::begin(filters_shape), 1), std::end(filters_shape)); for (std::size_t group{0}; group < get_groups(); ++group) { auto sliced_filter = sliced_filters[group]; if (m_groups_in_filters) { - // Remove group dimmension after slicing - sliced_filter = make_shared( - sliced_filters[group], - get_default_order(sliced_filters[group].get_shape().size()), - Shape(std::next(std::begin(filters_shape), 1), std::end(filters_shape))); + // Remove group dimension after slicing + sliced_filter = builder::opset1::reshape(sliced_filters[group], shape); } convolution_nodes.push_back( std::make_shared(sliced_data[group], diff --git a/ngraph/test/runtime/opset0_tbl.hpp b/ngraph/test/runtime/opset0_tbl.hpp index 32f3f75fbf3..ffadab1f4ef 100644 --- a/ngraph/test/runtime/opset0_tbl.hpp +++ b/ngraph/test/runtime/opset0_tbl.hpp @@ -108,7 +108,6 @@ NGRAPH_OP(QuantizedConvolution, ngraph::op) NGRAPH_OP(QuantizedDot, ngraph::op) NGRAPH_OP(Range, ngraph::op) NGRAPH_OP(Relu, ngraph::op) -NGRAPH_OP(Reshape, ngraph::op) NGRAPH_OP(Result, ngraph::op) NGRAPH_OP(ReverseSequence, ngraph::op) NGRAPH_OP(Select, ngraph::op) @@ -126,7 +125,6 @@ NGRAPH_OP(Split, ngraph::op) NGRAPH_OP(Sqrt, ngraph::op) NGRAPH_OP(SquaredDifference, ngraph::op) NGRAPH_OP(Squeeze, ngraph::op) -NGRAPH_OP(StopGradient, ngraph::op) NGRAPH_OP(Subtract, ngraph::op) NGRAPH_OP(Sum, ngraph::op) NGRAPH_OP(Tan, ngraph::op) diff --git a/ngraph/test/runtime/pass/dyn_elimination.cpp b/ngraph/test/runtime/pass/dyn_elimination.cpp index dbdb7043b1a..ac0406d2340 100644 --- a/ngraph/test/runtime/pass/dyn_elimination.cpp +++ b/ngraph/test/runtime/pass/dyn_elimination.cpp @@ -17,9 +17,9 @@ #include #include "dyn_elimination.hpp" +#include "ngraph/builder/reshape.hpp" #include "ngraph/op/broadcast.hpp" #include "ngraph/op/range.hpp" -#include "ngraph/op/reshape.hpp" #include "ngraph/op/slice.hpp" #include "ngraph/op/transpose.hpp" #include "ngraph/pattern/matcher.hpp" @@ -35,59 +35,9 @@ using namespace ngraph; pass::DynElimination::DynElimination() : GraphRewrite() { - construct_transpose(); construct_range(); } -void pass::DynElimination::construct_transpose() -{ - auto data_arg_label = make_shared(element::f32, Shape{1, 2, 3}); - auto perm_arg_label = - make_shared(element::i64, Shape{3}, pattern::has_class()); - - auto transpose = make_shared(data_arg_label, perm_arg_label); - - auto transpose_callback = [data_arg_label, perm_arg_label](pattern::Matcher& m) { - auto pattern_map = m.get_pattern_map(); - - auto data_arg = pattern_map[data_arg_label]; - auto perm_arg = static_pointer_cast(pattern_map[perm_arg_label]); - - // TODO(amprocte): Can't handle the case where data shape is dynamic, because static - // Reshape requries the exact output shape to be declared. See if we can come up with a - // workaround. - if (data_arg->get_output_partial_shape(0).is_dynamic()) - { - return false; - } - - auto& data_shape = data_arg->get_output_shape(0); - - NGRAPH_CHECK(perm_arg->get_output_partial_shape(0).rank().compatible(1)); - NGRAPH_CHECK(perm_arg->get_output_element_type(0).compatible(element::i64)); - - if (perm_arg->get_output_element_type(0).is_dynamic() || - perm_arg->get_output_partial_shape(0).is_dynamic()) - { - return false; - } - - auto perm = perm_arg->get_axis_vector_val(); - - auto output_shape = ngraph::apply_permutation(data_shape, perm); - - auto replacement = std::make_shared(data_arg, perm, output_shape); - - replace_node(m.get_match_root(), replacement); - return true; - }; - - auto transpose_matcher = make_shared(transpose, "DynElimination.Transpose"); - NGRAPH_SUPPRESS_DEPRECATED_START - add_matcher(transpose_matcher, transpose_callback, all_pass_property_off); - NGRAPH_SUPPRESS_DEPRECATED_END -} - template std::shared_ptr make_range_replacement(const element::Type& et, const Shape& shape, diff --git a/ngraph/test/runtime/pass/dyn_elimination.hpp b/ngraph/test/runtime/pass/dyn_elimination.hpp index 62aa0ac64ac..eed8fbd27d3 100644 --- a/ngraph/test/runtime/pass/dyn_elimination.hpp +++ b/ngraph/test/runtime/pass/dyn_elimination.hpp @@ -57,7 +57,6 @@ namespace ngraph DynElimination(); private: - void construct_transpose(); void construct_range(); }; } diff --git a/ngraph/test/runtime/pass/opset0_downgrade.cpp b/ngraph/test/runtime/pass/opset0_downgrade.cpp index 21ae1a9dd18..f2e2503109b 100644 --- a/ngraph/test/runtime/pass/opset0_downgrade.cpp +++ b/ngraph/test/runtime/pass/opset0_downgrade.cpp @@ -84,9 +84,10 @@ namespace opset0_downgrade { reshaped_output_shape.insert(reshaped_output_shape.begin() + axis, 1); } - auto reshaped_product = make_shared(replacement_node->output(0), - get_default_order(output_shape), - reshaped_output_shape); + auto shape_pattern = op::Constant::create( + element::u64, {reshaped_output_shape.size()}, reshaped_output_shape); + auto reshaped_product = + make_shared(replacement_node->output(0), shape_pattern, false); return reshaped_product; } else @@ -190,28 +191,6 @@ namespace opset0_downgrade return replacement_node; } - shared_ptr op_cast(shared_ptr node) - { - shared_ptr replacement_node; - - const auto target_shape_input = node->input_value(1).get_node_shared_ptr(); - const auto input_rank = node->get_input_partial_shape(0).rank(); - if (op::is_constant(target_shape_input) && node->get_output_partial_shape(0).is_static() && - input_rank.is_static()) - { - const auto output_shape = node->get_output_shape(0); - replacement_node = make_shared( - node->input_value(0), get_default_order(input_rank.get_length()), output_shape); - } - else - { - NGRAPH_CHECK(replacement_node, "Unable to convert Reshape:v1 with dynamic shape."); - } - - replace_node(node, replacement_node); - return replacement_node; - } - shared_ptr op_cast(shared_ptr node) { return op_cast_binary_elementwise_node(node); @@ -354,8 +333,9 @@ namespace opset0_downgrade { reshaped_output_shape.insert(reshaped_output_shape.begin() + axis, 1); } - count_node = make_shared( - count_node->output(0), get_default_order(output_shape), reshaped_output_shape); + auto shape_pattern = op::Constant::create( + element::u64, {reshaped_output_shape.size()}, reshaped_output_shape); + count_node = make_shared(count_node->output(0), shape_pattern, false); } const auto replacement_node = @@ -431,10 +411,9 @@ namespace opset0_downgrade if (p.reshape_in_shape != p.reshape_out_shape) { - replacement_node = - make_shared(replacement_node, - ngraph::get_default_order(p.reshape_in_shape), - p.reshape_out_shape); + auto shape_pattern = op::Constant::create( + element::u64, {p.reshape_out_shape.size()}, p.reshape_out_shape); + replacement_node = make_shared(replacement_node, shape_pattern, false); } if (!p.reverse_axes.empty()) @@ -466,44 +445,6 @@ namespace opset0_downgrade return op_cast_binary_elementwise_node(node); } - shared_ptr op_cast(shared_ptr node) - { - const auto data = node->input_value(0); - - const auto data_pshape = data.get_partial_shape(); - NGRAPH_CHECK(data_pshape.is_static(), - "Unable to convert Transpose:v1 to Reshape:v0 " - "if data shape is dynamic. Node: ", - *node); - const auto data_shape = data_pshape.to_shape(); - - const auto order_node = node->input_value(1).get_node_shared_ptr(); - NGRAPH_CHECK(op::is_constant(order_node), - "Unable to convert Transpose:v1 to Reshape:v0 " - "if order node is not constant. Node: ", - *node); - const auto order_const = as_type_ptr(order_node); - - auto order = order_const->get_axis_vector_val(); - Shape out_shape = data_shape; - if (order.empty()) - { - order.resize(out_shape.size()); - iota(begin(order), end(order), 0); - } - else - { - for (size_t i = 0; i < order.size(); ++i) - { - out_shape[i] = data_shape.at(order.at(i)); - } - } - - auto replacement_node = make_shared(data, order, out_shape); - replace_node(node, replacement_node); - return replacement_node; - } - shared_ptr op_cast(shared_ptr node) { const auto split_lengths = node->input_value(2).get_node_shared_ptr(); diff --git a/ngraph/test/runtime/pass/opset1_upgrade.cpp b/ngraph/test/runtime/pass/opset1_upgrade.cpp index ffa985d6dac..4335687ff25 100644 --- a/ngraph/test/runtime/pass/opset1_upgrade.cpp +++ b/ngraph/test/runtime/pass/opset1_upgrade.cpp @@ -127,14 +127,6 @@ namespace opset1_upgrade return replacement_node; } - shared_ptr op_cast(shared_ptr node) - { - shared_ptr replacement_node = - builder::opset1::reshape(node->input_value(0), node->get_reshape_output_shape()); - replace_node(node, replacement_node); - return replacement_node; - } - shared_ptr op_cast(shared_ptr node) { return op_cast_binary_elementwise_node(node); diff --git a/ngraph/test/type_prop/reshape.cpp b/ngraph/test/type_prop/reshape.cpp index a689ac4cb5a..0d2f73b60bf 100644 --- a/ngraph/test/type_prop/reshape.cpp +++ b/ngraph/test/type_prop/reshape.cpp @@ -18,15 +18,14 @@ #include "ngraph/ngraph.hpp" #include "util/type_prop.hpp" -NGRAPH_SUPPRESS_DEPRECATED_START - using namespace std; using namespace ngraph; TEST(type_prop, reshape_deduce_s2v) { auto param = make_shared(element::f32, Shape{}); - auto r = make_shared(param, AxisVector{}, Shape{1}); + auto r = make_shared( + param, op::Constant::create(element::u64, {1}, Shape{1}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{1})); } @@ -34,7 +33,8 @@ TEST(type_prop, reshape_deduce_s2v) TEST(type_prop, reshape_deduce_s2m) { auto param = make_shared(element::f32, Shape{}); - auto r = make_shared(param, AxisVector{}, Shape{1, 1}); + auto r = make_shared( + param, op::Constant::create(element::u64, {2}, Shape{1, 1}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{1, 1})); } @@ -42,39 +42,17 @@ TEST(type_prop, reshape_deduce_s2m) TEST(type_prop, reshape_deduce_s2t) { auto param = make_shared(element::f32, Shape{}); - auto r = make_shared(param, AxisVector{}, Shape{1, 1, 1}); + auto r = make_shared( + param, op::Constant::create(element::u64, {3}, Shape{1, 1, 1}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{1, 1, 1})); } -TEST(type_prop, reshape_deduce_v2s) -{ - auto param = make_shared(element::f32, Shape{1}); - auto r = make_shared(param, AxisVector{0}, Shape{}); - ASSERT_EQ(r->get_element_type(), element::f32); - ASSERT_EQ(r->get_shape(), (Shape{})); -} - -TEST(type_prop, reshape_deduce_m2s) -{ - auto param = make_shared(element::f32, Shape{1, 1}); - auto r = make_shared(param, AxisVector{0, 1}, Shape{}); - ASSERT_EQ(r->get_element_type(), element::f32); - ASSERT_EQ(r->get_shape(), (Shape{})); -} - -TEST(type_prop, reshape_deduce_t2s) -{ - auto param = make_shared(element::f32, Shape{1, 1, 1}); - auto r = make_shared(param, AxisVector{0, 1, 2}, Shape{}); - ASSERT_EQ(r->get_element_type(), element::f32); - ASSERT_EQ(r->get_shape(), (Shape{})); -} - TEST(type_prop, reshape_deduce_m2v_01) { auto param = make_shared(element::f32, Shape{3, 4}); - auto r = make_shared(param, AxisVector{0, 1}, Shape{12}); + auto r = make_shared( + param, op::Constant::create(element::u64, {1}, Shape{12}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{12})); } @@ -82,7 +60,8 @@ TEST(type_prop, reshape_deduce_m2v_01) TEST(type_prop, reshape_deduce_m2v_10) { auto param = make_shared(element::f32, Shape{3, 4}); - auto r = make_shared(param, AxisVector{1, 0}, Shape{12}); + auto r = make_shared( + param, op::Constant::create(element::u64, {1}, Shape{12}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{12})); } @@ -90,7 +69,8 @@ TEST(type_prop, reshape_deduce_m2v_10) TEST(type_prop, reshape_deduce_t2v_012) { auto param = make_shared(element::f32, Shape{3, 4, 5}); - auto r = make_shared(param, AxisVector{0, 1, 2}, Shape{60}); + auto r = make_shared( + param, op::Constant::create(element::u64, {1}, Shape{60}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{60})); } @@ -98,72 +78,19 @@ TEST(type_prop, reshape_deduce_t2v_012) TEST(type_prop, reshape_deduce_t2v_120) { auto param = make_shared(element::f32, Shape{3, 4, 5}); - auto r = make_shared(param, AxisVector{1, 2, 0}, Shape{60}); + auto r = make_shared( + param, op::Constant::create(element::u64, {1}, Shape{60}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_EQ(r->get_shape(), (Shape{60})); } -TEST(type_prop, reshape_deduce_not_enough_axes) +TEST(type_prop, reshape_deduce_zero_special) { auto param = make_shared(element::f32, Shape{3, 4, 5}); - try - { - auto r = make_shared(param, AxisVector{1, 0}, Shape{60}); - // Should have thrown, so fail if it didn't - FAIL() << "Not enough axes not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, reshape_deduce_too_many_axes) -{ - auto param = make_shared(element::f32, Shape{3, 4, 5}); - try - { - auto r = make_shared(param, AxisVector{1, 2, 0, 3}, Shape{60}); - // Should have thrown, so fail if it didn't - FAIL() << "Too many axes not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -TEST(type_prop, reshape_deduce_duplicate_axes) -{ - auto param = make_shared(element::f32, Shape{3, 4, 5}); - try - { - auto r = make_shared(param, AxisVector{1, 1, 0}, Shape{60}); - // Should have thrown, so fail if it didn't - FAIL() << "Too many axes not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } + auto r = make_shared( + param, op::Constant::create(element::u64, {3}, Shape{6, 2, 0}), true); + ASSERT_EQ(r->get_element_type(), element::f32); + ASSERT_EQ(r->get_shape(), (Shape{6, 2, 5})); } TEST(type_prop, reshape_deduce_wrong_output_shape) @@ -171,49 +98,16 @@ TEST(type_prop, reshape_deduce_wrong_output_shape) auto param = make_shared(element::f32, Shape{3, 4, 5}); try { - auto r = make_shared(param, AxisVector{1, 2, 0}, Shape{3, 3, 3}); + auto r = make_shared( + param, op::Constant::create(element::u64, {3}, Shape{3, 3, 3}), false); // Should have thrown, so fail if it didn't - FAIL() << "Too many axes not detected"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), - std::string("Product of output shape dimensions does not match " - "product of argument shape dimensions")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} - -// -// Input shape rank dynamic, so we should set the desired output shape if the axis vector is not -// known invalid (invalid means it's not a permutation of {0,...,n-1} for any n). -// -TEST(type_prop, reshape_partial_rank_dynamic_axisvector_ok) -{ - auto param = make_shared(element::f32, PartialShape::dynamic()); - auto r = make_shared(param, AxisVector{2, 1, 0, 3}, Shape{3, 1, 8, 2}); - ASSERT_EQ(r->get_element_type(), element::f32); - ASSERT_TRUE(r->get_output_partial_shape(0).is_static()); - ASSERT_EQ(r->get_shape(), (Shape{3, 1, 8, 2})); -} - -TEST(type_prop, reshape_partial_rank_dynamic_axisvector_not_ok) -{ - auto param = make_shared(element::f32, PartialShape::dynamic()); - try - { - auto r = make_shared(param, AxisVector{2, 1, 0, 4}, Shape{3, 1, 8, 2}); - // Should have thrown, so fail if it didn't - FAIL() << "Did not detect malformed AxisVector (input shape rank dynamic)"; + FAIL() << "No exception was thrown"; } catch (const NodeValidationFailure& error) { EXPECT_HAS_SUBSTRING( error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); + std::string("Check 'shape_size(get_input_shape(0)) == shape_size(output_shape)'")); } catch (...) { @@ -222,41 +116,31 @@ TEST(type_prop, reshape_partial_rank_dynamic_axisvector_not_ok) } // -// Input shape rank static but input shape is dynamic, so should set desired output shape if the -// axis vector is consistent with the static rank. +// Input shape rank dynamic, so we should set the desired output shape // -TEST(type_prop, reshape_partial_rank_static_dynamic_axisvector_ok) +TEST(type_prop, reshape_partial_rank_dynamic) { - auto param_shape = - PartialShape{Dimension::dynamic(), 6, Dimension::dynamic(), Dimension::dynamic()}; - auto param = make_shared(element::f32, param_shape); - auto r = make_shared(param, AxisVector{2, 1, 0, 3}, Shape{3, 1, 8, 2}); + auto param = make_shared(element::f32, PartialShape::dynamic()); + auto r = make_shared( + param, op::Constant::create(element::u64, {4}, Shape{3, 1, 8, 2}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_TRUE(r->get_output_partial_shape(0).is_static()); ASSERT_EQ(r->get_shape(), (Shape{3, 1, 8, 2})); } -TEST(type_prop, reshape_partial_rank_static_dynamic_axisvector_not_ok) +// +// Input shape rank static but input shape is dynamic, so should set desired output shape +// +TEST(type_prop, reshape_partial_rank_static) { auto param_shape = PartialShape{Dimension::dynamic(), 6, Dimension::dynamic(), Dimension::dynamic()}; auto param = make_shared(element::f32, param_shape); - try - { - auto r = make_shared(param, AxisVector{2, 1, 0}, Shape{3, 1, 8, 2}); - // Should have thrown, so fail if it didn't - FAIL() << "Did not detect AxisVector inconsistent with rank (rank-static dynamic shape)"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } + auto r = make_shared( + param, op::Constant::create(element::u64, {4}, Shape{3, 1, 8, 2}), false); + ASSERT_EQ(r->get_element_type(), element::f32); + ASSERT_TRUE(r->get_output_partial_shape(0).is_static()); + ASSERT_EQ(r->get_shape(), (Shape{3, 1, 8, 2})); } // @@ -268,32 +152,9 @@ TEST(type_prop, reshape_partial_rank_static_dynamic_but_zero_ok) auto param_shape = PartialShape{Dimension::dynamic(), 0, Dimension::dynamic(), Dimension::dynamic()}; auto param = make_shared(element::f32, PartialShape::dynamic()); - auto r = make_shared(param, AxisVector{2, 1, 0, 3}, Shape{3, 1, 0, 2}); + auto r = make_shared( + param, op::Constant::create(element::u64, {4}, Shape{3, 1, 0, 2}), false); ASSERT_EQ(r->get_element_type(), element::f32); ASSERT_TRUE(r->get_output_partial_shape(0).is_static()); ASSERT_EQ(r->get_shape(), (Shape{3, 1, 0, 2})); } - -TEST(type_prop, reshape_partial_rank_static_dynamic_but_zero_not_ok) -{ - auto param_shape = - PartialShape{Dimension::dynamic(), 0, Dimension::dynamic(), Dimension::dynamic()}; - auto param = make_shared(element::f32, param_shape); - try - { - auto r = make_shared(param, AxisVector{2, 1, 0}, Shape{3, 1, 8, 2}); - // Should have thrown, so fail if it didn't - FAIL() << "Did not detect inconsistent output shape with static-zero-element rank-dynamic" - " static input shape"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING( - error.what(), - std::string("Input axis order is not a permutation of argument's axis indices")); - } - catch (...) - { - FAIL() << "Deduced type check failed for unexpected reason"; - } -} diff --git a/ngraph/test/type_prop/ti.cpp b/ngraph/test/type_prop/ti.cpp index a7d6938b95f..6fdc2241c00 100644 --- a/ngraph/test/type_prop/ti.cpp +++ b/ngraph/test/type_prop/ti.cpp @@ -15,6 +15,7 @@ //***************************************************************************** #include "gtest/gtest.h" +#include "ngraph/builder/reshape.hpp" #include "ngraph/ngraph.hpp" #include "ngraph/opsets/opset5.hpp" #include "util/type_prop.hpp" @@ -43,15 +44,14 @@ TEST(type_prop, tensor_iterator_lstm) auto X = make_shared(element::f32, Shape{N, 1, I}); auto W_body = make_shared(element::f32, Shape{4 * H, I}); auto R_body = make_shared(element::f32, Shape{4 * H, H}); - auto LSTM_cell = make_shared( - make_shared(X, AxisVector{0, 1, 2}, Shape{N, I}), - make_shared(H_t, AxisVector{0, 1, 2}, Shape{N, H}), - make_shared(C_t, AxisVector{0, 1, 2}, Shape{N, H}), - W_body, - R_body, - H); - auto H_o = make_shared(LSTM_cell->output(0), AxisVector{0, 1}, Shape{N, 1, H}); - auto C_o = make_shared(LSTM_cell->output(1), AxisVector{0, 1}, Shape{N, 1, H}); + auto LSTM_cell = make_shared(builder::opset1::reshape(X, Shape{N, I}), + builder::opset1::reshape(H_t, Shape{N, H}), + builder::opset1::reshape(C_t, Shape{N, H}), + W_body, + R_body, + H); + auto H_o = builder::opset1::reshape(LSTM_cell->output(0), Shape{N, 1, H}); + auto C_o = builder::opset1::reshape(LSTM_cell->output(1), Shape{N, 1, H}); auto body = make_shared(OutputVector{H_o, C_o}, ParameterVector{X, H_t, C_t, W_body, R_body});