Compare commits

..
Author SHA1 Message Date
Alexey Suhov f103291b47 Publishing 2019 R3.2 content 2020-03-19 16:22:33 +03:00
Alexey Suhov 949b74059f Merge pull request #296 from dkurt/patch-1
Do not build CMake from source
2020-02-10 21:08:40 +03:00
Alexey Suhov 651161be1c Merge pull request #378 from Danile71/2019
Fix error (libpng-0)
2020-02-06 19:38:41 +03:00
Daniel f73852ea3d Fix error (libpng-0) 2020-02-06 16:07:14 +03:00
Alexey Suhov b0c5accaf8 fixed link to Intel models and model downloader 2019-11-15 13:55:44 +03:00
Alexey Suhov 733dae46cc lower minimal cmake version to 3.5 2019-11-06 17:42:34 +03:00
Alexey Suhov fe3f978b98 Merge pull request #309 from asuhov/2019-r31
Publishing 2019 R3.1 content
2019-10-28 21:34:43 +03:00
Alexey Suhov 6dfc778940 Publishing 2019 R3.1 content 2019-10-28 21:25:18 +03:00
Alexey Suhov 1798ac0d26 turned off cpplint by default 2019-10-24 17:39:17 +03:00
Dmitry Kurtaev 298900790c Do not build CMake from source 2019-10-22 10:32:43 +03:00
55 changed files with 1071 additions and 203 deletions
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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.
+3 -3
View File
@@ -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]+).*")
+3 -3
View File
@@ -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 {
/**
+13 -2
View File
@@ -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 {
/**
+1 -1
View File
@@ -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 {
//
+2 -2
View File
@@ -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
-1
View File
@@ -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}))
}
+1 -5
View File
@@ -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()])
+30 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,3 +1,3 @@
networkx>=1.11
networkx>=1.11,<2.4
numpy==1.13.0
defusedxml>=0.5.0
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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)