Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f103291b47 | ||
|
|
949b74059f | ||
|
|
651161be1c | ||
|
|
f73852ea3d | ||
|
|
b0c5accaf8 | ||
|
|
733dae46cc | ||
|
|
fe3f978b98 | ||
|
|
6dfc778940 | ||
|
|
1798ac0d26 | ||
|
|
298900790c |
@@ -87,12 +87,12 @@ This paragraph contains the steps to get the pre-trained model for sample infere
|
||||
|
||||
### Download a Trained Model
|
||||
|
||||
To run the Image Classification Sample you'll need a pre-trained model to run the inference on. This guide will use the public SqueezeNet 1.1 Caffe* model. You can find and download this model manually or use the OpenVINO™ [Model Downloader](https://github.com/opencv/open_model_zoo/tree/master/model_downloader).
|
||||
To run the Image Classification Sample you'll need a pre-trained model to run the inference on. This guide will use the public SqueezeNet 1.1 Caffe* model. You can find and download this model manually or use the OpenVINO™ [Model Downloader](https://github.com/opencv/open_model_zoo/tree/master/tools/downloader).
|
||||
|
||||
With the Model Downloader, you can download other popular public deep learning topologies and the [OpenVINO™ pre-trained models](https://github.com/opencv/open_model_zoo/tree/master/intel_models) prepared for running inference for a wide list of inference scenarios: object detection, object recognition, object re-identification, human pose estimation, action recognition and others.
|
||||
With the Model Downloader, you can download other popular public deep learning topologies and the [OpenVINO™ pre-trained models](https://github.com/opencv/open_model_zoo/tree/master/models/intel) prepared for running inference for a wide list of inference scenarios: object detection, object recognition, object re-identification, human pose estimation, action recognition and others.
|
||||
|
||||
To download the SqueezeNet 1.1 Caffe* model to a models folder with the Model Downloader:
|
||||
1. Install the [prerequisites](https://github.com/opencv/open_model_zoo/tree/master/model_downloader#prerequisites).
|
||||
1. Install the [prerequisites](https://github.com/opencv/open_model_zoo/tree/master/tools/downloader#prerequisites).
|
||||
2. Run the `downloader.py` with specifying the topology name and a `<models_dir>` path. For example to download the model to the `~/public_models` directory:
|
||||
```sh
|
||||
./downloader.py --name squeezenet1.1 --output_dir ~/public_models
|
||||
|
||||
@@ -6,7 +6,7 @@ if (APPLE)
|
||||
# due to https://cmake.org/cmake/help/v3.12/policy/CMP0068.html
|
||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||
else()
|
||||
cmake_minimum_required(VERSION 3.7.2 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
|
||||
endif()
|
||||
|
||||
project(InferenceEngine)
|
||||
|
||||
+45
-34
@@ -22,6 +22,7 @@
|
||||
- [Build Steps](#build-steps-2)
|
||||
- [Additional Build Options](#additional-build-options-3)
|
||||
- [Use Custom OpenCV Builds for Inference Engine](#use-custom-opencv-builds-for-inference-engine)
|
||||
- [Adding Inference Engine to your project](#adding-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)
|
||||
- [For Linux, Raspbian Stretch* OS](#for-linux-raspbian-stretch-os)
|
||||
- [For Windows](#for-windows-1)
|
||||
@@ -62,7 +63,13 @@ The software was validated on:
|
||||
git submodule init
|
||||
git submodule update --recursive
|
||||
```
|
||||
2. Install build dependencies using the `install_dependencies.sh` script in the project root folder.
|
||||
2. Install build dependencies using the `install_dependencies.sh` script in the project root folder:
|
||||
```sh
|
||||
chmod +x install_dependencies.sh
|
||||
```
|
||||
```sh
|
||||
./install_dependencies.sh
|
||||
```
|
||||
3. By default, the build enables the Inference Engine GPU plugin to infer models on your Intel® Processor Graphics. This requires you to [Install Intel® Graphics Compute Runtime for OpenCL™ Driver package 19.04.12237](https://github.com/intel/compute-runtime/releases/tag/19.04.12237) 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 Compute Runtime for OpenCL™ Driver.
|
||||
4. Create a build folder:
|
||||
```sh
|
||||
@@ -90,33 +97,20 @@ You can use the following additional build options:
|
||||
|
||||
- If the CMake-based build script can not find and download the OpenCV package that is supported on your platform, or if you want to use a custom build of the OpenCV library, refer to the [Use Custom OpenCV Builds](#use-custom-opencv-builds-for-inference-engine) section for details.
|
||||
|
||||
- To build the Python API wrapper, use the `-DENABLE_PYTHON=ON` option. To specify an exact Python version, use the following options:
|
||||
```sh
|
||||
-DPYTHON_EXECUTABLE=`which python3.7` \
|
||||
-DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so \
|
||||
-DPYTHON_INCLUDE_DIR=/usr/include/python3.7
|
||||
```
|
||||
- To build the Python API wrapper:
|
||||
1. Install all additional packages listed in the `/inference-engine/ie_bridges/python/requirements.txt` file:
|
||||
```sh
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. use the `-DENABLE_PYTHON=ON` option. To specify an exact Python version, use the following options:
|
||||
```sh
|
||||
-DPYTHON_EXECUTABLE=`which python3.7` \
|
||||
-DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so \
|
||||
-DPYTHON_INCLUDE_DIR=/usr/include/python3.7
|
||||
```
|
||||
|
||||
- To switch off/on the CPU and GPU plugins, use the `cmake` options `-DENABLE_MKL_DNN=ON/OFF` and `-DENABLE_CLDNN=ON/OFF` respectively.
|
||||
|
||||
5. Adding to your project
|
||||
|
||||
For CMake projects, set an environment variable `InferenceEngine_DIR`:
|
||||
|
||||
```sh
|
||||
export InferenceEngine_DIR=/path/to/dldt/inference-engine/build/
|
||||
```
|
||||
|
||||
Then you can find Inference Engine by `find_package`:
|
||||
|
||||
```cmake
|
||||
find_package(InferenceEngine)
|
||||
|
||||
include_directories(${InferenceEngine_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${InferenceEngine_LIBRARIES} dl)
|
||||
```
|
||||
|
||||
## Build for Raspbian Stretch* OS
|
||||
|
||||
> **NOTE**: Only the MYRIAD plugin is supported.
|
||||
@@ -204,6 +198,7 @@ with the following content:
|
||||
crossbuild-essential-armhf \
|
||||
git \
|
||||
wget \
|
||||
cmake \
|
||||
libusb-1.0-0-dev:armhf \
|
||||
libgtk-3-dev:armhf \
|
||||
libavcodec-dev:armhf \
|
||||
@@ -213,12 +208,6 @@ with the following content:
|
||||
libgstreamer-plugins-base1.0-dev:armhf \
|
||||
libpython3-dev:armhf \
|
||||
python3-pip
|
||||
|
||||
RUN wget https://www.cmake.org/files/v3.14/cmake-3.14.3.tar.gz && \
|
||||
tar xf cmake-3.14.3.tar.gz && \
|
||||
(cd cmake-3.14.3 && ./bootstrap --parallel=$(nproc --all) && make --jobs=$(nproc --all) && make install) && \
|
||||
rm -rf cmake-3.14.3 cmake-3.14.3.tar.gz
|
||||
|
||||
```
|
||||
|
||||
It uses the Debian\* Stretch (Debian 9) OS for compilation because it is a base of the Raspbian\* Stretch.
|
||||
@@ -371,7 +360,13 @@ The software was validated on:
|
||||
git submodule init
|
||||
git submodule update --recursive
|
||||
```
|
||||
2. Install build dependencies using the `install_dependencies.sh` script in the project root folder.
|
||||
2. Install build dependencies using the `install_dependencies.sh` script in the project root folder:
|
||||
```sh
|
||||
chmod +x install_dependencies.sh
|
||||
```
|
||||
```sh
|
||||
./install_dependencies.sh
|
||||
```
|
||||
3. Create a build folder:
|
||||
```sh
|
||||
mkdir build
|
||||
@@ -419,6 +414,22 @@ After you got the built OpenCV library, perform the following preparation steps
|
||||
1. Set the `OpenCV_DIR` environment variable to the directory where the `OpenCVConfig.cmake` file of you custom OpenCV build is located.
|
||||
2. Disable the package automatic downloading with using the `-DENABLE_OPENCV=OFF` option for CMake-based build script for Inference Engine.
|
||||
|
||||
## Adding Inference Engine to your project
|
||||
|
||||
For CMake projects, set the `InferenceEngine_DIR` environment variable:
|
||||
|
||||
```sh
|
||||
export InferenceEngine_DIR=/path/to/dldt/inference-engine/build/
|
||||
```
|
||||
|
||||
Then you can find Inference Engine by `find_package`:
|
||||
|
||||
```cmake
|
||||
find_package(InferenceEngine)
|
||||
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
|
||||
|
||||
> **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](https://software.intel.com/en-us/neural-compute-stick/get-started)
|
||||
@@ -461,7 +472,7 @@ For Intel® Movidius™ Neural Compute Stick and Intel® Neural Compute Stick 2,
|
||||
1. Go to the `<DLDT_ROOT_DIR>/inference-engine/thirdparty/movidius/MovidiusDriver` directory, where the `DLDT_ROOT_DIR` is the directory to which the DLDT repository was cloned.
|
||||
2. Right click on the `Movidius_VSC_Device.inf` file and choose **Install** from the pop up menu.
|
||||
|
||||
You have installed the driver for your Intel® Movidius™ Neural Compute Stick or Intel® Neural Compute Stick 2.
|
||||
You have installed the driver for your Intel® Movidius™ Neural Compute Stick or Intel® Neural Compute Stick 2.
|
||||
|
||||
## Next Steps
|
||||
|
||||
@@ -478,4 +489,4 @@ Congratulations, you have built the Inference Engine. To get started with the Op
|
||||
* [Model Optimizer Developer Guide](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html)
|
||||
|
||||
---
|
||||
\* Other names and brands may be claimed as the property of others.
|
||||
\* Other names and brands may be claimed as the property of others.
|
||||
|
||||
@@ -72,18 +72,18 @@ if (THREADING STREQUAL "TBB" OR THREADING STREQUAL "TBB_AUTO")
|
||||
if (WIN32)
|
||||
#TODO: add target_path to be platform specific as well, to avoid following if
|
||||
RESOLVE_DEPENDENCY(TBB
|
||||
ARCHIVE_WIN "tbb2019_20181010_win.zip" #TODO: windows zip archive created incorrectly using old name for folder
|
||||
ARCHIVE_WIN "tbb2019_20181010_win_with_mall_proxy.zip" #TODO: windows zip archive created incorrectly using old name for folder
|
||||
TARGET_PATH "${TEMP}/tbb"
|
||||
ENVIRONMENT "TBBROOT"
|
||||
VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*")
|
||||
elseif(LINUX)
|
||||
RESOLVE_DEPENDENCY(TBB
|
||||
ARCHIVE_LIN "tbb2019_20181010_lin.tgz"
|
||||
ARCHIVE_LIN "tbb2019_20181010_lin_with_mall_proxy.tgz"
|
||||
TARGET_PATH "${TEMP}/tbb"
|
||||
ENVIRONMENT "TBBROOT")
|
||||
else(APPLE)
|
||||
RESOLVE_DEPENDENCY(TBB
|
||||
ARCHIVE_MAC "tbb2019_20190414_v1_mac.tgz"
|
||||
ARCHIVE_MAC "tbb2019_20190414_v1_mac_with_mall_proxy.tgz"
|
||||
TARGET_PATH "${TEMP}/tbb"
|
||||
ENVIRONMENT "TBBROOT"
|
||||
VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*")
|
||||
|
||||
@@ -112,14 +112,14 @@ if (UNIX AND NOT APPLE AND CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSIO
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
ie_option(ENABLE_CPPLINT "Enable cpplint checks during the build" ON)
|
||||
ie_option(ENABLE_CPPLINT "Enable cpplint checks during the build" OFF)
|
||||
ie_option(ENABLE_CPPLINT_REPORT "Build cpplint report instead of failing the build" OFF)
|
||||
else()
|
||||
set(ENABLE_CPPLINT OFF)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.10)
|
||||
ie_option(ENABLE_CPPCHECK "Enable cppcheck during the build" ON)
|
||||
if (UNIX AND NOT APPLE)
|
||||
ie_option(ENABLE_CPPCHECK "Enable cppcheck during the build" OFF)
|
||||
else()
|
||||
set(ENABLE_CPPCHECK OFF)
|
||||
endif()
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#include <vector>
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief Neural network builder API
|
||||
*/
|
||||
namespace Builder {
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief GPU plugin configuration
|
||||
*/
|
||||
namespace CLDNNConfigParams {
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
|
||||
#include <memory>
|
||||
#include "ie_so_loader.h"
|
||||
|
||||
#include "ie_common.h"
|
||||
#include "ie_plugin.hpp"
|
||||
#include "details/ie_exception.hpp"
|
||||
#include "details/ie_no_release.hpp"
|
||||
#include "details/os/os_filesystem.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
@@ -86,11 +90,17 @@ public:
|
||||
* @brief The main constructor
|
||||
* @param name Name of a shared library file
|
||||
*/
|
||||
explicit SOPointer(const file_name_t &name)
|
||||
: _so_loader(new Loader(name.c_str()))
|
||||
, _pointedObj(details::shared_from_irelease(
|
||||
SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {
|
||||
}
|
||||
template <typename C,
|
||||
typename = enableIfSupportedChar<C>>
|
||||
explicit SOPointer(const std::basic_string<C> & name)
|
||||
: _so_loader(new Loader(name.c_str())),
|
||||
_pointedObj(details::shared_from_irelease(
|
||||
SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {}
|
||||
|
||||
explicit SOPointer(const char * name)
|
||||
: _so_loader(new Loader(name)),
|
||||
_pointedObj(details::shared_from_irelease(
|
||||
SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an object with existing reference
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "../../ie_api.h"
|
||||
#include "../ie_exception.hpp"
|
||||
#include "ie_api.h"
|
||||
#include "details/ie_exception.hpp"
|
||||
#include "details/os/os_filesystem.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
@@ -35,6 +36,18 @@ public:
|
||||
if (shared_object == nullptr)
|
||||
THROW_IE_EXCEPTION << "Cannot load library '" << pluginName << "': " << dlerror();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
/**
|
||||
* @brief Loads a library with the name specified. The library is loaded according to
|
||||
* the POSIX rules for dlopen
|
||||
* @param pluginName Full or relative path to the library
|
||||
*/
|
||||
explicit SharedObjectLoader(const wchar_t* pluginName) : SharedObjectLoader(wStringtoMBCSstringChar(pluginName).c_str()) {
|
||||
}
|
||||
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
~SharedObjectLoader() noexcept(false) {
|
||||
if (0 != dlclose(shared_object)) {
|
||||
THROW_IE_EXCEPTION << "dlclose failed: " << dlerror();
|
||||
|
||||
@@ -9,13 +9,20 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
|
||||
template<typename C>
|
||||
using enableIfSupportedChar = typename std::enable_if<(std::is_same<C, char>::value || std::is_same<C, wchar_t>::value)>::type;
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
/**
|
||||
* @brief Conversion from wide character string to a single-byte chain.
|
||||
*/
|
||||
@@ -33,7 +40,7 @@ inline const std::wstring multiByteCharToWString(const char* str) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
} // namespace details
|
||||
} // namespace InferenceEngine
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../ie_api.h"
|
||||
#include "../ie_exception.hpp"
|
||||
#include "ie_api.h"
|
||||
#include "details/ie_exception.hpp"
|
||||
#include "details/os/os_filesystem.hpp"
|
||||
|
||||
// Avoidance of Windows.h to include winsock library.
|
||||
#define _WINSOCKAPI_
|
||||
@@ -30,14 +31,7 @@ class SharedObjectLoader {
|
||||
private:
|
||||
HMODULE shared_object;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Loads a library with the name specified. The library is loaded according to the
|
||||
* WinAPI LoadLibrary rules
|
||||
* @param pluginName Full or relative path to the plugin library
|
||||
*/
|
||||
explicit SharedObjectLoader(LPCTSTR pluginName) {
|
||||
char cwd[1024];
|
||||
void ExcludeCurrentDirectory() {
|
||||
// Exclude current directory from DLL search path process wise.
|
||||
// If application specific path was configured before then
|
||||
// current directory is alread excluded.
|
||||
@@ -45,21 +39,38 @@ public:
|
||||
// path was set to "" or NULL so reset it to "" to keep
|
||||
// aplication safe.
|
||||
if (GetDllDirectory(0, NULL) <= 1) {
|
||||
SetDllDirectory(
|
||||
#if defined UNICODE
|
||||
L"");
|
||||
#else
|
||||
"");
|
||||
#endif
|
||||
}
|
||||
shared_object = LoadLibrary(pluginName);
|
||||
if (!shared_object) {
|
||||
THROW_IE_EXCEPTION << "Cannot load library '"
|
||||
<< pluginName << "': "
|
||||
<< GetLastError()
|
||||
<< " from cwd: " << _getcwd(cwd, 1024);
|
||||
SetDllDirectory(TEXT(""));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Loads a library with the name specified. The library is loaded according to the
|
||||
* WinAPI LoadLibrary rules
|
||||
* @param pluginName Full or relative path to the plugin library
|
||||
*/
|
||||
explicit SharedObjectLoader(LPCWSTR pluginName) {
|
||||
ExcludeCurrentDirectory();
|
||||
|
||||
shared_object = LoadLibraryW(pluginName);
|
||||
if (!shared_object) {
|
||||
char cwd[1024];
|
||||
THROW_IE_EXCEPTION << "Cannot load library '" << details::wStringtoMBCSstringChar(std::wstring(pluginName)) << "': " << GetLastError()
|
||||
<< " from cwd: " << _getcwd(cwd, sizeof(cwd));
|
||||
}
|
||||
}
|
||||
|
||||
explicit SharedObjectLoader(LPCSTR pluginName) {
|
||||
ExcludeCurrentDirectory();
|
||||
|
||||
shared_object = LoadLibrary(pluginName);
|
||||
if (!shared_object) {
|
||||
char cwd[1024];
|
||||
THROW_IE_EXCEPTION << "Cannot load library '" << pluginName << "': " << GetLastError()
|
||||
<< " from cwd: " << _getcwd(cwd, sizeof(cwd));
|
||||
}
|
||||
}
|
||||
|
||||
~SharedObjectLoader() {
|
||||
FreeLibrary(shared_object);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief DLIA plugin metrics
|
||||
*/
|
||||
namespace DliaMetrics {
|
||||
|
||||
/**
|
||||
@@ -37,6 +40,9 @@ DECLARE_DLIA_METRIC_VALUE(INPUT_STREAMING);
|
||||
|
||||
} // namespace DliaMetrics
|
||||
|
||||
/**
|
||||
* @brief DLIA plugin configuration
|
||||
*/
|
||||
namespace DLIAConfigParams {
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief A header that defines advanced related properties for VPU plugins.
|
||||
* @brief A header that defines advanced related properties for GNA plugin.
|
||||
* These properties should be used in SetConfig() and LoadNetwork() methods of plugins
|
||||
*
|
||||
* @file vpu_plugin_config.hpp
|
||||
* @file gna_config.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -16,9 +16,20 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief GNA plugin configuration
|
||||
*/
|
||||
namespace GNAConfigParams {
|
||||
|
||||
/**
|
||||
* @def GNA_CONFIG_KEY(name)
|
||||
* @brief Shortcut for defining configuration keys
|
||||
*/
|
||||
#define GNA_CONFIG_KEY(name) InferenceEngine::GNAConfigParams::_CONFIG_KEY(GNA_##name)
|
||||
/**
|
||||
* @def GNA_CONFIG_VALUE(name)
|
||||
* @brief Shortcut for defining configuration values
|
||||
*/
|
||||
#define GNA_CONFIG_VALUE(name) InferenceEngine::GNAConfigParams::GNA_##name
|
||||
|
||||
#define DECLARE_GNA_CONFIG_KEY(name) DECLARE_CONFIG_KEY(GNA_##name)
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief Heterogeneous plugin configuration
|
||||
*/
|
||||
namespace HeteroConfigParams {
|
||||
|
||||
/**
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
#ifndef ENABLE_UNICODE_PATH_SUPPORT
|
||||
#if defined(_WIN32)
|
||||
#define ENABLE_UNICODE_PATH_SUPPORT
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2))
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__)
|
||||
#define ENABLE_UNICODE_PATH_SUPPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief %Metrics
|
||||
*/
|
||||
namespace Metrics {
|
||||
|
||||
#ifndef DECLARE_METRIC_KEY_IMPL
|
||||
@@ -144,6 +147,9 @@ DECLARE_EXEC_NETWORK_METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS, unsigned int);
|
||||
|
||||
} // namespace Metrics
|
||||
|
||||
/**
|
||||
* @brief Generic plugin configuration
|
||||
*/
|
||||
namespace PluginConfigParams {
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include <cpp/ie_executable_network.hpp>
|
||||
#include <ie_version.hpp>
|
||||
|
||||
/**
|
||||
* @brief Inference Engine API
|
||||
*/
|
||||
namespace InferenceEngine {
|
||||
/**
|
||||
* @brief Gets the top n results from a tblob
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief Multi Device plugin configuration
|
||||
*/
|
||||
namespace MultiDeviceConfigParams {
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
/**
|
||||
* @brief VPU plugin configuration
|
||||
*/
|
||||
namespace VPUConfigParams {
|
||||
|
||||
//
|
||||
|
||||
@@ -51,7 +51,7 @@ if [ -f /etc/lsb-release ]; then
|
||||
gstreamer1.0-plugins-base \
|
||||
libusb-1.0-0-dev \
|
||||
libopenblas-dev
|
||||
if apt-cache search --names-only '^libpng12'| grep -q libpng12; then
|
||||
if apt-cache search --names-only '^libpng12-dev'| grep -q libpng12; then
|
||||
sudo -E apt-get install -y libpng12-dev
|
||||
else
|
||||
sudo -E apt-get install -y libpng-dev
|
||||
@@ -160,4 +160,4 @@ elif [ -f /etc/os-release ] && grep -q "raspbian" /etc/os-release; then
|
||||
fi
|
||||
else
|
||||
echo "Unknown OS, please install build dependencies manually"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -49,13 +49,32 @@ class ConsoleErrorListener : public InferenceEngine::IErrorListener {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Trims from both ends (in place)
|
||||
* @brief trim from start (in place)
|
||||
* @param s - string to trim
|
||||
*/
|
||||
inline void ltrim(std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c){
|
||||
return !std::isspace(c);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief trim from end (in place)
|
||||
* @param s - string to trim
|
||||
*/
|
||||
inline void rtrim(std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) {
|
||||
return !std::isspace(c);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief trim from both ends (in place)
|
||||
* @param s - string to trim
|
||||
* @return trimmed string
|
||||
*/
|
||||
inline std::string &trim(std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
ltrim(s);
|
||||
rtrim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace InferenceEngine {
|
||||
|
||||
TaskExecutor::TaskExecutor(std::string name) : _isStopped(false), _name(name) {
|
||||
_thread = std::make_shared<std::thread>([&] {
|
||||
anotateSetThreadName(("TaskExecutor thread for " + _name).c_str());
|
||||
annotateSetThreadName(("TaskExecutor thread for " + _name).c_str());
|
||||
while (!_isStopped) {
|
||||
bool isQueueEmpty;
|
||||
Task::Ptr currentTask;
|
||||
|
||||
@@ -53,34 +53,3 @@ void FileUtils::readAllFile(const std::string &string_file_name, void *buffer, s
|
||||
inputFile.close();
|
||||
}
|
||||
|
||||
std::string FileUtils::folderOf(const std::string &filepath) {
|
||||
auto pos = filepath.rfind(FileSeparator);
|
||||
if (pos == std::string::npos) pos = filepath.rfind(FileSeparator2);
|
||||
if (pos == std::string::npos) return "";
|
||||
return filepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::string FileUtils::makePath(const std::string &folder, const std::string &file) {
|
||||
if (folder.empty()) return file;
|
||||
return folder + FileSeparator + file;
|
||||
}
|
||||
|
||||
std::string FileUtils::fileNameNoExt(const std::string &filepath) {
|
||||
auto pos = filepath.rfind('.');
|
||||
if (pos == std::string::npos) return filepath;
|
||||
return filepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::string FileUtils::fileExt(const char *filename) {
|
||||
return fileExt(std::string(filename));
|
||||
}
|
||||
|
||||
std::string FileUtils::fileExt(const std::string &filename) {
|
||||
auto pos = filename.rfind('.');
|
||||
if (pos == std::string::npos) return "";
|
||||
return filename.substr(pos + 1);
|
||||
}
|
||||
|
||||
bool FileUtils::isSharedLibrary(const std::string& fileName) {
|
||||
return 0 == strncasecmp(fileExt(fileName).c_str(), SharedLibraryExt, strlen(SharedLibraryExt));
|
||||
}
|
||||
|
||||
@@ -24,60 +24,102 @@
|
||||
#endif
|
||||
|
||||
#include "ie_api.h"
|
||||
#include "ie_unicode.hpp"
|
||||
#include "details/os/os_filesystem.hpp"
|
||||
#include "details/ie_so_pointer.hpp"
|
||||
|
||||
namespace FileUtils {
|
||||
|
||||
template <typename T> struct FileTraits;
|
||||
|
||||
#ifdef _WIN32
|
||||
/// @brief File path separator
|
||||
const char FileSeparator = '\\';
|
||||
const char SharedLibraryExt[] = "dll";
|
||||
#elif __APPLE__
|
||||
const char SharedLibraryExt[] = "dylib";
|
||||
template<> struct FileTraits<char> {
|
||||
constexpr static const auto FileSeparator = ::FileUtils::FileSeparator;
|
||||
static std::string SharedLibraryPrefix() { return { }; }
|
||||
static std::string SharedLibraryExt() { return { "dll" }; }
|
||||
};
|
||||
template<> struct FileTraits<wchar_t> {
|
||||
constexpr static const auto FileSeparator = L'\\';
|
||||
static std::wstring SharedLibraryPrefix() { return { }; }
|
||||
static std::wstring SharedLibraryExt() { return { L"dll" }; }
|
||||
};
|
||||
#elif defined __APPLE__
|
||||
/// @brief File path separator
|
||||
const char FileSeparator = '/';
|
||||
template<> struct FileTraits<char> {
|
||||
constexpr static const auto FileSeparator = ::FileUtils::FileSeparator;
|
||||
static std::string SharedLibraryPrefix() { return { "lib" }; }
|
||||
static std::string SharedLibraryExt() { return { "dylib" }; }
|
||||
};
|
||||
template<> struct FileTraits<wchar_t> {
|
||||
constexpr static const auto FileSeparator = L'/';
|
||||
static std::wstring SharedLibraryPrefix() { return { L"lib" }; }
|
||||
static std::wstring SharedLibraryExt() { return { L"dylib" }; }
|
||||
};
|
||||
#else
|
||||
const char SharedLibraryExt[] = "so";
|
||||
/// @brief File path separator
|
||||
const char FileSeparator = '/';
|
||||
template<> struct FileTraits<char> {
|
||||
constexpr static const auto FileSeparator = ::FileUtils::FileSeparator;
|
||||
static std::string SharedLibraryPrefix() { return { "lib" }; }
|
||||
static std::string SharedLibraryExt() { return { "so" }; }
|
||||
};
|
||||
template<> struct FileTraits<wchar_t> {
|
||||
constexpr static const auto FileSeparator = L'/';
|
||||
static std::wstring SharedLibraryPrefix() { return { L"lib" }; }
|
||||
static std::wstring SharedLibraryExt() { return { L"so" }; }
|
||||
};
|
||||
#endif
|
||||
/// @brief Alternative file path separator
|
||||
const char FileSeparator2 = '/'; // second option
|
||||
|
||||
/**
|
||||
* @brief Interface function to get the size of a file
|
||||
* @brief Interface function to get the size of a file. The function supports UNICODE path
|
||||
* @param fileName - name of the file
|
||||
* @return size of the file
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(long long) fileSize(const char *fileName);
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
inline long long fileSize(const wchar_t* fileName) {
|
||||
return fileSize(InferenceEngine::details::wStringtoMBCSstringChar(fileName).c_str());
|
||||
}
|
||||
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
/**
|
||||
* @brief Function to get the size of a file
|
||||
* @brief Function to get the size of a file. The function supports UNICODE path
|
||||
* @param f - string name of the file
|
||||
* @return size of the file
|
||||
*/
|
||||
inline long long fileSize(const std::string &f) {
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline long long fileSize(const std::basic_string<C> &f) {
|
||||
return fileSize(f.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check if file with a given filename exists
|
||||
* @brief check if file with a given filename exists. The function supports UNICODE path
|
||||
* @param fileName - given filename
|
||||
* @return true is exists
|
||||
*/
|
||||
inline bool fileExist(const char *fileName) {
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline bool fileExist(const C * fileName) {
|
||||
return fileSize(fileName) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check if file with a given filename exists
|
||||
* @brief check if file with a given filename exists. The function supports UNICODE path
|
||||
* @param fileName - string with a given filename
|
||||
* @return true is exists
|
||||
*/
|
||||
inline bool fileExist(const std::string &fileName) {
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline bool fileExist(const std::basic_string<C> &fileName) {
|
||||
return fileExist(fileName.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to read a file. In case of read error throws an exception
|
||||
* @brief CPP Interface function to read a file. In case of read error throws an exception. The function supports UNICODE path
|
||||
* @param file_name - name of the file to read
|
||||
* @param buffer - buffer to read file to
|
||||
* @param maxSize - maximum size in bytes to read
|
||||
@@ -92,40 +134,84 @@ INFERENCE_ENGINE_API_CPP(void) readAllFile(const std::string &file_name, void *b
|
||||
INFERENCE_ENGINE_API_CPP(std::string) folderOf(const std::string &filepath);
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to combint path with filename
|
||||
* @brief CPP Interface function to combint path with filename. The function supports UNICODE path
|
||||
* @param folder - path to add filename to
|
||||
* @param file - filename to add to path
|
||||
* @return string with combination of the path and the filename divided by file separator
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(std::string) makePath(const std::string &folder, const std::string &file);
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline std::basic_string<C> makePath(const std::basic_string<C> &folder, const std::basic_string<C> &file) {
|
||||
if (folder.empty())
|
||||
return file;
|
||||
return folder + FileTraits<C>::FileSeparator + file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to remove file extension
|
||||
* @param filepath - filename with extension
|
||||
* @return string containing filename without extension
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(std::string) fileNameNoExt(const std::string &filepath);
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to extract extension from filename
|
||||
* @param filename - name of the file which extension should be extracted
|
||||
* @return string with extracted file extension
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(std::string) fileExt(const char *filename);
|
||||
template <typename C> struct DotSymbol;
|
||||
template <> struct DotSymbol<char> { constexpr static const char value = '.'; };
|
||||
template <> struct DotSymbol<wchar_t> { constexpr static const wchar_t value = L'.'; };
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to extract extension from filename
|
||||
* @param filename - string with the name of the file which extension should be extracted
|
||||
* @return string with extracted file extension
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(std::string) fileExt(const std::string &filename);
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline std::basic_string<C> fileExt(const std::basic_string<C> &filename) {
|
||||
auto pos = filename.rfind(DotSymbol<C>::value);
|
||||
if (pos == std::string::npos)
|
||||
return {};
|
||||
return filename.substr(pos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CPP Interface function to check if given filename belongs to shared library
|
||||
* @param filename - file name to check
|
||||
* @return true if filename is a shared library filename
|
||||
*/
|
||||
INFERENCE_ENGINE_API_CPP(bool) isSharedLibrary(const std::string &fileName);
|
||||
inline bool isSharedLibrary(const std::string &fileName) {
|
||||
return 0 ==
|
||||
#ifdef _WIN32
|
||||
_strnicmp
|
||||
#else
|
||||
strncasecmp
|
||||
#endif
|
||||
(fileExt(fileName).c_str(), FileTraits<char>::SharedLibraryExt().c_str(),
|
||||
FileTraits<char>::SharedLibraryExt().size());
|
||||
}
|
||||
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C>>
|
||||
inline std::basic_string<C> makeSharedLibraryName(const std::basic_string<C> &path, const std::basic_string<C> &input) {
|
||||
std::basic_string<C> separator(1, FileTraits<C>::FileSeparator);
|
||||
if (path.empty())
|
||||
separator = {};
|
||||
return path + separator + FileTraits<C>::SharedLibraryPrefix() + input + DotSymbol<C>::value + FileTraits<C>::SharedLibraryExt();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
using FilePath = std::wstring;
|
||||
|
||||
inline std::string fromFilePath(const FilePath & path) {
|
||||
return InferenceEngine::details::wStringtoMBCSstringChar(path);
|
||||
}
|
||||
|
||||
inline FilePath toFilePath(const std::string & path) {
|
||||
return InferenceEngine::details::multiByteCharToWString(path.c_str());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using FilePath = std::string;
|
||||
|
||||
inline std::string fromFilePath(const FilePath & path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
inline FilePath toFilePath(const std::string & path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
/**
|
||||
* @brief TODO: description
|
||||
|
||||
@@ -112,9 +112,9 @@ class Core::Impl : public ICore {
|
||||
mutable std::map<std::string, InferencePlugin, details::CaselessLess<std::string> > plugins;
|
||||
|
||||
struct PluginDescriptor {
|
||||
file_name_t libraryLocation;
|
||||
FileUtils::FilePath libraryLocation;
|
||||
std::map<std::string, std::string> defaultConfig;
|
||||
std::vector<std::string> listOfExtentions;
|
||||
std::vector<FileUtils::FilePath> listOfExtentions;
|
||||
};
|
||||
std::map<std::string, PluginDescriptor, details::CaselessLess<std::string> > pluginRegistry;
|
||||
IErrorListener * listener = nullptr;
|
||||
@@ -123,12 +123,20 @@ public:
|
||||
~Impl() override;
|
||||
|
||||
/**
|
||||
* @brief Register plugins for devices which are located in .xml configuration file
|
||||
* @brief Register plugins for devices which are located in .xml configuration file. The function supports UNICODE path
|
||||
* @param xmlConfigFile - an .xml configuraion with device / plugin information
|
||||
*/
|
||||
void RegisterPluginsInRegistry(const std::string & xmlConfigFile) {
|
||||
#if defined(ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32)
|
||||
std::wstring wFilePath = InferenceEngine::details::multiByteCharToWString(xmlConfigFile.c_str());
|
||||
const wchar_t* resolvedFilepath = wFilePath.c_str();
|
||||
#else
|
||||
const char* resolvedFilepath = xmlConfigFile.c_str();
|
||||
#endif
|
||||
|
||||
|
||||
pugi::xml_document xmlDoc;
|
||||
pugi::xml_parse_result res = xmlDoc.load_file(xmlConfigFile.c_str());
|
||||
pugi::xml_parse_result res = xmlDoc.load_file(resolvedFilepath);
|
||||
|
||||
if (res.status != pugi::status_ok) {
|
||||
std::ifstream t(xmlConfigFile);
|
||||
@@ -160,7 +168,7 @@ public:
|
||||
for (auto pluginNode = devicesNode.child("plugin"); !pluginNode.empty();
|
||||
pluginNode = pluginNode.next_sibling("plugin")) {
|
||||
std::string deviceName = GetStrAttr(pluginNode, "name");
|
||||
file_name_t pluginPath = GetStrAttr(pluginNode, "location");
|
||||
FileUtils::FilePath pluginPath = FileUtils::toFilePath(GetStrAttr(pluginNode, "location").c_str());
|
||||
|
||||
if (deviceName.find('.') != std::string::npos) {
|
||||
THROW_IE_EXCEPTION << "Device name must not contain dot '.' symbol";
|
||||
@@ -168,9 +176,8 @@ public:
|
||||
|
||||
// append IR library path for default IE plugins
|
||||
{
|
||||
std::string absPluginPath = FileUtils::makePath(getIELibraryPath(), pluginPath);
|
||||
if (FileUtils::fileExist(absPluginPath))
|
||||
pluginPath = absPluginPath;
|
||||
FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath);
|
||||
if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath;
|
||||
}
|
||||
|
||||
// check properties
|
||||
@@ -188,12 +195,12 @@ public:
|
||||
|
||||
// check extensions
|
||||
auto extensionsNode = pluginNode.child("extensions");
|
||||
std::vector<std::string> listOfExtentions;
|
||||
std::vector<FileUtils::FilePath> listOfExtentions;
|
||||
|
||||
if (extensionsNode) {
|
||||
for (auto extensionNode = extensionsNode.child("extension"); !extensionNode.empty();
|
||||
extensionNode = extensionNode.next_sibling("extension")) {
|
||||
std::string extensionLocation = GetStrAttr(extensionNode, "location");
|
||||
FileUtils::FilePath extensionLocation = FileUtils::toFilePath(GetStrAttr(extensionNode, "location").c_str());
|
||||
listOfExtentions.push_back(extensionLocation);
|
||||
}
|
||||
}
|
||||
@@ -262,8 +269,10 @@ public:
|
||||
{
|
||||
cppPlugin.SetConfig(desc.defaultConfig);
|
||||
|
||||
for (auto && extensionLocation : desc.listOfExtentions) {
|
||||
cppPlugin.AddExtension(make_so_pointer<IExtension>(extensionLocation));
|
||||
for (auto&& extensionLocation : desc.listOfExtentions) {
|
||||
// TODO: fix once InferenceEngine::Extension can accept FileUtils::FilePath
|
||||
// currently, extensions cannot be loaded using wide path
|
||||
cppPlugin.AddExtension(make_so_pointer<IExtension>(FileUtils::fromFilePath(extensionLocation)));
|
||||
}
|
||||
|
||||
if (listener)
|
||||
@@ -271,8 +280,9 @@ public:
|
||||
}
|
||||
|
||||
plugins[deviceName] = cppPlugin;
|
||||
} catch (const details::InferenceEngineException & ex) {
|
||||
THROW_IE_EXCEPTION << "Failed to create plugin " << desc.libraryLocation << " for device " << deviceName << "\n"
|
||||
} catch (const details::InferenceEngineException& ex) {
|
||||
THROW_IE_EXCEPTION << "Failed to create plugin " << FileUtils::fromFilePath(desc.libraryLocation)
|
||||
<< " for device " << deviceName << "\n"
|
||||
<< "Please, check your environment\n"
|
||||
<< ex.what() << "\n";
|
||||
}
|
||||
@@ -309,13 +319,12 @@ public:
|
||||
}
|
||||
|
||||
// append IR library path for default IE plugins
|
||||
std::string pluginPath;
|
||||
FileUtils::FilePath pluginPath;
|
||||
{
|
||||
pluginPath = make_plugin_name(file_name_t(), pluginName);
|
||||
pluginPath = FileUtils::makeSharedLibraryName({}, FileUtils::toFilePath(pluginName.c_str()));
|
||||
|
||||
std::string absPluginPath = FileUtils::makePath(getIELibraryPath(), pluginPath);
|
||||
if (FileUtils::fileExist(absPluginPath))
|
||||
pluginPath = absPluginPath;
|
||||
FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath);
|
||||
if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath;
|
||||
}
|
||||
|
||||
PluginDescriptor desc = { pluginPath, { }, { } };
|
||||
@@ -368,7 +377,8 @@ Core::Core(const std::string & xmlConfigFile) {
|
||||
std::string xmlConfigFile_ = xmlConfigFile;
|
||||
if (xmlConfigFile_.empty()) {
|
||||
// register plugins from default plugins.xml config
|
||||
xmlConfigFile_ = FileUtils::makePath(getIELibraryPath(), "plugins.xml");
|
||||
FileUtils::FilePath xmlConfigFileDefault = FileUtils::makePath(getInferenceEngineLibraryPath(), FileUtils::toFilePath("plugins.xml"));
|
||||
xmlConfigFile_ = FileUtils::fromFilePath(xmlConfigFileDefault);
|
||||
}
|
||||
|
||||
RegisterPlugins(xmlConfigFile_);
|
||||
|
||||
@@ -263,7 +263,7 @@ inline static void annotateEnd(IttStatic&, IttProfilingTask& t) {
|
||||
|
||||
#define IE_PROFILING_AUTO_SCOPE_TASK(PROFILING_TASK) IE_ITT_TASK_SCOPE(PROFILING_TASK); IE_TIMER_SCOPE(PROFILING_TASK.name)
|
||||
|
||||
inline static void anotateSetThreadName(const char* name) {
|
||||
inline static void annotateSetThreadName(const char* name) {
|
||||
#ifdef ENABLE_PROFILING_ITT
|
||||
__itt_thread_set_name(name);
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "ie_icnn_network_stats.hpp"
|
||||
#include "cpp/ie_plugin_cpp.hpp"
|
||||
#include "details/ie_cnn_network_tools.h"
|
||||
#include "details/os/os_filesystem.hpp"
|
||||
#include "file_utils.h"
|
||||
#include "net_pass.h"
|
||||
#include "precision_utils.h"
|
||||
@@ -737,32 +738,54 @@ std::unordered_set<DataPtr> getRootDataObjects(ICNNNetwork &network) {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string getPathName(const std::string & s) {
|
||||
size_t i = s.rfind(FileUtils::FileSeparator, s.length());
|
||||
template <typename C, typename = InferenceEngine::details::enableIfSupportedChar<C> >
|
||||
std::basic_string<C> getPathName(const std::basic_string<C>& s) {
|
||||
size_t i = s.rfind(FileUtils::FileTraits<C>::FileSeparator, s.length());
|
||||
if (i != std::string::npos) {
|
||||
return(s.substr(0, i));
|
||||
}
|
||||
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string getIELibraryPath() {
|
||||
#ifndef _WIN32
|
||||
|
||||
static std::string getIELibraryPathUnix() {
|
||||
Dl_info info;
|
||||
dladdr(reinterpret_cast<void*>(getIELibraryPath), &info);
|
||||
return getPathName(std::string(info.dli_fname)).c_str();
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
std::wstring getIELibraryPathW() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
char ie_library_path[2048];
|
||||
wchar_t ie_library_path[4096];
|
||||
HMODULE hm = NULL;
|
||||
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCSTR)getIELibraryPath, &hm)) {
|
||||
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCWSTR)getIELibraryPath, &hm)) {
|
||||
THROW_IE_EXCEPTION << "GetModuleHandle returned " << GetLastError();
|
||||
}
|
||||
GetModuleFileNameA(hm, (LPSTR)ie_library_path, sizeof(ie_library_path));
|
||||
return getPathName(ie_library_path);
|
||||
GetModuleFileNameW(hm, (LPWSTR)ie_library_path, sizeof(ie_library_path));
|
||||
return getPathName(std::wstring(ie_library_path));
|
||||
#else
|
||||
Dl_info info;
|
||||
dladdr(reinterpret_cast<void *>(getIELibraryPath), &info);
|
||||
return getPathName(info.dli_fname);
|
||||
dladdr(reinterpret_cast<void*>(getIELibraryPath), &info);
|
||||
return details::multiByteCharToWString(getIELibraryPathUnix().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::string getIELibraryPath() {
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
return details::wStringtoMBCSstringChar(getIELibraryPathW());
|
||||
#else
|
||||
return getIELibraryPathUnix();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <cpp/ie_cnn_network.h>
|
||||
#include <cnn_network_impl.hpp>
|
||||
#include <file_utils.h>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -187,6 +188,17 @@ getRootDataObjects(ICNNNetwork &network);
|
||||
|
||||
INFERENCE_ENGINE_API_CPP(std::string) getIELibraryPath();
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
INFERENCE_ENGINE_API_CPP(std::wstring) getIELibraryPathW();
|
||||
inline ::FileUtils::FilePath getInferenceEngineLibraryPath() {
|
||||
return getIELibraryPathW();
|
||||
}
|
||||
#else
|
||||
inline ::FileUtils::FilePath getInferenceEngineLibraryPath() {
|
||||
return getIELibraryPath();
|
||||
}
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
} // namespace InferenceEngine
|
||||
|
||||
#endif // IE_UTIL_HPP
|
||||
|
||||
@@ -328,6 +328,42 @@ void MKLDNNSplitNode::selectOptimalPrimitiveDescriptor() {
|
||||
}
|
||||
}
|
||||
|
||||
// This logic is needed to cover cases when Split node cannot be optimized out for particular block size
|
||||
// In general it is significantly better to have additional reorders in graph than to use reference Split implementation
|
||||
if (convertTo == memory::nChw16c || convertTo == memory::nCdhw16c ||
|
||||
convertTo == memory::nChw8c || convertTo == memory::nCdhw8c) {
|
||||
int blockSize = convertTo == memory::nChw16c || convertTo == memory::nCdhw16c ? 16 : 8;
|
||||
bool shouldDecreaseBlockSize = false;
|
||||
for (auto& parentEdge : getParentEdges()) {
|
||||
if (parentEdge.lock()->getDims()[1] % blockSize != 0)
|
||||
shouldDecreaseBlockSize = true;
|
||||
}
|
||||
|
||||
for (auto& childEdge : getChildEdges()) {
|
||||
if (childEdge.lock()->getDims()[1] % blockSize != 0)
|
||||
shouldDecreaseBlockSize = true;
|
||||
}
|
||||
|
||||
if (shouldDecreaseBlockSize) {
|
||||
int decreasedBlockSize = 8;
|
||||
bool canDecreaseBlockSize = true;
|
||||
for (auto &parentEdge : getParentEdges()) {
|
||||
if (parentEdge.lock()->getDims()[1] % decreasedBlockSize != 0)
|
||||
canDecreaseBlockSize = false;
|
||||
}
|
||||
|
||||
for (auto &childEdge : getChildEdges()) {
|
||||
if (childEdge.lock()->getDims()[1] % decreasedBlockSize != 0)
|
||||
canDecreaseBlockSize = false;
|
||||
}
|
||||
|
||||
if (canDecreaseBlockSize)
|
||||
convertTo = getParentEdgeAt(0)->getDims().ndims() == 5 ? memory::nCdhw8c : memory::nChw8c;
|
||||
else
|
||||
convertTo = MKLDNNMemory::GetPlainFormat(getParentEdgeAt(0)->getDims());
|
||||
}
|
||||
}
|
||||
|
||||
if (canOptimize && MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, convertTo).blocksExtended())
|
||||
canOptimize = false;
|
||||
for (size_t i = 0; canOptimize && i < getChildEdges().size(); i++) {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2018-2019 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <details/os/os_filesystem.hpp>
|
||||
|
||||
#ifdef ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
static void fixSlashes(std::string &str) {
|
||||
std::replace(str.begin(), str.end(), '/', '\\');
|
||||
}
|
||||
|
||||
static void fixSlashes(std::wstring &str) {
|
||||
std::replace(str.begin(), str.end(), L'/', L'\\');
|
||||
}
|
||||
|
||||
static std::wstring stringToWString(std::string input) {
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||
std::wstring result = converter.from_bytes(input);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool copyFile(std::wstring source_path, std::wstring dest_path) {
|
||||
#ifndef _WIN32
|
||||
std::ifstream source(InferenceEngine::details::wStringtoMBCSstringChar(source_path), std::ios::binary);
|
||||
std::ofstream dest(InferenceEngine::details::wStringtoMBCSstringChar(dest_path), std::ios::binary);
|
||||
#else
|
||||
fixSlashes(source_path);
|
||||
fixSlashes(dest_path);
|
||||
std::ifstream source(source_path, std::ios::binary);
|
||||
std::ofstream dest(dest_path, std::ios::binary);
|
||||
#endif
|
||||
bool result = source && dest;
|
||||
std::istreambuf_iterator<char> begin_source(source);
|
||||
std::istreambuf_iterator<char> end_source;
|
||||
std::ostreambuf_iterator<char> begin_dest(dest);
|
||||
copy(begin_source, end_source, begin_dest);
|
||||
|
||||
source.close();
|
||||
dest.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool copyFile(std::string source_path, std::wstring dest_path) {
|
||||
return copyFile(stringToWString(source_path), dest_path);
|
||||
}
|
||||
|
||||
static std::wstring addUnicodePostfixToPath(std::string source_path, std::wstring postfix) {
|
||||
fixSlashes(source_path);
|
||||
std::wstring result = stringToWString(source_path);
|
||||
std::wstring file_name = result.substr(0, result.size() - 4);
|
||||
std::wstring extension = result.substr(result.size() - 4, result.size());
|
||||
result = file_name + postfix + extension;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void removeFile(std::wstring path) {
|
||||
int result = 0;
|
||||
if (!path.empty()) {
|
||||
#ifdef _WIN32
|
||||
result = _wremove(path.c_str());
|
||||
#else
|
||||
result = remove(InferenceEngine::details::wStringtoMBCSstringChar(path).c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static const std::vector<std::wstring> test_unicode_postfix_vector = {
|
||||
L"unicode_Яㅎあ",
|
||||
L"ひらがな日本語",
|
||||
L"大家有天分",
|
||||
L"עפצקרשתםןףץ",
|
||||
L"ث خ ذ ض ظ غ",
|
||||
L"그것이정당하다",
|
||||
L"АБВГДЕЁЖЗИЙ",
|
||||
L"СТУФХЦЧШЩЬЮЯ"
|
||||
};
|
||||
|
||||
#endif // ENABLE_UNICODE_PATH_SUPPORT
|
||||
@@ -615,12 +615,19 @@ status_t jit_avx2_conv_fwd_kernel_f32::init_conf(jit_conv_conf_t &jcp,
|
||||
// adjust one of nb_oc_block, ur_w preserving to ur_w >= l_pad
|
||||
if (jcp.ur_w > jcp.l_pad && jcp.ur_w > 1)
|
||||
jcp.ur_w -= 1;
|
||||
else
|
||||
for (int b = 3; b > 1; b--)
|
||||
else {
|
||||
for (int b = 3; b > 1; b--) {
|
||||
if (jcp.nb_oc % b == 0) {
|
||||
jcp.nb_oc_blocking = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((jcp.nb_oc_blocking + 1) * jcp.ur_w > num_avail_regs) {
|
||||
// No optimal size for 'nb_oc_blocking' with regards to
|
||||
// 'nb_oc', default to only unroll by 'ur_w'.
|
||||
jcp.nb_oc_blocking = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ inline void rtus_prepare(conv_pd_t *self, const convolution_desc_t *&conv_d,
|
||||
template <typename conv_pd_t>
|
||||
inline void rtus_prepare_space_info(conv_pd_t *self,
|
||||
memory_tracking::registrar_t &scratchpad) {
|
||||
if (!self->rtus_.reduce_src_) return;
|
||||
const auto &jcp = self->jcp_;
|
||||
|
||||
const int max_threads = mkldnn_get_max_threads();
|
||||
|
||||
@@ -136,7 +136,7 @@ Command line:
|
||||
python collect_statistics.py --config ~/inception_v1.yml -d ~/defenitions.yml -M /home/user/intel/openvino/deployment_tools/model_optimizer --models ~/models --source /media/user/calibration/datasets --annotations ~/annotations --converted_models ~/models
|
||||
```
|
||||
|
||||
Result model has statistics which allow you to infer this model in INT8 precision. To measure performance, you can use the [Benchmark App](./inference-engine/ie_bridges/python/sample/benchmark_app/README.md).
|
||||
Result model has statistics which allow you to infer this model in INT8 precision. To measure performance, you can use the [Benchmark App](./inference-engine/tools/benchmark_tool/README.md).
|
||||
|
||||
### Calibrate the Model
|
||||
During calibration process, the model is adjusted for efficient quantization and minimization of accuracy drop on calibration dataset. Calibration tool produces calibrated model which will be executed in low precision 8-bit quantized mode after loading into CPU plugin.
|
||||
@@ -180,4 +180,6 @@ To run the Calibration Tool in the simplified mode, use the following command:
|
||||
```sh
|
||||
python3 calibrate.py -sm -m <path-to-ir.xml> -s <path-to-dataset> -ss <images-number> -e <path-to-extensions-folder> -td <target-device> -precision <output-ir-precision> --output-dir <output-directory-path>
|
||||
```
|
||||
It accepts models with FP32, FP16 precisions and image files as the dataset.
|
||||
Input:
|
||||
- FP32 and FP16 models
|
||||
- image files as a dataset
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
Copyright (c) 2019 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 logging as log
|
||||
|
||||
import numpy as np
|
||||
|
||||
from mo.graph.graph import Graph
|
||||
from mo.utils.model_analysis import AnalyzeAction
|
||||
|
||||
|
||||
class InputsAnalysis(AnalyzeAction):
|
||||
"""
|
||||
The analyser gets information about model inputs and their default values if any.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def fifo_queue_analysis(cls, graph: Graph, inputs_desc: dict):
|
||||
"""
|
||||
The FIFOQueue with QueueDeque has a separate input that specifies the size of batch to extract from queue. This
|
||||
input is redundant and should be remove from the model analysis output.
|
||||
"""
|
||||
inputs_to_ignore = set()
|
||||
for fifo_queue in graph.get_op_nodes(op='FIFOQueueV2'):
|
||||
if len(fifo_queue.get_outputs({'out': 0})) != 1:
|
||||
log.debug('The FIFOQueue operation "{}" has more than 1 consumers'.format(fifo_queue.id))
|
||||
continue
|
||||
queue_deque = fifo_queue.out_node(0)
|
||||
if queue_deque.op in ['QueueDequeueMany', 'QueueDequeueManyV2', 'QueueDequeueUpTo', 'QueueDequeueUpToV2']:
|
||||
queue_deque_input_1 = queue_deque.in_node(1)
|
||||
if queue_deque_input_1.op in ['Parameter', 'PlaceholderWithDefault']:
|
||||
log.debug('Adding node "{}" to placeholder ignore list'.format(queue_deque_input_1.id))
|
||||
inputs_to_ignore.add(queue_deque_input_1.id)
|
||||
|
||||
# create input per each QueueDeque output port
|
||||
for port_ind in range(len(queue_deque.out_nodes())):
|
||||
inputs_desc["{}:{}".format(queue_deque.id, port_ind)] = {'shape': fifo_queue.shapes[port_ind].tolist(),
|
||||
'value': None,
|
||||
'data_type': fifo_queue.types[port_ind]}
|
||||
return inputs_to_ignore
|
||||
|
||||
@classmethod
|
||||
def ignore_mxnet_softmax_inputs(cls, graph: Graph):
|
||||
"""
|
||||
MxNet Softmax layers may have additional inputs which should be ignored. Refer to the
|
||||
extensions/front/mxnet/check_softmax_node_inputs.py.
|
||||
"""
|
||||
inputs_to_ignore = set()
|
||||
softmax_nodes = []
|
||||
[softmax_nodes.extend(graph.get_op_nodes(op=op)) for op in ('SoftMax', 'SoftmaxActivation', 'SoftmaxOutput')]
|
||||
for softmax_node in softmax_nodes:
|
||||
for i in range(1, len(softmax_node.in_nodes())):
|
||||
if softmax_node.in_node(i).has_valid('op') and softmax_node.in_node(i).op == 'Parameter':
|
||||
inputs_to_ignore.add(softmax_node.in_node(i).id)
|
||||
return inputs_to_ignore
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
inputs_desc = dict()
|
||||
|
||||
inputs_to_ignore = InputsAnalysis.fifo_queue_analysis(graph, inputs_desc)
|
||||
if graph.graph['fw'] == 'mxnet':
|
||||
inputs_to_ignore.update(InputsAnalysis.ignore_mxnet_softmax_inputs(graph))
|
||||
|
||||
inputs = graph.get_op_nodes(op='Parameter')
|
||||
for input in inputs:
|
||||
inputs_desc[input.name] = {'shape': input.soft_get('shape', None),
|
||||
'data_type': input.soft_get('data_type', None),
|
||||
'value': None,
|
||||
}
|
||||
|
||||
placeholders_with_default = graph.get_op_nodes(op='PlaceholderWithDefault')
|
||||
for input in placeholders_with_default:
|
||||
inputs_desc[input.name] = {'shape': input.soft_get('shape', None),
|
||||
'data_type': input.soft_get('data_type', None),
|
||||
'value': input.in_node(0).value if 0 in input.in_nodes() and
|
||||
input.in_node(0).has_valid('value') else None}
|
||||
|
||||
for input_to_ignore in inputs_to_ignore:
|
||||
del inputs_desc[input_to_ignore]
|
||||
|
||||
# workaround for the ONNX models case where input shape is specified as string value like: "width", "height".
|
||||
# In this case the string value is converted to 0, but in fact it is an arbitrary value so should be -1
|
||||
if graph.graph['fw'] == 'onnx':
|
||||
for inp in inputs_desc.values():
|
||||
inp['shape'] = [-1 if item == 0 else item for item in inp['shape']]
|
||||
return {'inputs': inputs_desc}
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
Copyright (c) 2019 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 json
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
from extensions.front.user_data_repack import UserDataRepack
|
||||
from mo.graph.graph import Graph
|
||||
from mo.middle.passes.convert_data_type import np_data_type_to_precision
|
||||
from mo.utils.model_analysis import AnalyzeAction, AnalysisCollectorAnchor
|
||||
|
||||
|
||||
def prepare_obj_for_dump(obj: object):
|
||||
if isinstance(obj, dict):
|
||||
return {k: prepare_obj_for_dump(v) for k, v in obj.items()}
|
||||
elif isinstance(obj, np.ndarray) or isinstance(obj, list):
|
||||
return [prepare_obj_for_dump(elem) for elem in obj]
|
||||
elif isinstance(obj, type):
|
||||
return np_data_type_to_precision(obj)
|
||||
elif isinstance(obj, np.generic):
|
||||
return obj.item()
|
||||
else:
|
||||
return obj
|
||||
|
||||
|
||||
class AnalysisJSONPrint(AnalyzeAction):
|
||||
"""
|
||||
The action prints the analysis results in JSON format.
|
||||
"""
|
||||
enabled = False
|
||||
id = 'ANALYSIS_JSON_PRINT'
|
||||
|
||||
def run_before(self):
|
||||
return [UserDataRepack]
|
||||
|
||||
def run_after(self):
|
||||
return [AnalysisCollectorAnchor]
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
if 'analysis_results' in graph.graph and graph.graph['analysis_results'] is not None:
|
||||
print(json.dumps(prepare_obj_for_dump(graph.graph['analysis_results'])))
|
||||
sys.exit(0)
|
||||
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
Copyright (c) 2019 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.
|
||||
"""
|
||||
from mo.graph.graph import Graph
|
||||
from mo.utils.model_analysis import AnalyzeAction
|
||||
|
||||
|
||||
class IntermediatesNodesAnalysis(AnalyzeAction):
|
||||
"""
|
||||
The analyser gets node names, their shapes and values (if possible) of all nodes in the model.
|
||||
"""
|
||||
def analyze(self, graph: Graph):
|
||||
outputs_desc = dict()
|
||||
|
||||
for node in graph.get_op_nodes():
|
||||
outputs_desc[node.id] = {'shape': node.soft_get('shape', None),
|
||||
'data_type': None,
|
||||
'value': None,
|
||||
}
|
||||
return {'intermediate': outputs_desc}
|
||||
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
Copyright (c) 2019 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 logging as log
|
||||
|
||||
from mo.graph.graph import Graph
|
||||
from mo.utils.model_analysis import AnalyzeAction, graph_contains_scope
|
||||
from mo.utils.utils import files_by_pattern, get_mo_root_dir
|
||||
|
||||
|
||||
class TensorFlowObjectDetectionAPIAnalysis(AnalyzeAction):
|
||||
"""
|
||||
The analyser checks if the provided model is TF OD API model from
|
||||
https://github.com/tensorflow/models/tree/master/research/object_detection/g3doc/detection_model_zoo.md of one of 4
|
||||
supported flavors: SSD, RFCN, Faster RCNN, Mask RCNN.
|
||||
"""
|
||||
graph_condition = [lambda graph: graph.graph['fw'] == 'tf']
|
||||
|
||||
model_scopes = [('MaskRCNN', ['Preprocessor',
|
||||
'FirstStageFeatureExtractor',
|
||||
'SecondStageFeatureExtractor',
|
||||
'SecondStageBoxPredictor',
|
||||
'SecondStageBoxPredictor_1',
|
||||
'SecondStageFeatureExtractor_1',
|
||||
]),
|
||||
('RFCN', ['Preprocessor',
|
||||
'FirstStageFeatureExtractor',
|
||||
'SecondStageFeatureExtractor',
|
||||
'SecondStageBoxPredictor',
|
||||
'SecondStageBoxPredictor/map',
|
||||
'SecondStageBoxPredictor/map_1',
|
||||
'SecondStagePostprocessor',
|
||||
]),
|
||||
('FasterRCNN', ['Preprocessor',
|
||||
'FirstStageFeatureExtractor',
|
||||
'SecondStageFeatureExtractor',
|
||||
'SecondStageBoxPredictor',
|
||||
'SecondStagePostprocessor',
|
||||
]),
|
||||
('SSD', ['Preprocessor',
|
||||
'FeatureExtractor',
|
||||
'Postprocessor',
|
||||
]),
|
||||
]
|
||||
|
||||
file_patterns = {'MaskRCNN': 'mask_rcnn_support.*\\.json',
|
||||
'RFCN': 'rfcn_support.*\\.json',
|
||||
'FasterRCNN': 'faster_rcnn_support.*\\.json',
|
||||
'SSD': 'ssd.*_support.*\\.json',
|
||||
}
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
if any([name not in graph.nodes() for name in ['image_tensor', 'detection_classes', 'detection_boxes',
|
||||
'detection_scores']]):
|
||||
log.debug('The model does not contain nodes that must exist in the TF OD API models')
|
||||
return None
|
||||
|
||||
for flavor, scopes in __class__.model_scopes:
|
||||
if all([graph_contains_scope(graph, scope) for scope in scopes]):
|
||||
result = dict()
|
||||
result['flavor'] = flavor
|
||||
result['mandatory_parameters'] = {'tensorflow_use_custom_operations_config':
|
||||
files_by_pattern(get_mo_root_dir() + '/extensions/front/tf',
|
||||
__class__.file_patterns[flavor],
|
||||
add_prefix=True),
|
||||
'tensorflow_object_detection_api_pipeline_config': None,
|
||||
}
|
||||
return {'model_type': {'TF_OD_API': result}}
|
||||
return None
|
||||
@@ -0,0 +1,107 @@
|
||||
"""
|
||||
Copyright (c) 2019 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.
|
||||
"""
|
||||
|
||||
from mo.graph.graph import Graph
|
||||
from mo.middle.pattern_match import apply_pattern
|
||||
from mo.utils.model_analysis import AnalyzeAction, graph_contains_scope
|
||||
|
||||
|
||||
YOLO_PATTERN = {
|
||||
'nodes': [
|
||||
('pad', dict(op='Pad')),
|
||||
('conv', dict(op='Conv2D')),
|
||||
('sub', dict(op='Sub')),
|
||||
('div', dict(op='Div')),
|
||||
('mul', dict(op='Mul')),
|
||||
('bias_add', dict(op='Add')),
|
||||
('mul_2', dict(op='Mul')),
|
||||
('max', dict(op='Maximum')),
|
||||
],
|
||||
'edges': [
|
||||
('pad', 'conv', {'out': 0}),
|
||||
('conv', 'sub', {'out': 0}),
|
||||
('sub', 'div', {'out': 0}),
|
||||
('div', 'mul', {'out': 0}),
|
||||
('mul', 'bias_add', {'out': 0}),
|
||||
('bias_add', 'mul_2', {'out': 0}),
|
||||
('bias_add', 'max', {'out': 0}),
|
||||
('mul_2', 'max', {'out': 0}),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def pattern_instance_counter(graph: Graph, match: dict):
|
||||
pattern_instance_counter.counter += 1
|
||||
|
||||
|
||||
pattern_instance_counter.counter = 0
|
||||
|
||||
|
||||
YOLO_CONFIGS = {'YOLOV2Full': ['extensions/front/tf/yolo_v2.json', 'extensions/front/tf/yolo_v2_voc.json'],
|
||||
'YOLOV3Full': ['extensions/front/tf/yolo_v3.json', 'extensions/front/tf/yolo_v3_voc.json'],
|
||||
'YOLOV2Tiny': ['extensions/front/tf/yolo_v2_tiny.json', 'extensions/front/tf/yolo_v2_tiny_voc.json'],
|
||||
'YOLOV3Tiny': ['extensions/front/tf/yolo_v3_tiny.json', 'extensions/front/tf/yolo_v3_tiny_voc.json'],
|
||||
}
|
||||
|
||||
|
||||
def get_YOLO_params_by_flavor(flavor: str):
|
||||
result = dict()
|
||||
result['flavor'] = flavor
|
||||
result['mandatory_parameters'] = {'tensorflow_use_custom_operations_config': YOLO_CONFIGS[flavor]}
|
||||
return result
|
||||
|
||||
|
||||
class TensorFlowYOLOV1V2Analysis(AnalyzeAction):
|
||||
"""
|
||||
The analyser checks if the provided model is TensorFlow YOLO models from https://github.com/thtrieu/darkflow .
|
||||
"""
|
||||
graph_condition = [lambda graph: graph.graph['fw'] == 'tf']
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
pattern_instance_counter.counter = 0
|
||||
apply_pattern(graph, **YOLO_PATTERN, action=pattern_instance_counter)
|
||||
|
||||
flavor = None
|
||||
if pattern_instance_counter.counter > 0:
|
||||
if pattern_instance_counter.counter == 22:
|
||||
flavor = 'YOLOV2Full'
|
||||
elif pattern_instance_counter.counter == 8:
|
||||
flavor = 'YOLOV2Tiny'
|
||||
|
||||
if flavor is not None:
|
||||
return {'model_type': {'YOLO': get_YOLO_params_by_flavor(flavor)}}
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class TensorFlowYOLOV3Analysis(AnalyzeAction):
|
||||
"""
|
||||
The analyser checks if the provided model is TensorFlow YOLO models from
|
||||
https://github.com/mystic123/tensorflow-yolo-v3.
|
||||
"""
|
||||
graph_condition = [lambda graph: graph.graph['fw'] == 'tf']
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
flavor = None
|
||||
if graph_contains_scope(graph, 'detector/yolo-v3') and graph_contains_scope(graph, 'detector/darknet-53'):
|
||||
flavor = 'YOLOV3Full'
|
||||
elif graph_contains_scope(graph, 'detector/yolo-v3-tiny'):
|
||||
flavor = 'YOLOV3Tiny'
|
||||
|
||||
if flavor is not None:
|
||||
return {'model_type': {'YOLO': get_YOLO_params_by_flavor(flavor)}}
|
||||
else:
|
||||
return None
|
||||
@@ -65,6 +65,7 @@ class FIFOQueue(FrontReplacementSubgraph):
|
||||
"""
|
||||
true_placeholder_shape = match['placeholder'].shape
|
||||
placeholder_shape = match['fifo_queue'].shapes[0]
|
||||
placeholder_data_type = match['fifo_queue'].types[0]
|
||||
assert true_placeholder_shape.ndim <= 1
|
||||
if true_placeholder_shape.ndim == 1 and len(true_placeholder_shape) > 1:
|
||||
log.warning(
|
||||
@@ -81,7 +82,8 @@ class FIFOQueue(FrontReplacementSubgraph):
|
||||
graph.remove_node(out.out_node().id)
|
||||
graph.remove_node(out.id)
|
||||
graph.remove_node(match['batch_join'].id)
|
||||
placeholder = Parameter(graph, {'name': placeholder_name, 'shape': placeholder_shape}).create_node()
|
||||
placeholder = Parameter(graph, {'name': placeholder_name, 'shape': placeholder_shape,
|
||||
'data_type': placeholder_data_type}).create_node()
|
||||
graph.create_edge(placeholder, match['image_batch'])
|
||||
log.info("FIFOQueueV2 pattern was detected. New shape of placeholder {} is {}. Use -b to set batch size if "
|
||||
"needed".format(placeholder.id, placeholder['shape']))
|
||||
|
||||
@@ -27,7 +27,7 @@ class TestFIFOQueueReplacement(unittest.TestCase):
|
||||
nodes = {
|
||||
'placeholder': {'op': 'Parameter', 'data_type': np.int32, 'kind': 'op', 'shape': np.array(1)},
|
||||
'batch_join/fifo_queue': {'op': 'FIFOQueueV2', 'name': 'batch_join/fifo_queue',
|
||||
'shapes': np.array([[1, 2, 3]]), 'kind': 'op'},
|
||||
'shapes': np.array([[1, 2, 3]]), 'types': np.array([np.float32]), 'kind': 'op'},
|
||||
'batch_join': {'op': 'QueueDequeueUpToV2', 'kind': 'op'},
|
||||
'image_batch': {'op': 'Identity', 'data_type': np.float32, 'kind': 'op'},
|
||||
'label_batch': {'op': 'Identity', 'kind': 'op'},
|
||||
@@ -56,7 +56,7 @@ class TestFIFOQueueReplacement(unittest.TestCase):
|
||||
nodes_no_label = {
|
||||
'placeholder': {'op': 'Parameter', 'data_type': np.int32, 'kind': 'op', 'shape': np.array(0)},
|
||||
'batch_join/fifo_queue': {'op': 'FIFOQueueV2', 'name': 'batch_join/fifo_queue',
|
||||
'shapes': np.array([[1, 2, 3]]), 'kind': 'op'},
|
||||
'shapes': np.array([[1, 2, 3]]), 'types': np.array([np.float32]), 'kind': 'op'},
|
||||
'batch_join': {'op': 'QueueDequeueUpToV2', 'kind': 'op'},
|
||||
'image_batch': {'op': 'Identity', 'data_type': np.float32, 'kind': 'op'},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Copyright (c) 2019 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.
|
||||
"""
|
||||
from mo.front.extractor import FrontExtractorOp
|
||||
from mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape
|
||||
from mo.ops.op import Op
|
||||
|
||||
|
||||
class PlaceholderWithDefaultExtractor(FrontExtractorOp):
|
||||
op = 'PlaceholderWithDefault'
|
||||
enabled = True
|
||||
|
||||
@staticmethod
|
||||
def extract(node):
|
||||
attrs = {
|
||||
'data_type': tf_dtype_extractor(node.pb.attr["dtype"].type),
|
||||
'shape': tf_tensor_shape(node.pb.attr["shape"].shape),
|
||||
'identity': True,
|
||||
}
|
||||
Op.update_node_stat(node, attrs)
|
||||
return __class__.enabled
|
||||
@@ -82,7 +82,6 @@ tf_op_extractors = {
|
||||
'SpaceToBatchND': node_pb_arg(tf_space_to_batch_ext),
|
||||
'BatchToSpaceND': node_pb_arg(tf_batch_to_space_ext),
|
||||
'ReadVariableOp': node_pb_arg(make_tf_eltwise(lambda v: v, attrs={'identity': True})),
|
||||
'PlaceholderWithDefault': node_pb_arg(make_tf_eltwise(lambda v: v, attrs={'identity': True}))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -175,10 +175,6 @@ def driver(argv: argparse.Namespace):
|
||||
if ret_code:
|
||||
return ret_code
|
||||
|
||||
if is_mxnet and not argv.input_shape:
|
||||
raise Error('Input shape is required to convert MXNet model. Please provide it with --input_shape. ' +
|
||||
refer_to_faq_msg(16))
|
||||
|
||||
mean_file_offsets = None
|
||||
if is_caffe and argv.mean_file and argv.mean_values:
|
||||
raise Error('Both --mean_file and mean_values are specified. Specify either mean file or mean values. ' +
|
||||
@@ -279,7 +275,7 @@ def driver(argv: argparse.Namespace):
|
||||
|
||||
if ret_res != 0:
|
||||
return ret_res
|
||||
if not (is_tf and argv.tensorflow_custom_operations_config_update):
|
||||
if not (is_tf and argv.tensorflow_custom_operations_config_update) and not argv.silent:
|
||||
output_dir = argv.output_dir if argv.output_dir != '.' else os.getcwd()
|
||||
print('\n[ SUCCESS ] Generated IR model.')
|
||||
print('[ SUCCESS ] XML file: {}.xml'.format(os.path.join(output_dir, model_name)))
|
||||
|
||||
@@ -30,6 +30,7 @@ SUPPORTED_DATA_TYPES = {
|
||||
'uint8': (np.uint8, 'UI8'),
|
||||
'int32': (np.int32, 'I32'),
|
||||
'int64': (np.int64, 'I64'),
|
||||
'bool': (np.bool, 'BOOL'),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ from mo.back.replacement import BackReplacementPattern
|
||||
from mo.middle.replacement import MiddleReplacementPattern
|
||||
from mo.ops.op import Op
|
||||
from mo.utils.class_registration import _check_unique_ids, update_registration, get_enabled_and_disabled_transforms
|
||||
from mo.utils.model_analysis import AnalyzeAction
|
||||
|
||||
|
||||
def import_by_path(path: str, middle_names: list = ()):
|
||||
@@ -73,6 +74,7 @@ def load_dir(framework: str, path: str, get_front_classes: callable):
|
||||
front_classes = get_front_classes()
|
||||
internal_dirs = {
|
||||
('ops', ): [Op],
|
||||
('analysis',): [AnalyzeAction],
|
||||
('front', ): front_classes,
|
||||
('front', framework): front_classes,
|
||||
('middle', ): [MiddleReplacementPattern],
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
Copyright (c) 2019 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 sys
|
||||
|
||||
from extensions.front.user_data_repack import UserDataRepack
|
||||
from mo.graph.graph import Graph
|
||||
from mo.utils import class_registration
|
||||
from mo.utils.error import Error
|
||||
|
||||
|
||||
class AnalyzeAction(object):
|
||||
registered_cls = []
|
||||
registered_ops = {}
|
||||
excluded_replacers = []
|
||||
run_not_recursively = True
|
||||
|
||||
def find_and_replace_pattern(self, graph: Graph):
|
||||
if 'analysis_results' not in graph.graph:
|
||||
graph.graph['analysis_results'] = {'failed_analysers': []}
|
||||
|
||||
try:
|
||||
result = self.analyze(graph) # pylint: disable=assignment-from-no-return
|
||||
except SystemExit:
|
||||
# the analysis transformation printing analysis results to the screen calls sys.exit(0) which in fact raises
|
||||
# SystemExit exception, so we handle it here
|
||||
sys.exit(0)
|
||||
except:
|
||||
graph.graph['analysis_results']['failed_analysers'].append(str(self.__class__))
|
||||
result = None
|
||||
|
||||
if result is not None:
|
||||
graph.graph['analysis_results'].update(result)
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
raise Error('The method must be implemented in the sub-class')
|
||||
|
||||
def run_before(self):
|
||||
"""
|
||||
Returns list of replacer classes which this replacer must be run before.
|
||||
:return: list of classes
|
||||
"""
|
||||
return [AnalysisCollectorAnchor, UserDataRepack]
|
||||
|
||||
def run_after(self):
|
||||
"""
|
||||
Returns list of replacer classes which this replacer must be run after.
|
||||
:return: list of classes
|
||||
"""
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def class_type(cls):
|
||||
return class_registration.ClassType.FRONT_REPLACER
|
||||
|
||||
|
||||
class AnalysisCollectorAnchor(AnalyzeAction):
|
||||
"""
|
||||
All analyzers should depend on this one which is an anchor analyzer to develop custom post-processor of all
|
||||
analyzers results.
|
||||
"""
|
||||
|
||||
def run_before(self):
|
||||
return []
|
||||
|
||||
def analyze(self, graph: Graph):
|
||||
pass
|
||||
|
||||
|
||||
def graph_contains_scope(graph: Graph, scope: str):
|
||||
"""
|
||||
Checks whether the graph contains node(s) which name starts with "scope" string.
|
||||
:param graph: graph to check
|
||||
:param scope: string defining the scope
|
||||
:return: the result of the check (True/False)
|
||||
"""
|
||||
if scope[-1] != '/':
|
||||
scope += '/'
|
||||
return any([node.soft_get('name').startswith(scope) for node in graph.get_op_nodes()])
|
||||
@@ -14,8 +14,10 @@
|
||||
limitations under the License.
|
||||
"""
|
||||
import functools
|
||||
import os
|
||||
import re
|
||||
import warnings
|
||||
import logging as log
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
@@ -77,3 +79,30 @@ def shrink_str_value(value: np.array, max_symbols=100):
|
||||
if len(value) > max_symbols:
|
||||
value = value.strip('\n')[:max_symbols - 3] + '...'
|
||||
return value
|
||||
|
||||
|
||||
def files_by_pattern(dir: str, pattern: str, files_only=True, add_prefix=False):
|
||||
"""
|
||||
Return a list of files and directories (or only files if the files_only is set to True) in the directory dir that
|
||||
match pattern string pattern.
|
||||
:param dir: Directory to search for files
|
||||
:param pattern: string defining pattern name
|
||||
:param files_only: flag to include only files (not directories) to the result
|
||||
:param add_prefix: flag to include the prefix string to the file names
|
||||
:return: list of file and directory names
|
||||
"""
|
||||
pattern_compiled = re.compile(pattern)
|
||||
matched_file_names = []
|
||||
for file_name in os.listdir(dir):
|
||||
if re.match(pattern_compiled, file_name) and (not files_only or os.path.isfile(os.path.join(dir, file_name))):
|
||||
matched_file_names.append(os.path.join(dir, file_name) if add_prefix else file_name)
|
||||
return matched_file_names
|
||||
|
||||
|
||||
def get_mo_root_dir():
|
||||
"""
|
||||
Return the absolute path to the Model Optimizer root directory (where mo.py file is located)
|
||||
:return: path to the MO root directory
|
||||
"""
|
||||
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(os.path.realpath(__file__))), os.pardir,
|
||||
os.pardir))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tensorflow>=1.2.0,<2.0.0
|
||||
mxnet>=1.0.0,<=1.3.1
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy>=1.12.0
|
||||
protobuf==3.6.1
|
||||
onnx>=1.1.2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy>=1.12.0
|
||||
protobuf==3.6.1
|
||||
defusedxml>=0.5.0
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy==1.13.0
|
||||
defusedxml>=0.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
mxnet>=1.0.0,<=1.3.1
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy>=1.12.0
|
||||
defusedxml>=0.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
onnx>=1.1.2
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy>=1.12.0
|
||||
defusedxml>=0.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tensorflow>=1.2.0,<2.0.0
|
||||
networkx>=1.11
|
||||
networkx>=1.11,<2.4
|
||||
numpy>=1.12.0
|
||||
defusedxml>=0.5.0
|
||||
|
||||
@@ -91,7 +91,7 @@ logging.config.dictConfig(_LOGGING_CONFIGURATION)
|
||||
default_logger = logging.getLogger(_DEFAULT_LOGGER_NAME)
|
||||
|
||||
|
||||
def _warning_handler(message, category, filename, lineno):
|
||||
def _warning_handler(message, category, filename, lineno, *args, **kwargs):
|
||||
s = warnings.formatwarning(message, category, filename, lineno)
|
||||
default_logger.warning(s)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user