diff --git a/BUILD.md b/BUILD.md
index 8f30421af9..87783f6675 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -338,20 +338,21 @@ See more information on the nGraph Execution Provider [here](./docs/execution_pr
See more information on the OpenVINO Execution Provider [here](./docs/execution_providers/OpenVINO-ExecutionProvider.md).
#### Prerequisites
-1. Install the Intel® Distribution of OpenVINOTM Toolkit **Release 2020.4** for the appropriate OS and target hardware :
+1. Install the Intel® Distribution of OpenVINOTM Toolkit **Release 2021.1** for the appropriate OS and target hardware :
* [Linux - CPU, GPU, VPU, VAD-M](https://software.intel.com/en-us/openvino-toolkit/choose-download/free-download-linux)
* [Linux - FPGA](https://software.intel.com/en-us/openvino-toolkit/choose-download/free-download-linux-fpga)
* [Windows - CPU, GPU, VPU, VAD-M](https://software.intel.com/en-us/openvino-toolkit/choose-download/free-download-windows).
- Follow [documentation](https://docs.openvinotoolkit.org/2020.4/index.html) for detailed instructions.
+ Follow [documentation](https://docs.openvinotoolkit.org/2021.1/index.html) for detailed instructions.
- *2020.4 is the recommended OpenVINO version. [OpenVINO 2020.2](https://docs.openvinotoolkit.org/2020.2/index.html) is minimal OpenVINO version requirement.*
+ *2021.1 is the recommended OpenVINO version. [OpenVINO 2020.2](https://docs.openvinotoolkit.org/2020.2/index.html) is minimal OpenVINO version requirement.*
+ *The minimum ubuntu version to support 2021.1 is 18.04.*
2. Configure the target hardware with specific follow on instructions:
- * To configure Intel® Processor Graphics(GPU) please follow these instructions: [Windows](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_windows.html#Install-GPU), [Linux](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_linux.html#additional-GPU-steps)
- * To configure Intel® MovidiusTM USB, please follow this getting started guide: [Linux](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_linux.html#additional-NCS-steps)
- * To configure Intel® Vision Accelerator Design based on 8 MovidiusTM MyriadX VPUs, please follow this configuration guide: [Windows](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_windows.html#hddl-myriad), [Linux](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_linux.html#install-VPU). Follow steps 3 and 4 to complete the configuration.
- * To configure Intel® Vision Accelerator Design with an Intel® Arria® 10 FPGA, please follow this configuration guide: [Linux](https://docs.openvinotoolkit.org/2020.4/openvino_docs_install_guides_installing_openvino_linux_fpga.html)
+ * To configure Intel® Processor Graphics(GPU) please follow these instructions: [Windows](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_windows.html#Install-GPU), [Linux](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_linux.html#additional-GPU-steps)
+ * To configure Intel® MovidiusTM USB, please follow this getting started guide: [Linux](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_linux.html#additional-NCS-steps)
+ * To configure Intel® Vision Accelerator Design based on 8 MovidiusTM MyriadX VPUs, please follow this configuration guide: [Windows](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_windows.html#hddl-myriad), [Linux](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_linux.html#install-VPU). Follow steps 3 and 4 to complete the configuration.
+ * To configure Intel® Vision Accelerator Design with an Intel® Arria® 10 FPGA, please follow this configuration guide: [Linux](https://docs.openvinotoolkit.org/2021.1/openvino_docs_install_guides_installing_openvino_linux_fpga.html)
3. Initialize the OpenVINO environment by running the setupvars script as shown below:
* For Linux run:
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 6f25b2f4d2..91f6786a30 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -968,6 +968,9 @@ if(onnxruntime_USE_OPENVINO)
elseif ($ENV{INTEL_OPENVINO_DIR} MATCHES "2020.4")
set(OPENVINO_VERSION "2020.4")
add_definitions(-DOPENVINO_2020_4=1)
+ elseif ($ENV{INTEL_OPENVINO_DIR} MATCHES "2021.1")
+ set(OPENVINO_VERSION "2021.1")
+ add_definitions(-DOPENVINO_2021_1=1)
else()
message(FATAL_ERROR "Unsupported OpenVINO version: ${INTEL_OPENVINO_DIR}")
endif()
diff --git a/cmake/onnxruntime_providers.cmake b/cmake/onnxruntime_providers.cmake
index c449611009..4cdf1f57bd 100644
--- a/cmake/onnxruntime_providers.cmake
+++ b/cmake/onnxruntime_providers.cmake
@@ -561,6 +561,7 @@ if (onnxruntime_USE_OPENVINO)
if ((OPENVINO_VERSION VERSION_GREATER_EQUAL "2020.3") OR (WIN32))
# Link to nGraph from OpenVINO installation
list(APPEND OPENVINO_INCLUDE_DIR_LIST $ENV{INTEL_OPENVINO_DIR}/deployment_tools/ngraph/include)
+ list(APPEND OPENVINO_INCLUDE_DIR_LIST $ENV{INTEL_OPENVINO_DIR}/deployment_tools/ngraph/include/ngraph/frontend)
list(APPEND OPENVINO_LIB_DIR_LIST $ENV{INTEL_OPENVINO_DIR}/deployment_tools/ngraph/lib)
if (WIN32)
list(APPEND OPENVINO_LIB_LIST ngraph.lib)
diff --git a/dockerfiles/Dockerfile.openvino b/dockerfiles/Dockerfile.openvino
index 3a358238e1..13526da838 100644
--- a/dockerfiles/Dockerfile.openvino
+++ b/dockerfiles/Dockerfile.openvino
@@ -15,7 +15,7 @@ ARG MY_ROOT=/code
ENV PATH /opt/miniconda/bin:/code/cmake-3.14.3-Linux-x86_64/bin:$PATH
ENV LD_LIBRARY_PATH=/opt/miniconda/lib:/usr/lib:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
-ENV INTEL_OPENVINO_DIR=/opt/intel/openvino_2020.4.287
+ENV INTEL_OPENVINO_DIR=/opt/intel/openvino_2021.1.110
ENV InferenceEngine_DIR=${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/share
ENV IE_PLUGINS_PATH=${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/lib/intel64
ENV LD_LIBRARY_PATH=/opt/intel/opencl:${INTEL_OPENVINO_DIR}/inference_engine/external/gna/lib:${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/mkltiny_lnx/lib:$INTEL_OPENVINO_DIR/deployment_tools/ngraph/lib:${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/omp/lib:${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/tbb/lib:${IE_PLUGINS_PATH}:${LD_LIBRARY_PATH}
@@ -24,6 +24,7 @@ ENV LD_LIBRARY_PATH=${INTEL_OPENVINO_DIR}/opencv/lib:${INTEL_OPENVINO_DIR}/openc
ENV HDDL_INSTALL_DIR=${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/hddl
ENV LD_LIBRARY_PATH=${INTEL_OPENVINO_DIR}/deployment_tools/inference_engine/external/hddl/lib:$LD_LIBRARY_PATH
ENV LANG en_US.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && \
apt -y install apt-transport-https ca-certificates python3 python3-pip zip x11-apps lsb-core wget cpio sudo libboost-python-dev libpng-dev zlib1g-dev git libnuma1 ocl-icd-libopencl1 clinfo libboost-filesystem1.65-dev libboost-thread1.65-dev protobuf-compiler libprotoc-dev autoconf automake libtool libjson-c-dev unattended-upgrades && \
@@ -31,12 +32,12 @@ RUN apt update && \
rm -rf /var/lib/apt/lists/* && \
# Install OpenVINO
cd ${MY_ROOT} && \
- wget https://apt.repos.intel.com/openvino/2020/GPG-PUB-KEY-INTEL-OPENVINO-2020 && \
- apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2020 && rm GPG-PUB-KEY-INTEL-OPENVINO-2020 && \
+ wget https://apt.repos.intel.com/openvino/2021/GPG-PUB-KEY-INTEL-OPENVINO-2021 && \
+ apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2021 && rm GPG-PUB-KEY-INTEL-OPENVINO-2021 && \
cd /etc/apt/sources.list.d && \
- echo "deb https://apt.repos.intel.com/openvino/2020 all main">intel-openvino-2020.list && \
+ echo "deb https://apt.repos.intel.com/openvino/2021 all main">intel-openvino-2021.list && \
apt update && \
- apt -y install intel-openvino-dev-ubuntu18-2020.4.287 && \
+ apt -y install intel-openvino-dev-ubuntu18-2021.1.110 && \
cd ${INTEL_OPENVINO_DIR}/install_dependencies && ./install_openvino_dependencies.sh && \
cd ${INTEL_OPENVINO_DIR} && rm -rf documentation && cd deployment_tools/ && rm -rf model_optimizer open_model_zoo demo && cd inference_engine && rm -rf samples && \
# Install GPU runtime and drivers
@@ -54,14 +55,9 @@ RUN apt update && \
dpkg -i /tmp/opencl/*.deb && \
ldconfig && \
rm -rf /tmp/opencl && \
-# Install CMake
cd ${MY_ROOT} && \
locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8 && \
- pip3 install cython numpy && \
- mkdir -p /opt/cmake/bin && \
- cd ${MY_ROOT} && \
- wget https://github.com/Kitware/CMake/releases/download/v3.13.2/cmake-3.13.2-Linux-x86_64.tar.gz && \
- tar -xf cmake-3.13.2-Linux-x86_64.tar.gz --strip 1 -C /opt/cmake && rm -rf ${MY_ROOT}/cmake-3.13.2-Linux-x86_64.tar.gz && \
+ pip3 install cython && \
# Download and build ONNX Runtime
cd ${MY_ROOT} && \
git clone --recursive -b ${ONNXRUNTIME_BRANCH} ${ONNXRUNTIME_REPO} && \
@@ -69,4 +65,4 @@ RUN apt update && \
cd onnxruntime/cmake/external/onnx && python3 setup.py install && \
cd ${MY_ROOT}/onnxruntime && ./build.sh --config Release --update --build --parallel --use_openvino ${DEVICE} --build_wheel && \
pip install build/Linux/Release/dist/*-linux_x86_64.whl && \
- cd ${MY_ROOT}/ && rm -rf cmake-3.14.3-Linux-x86_64 onnxruntime
+ cd ${MY_ROOT}/ && rm -rf onnxruntime
diff --git a/dockerfiles/README.md b/dockerfiles/README.md
index be793553ef..687828eade 100644
--- a/dockerfiles/README.md
+++ b/dockerfiles/README.md
@@ -120,7 +120,7 @@ Therefore, ONNX RT Execution Provider for **nGraph** will be deprecated starting
Retrieve your docker image in one of the following ways.
- - Choose Dockerfile.openvino as the dockerfile for building an OpenVINO 2020.4 based Docker image. Providing the docker build argument DEVICE enables the onnxruntime build for that particular device. You can also provide arguments ONNXRUNTIME_REPO and ONNXRUNTIME_BRANCH to test that particular repo and branch. Default repository is http://github.com/microsoft/onnxruntime and default branch is master.
+ - Choose Dockerfile.openvino as the dockerfile for building an OpenVINO 2021.1 based Docker image. Providing the docker build argument DEVICE enables the onnxruntime build for that particular device. You can also provide arguments ONNXRUNTIME_REPO and ONNXRUNTIME_BRANCH to test that particular repo and branch. Default repository is http://github.com/microsoft/onnxruntime and default branch is master.
```
docker build --rm -t onnxruntime --build-arg DEVICE=$DEVICE -f Dockerfile.openvino .
```
@@ -176,7 +176,7 @@ Therefore, ONNX RT Execution Provider for **nGraph** will be deprecated starting
### OpenVINO on VAD-M Accelerator Version
-1. Download OpenVINO **Full package** for version **2020.3** for Linux on host machine from [this link](https://software.intel.com/en-us/openvino-toolkit/choose-download) and install it with the help of instructions from [this link](https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_linux.html)
+1. Download OpenVINO **Full package** for version **2021.1** for Linux on host machine from [this link](https://software.intel.com/en-us/openvino-toolkit/choose-download) and install it with the help of instructions from [this link](https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_linux.html)
2. Install the drivers on the host machine according to the reference in [here](https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_linux_ivad_vpu.html)
diff --git a/docs/execution_providers/OpenVINO-ExecutionProvider.md b/docs/execution_providers/OpenVINO-ExecutionProvider.md
index 5b3d76ec89..e409cae97a 100644
--- a/docs/execution_providers/OpenVINO-ExecutionProvider.md
+++ b/docs/execution_providers/OpenVINO-ExecutionProvider.md
@@ -125,6 +125,7 @@ VPUs as well as Intel® Vision accelerator Design with Intel Movidiu
| Equal | Yes | Yes | Yes |
| Erf | Yes | Yes | Yes |
| Exp | Yes | Yes | Yes |
+| Expand | No | No | Yes |
| Flatten | Yes | Yes | Yes |
| Floor | Yes | Yes | Yes |
| Gather | Yes | Yes | Yes |
@@ -145,6 +146,8 @@ VPUs as well as Intel® Vision accelerator Design with Intel Movidiu
| Min | Yes | Yes | Yes |
| Mul | Yes | Yes | Yes |
| Neg | Yes | Yes | Yes |
+| NonMaxSuppression | No | No | Yes |
+| NonZero | Yes | No | Yes |
| Not | Yes | Yes | No |
| OneHot | Yes | Yes | Yes |
| Pad | Yes | Yes | Yes |
@@ -160,7 +163,9 @@ VPUs as well as Intel® Vision accelerator Design with Intel Movidiu
| ReduceSumSquare | Yes | No | Yes |
| Relu | Yes | Yes | Yes |
| Reshape | Yes | Yes | Yes |
-| Resize | Yes | No | No |
+| Resize | Yes | No | Yes |
+| RoiAlign | No | No | Yes |
+| Scatter | No | No | Yes |
| Selu | Yes | Yes | No |
| Shape | Yes | Yes | Yes |
| Sigmoid | Yes | Yes | Yes |
@@ -216,6 +221,7 @@ Below topologies from ONNX open model zoo are fully supported on OpenVINO Execut
| zfnet512 | Yes | Yes | Yes | Yes* |
| arcface | Yes | Yes | Yes | Yes* |
+
## Image Recognition Networks
| **MODEL NAME** | **CPU** | **GPU** | **VPU** | **FPGA** |
| --- | --- | --- | --- | --- |
@@ -226,6 +232,15 @@ Below topologies from ONNX open model zoo are fully supported on OpenVINO Execut
| --- | --- | --- | --- | --- |
| tiny_yolov2 | Yes | Yes | Yes | Yes* |
+## Image Manipulation Networks
+| **MODEL NAME** | **CPU** | **GPU** | **VPU** | **FPGA** |
+| --- | --- | --- | --- | --- |
+| mosaic | Yes | No | No | No* |
+| candy | Yes | No | No | No* |
+| rain_princess | Yes | No | No | No* |
+| pointilism | Yes | No | No | No* |
+| udnie | Yes | No | No | No* |
+
*FPGA only runs in HETERO mode wherein the layers that are not supported on FPGA fall back to OpenVINO CPU.
## CSharp API
diff --git a/onnxruntime/core/providers/openvino/backend_utils.cc b/onnxruntime/core/providers/openvino/backend_utils.cc
index 96b7afcb55..ccb1154e90 100644
--- a/onnxruntime/core/providers/openvino/backend_utils.cc
+++ b/onnxruntime/core/providers/openvino/backend_utils.cc
@@ -41,6 +41,12 @@ void DumpOnnxModelProto(const ONNX_NAMESPACE::ModelProto& model_proto, std::stri
#endif
+struct static_cast_int64
+{
+ template // T1 models type statically convertible to T
+ int64_t operator()(const T1& x) const { return static_cast(x); }
+};
+
std::shared_ptr
CreateCNNNetwork(const ONNX_NAMESPACE::ModelProto& model_proto, const GlobalContext& global_context, const SubGraphContext& subgraph_context, std::map>& const_outputs_map) {
@@ -74,21 +80,23 @@ CreateCNNNetwork(const ONNX_NAMESPACE::ModelProto& model_proto, const GlobalCont
ng_function->validate_nodes_and_infer_types();
}
-#if defined(OPENVINO_2020_4)
- std::map result_to_output;
- for(auto& result : ng_function->get_results()){
- result_to_output[result->get_friendly_name()] = result->input_value(0).get_node_shared_ptr()->get_friendly_name();
- }
-
- ngraph::pass::ConstantFolding().run_on_function(ng_function);
- auto& results = const_cast<::ngraph::ResultVector&>(ng_function->get_results());
- size_t index = results.size() - 1;
- for (auto it = results.rbegin(); it != results.rend(); ++it){
- if(auto const_node = std::dynamic_pointer_cast((*it)->input_value(0).get_node_shared_ptr())){
- const_outputs_map[result_to_output.at((*it)->get_friendly_name())] = const_node;
- results.erase(results.begin() + index);
+#if (defined OPENVINO_2020_4) || (defined OPENVINO_2021_1)
+ if(!global_context.is_wholly_supported_graph){
+ std::map result_to_output;
+ for(auto& result : ng_function->get_results()){
+ result_to_output[result->get_friendly_name()] = result->input_value(0).get_node_shared_ptr()->get_friendly_name();
+ }
+
+ ngraph::pass::ConstantFolding().run_on_function(ng_function);
+ auto& results = const_cast<::ngraph::ResultVector&>(ng_function->get_results());
+ size_t index = results.size() - 1;
+ for (auto it = results.rbegin(); it != results.rend(); ++it){
+ if(auto const_node = std::dynamic_pointer_cast((*it)->input_value(0).get_node_shared_ptr())){
+ const_outputs_map[result_to_output.at((*it)->get_friendly_name())] = const_node;
+ results.erase(results.begin() + index);
+ }
+ --index;
}
- --index;
}
#endif
@@ -102,7 +110,7 @@ CreateCNNNetwork(const ONNX_NAMESPACE::ModelProto& model_proto, const GlobalCont
}
}
-InferenceEngine::Precision ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::TypeProto& onnx_type) {
+InferenceEngine::Precision ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::TypeProto& onnx_type, std::string device) {
ONNX_NAMESPACE::DataType type_string = ONNX_NAMESPACE::Utils::DataTypeUtils::ToType(onnx_type);
if (*type_string == "float" || *type_string == "tensor(float)") {
return InferenceEngine::Precision::FP32;
@@ -119,7 +127,11 @@ InferenceEngine::Precision ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::
} else if (*type_string == "uint8" || *type_string == "tensor(uint8)") {
return InferenceEngine::Precision::U8;
} else if (*type_string == "bool" || *type_string == "tensor(bool)") {
- return InferenceEngine::Precision::U8;
+ if (device == "MYRIAD") {
+ return InferenceEngine::Precision::I32;
+ } else {
+ return InferenceEngine::Precision::U8;
+ }
} else if (*type_string == "int64" || *type_string == "tensor(int64)") {
return InferenceEngine::Precision::I32;
} else {
@@ -130,7 +142,8 @@ InferenceEngine::Precision ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::
void SetIODefs(const ONNX_NAMESPACE::ModelProto& model_proto,
std::shared_ptr network,
std::unordered_map output_names,
- std::map>& const_outputs_map) {
+ std::map>& const_outputs_map,
+ std::string device) {
// Configure input & output
// Prepare input blobs
@@ -141,7 +154,7 @@ void SetIODefs(const ONNX_NAMESPACE::ModelProto& model_proto,
int input_idx = 0;
for (auto iter = inputInfo.begin(); iter != inputInfo.end(); ++iter, ++input_idx) {
// Get the onnx index for the corresponding input (ignoring initializers)
- auto precision = ConvertPrecisionONNXToOpenVINO(model_proto.graph().input(input_idx).type());
+ auto precision = ConvertPrecisionONNXToOpenVINO(model_proto.graph().input(input_idx).type(), device);
iter->second->setPrecision(precision);
}
@@ -149,75 +162,79 @@ void SetIODefs(const ONNX_NAMESPACE::ModelProto& model_proto,
auto outputInfo = network->getOutputsInfo();
for (auto iter = outputInfo.begin(); iter != outputInfo.end(); ++iter) {
auto output_name = iter->first;
-#if defined(OPENVINO_2020_4)
+#if (defined OPENVINO_2020_4) || (defined OPENVINO_2021_1)
auto it = const_outputs_map.find(output_name);
//Output is constant and don't need to set precision
if(it != const_outputs_map.end())
break;
#endif
- auto precision = ConvertPrecisionONNXToOpenVINO(model_proto.graph().output(output_names.at(output_name)).type());
+ auto itr = output_names.find(output_name);
+ if(itr == output_names.end()){
+ ORT_THROW(log_tag + "Output Names Mismatch: " + output_name + " doesn't exist");
+ }
+ auto precision = ConvertPrecisionONNXToOpenVINO(model_proto.graph().output(itr->second).type(), device);
iter->second->setPrecision(precision);
}
}
-std::vector
-GetOutputTensors(Ort::CustomOpApi& ort, OrtKernelContext* context, size_t batch_size,
+OrtValue*
+GetOutputTensor(Ort::CustomOpApi& ort, OrtKernelContext* context, size_t batch_size,
InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network,
- std::unordered_map output_names, std::map> const_output_map) {
- std::vector output_tensors;
+ std::string output_name,
+ std::unordered_map output_names) {
- if(output_names.size() != const_output_map.size()){
- auto graph_output_info = ie_cnn_network->getOutputsInfo();
+ OrtValue* output_tensor;
- size_t i = 0;
- for (auto output_info_iter = graph_output_info.begin();
- output_info_iter != graph_output_info.end(); ++output_info_iter, ++i) {
- auto graph_output_blob = infer_request->GetBlob(output_info_iter->first);
- auto graph_output_dims = graph_output_blob->getTensorDesc().getDims();
-
- if (batch_size > 1) {
- // Add the batch size as dim 0.
- graph_output_dims.insert(graph_output_dims.begin(), batch_size);
- }
- size_t num_dims = graph_output_dims.size();
- auto output_shape = new int64_t[num_dims];
- for (size_t j = 0; j < num_dims; j++) {
- output_shape[j] = static_cast(graph_output_dims[j]);
- }
- auto it = output_names.find(output_info_iter->first);
- if (it == output_names.end()) {
- ORT_THROW(log_tag + "Output names mismatch between OpenVINO and ONNX");
- }
- int index = it->second;
-
- output_tensors.push_back(ort.KernelContext_GetOutput(context, index, output_shape, num_dims));
- delete output_shape;
- }
+ auto graph_output_blob = infer_request->GetBlob(output_name);
+ auto graph_output_dims = graph_output_blob->getTensorDesc().getDims();
+ if (batch_size > 1) {
+ // Add the batch size as dim 0.
+ graph_output_dims.insert(graph_output_dims.begin(), batch_size);
}
-#if defined(OPENVINO_2020_4)
- for(auto item : const_output_map){
- auto it = output_names.find(item.first);
- if(it == output_names.end()) {
- ORT_THROW(log_tag + "Output names mismatch between OpenVINO and ONNX");
- }
- int index = it->second;
- auto node = item.second;
- auto shape = node->get_shape();
-
- size_t num_dims = shape.size();
- auto output_shape = new int64_t[num_dims];
- for(size_t j = 0; j < num_dims; j++){
- output_shape[j] = static_cast(shape[j]);
- }
-
- output_tensors.push_back(ort.KernelContext_GetOutput(context, index, output_shape, num_dims));
- delete output_shape;
+ size_t num_dims = graph_output_dims.size();
+ auto output_shape = new int64_t[num_dims];
+ for (size_t j = 0; j < num_dims; j++) {
+ output_shape[j] = static_cast(graph_output_dims[j]);
}
-#endif
- return output_tensors;
+ auto it = output_names.find(output_name);
+ if (it == output_names.end()) {
+ ORT_THROW(log_tag + "Output names mismatch between OpenVINO and ONNX");
+ }
+ int index = it->second;
+
+ output_tensor = ort.KernelContext_GetOutput(context, index, output_shape, num_dims);
+ delete[] output_shape;
+
+ return output_tensor;
}
+#if (defined OPENVINO_2020_4) || (defined OPENVINO_2021_1)
+OrtValue*
+GetOutputTensor(Ort::CustomOpApi& ort, OrtKernelContext* context,
+ std::string output_name,
+ std::unordered_map output_names,
+ std::shared_ptr node){
+
+ OrtValue* output_tensor;
+ auto it = output_names.find(output_name);
+ if (it == output_names.end()) {
+ ORT_THROW(log_tag + "Output names mismatch between OpenVINO and ONNX");
+ }
+ int index = it->second;
+ auto shape = node->get_shape();
+
+ size_t num_dims = shape.size();
+ auto output_shape = new int64_t[num_dims];
+ for(size_t j = 0; j < num_dims; j++){
+ output_shape[j] = static_cast(shape[j]);
+ }
+ output_tensor = ort.KernelContext_GetOutput(context, index, output_shape, num_dims);
+ delete[] output_shape;
+
+ return output_tensor;
+}
+#endif
+
int GetFirstAvailableDevice(GlobalContext& global_context){
int i = 0;
@@ -242,7 +259,7 @@ int GetFirstAvailableDevice(GlobalContext& global_context){
return i;
}
-#if defined(OPENVINO_2020_4)
+#if (defined OPENVINO_2020_4) || (defined OPENVINO_2021_1)
void FillOutputsWithConstantData(Ort::CustomOpApi& ort, std::shared_ptr node, OrtValue* out_tensor){
@@ -274,7 +291,7 @@ void FillOutputsWithConstantData(Ort::CustomOpApi& ort, std::shared_ptr
void FillOutputHelper(Ort::CustomOpApi& ort, OrtValue* out_tensor, std::shared_ptr node){
@@ -285,6 +302,73 @@ void FillOutputHelper(Ort::CustomOpApi& ort, OrtValue* out_tensor, std::shared_p
}
#endif
+void FillInputBlob(InferenceEngine::Blob::Ptr& inputBlob, size_t request_id, size_t batch_slice_idx,
+ std::string input_name, Ort::CustomOpApi& ort, OrtKernelContext* context,
+ InferenceEngine::Precision precision, const SubGraphContext& subgraph_context){
+
+ auto minput = InferenceEngine::as(inputBlob);
+ auto minputHolder = minput->wmap();
+
+ auto input_data = minputHolder.as::value_type*>();
+ size_t input_data_size = inputBlob->byteSize();
+
+#if (defined OPENVINO_2020_2) || (defined OPENVINO_2020_3)
+ const OrtValue* tensor = ort.KernelContext_GetInput(context, subgraph_context.input_indexes[request_id]);
+#else
+ ORT_UNUSED_PARAMETER(request_id);
+ const OrtValue* tensor = ort.KernelContext_GetInput(context, subgraph_context.input_names.at(input_name));
+#endif
+ auto tensor_shape = ort.GetTensorTypeAndShape(tensor);
+ auto elem_type = ort.GetTensorElementType(tensor_shape);
+
+ if ((elem_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) &&
+ (precision == InferenceEngine::Precision::I32)) {
+
+ const int64_t* tensor_data_64 = ort.GetTensorData(tensor);
+ auto data_len = (input_data_size * 2) / sizeof(int64_t);
+ const int64_t* batch_memory_offset = tensor_data_64 + data_len * batch_slice_idx;
+
+ std::copy(batch_memory_offset, batch_memory_offset+data_len, (uint32_t*)input_data);
+ } else {
+
+ // Copy input data into OpenVINO's input buffer
+ const char* tensor_data = ort.GetTensorData(tensor);
+ const char* batch_memory_offset = tensor_data + input_data_size * batch_slice_idx;
+ std::memcpy(input_data, batch_memory_offset, input_data_size);
+ }
+}
+
+void FillOutputBlob(InferenceEngine::Blob::Ptr& outputBlob, OrtValue* output_tensor,
+ Ort::CustomOpApi& ort, InferenceEngine::Precision precision, size_t batch_slice_idx){
+
+ auto moutput = InferenceEngine::as(outputBlob);
+
+ auto moutputHolder = moutput->rmap();
+
+ const auto output_data = moutputHolder.
+ as::value_type*>();
+
+ size_t output_data_size = outputBlob->byteSize();
+ auto tensor_shape = ort.GetTensorTypeAndShape(output_tensor);
+ auto elem_type = ort.GetTensorElementType(tensor_shape);
+
+ if ((elem_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) &&
+ (precision == InferenceEngine::Precision::I32)) {
+
+ int64_t* tensor_data = ort.GetTensorMutableData(output_tensor);
+ auto data_len = output_data_size/sizeof(int32_t);
+ int64_t* batch_memory_offset = tensor_data + data_len * batch_slice_idx;
+
+ std::transform((int32_t*)output_data,((int32_t*)output_data) + data_len, batch_memory_offset, static_cast_int64());
+
+ } else {
+ char* tensor_data = ort.GetTensorMutableData(output_tensor);
+ char* batch_memory_offset = tensor_data + output_data_size * batch_slice_idx;
+
+ std::memcpy(batch_memory_offset, output_data, output_data_size);
+ }
+}
+
} // namespace backend_utils
} // namespace openvino_ep
} // namespace onnxruntime
diff --git a/onnxruntime/core/providers/openvino/backend_utils.h b/onnxruntime/core/providers/openvino/backend_utils.h
index c7d87889fc..2efdafeeab 100644
--- a/onnxruntime/core/providers/openvino/backend_utils.h
+++ b/onnxruntime/core/providers/openvino/backend_utils.h
@@ -20,7 +20,8 @@ bool IsDebugEnabled();
void SetIODefs(const ONNX_NAMESPACE::ModelProto& model_proto,
std::shared_ptr network,
std::unordered_map output_names,
- std::map>& const_outputs_map);
+ std::map>& const_outputs_map,
+ std::string device);
std::shared_ptr
CreateCNNNetwork(const ONNX_NAMESPACE::ModelProto& model_proto, const GlobalContext& global_context, const SubGraphContext& subgraph_context, std::map node, OrtValue* out_tensor);
template
void FillOutputHelper(Ort::CustomOpApi& ort, OrtValue* out_tensor, std::shared_ptr node);
+
+OrtValue*
+GetOutputTensor(Ort::CustomOpApi& ort, OrtKernelContext* context,
+ std::string output_name,
+ std::unordered_map output_names,
+ std::shared_ptr node);
#endif
InferenceEngine::Precision
-ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::TypeProto& onnx_type);
+ConvertPrecisionONNXToOpenVINO(const ONNX_NAMESPACE::TypeProto& onnx_type, std::string device);
-std::vector GetOutputTensors(Ort::CustomOpApi& ort,
- OrtKernelContext* context, size_t batch_size,
- InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network,
- std::unordered_map output_names, std::map> const_output_map);
+OrtValue*
+GetOutputTensor(Ort::CustomOpApi& ort, OrtKernelContext* context, size_t batch_size,
+ InferenceEngine::InferRequest::Ptr infer_request,
+ std::string output_name,
+ std::unordered_map output_names);
+
+
+void FillInputBlob(InferenceEngine::Blob::Ptr& inputBlob, size_t request_id, size_t batch_slice_idx,
+ std::string input_name, Ort::CustomOpApi& ort, OrtKernelContext* context,
+ InferenceEngine::Precision precision, const SubGraphContext& subgraph_context);
+
+void FillOutputBlob(InferenceEngine::Blob::Ptr& outputBlob, OrtValue* output_tensor,
+ Ort::CustomOpApi& ort, InferenceEngine::Precision precision, size_t batch_slice_idx);
} // namespace backend_utils
} // namespace openvino_ep
diff --git a/onnxruntime/core/providers/openvino/backends/basic_backend.cc b/onnxruntime/core/providers/openvino/backends/basic_backend.cc
index 3e9a832cdb..d89536e688 100644
--- a/onnxruntime/core/providers/openvino/backends/basic_backend.cc
+++ b/onnxruntime/core/providers/openvino/backends/basic_backend.cc
@@ -24,23 +24,17 @@ namespace openvino_ep {
using namespace backend_utils;
-
-struct static_cast_int64
-{
- template // T1 models type statically convertible to T
- int64_t operator()(const T1& x) const { return static_cast(x); }
-};
-
BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
GlobalContext& global_context,
const SubGraphContext& subgraph_context)
: global_context_(global_context), subgraph_context_(subgraph_context) {
ie_cnn_network_ = CreateCNNNetwork(model_proto, global_context_, subgraph_context_, const_outputs_map_);
- SetIODefs(model_proto, ie_cnn_network_, subgraph_context_.output_names, const_outputs_map_);
+ SetIODefs(model_proto, ie_cnn_network_, subgraph_context_.output_names, const_outputs_map_, global_context_.device_type);
+
InferenceEngine::ExecutableNetwork exe_network;
-#if defined(OPENVINO_2020_4)
+#if defined(OPENVINO_2020_4) || defined(OPENVINO_2021_1)
if(const_outputs_map_.size() == subgraph_context_.output_names.size())
subgraph_context_.is_constant = true;
#endif
@@ -83,20 +77,18 @@ BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
// Starts an asynchronous inference request for data in slice indexed by batch_slice_idx on
// an Infer Request indexed by infer_req_idx
-void BasicBackend::StartAsyncInference(Ort::CustomOpApi& ort,
- OrtKernelContext* context,
- InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network) {
- auto graph_input_info = ie_cnn_network->getInputsInfo();
+void BasicBackend::StartAsyncInference(Ort::CustomOpApi& ort, OrtKernelContext* context) {
- size_t i = 0;
+ auto graph_input_info = ie_cnn_network_->getInputsInfo();
+
+ size_t index = 0;
for (auto input_info_iter = graph_input_info.begin();
- input_info_iter != graph_input_info.end(); ++input_info_iter, ++i) {
+ input_info_iter != graph_input_info.end(); ++input_info_iter, ++index) {
// Get OpenVINO's input buffer
InferenceEngine::Blob::Ptr graph_input_blob;
std::string input_name = input_info_iter->first;
try {
- graph_input_blob = infer_request->GetBlob(input_name);
+ graph_input_blob = infer_request_->GetBlob(input_name);
} catch (InferenceEngine::details::InferenceEngineException e) {
ORT_THROW(log_tag + " Cannot access IE Blob for input: " + input_name + e.what());
@@ -104,38 +96,12 @@ void BasicBackend::StartAsyncInference(Ort::CustomOpApi& ort,
ORT_THROW(log_tag + " Cannot access IE Blob for input: " + input_name);
}
auto precision = input_info_iter->second->getPrecision();
- auto graph_input_buffer = graph_input_blob->buffer()
- .as::value_type*>();
- size_t input_data_size = graph_input_blob->byteSize();
-
- #if (defined OPENVINO_2020_2) || (defined OPENVINO_2020_3)
- const OrtValue* tensor = ort.KernelContext_GetInput(context, subgraph_context_.input_indexes[i]);
- #else
- const OrtValue* tensor = ort.KernelContext_GetInput(context, subgraph_context_.input_names.at(input_name));
- #endif
-
- auto tensor_shape = ort.GetTensorTypeAndShape(tensor);
- auto elem_type = ort.GetTensorElementType(tensor_shape);
-
- if ((elem_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) &&
- (precision == InferenceEngine::Precision::I32)) {
-
- const int64_t* tensor_data_64 = ort.GetTensorData(tensor);
- auto data_len = (input_data_size * 2) / sizeof(int64_t) ;
-
- std::copy(tensor_data_64, tensor_data_64+data_len, (uint32_t*)graph_input_buffer);
- } else {
-
- // Copy input data into OpenVINO's input buffer
- const char* tensor_data = ort.GetTensorData(tensor);
- std::memcpy(graph_input_buffer, tensor_data, input_data_size);
-
- }
-
+ size_t batch_slice = 0;
+ FillInputBlob(graph_input_blob, index, batch_slice, input_name, ort, context, precision, subgraph_context_);
}
// Start Async inference
try {
- infer_request->StartAsync();
+ infer_request_->StartAsync();
} catch (InferenceEngine::details::InferenceEngineException e) {
ORT_THROW(log_tag + " Couldn't start Inference: " + e.what());
} catch (...) {
@@ -145,64 +111,44 @@ void BasicBackend::StartAsyncInference(Ort::CustomOpApi& ort,
// Wait for asynchronous inference completion on an Infer Request object indexed by infer_req_idx
// and copy the results into a slice location within the batched output buffer indexed by batch_slice_idx
-void BasicBackend::CompleteAsyncInference(Ort::CustomOpApi& ort,
- std::vector output_tensors,
- InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network) {
+void BasicBackend::CompleteAsyncInference(Ort::CustomOpApi& ort, OrtKernelContext* context) {
// Wait for Async inference completion
try {
- infer_request->Wait(InferenceEngine::IInferRequest::WaitMode::RESULT_READY);
+ infer_request_->Wait(InferenceEngine::IInferRequest::WaitMode::RESULT_READY);
} catch (InferenceEngine::details::InferenceEngineException e) {
ORT_THROW(log_tag + " Exception with completing Inference: " + e.what());
} catch (...) {
ORT_THROW(log_tag + " Exception with completing Inference");
}
- auto graph_output_info = ie_cnn_network->getOutputsInfo();
+ auto graph_output_info = ie_cnn_network_->getOutputsInfo();
- size_t i = 0;
for (auto output_info_iter = graph_output_info.begin();
- output_info_iter != graph_output_info.end(); ++output_info_iter, ++i) {
+ output_info_iter != graph_output_info.end(); ++output_info_iter) {
// Get OpenVINO's output blob
InferenceEngine::Blob::Ptr graph_output_blob;
+ auto output_name = output_info_iter->first;
try {
- graph_output_blob = infer_request->GetBlob(output_info_iter->first);
+ graph_output_blob = infer_request_->GetBlob(output_name);
} catch (InferenceEngine::details::InferenceEngineException e) {
- ORT_THROW(log_tag + " Cannot access IE Blob for output: " + output_info_iter->first + e.what());
+ ORT_THROW(log_tag + " Cannot access IE Blob for output: " + output_name + e.what());
} catch (...) {
- ORT_THROW(log_tag + " Cannot access IE Blob for output: " + output_info_iter->first);
+ ORT_THROW(log_tag + " Cannot access IE Blob for output: " + output_name);
}
-
- auto graph_output_buffer = graph_output_blob->buffer()
- .as::value_type*>();
-
- size_t output_data_size = graph_output_blob->byteSize();
-
- auto tensor_shape = ort.GetTensorTypeAndShape(output_tensors[i]);
- auto elem_type = ort.GetTensorElementType(tensor_shape);
+ size_t batch_size = 1;
+ auto output_tensor = GetOutputTensor(ort, context, batch_size, infer_request_, output_name, subgraph_context_.output_names);
auto precision = output_info_iter->second->getPrecision();
- if ((elem_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) &&
- (precision == InferenceEngine::Precision::I32)) {
-
- int64_t* tensor_data = ort.GetTensorMutableData(output_tensors[i]);
-
- auto data_len = output_data_size/sizeof(int32_t);
- std::transform((int32_t*)graph_output_buffer,((int32_t*)graph_output_buffer) + data_len, tensor_data, static_cast_int64());
-
- } else {
- char* tensor_data = ort.GetTensorMutableData(output_tensors[i]);
- std::memcpy(tensor_data, graph_output_buffer, output_data_size);
-
- }
+ size_t batch_slice = 0;
+ FillOutputBlob(graph_output_blob, output_tensor, ort, precision, batch_slice);
}
-#if defined(OPENVINO_2020_4)
+#if defined(OPENVINO_2020_4) || defined(OPENVINO_2021_1)
if(!const_outputs_map_.empty()){
- size_t j = i;
for(auto item : const_outputs_map_){
+ auto out_name = item.first;
auto node = item.second;
- FillOutputsWithConstantData(ort,node,output_tensors[j]);
- j++;
+ auto output_tensor = GetOutputTensor(ort, context, out_name, subgraph_context_.output_names, node);
+ FillOutputsWithConstantData(ort,node,output_tensor);
}
}
#endif
@@ -216,21 +162,19 @@ void BasicBackend::Infer(Ort::CustomOpApi& ort, OrtKernelContext* context) {
LOGS_DEFAULT(INFO) << log_tag << "In Infer";
std::lock_guard lock(compute_lock_);
- size_t batch_size = 1;
- auto output_tensors = GetOutputTensors(ort, context, batch_size, infer_request_, ie_cnn_network_, subgraph_context_.output_names, const_outputs_map_);
if(subgraph_context_.is_constant){
-#if defined(OPENVINO_2020_4)
- size_t i = 0;
+#if defined(OPENVINO_2020_4) || defined(OPENVINO_2021_1)
for(auto item : const_outputs_map_){
+ auto out_name = item.first;
auto node = item.second;
- FillOutputsWithConstantData(ort,node, output_tensors[i]);
- i++;
+ auto output_tensor = GetOutputTensor(ort, context, out_name, subgraph_context_.output_names, node);
+ FillOutputsWithConstantData(ort,node, output_tensor);
}
#endif
}
else{
- StartAsyncInference(ort, context, infer_request_, ie_cnn_network_);
- CompleteAsyncInference(ort, output_tensors, infer_request_, ie_cnn_network_);
+ StartAsyncInference(ort, context);
+ CompleteAsyncInference(ort, context);
}
// Get Output tensors
LOGS_DEFAULT(INFO) << log_tag << "Inference successful";
diff --git a/onnxruntime/core/providers/openvino/backends/basic_backend.h b/onnxruntime/core/providers/openvino/backends/basic_backend.h
index 924ad39f0f..8782f51271 100644
--- a/onnxruntime/core/providers/openvino/backends/basic_backend.h
+++ b/onnxruntime/core/providers/openvino/backends/basic_backend.h
@@ -22,13 +22,9 @@ class BasicBackend : public IBackend {
void Infer(Ort::CustomOpApi& ort, OrtKernelContext* context) override;
private:
- void StartAsyncInference(Ort::CustomOpApi& ort, OrtKernelContext* context,
- InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network);
+ void StartAsyncInference(Ort::CustomOpApi& ort, OrtKernelContext* context);
- void CompleteAsyncInference(Ort::CustomOpApi& ort, std::vector output_tensors,
- InferenceEngine::InferRequest::Ptr infer_request,
- std::shared_ptr ie_cnn_network);
+ void CompleteAsyncInference(Ort::CustomOpApi& ort, OrtKernelContext* context);
GlobalContext& global_context_;
SubGraphContext subgraph_context_;
diff --git a/onnxruntime/core/providers/openvino/backends/vadm_backend.cc b/onnxruntime/core/providers/openvino/backends/vadm_backend.cc
index d04827600c..7c820e13a0 100644
--- a/onnxruntime/core/providers/openvino/backends/vadm_backend.cc
+++ b/onnxruntime/core/providers/openvino/backends/vadm_backend.cc
@@ -1,6 +1,5 @@
// Copyright(C) 2019 Intel Corporation
// Licensed under the MIT License
-
#include