Inference engine as a static library#3219
Inference engine as a static library#3219emmanuelattia wants to merge 24 commits intoopenvinotoolkit:masterfrom
Conversation
Removed dllimport when is not appropriate
|
|
||
| if (NOT BUILD_SHARED_LIBS) | ||
| target_compile_definitions(${TARGET_NAME}_obj PRIVATE NGRAPH_STATIC_LIBRARY) | ||
| endif() |
There was a problem hiding this comment.
maybe we can add $<TARGET_PROPERTY:ngraph,INTERFACE_INCLUDE_DIRECTORIES> to target_include_directories above?
There was a problem hiding this comment.
Will that add the compile definition ?
By the way i was thinking about renaming NGRAPH_STATIC_LIBRARY to USE_STATIC_NGRAPH
| list(APPEND PLUGIN_FILES "${IE_PLUGIN_DEVICE_NAME}:${IE_PLUGIN_NAME}") | ||
| list(REMOVE_DUPLICATES PLUGIN_FILES) | ||
| set(PLUGIN_FILES "${PLUGIN_FILES}" CACHE INTERNAL "" FORCE) | ||
| if (BUILD_SHARED_LIBS) |
There was a problem hiding this comment.
maybe we call leave this as is, but don't call ie_register_plugins?
There was a problem hiding this comment.
I think we can use plugins passed to ie_register_plugins to create a map of function pointers to plugin's CreatePluginEngine_xxx functions..
But it can be done in a separate PR, right? or you are going to add more changes to this PR?
There was a problem hiding this comment.
I intend to add more change to this PR (see above description)
|
When I compiled with I except different error.. |
I guess it's because ngraph is linked statically and unit test are implemented as global variable initializers, the unit test relies on the fact that ngraph global variables (here ngraph::element::f32) being initialized before convolution_transformation.cpp:testValues which is not guaranteed since they are all part of the same executable in the end. That could be easily fixed by replacing global testValues by a static getTestValues() that returns a static variable (and enforce its initialization just at the instantiation) but i'm afraid this kind of global initialization order issue might appear somewhere else |
…se they might depend on other global variables and, if link statically, there is no guarantee in the initialization order.
|
Last commit should fix the unit test crash in ieFuncTests @ilya-lavrenov, it's not fully validated yet of course because some of them need the readers. |
Looks like you right. @ilyachur it's not a good to have such global variables inside ngraph.. Don't know whether we can remove them or convert to enum.. |
I agree that we should avoid global variables. I created a PR #3279 which should fix this behaviour. |
|
PR with deprecation of nGraph global variables was merged to the master branch. |
Should I proceed by replacing test initializations by functions instead of global variable initializations or should i change all tests to avoid using global variable. |
I suppose no changes in tests are needed since the issue with global variables had to have gone. |
Unless i'm mistaken, tests in ieFuncTests still reference deprecated global variables. LayerTransformation::createParamsU8I8(),
// ActualValues
{
ngraph::element::u8,
{{element::f32}, {}, { {0.02f}, element::f32 }},
op::Constant::create(ngraph::element::f32, ngraph::Shape{}, std::vector<float>{ 2.f }),
{ 255ul, Shape({ 1, 1, 1, 1 }), { 0.f }, { 254.f }, { -1.27f }, { 1.27f } }
}, |
In this case we need to remove their usage with proposed alternatives. CC @ilyachur |
|
I created another PR #3463 where I tried to remove extern global element types. |
|
Another major issue is that when i try to link statically inference_engine_ir_reader, inference_engine_ir_v7_reader with inference_engine they are many duplicated symbols, for instance:
They are also duplicated symbols between inference_engine_ir_reader and inference_engine_legacy Should I move each ir_reader in its own unique namespace ? (instead of namespace InferenceEngine) |
|
@emmanuelattia-philips will it help if we change: size_t GetIRVersion(std::istream& model);to ? |
Basically it concerns every symbols of the reader, not just frunction but also class members |
|
Ok, in this case we can compile using different namespaces as you suggested |
…sion when statically linking everything together Readers can be linked statically
Ok just pushed these (quite big) modifications, next step are the DNN plugins. |
…into ie_static_lib
* Each plugin has a uniquely named factory * Each plugin is referenced by ie_core in static mode (even if no plugins.xml), there is still support for additional definitions in plugins.xml * New macro : - INTERENCE_PLUGIN_API now is extern "C" only when extensions are not statically linked - INFERENCE_PLUGIN_STATIC_API is always extern "C" - IE_DEFINE_PLUGIN_CREATE_FUNCTION_EX allow to specify a unique name for the factory activated only when USE_STATIC_IE_EXTENSIONS is defined otherwise behaves like IE_DEFINE_PLUGIN_CREATE_FUNCTION * Some refactoring of the code in ie_so_pointer.hpp to be able to create a shared_ptr directly from a factory function with the same code as creating a shared_ptr from a dynamic object/library symbol.
|
Now i'm stuck with MKLDNNPlugin because registration of the node rely on static global variables (see mkldnn_node.h) And since these variables are not referenced, they are not linked statically and node are not registered. |
Allows whole_archive cmake macros to specify visibility When linking statically, using whole_archive to include MKLDNNPlugin so global variables that does registration of the nodes are included in the final executable
…ic factory and whole archive flag to force initialization (like in mkldnn) - static inference plugin now take into account parameters in plugins.xml, static factory is used only if plugin is not present or library name is empty or invalid.
…ATIC/SHARED - fixed ie_core when SHARED mode
…into ie_static_lib
| file(GLOB_RECURSE SRC *.cpp) | ||
|
|
||
| add_library(${TARGET_NAME} SHARED ${SRC}) | ||
| add_library(${TARGET_NAME} ${SRC}) |
There was a problem hiding this comment.
if we remove SHARED from here and users take this code as a template for their standalone extensions, it will be built as a static library. Can we either keep SHARED here or add something like:
if((NOT DEFINED BUILD_SHARED_LIBS) OR BUILD_SHARED_LIBS)
set(LIBRARY_TYPE SHARED)
else()
set(LIBRARY_TYPE STATIC)
endif()
add_library(${TARGET_NAME} ${LIBRARY_TYPE} ${SRC})There was a problem hiding this comment.
Should be fixed
|
|
||
| if (NOT BUILD_SHARED_LIBS) | ||
| add_definitions(-DUSE_STATIC_IE) | ||
| add_definitions(-DUSE_STATIC_IE_EXTENSIONS) |
There was a problem hiding this comment.
can we rename USE_STATIC_IE_EXTENSIONS to USE_STATIC_IE_PLUGINS?
| * @brief Constructs an object with existing reference | ||
| * @param pointedObj Existing reference to wrap | ||
| */ | ||
| explicit SOPointer(std::shared_ptr<T> pointedObj): _so_loader(), _pointedObj(pointedObj) { |
There was a problem hiding this comment.
we already have a ctor with existing reference, but with raw pointer. Do we need both of them? Can we keep only one? (maybe the one with shared_ptr)
| # define INFERENCE_ENGINE_CDECL __cdecl | ||
| #endif | ||
|
|
||
| #if (!defined(__GNUC__) && defined(USE_STATIC_IE)) || (defined(__GNUC__) && (__GNUC__ < 4)) |
There was a problem hiding this comment.
why do we need !defined(__GNUC__) here? Does not look consistent with other similar places.
There was a problem hiding this comment.
Otherwise i have to add a #ifdef USE_STATIC_LIB inside the #if defined(_WIN32)
inference-engine/include/ie_api.h
Outdated
| * @param type A plugin type | ||
| */ | ||
|
|
||
| #if (__GNUC__ >= 4) // NOLINT |
There was a problem hiding this comment.
I think we need #if (__GNUC__ >= 4) -> #if defined(__GNUC__ ) && (__GNUC__ >= 4)
inference-engine/src/CMakeLists.txt
Outdated
| endif() | ||
|
|
||
| ieTargetLinkWholeArchiveEx(inference_engine PRIVATE HeteroPlugin MultiDevicePlugin) | ||
|
|
There was a problem hiding this comment.
will we have a single inference_engine.a static library with all plugins integrated into it?
There was a problem hiding this comment.
Yes, the objective is to have every plugin inside the static library
ENABLE_CLDNN, ENABLE_MKLDNN etc... allows to make a lighter static library.
There was a problem hiding this comment.
I've tried to build this branch and inference_engine.a contains only IE object files. But plugin object files are not present here..
There was a problem hiding this comment.
Right now i have successfully tested it under Windows (my main OS), looking at linux now...
| namespace InferenceEngine { | ||
| #include "ie_ir_reader_namespace.hpp" | ||
|
|
||
| namespace InferenceEngineIRReader { |
There was a problem hiding this comment.
do we need to change namespace for all the classes / functions inside reader plugin? I suppose we need only ie_ir_reader.cpp, ie_ir_reader.hpp files, is not it?
There was a problem hiding this comment.
I think they are other colliding symbols between inference_engine_ir_reader and inference_engine_ir_v7_reader in the other files.
| namespace InferenceEngine { | ||
| namespace InferenceEngineIRReader { | ||
|
|
||
| INFERENCE_PLUGIN_API(StatusCode) CreateReader(IReader*& reader, ResponseDesc *resp) noexcept; |
There was a problem hiding this comment.
why do we need this declaration inside hpp?
There was a problem hiding this comment.
No, i can remove it
| } | ||
|
|
||
| INFERENCE_PLUGIN_API(StatusCode) InferenceEngine::CreateReader(IReader*& reader, ResponseDesc *resp) noexcept { | ||
| INFERENCE_PLUGIN_API(StatusCode) InferenceEngineONNXReader::CreateReader(IReader*& reader, ResponseDesc *resp) noexcept { |
There was a problem hiding this comment.
@ilyachur looks strange that create function for reader plugins is located inside namespace.
For inference plugin we don't have it. Can we remove namespace for exported CreateReader functions?
There was a problem hiding this comment.
That's a good question, since it's exported as "C", it does reserve the global name "CreateReader" anyways...
There was a problem hiding this comment.
Ok, but not to confuse others I suggesting removing namespace :)
There was a problem hiding this comment.
Do I remove the definition of CreateReader inside the namespace in ie_reader.hpp, it was here before this PR.
If I don't remove it, when i call it internally i have to use explicit global namespace otherwise there is ambiguity at compile time.
|
|
||
| using namespace InferenceEngine; | ||
|
|
||
| INFERENCE_PLUGIN_API(StatusCode) CreateReader(IReader*& reader, ResponseDesc *resp) noexcept; |
There was a problem hiding this comment.
do we need this declaration?
There was a problem hiding this comment.
No i will remove it
| file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) | ||
|
|
||
| # create library | ||
| add_library(${TARGET_NAME} SHARED ${HEADERS} ${SOURCES}) |
There was a problem hiding this comment.
this code is a part of release OpenVINO package where BUILD_SHARED_LIBS is not defined. I think we need to add explicit BUILD_SHARED_LIBS=ON inside https://github.com/openvinotoolkit/openvino/blob/master/inference-engine/samples/CMakeLists.txt which works for both C and C++ samples.
|
I also have: when compiling the |
- template_extension now defaulted to shared - ie_so_pointer: removed raw pointer constructor (implicit cast to shared_ptr is enough) - CreateReader out of namespace
|
This project (static version of OpenVINO) is very interesting for us. Can I help you with this PR? |
Hello, this PR is a littler bit on hgold for holidays. A way to solve the problem of static initialization is to use whole-archive flag for linking, but i haven't tracked yet all the needed changes |
|
If
If we use static version of libraries with --whole-archive and multiply definition flags, is it possible to run the most simple inference? |
…into ie_static_lib
|
Hello everyone, thanks for your work so far, I think this will be a really useful feature! |
Hello, I don't know if i'll be able to pursue this work |
That's unfortunate but thank you anyway for your previous effort! |
|
Static libraries are now enabled in OpenVINO. See https://github.com/openvinotoolkit/openvino/wiki/StaticLibraries |
This PR is currently a draft.
The objective is:
Right now i relied a lot on the already existing flag USE_STATIC_IE (that was used for tests) but maybe it's not a good idea ?
Issue reference: #2675
Mainteners that might be interested: @ilya-lavrenov @ilyachur
Feel free to comment that objectives