[Feature] Dynamically load net module to remove dependencies of mmdeploy.so (#1776) (#1822)

* dynamic load net module

* export xxx_net

* add runpath

* link dl

* remove -ldl for macos

* fix rpath

* module -> shared

* set MMDEPLOY_DYNAMIC_BACKEND OFF when MMDEPLOY_BUILD_SDK_MONOLITHIC is OFF
pull/1855/head
Chen Xin 2023-03-03 11:48:59 +08:00 committed by GitHub
parent 7de413a19c
commit d95950d705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 77 additions and 12 deletions

View File

@ -24,6 +24,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# options
option(MMDEPLOY_SHARED_LIBS "build shared libs" OFF)
option(MMDEPLOY_BUILD_SDK "build MMDeploy SDK" OFF)
option(MMDEPLOY_DYNAMIC_BACKEND "dynamic load backend" OFF)
option(MMDEPLOY_BUILD_SDK_MONOLITHIC "build single lib for SDK API" ON)
option(MMDEPLOY_BUILD_TEST "build unittests" OFF)
option(MMDEPLOY_BUILD_SDK_PYTHON_API "build SDK Python API" OFF)
@ -39,6 +40,10 @@ set(MMDEPLOY_TARGET_DEVICES "cpu" CACHE STRING "target devices to support")
set(MMDEPLOY_TARGET_BACKENDS "" CACHE STRING "target inference engines to support")
set(MMDEPLOY_CODEBASES "all" CACHE STRING "select OpenMMLab codebases")
if ((NOT MMDEPLOY_BUILD_SDK_MONOLITHIC) AND MMDEPLOY_DYNAMIC_BACKEND)
set(MMDEPLOY_DYNAMIC_BACKEND OFF)
endif ()
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "choose 'Release' as default build type" FORCE)
endif ()

View File

@ -12,6 +12,15 @@ function (mmdeploy_export NAME)
RUNTIME DESTINATION bin)
endfunction ()
macro(mmdeploy_add_net NAME)
if (MMDEPLOY_DYNAMIC_BACKEND)
mmdeploy_add_library(${NAME} SHARED ${ARGN})
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy)
set(BACKEND_LIB_NAMES ${BACKEND_LIB_NAMES} ${PROJECT_NAME} PARENT_SCOPE)
else ()
mmdeploy_add_module(${NAME} ${ARGN})
endif ()
endmacro()
function (mmdeploy_add_library NAME)
# EXCLUDE: exclude from registering & exporting

View File

@ -1,15 +1,37 @@
// Copyright (c) OpenMMLab. All rights reserved.
#include <Windows.h>
#include <string>
#include <cstdio>
#ifdef _WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
#ifdef _WIN32
#define LIBPREFIX ""
#define LIBSUFFIX ".dll"
#elif defined(__APPLE__)
#define LIBPREFIX "lib"
#define LIBSUFFIX ".dylib"
#else
#define LIBPREFIX "lib"
#define LIBSUFFIX ".so"
#endif
namespace mmdeploy {
namespace {
void* mmdeploy_load_library(const char* name) {
fprintf(stderr, "loading %s ...\n", name);
auto handle = LoadLibraryA(name);
#ifdef _WIN32
auto handle = LoadLibraryExA(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
#else
auto handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
#endif
if (!handle) {
fprintf(stderr, "failed to load library %s\n", name);
return nullptr;
@ -26,7 +48,8 @@ class Loader {
@_MMDEPLOY_DYNAMIC_MODULES@
};
for (const auto name : modules) {
mmdeploy_load_library(name);
std::string libname = std::string{} + LIBPREFIX + name + LIBSUFFIX;
mmdeploy_load_library(libname.c_str());
}
}
};

View File

@ -80,5 +80,14 @@ if (MMDEPLOY_BUILD_SDK_CSHARP_API OR MMDEPLOY_BUILD_SDK_MONOLITHIC)
set_target_properties(mmdeploy PROPERTIES
VERSION ${MMDEPLOY_VERSION}
SOVERSION ${MMDEPLOY_VERSION_MAJOR})
if (APPLE)
set_target_properties(mmdeploy PROPERTIES
INSTALL_RPATH "@loader_path"
BUILD_RPATH "@loader_path")
else ()
set_target_properties(mmdeploy PROPERTIES
INSTALL_RPATH "\$ORIGIN"
BUILD_RPATH "\$ORIGIN")
endif ()
mmdeploy_export(mmdeploy)
endif ()

View File

@ -2,6 +2,8 @@
project(mmdeploy_net_module)
set(BACKEND_LIB_NAMES)
if ("trt" IN_LIST MMDEPLOY_TARGET_BACKENDS)
add_subdirectory(trt)
endif ()
@ -46,5 +48,22 @@ if ("rknn" IN_LIST MMDEPLOY_TARGET_BACKENDS)
add_subdirectory(rknn)
endif ()
mmdeploy_add_module(${PROJECT_NAME} net_module.cpp)
if (MMDEPLOY_DYNAMIC_BACKEND)
set(_MODULE_STR ${BACKEND_LIB_NAMES})
list(TRANSFORM _MODULE_STR REPLACE "(.+)" "\"\\1\"")
string(JOIN ",\n " _MODULE_STR ${_MODULE_STR})
set(_MMDEPLOY_DYNAMIC_MODULES ${_MODULE_STR})
set(_LOADER_NAME net_loader)
set(_LOADER_PATH ${${PROJECT_NAME}_BINARY_DIR}/${_LOADER_NAME}.cpp)
configure_file(
${CMAKE_SOURCE_DIR}/cmake/loader.cpp.in
${_LOADER_PATH})
if (NOT (WIN32 OR APPLE))
SET(_DL_LIB dl)
endif ()
endif ()
mmdeploy_add_module(${PROJECT_NAME} net_module.cpp ${_LOADER_PATH})
target_link_libraries(${PROJECT_NAME} PUBLIC ${_DL_LIB})
add_library(mmdeploy::net_module ALIAS ${PROJECT_NAME})

View File

@ -5,7 +5,7 @@ project(mmdeploy_coreml_net)
if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
find_library(CORE_ML CoreML)
find_library(FOUNDATION Foundation)
mmdeploy_add_module(${PROJECT_NAME} coreml_net.mm)
mmdeploy_add_net(${PROJECT_NAME} coreml_net.mm)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${CORE_ML} ${FOUNDATION})
add_library(mmdeploy::coreml_net ALIAS ${PROJECT_NAME})

View File

@ -6,7 +6,7 @@ if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
find_package(ncnn REQUIRED)
mmdeploy_add_module(${PROJECT_NAME} ncnn_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} ncnn_net.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_ncnn_ops_obj)
target_link_libraries(${PROJECT_NAME} PRIVATE ncnn)
add_library(mmdeploy::ncnn_net ALIAS ${PROJECT_NAME})

View File

@ -5,7 +5,7 @@ project(mmdeploy_openvino_net)
if ("cpu" IN_LIST MMDEPLOY_TARGET_DEVICES)
find_package(InferenceEngine REQUIRED)
mmdeploy_add_module(${PROJECT_NAME} openvino_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} openvino_net.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE
${InferenceEngine_LIBRARIES})
add_library(mmdeploy::openvino_net ALIAS ${PROJECT_NAME})

View File

@ -4,7 +4,7 @@ project(mmdeploy_ort_net)
include(${CMAKE_SOURCE_DIR}/cmake/modules/FindONNXRUNTIME.cmake)
mmdeploy_add_module(${PROJECT_NAME} ort_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} ort_net.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE ${ONNXRUNTIME_DIR}/include)
target_link_libraries(${PROJECT_NAME} PRIVATE mmdeploy_onnxruntime_ops_obj)
target_link_libraries(${PROJECT_NAME} PUBLIC onnxruntime)

View File

@ -8,7 +8,7 @@ if (MMDEPLOY_TORCHSCRIPT_SDK_BACKEND)
find_package(Torch REQUIRED)
find_package(TorchVision QUIET)
mmdeploy_add_module(${PROJECT_NAME} torch_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} torch_net.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE
${TORCH_LIBRARIES})

View File

@ -4,7 +4,7 @@ project(mmdeploy_trt_net)
include(${CMAKE_SOURCE_DIR}/cmake/tensorrt.cmake)
mmdeploy_add_module(${PROJECT_NAME} trt_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} trt_net.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE
${TENSORRT_INCLUDE_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${CUDNN_DIR}/include)

View File

@ -4,7 +4,7 @@ project(mmdeploy_tvm_net)
include(${CMAKE_SOURCE_DIR}/cmake/modules/FindTVM.cmake)
mmdeploy_add_module(${PROJECT_NAME} tvm_net.cpp)
mmdeploy_add_net(${PROJECT_NAME} tvm_net.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE ${TVM_INCLUDE_DIR} ${DLPACK_INCLUDE_DIR} ${DMLC_CORE_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE tvm_runtime mmdeploy_dlpack_utils)