[Enhancement] build sdk python api in standard-alone manner (#810)
* build sdk python api in standard-alone manner * enable MMDEPLOY_BUILD_SDK_MONOLITHIC and MMDEPLOY_BUILD_EXAMPLES in prebuild config * link mmdeploy to python target when monolithic option is on * checkin README to describe precompiled package build procedure * use packaging.version.parse(python_version) instead of list(python_version) * fix according to review results * rebase master * rollback cmake.in and apis/python/CMakeLists.txt * reorganize files in install/example * let cmake detect visual studio instead of specifying 2019 * rename whl name of precompiled package * fix according to review resultspull/852/head
parent
1d3ce15e35
commit
a15365e93f
|
@ -13,4 +13,4 @@ make -j$(nproc) && make install
|
|||
cd install/example
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. -DMMDeploy_DIR="$MMDEPLOY_DIR"/build/install/lib/cmake/MMDeploy "${ARGS[@]:2}" && make -j$(nproc)
|
||||
cmake ../cpp -DMMDeploy_DIR="$MMDEPLOY_DIR"/build/install/lib/cmake/MMDeploy "${ARGS[@]:2}" && make -j$(nproc)
|
||||
|
|
|
@ -225,7 +225,7 @@ jobs:
|
|||
cd install/example
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cd build
|
||||
cmake .. -G "Visual Studio 16 2019" -A x64 -T v142 `
|
||||
cmake ../cpp -G "Visual Studio 16 2019" -A x64 -T v142 `
|
||||
-DMMDeploy_DIR="$env:MMDEPLOY_DIR/build/install/lib/cmake/MMDeploy" `
|
||||
-DOpenCV_DIR="$env:OPENCV_PACKAGE_DIR"
|
||||
cmake --build . --config Release -- /m
|
||||
|
|
|
@ -52,7 +52,7 @@ jobs:
|
|||
make install
|
||||
pushd install/example
|
||||
mkdir build && pushd build
|
||||
cmake .. -DMMDeploy_DIR=${PWD}/../../lib/cmake/MMDeploy
|
||||
cmake ../cpp -DMMDeploy_DIR=${PWD}/../../lib/cmake/MMDeploy
|
||||
make -j2
|
||||
ls ./*
|
||||
popd
|
||||
|
|
|
@ -166,8 +166,6 @@ if (MMDEPLOY_BUILD_SDK)
|
|||
DESTINATION lib/cmake/MMDeploy
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/demo/csrc/ DESTINATION example)
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.17.0")
|
||||
install(SCRIPT cmake/post-install.cmake)
|
||||
endif ()
|
||||
|
|
|
@ -16,7 +16,7 @@ set(MMDEPLOY_VERSION_MAJOR @MMDEPLOY_VERSION_MAJOR@)
|
|||
set(MMDEPLOY_VERSION_MINOR @MMDEPLOY_VERSION_MINOR@)
|
||||
set(MMDEPLOY_VERSION_PATCH @MMDEPLOY_VERSION_PATCH@)
|
||||
|
||||
if (NOT MMDEPLOY_BUILD_SHARED AND NOT MMDEPLOY_BUILD_SDK_MONOLITHIC)
|
||||
if (NOT MMDEPLOY_BUILD_SHARED)
|
||||
if ("cuda" IN_LIST MMDEPLOY_TARGET_DEVICES)
|
||||
find_package(CUDA REQUIRED)
|
||||
if(MSVC)
|
||||
|
|
|
@ -55,6 +55,12 @@ foreach (TASK ${TASK_LIST})
|
|||
DESTINATION include/mmdeploy)
|
||||
endforeach ()
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/demo/csrc/ DESTINATION example/cpp
|
||||
FILES_MATCHING
|
||||
PATTERN "*.cpp"
|
||||
PATTERN "CMakeLists.txt"
|
||||
)
|
||||
|
||||
if (MMDEPLOY_BUILD_SDK_CSHARP_API OR MMDEPLOY_BUILD_SDK_MONOLITHIC)
|
||||
add_library(mmdeploy SHARED)
|
||||
mmdeploy_load_static(mmdeploy MMDeployStaticModules)
|
||||
|
|
|
@ -21,4 +21,8 @@ if (MMDEPLOY_BUILD_SDK_CXX_API)
|
|||
mmdeploy_export(${PROJECT_NAME})
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mmdeploy/common.hpp
|
||||
DESTINATION include/mmdeploy)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/demo/csrc/ DESTINATION example/cpp
|
||||
FILES_MATCHING
|
||||
PATTERN "*.cxx"
|
||||
)
|
||||
endif ()
|
||||
|
|
|
@ -21,6 +21,7 @@ endforeach ()
|
|||
|
||||
pybind11_add_module(${PROJECT_NAME} ${MMDEPLOY_PYTHON_SRCS})
|
||||
|
||||
|
||||
mmdeploy_load_static(${PROJECT_NAME} MMDeployStaticModules)
|
||||
mmdeploy_load_dynamic(${PROJECT_NAME} MMDeployDynamicModules)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE MMDeployLibs)
|
||||
|
@ -28,3 +29,4 @@ target_link_libraries(${PROJECT_NAME} PRIVATE MMDeployLibs)
|
|||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/demo/python/ DESTINATION example/python)
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# Precompiled package
|
||||
|
||||
This document is going to describe the way to build MMDeploy package.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Download and install Miniconda from the [official website](https://docs.conda.io/en/latest/miniconda.html).
|
||||
|
||||
- Create conda environments for python 3.6, 3.7, 3.8 and 3.9, respectively.
|
||||
|
||||
```shell
|
||||
for PYTHON_VERSION in 3.6 3.7 3.8 3.9
|
||||
do
|
||||
conda create --name mmdeploy-$PYTHON_VERSION python=$PYTHON_VERSION -y
|
||||
done
|
||||
```
|
||||
|
||||
- Prepare MMDeploy dependencies
|
||||
|
||||
Please follow the [build-on-Linux guide](../../docs/en/01-how-to-build/linux-x86_64.md) or [build-on-Windows guide](../../docs/en/01-how-to-build/linux-x86_64.md) to install dependencies of MMDeploy,
|
||||
including PyTorch, MMCV, OpenCV, ppl.cv, ONNX Runtime and TensorRT.
|
||||
|
||||
Make sure the environment variables `pplcv_DIR`, `ONNXRUNTIME_DIR`, `TENSORRT_DIR`, `CUDNN_DIR` and `CUDA_TOOLKIT_ROOT_DIR` are exported.
|
||||
|
||||
## Run precompiled command
|
||||
|
||||
- On Linux platform,
|
||||
|
||||
```shell
|
||||
conda activate mmdeploy-3.6
|
||||
pip install pyyaml
|
||||
cd the/root/path/of/mmdeploy
|
||||
python tools/package_tools/mmdeploy_builder.py tools/package_tools/configs/linux_x64.yaml .
|
||||
```
|
||||
|
||||
You will get the precompiled packages `mmdeploy-{version}-linux-x86_64-cuda11.1-tensorrt8.2.3.0` and `mmdeploy-{version}-linux-x86_64-onnxruntime1.8.1` in the current directory if everything's going well.
|
||||
|
||||
- On Windows platform, open `Anaconda Powershell Prompt` from the start menu and execute:
|
||||
|
||||
```shell
|
||||
conda activate mmdeploy-3.6
|
||||
pip install pyyaml
|
||||
cd the/root/path/of/MMDeploy
|
||||
python tools/package_tools/mmdeploy_builder.py tools/package_tools/configs/windows_x64.yaml .
|
||||
```
|
||||
|
||||
When the build procedure finishes successfully, you will find `mmdeploy-{version}-windows-amd64-cuda11.1-tensorrt8.2.3.0` and `mmdeploy-{version}-windows-amd64-onnxruntime1.8.1` precompiled packages in the current directory.
|
|
@ -2,7 +2,11 @@ global_config:
|
|||
cmake_envs:
|
||||
CMAKE_CXX_COMPILER: "g++-7"
|
||||
MMDEPLOY_BUILD_SDK: "ON"
|
||||
MMDEPLOY_BUILD_SDK_PYTHON_API: "ON"
|
||||
MMDEPLOY_BUILD_SDK_MONOLITHIC: "ON"
|
||||
MMDEPLOY_BUILD_SDK_CXX_API: "ON"
|
||||
MMDEPLOY_BUILD_EXAMPLES: "ON"
|
||||
MMDEPLOY_SHARED_LIBS: "OFF"
|
||||
OpenCV_DIR: "${OpenCV_DIR}"
|
||||
|
||||
local_configs:
|
||||
- BUILD_NAME: "mmdeploy-{mmdeploy_v}-{system}-{machine}-onnxruntime{ort_v}"
|
||||
|
@ -15,6 +19,6 @@ local_configs:
|
|||
MMDEPLOY_TARGET_DEVICES: '"cuda"'
|
||||
MMDEPLOY_TARGET_BACKENDS: "trt"
|
||||
TENSORRT_DIR: "${TENSORRT_DIR}"
|
||||
CUDA_TOOLKIT_ROOT_DIR: "/usr/local/cuda-11.3"
|
||||
CUDA_TOOLKIT_ROOT_DIR: "${CUDA_TOOLKIT_ROOT_DIR}"
|
||||
CUDNN_DIR: "${CUDNN_DIR}"
|
||||
pplcv_DIR: ${pplcv_DIR}/cuda-build/install/lib/cmake/ppl
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
global_config:
|
||||
cmake_flags: ['-G "Visual Studio 16 2019" -A x64 -T v142']
|
||||
cmake_flags: ['-A x64 -T v142']
|
||||
cmake_envs:
|
||||
MMDEPLOY_BUILD_SDK: "ON"
|
||||
MMDEPLOY_BUILD_SDK_PYTHON_API: "ON"
|
||||
MMDEPLOY_BUILD_SDK_MONOLITHIC: "ON"
|
||||
MMDEPLOY_BUILD_SDK_CXX_API: "ON"
|
||||
MMDEPLOY_BUILD_EXAMPLES: "ON"
|
||||
MMDEPLOY_SHARED_LIBS: "OFF"
|
||||
MMDEPLOY_CODEBASES: "all"
|
||||
OpenCV_DIR: "%OpenCV_DIR%"
|
||||
spdlog_DIR: '"%spdlog_DIR%"'
|
||||
|
||||
local_configs:
|
||||
- BUILD_NAME: "mmdeploy-{mmdeploy_v}-{system}-{machine}-onnxruntime{ort_v}"
|
||||
|
|
|
@ -15,6 +15,7 @@ from subprocess import CalledProcessError, check_output, run
|
|||
from typing import Dict
|
||||
|
||||
import yaml
|
||||
from packaging import version
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.INFO)
|
||||
|
@ -94,8 +95,8 @@ def _create_bdist_cmd(cfg, c_ext=False, dist_dir=None):
|
|||
bdist_cmd += f' --plat-name {PLATFORM_TAG} '
|
||||
|
||||
# python tag
|
||||
py_flag = 'cp' if c_ext else 'py'
|
||||
python_tag = f'{py_flag}{sys.version_info.major}{sys.version_info.minor}'
|
||||
python_tag = f'cp{sys.version_info.major}{sys.version_info.minor}'\
|
||||
if c_ext else 'py3'
|
||||
if 'python_tag' in bdist_tags:
|
||||
python_tag = bdist_tags['python_tag']
|
||||
bdist_cmd += f' --python-tag {python_tag} '
|
||||
|
@ -173,6 +174,41 @@ def build_mmdeploy(cfg, mmdeploy_dir, dist_dir=None):
|
|||
_call_command(bdist_cmd, mmdeploy_dir)
|
||||
|
||||
|
||||
def build_mmdeploy_python(python_executable, cfg, mmdeploy_dir):
|
||||
cmake_flags = cfg.get('cmake_flags', [])
|
||||
cmake_envs = cfg.get('cmake_envs', dict())
|
||||
|
||||
args = [f'-D{k}={v}' for k, v in cmake_envs.items()]
|
||||
args.append(
|
||||
f'-DMMDeploy_DIR={mmdeploy_dir}/build/install/lib/cmake/MMDeploy')
|
||||
args.append(f'-DPYTHON_EXECUTABLE={python_executable}')
|
||||
|
||||
if sys.platform == 'win32':
|
||||
build_cmd = 'cmake --build . --config Release -- /m'
|
||||
pass
|
||||
else:
|
||||
build_cmd = 'cmake --build . -- -j$(nproc)'
|
||||
cmake_cmd = ' '.join(['cmake ../csrc/mmdeploy/apis/python'] + cmake_flags +
|
||||
args)
|
||||
|
||||
build_dir = osp.join(mmdeploy_dir, 'build_python')
|
||||
_remove_if_exist(build_dir)
|
||||
os.mkdir(build_dir)
|
||||
|
||||
_call_command(cmake_cmd, build_dir)
|
||||
_call_command(build_cmd, build_dir)
|
||||
|
||||
python_api_lib_path = []
|
||||
lib_patterns = ['*mmdeploy_python*.so', '*mmdeploy_python*.pyd']
|
||||
for pattern in lib_patterns:
|
||||
python_api_lib_path.extend(
|
||||
glob(
|
||||
osp.join(mmdeploy_dir, 'build_python/**', pattern),
|
||||
recursive=True,
|
||||
))
|
||||
return python_api_lib_path[0]
|
||||
|
||||
|
||||
def get_dir_name(cfg, tag, default_name):
|
||||
if tag not in cfg:
|
||||
logging.warning(f'{tag} not found, use `{default_name}` as default.')
|
||||
|
@ -197,8 +233,8 @@ def check_env(cfg: Dict):
|
|||
|
||||
CUDA_TOOLKIT_ROOT_DIR = cmake_envs.get('CUDA_TOOLKIT_ROOT_DIR', '')
|
||||
CUDA_TOOLKIT_ROOT_DIR = osp.expandvars(CUDA_TOOLKIT_ROOT_DIR)
|
||||
nvcc_cmd = 'nvcc' if len(CUDA_TOOLKIT_ROOT_DIR) <= 0 else osp.join(
|
||||
CUDA_TOOLKIT_ROOT_DIR, 'bin', 'nvcc')
|
||||
nvcc_cmd = ('nvcc' if len(CUDA_TOOLKIT_ROOT_DIR) <= 0 else osp.join(
|
||||
CUDA_TOOLKIT_ROOT_DIR, 'bin', 'nvcc'))
|
||||
|
||||
try:
|
||||
nvcc = check_output(f'"{nvcc_cmd}" -V', shell=True)
|
||||
|
@ -242,10 +278,9 @@ def check_env(cfg: Dict):
|
|||
patch = re.search(r'#define NV_TENSORRT_PATCH (\d+)', data)
|
||||
build = re.search(r'#define NV_TENSORRT_BUILD (\d+)', data)
|
||||
if major is not None and minor is not None and patch is not None:
|
||||
tensorrt_version = f'{major.group(1)}.' +\
|
||||
f'{minor.group(1)}.' +\
|
||||
f'{patch.group(1)}.' +\
|
||||
f'{build.group(1)}'
|
||||
tensorrt_version = (f'{major.group(1)}.' +
|
||||
f'{minor.group(1)}.' +
|
||||
f'{patch.group(1)}.' + f'{build.group(1)}')
|
||||
|
||||
env_info['trt_v'] = tensorrt_version
|
||||
|
||||
|
@ -259,7 +294,7 @@ def create_package(cfg: Dict, mmdeploy_dir: str):
|
|||
# load flags
|
||||
cfg, build_dir = get_dir_name(cfg, 'BUILD_NAME', build_dir)
|
||||
cmake_envs = cfg.get('cmake_envs', dict())
|
||||
build_sdk_flag = cmake_envs.get('MMDEPLOY_BUILD_SDK', False)
|
||||
build_sdk_flag = cmake_envs.get('MMDEPLOY_BUILD_SDK', 'OFF')
|
||||
if 'TAR_NAME' in cfg:
|
||||
cfg, sdk_tar_name = get_dir_name(cfg, 'TAR_NAME', sdk_tar_name)
|
||||
|
||||
|
@ -283,42 +318,54 @@ def create_package(cfg: Dict, mmdeploy_dir: str):
|
|||
dist_dir = osp.join(build_dir, 'dist')
|
||||
build_mmdeploy(cfg, mmdeploy_dir, dist_dir=dist_dir)
|
||||
|
||||
if build_sdk_flag:
|
||||
if build_sdk_flag == 'ON':
|
||||
|
||||
sdk_tar_dir = osp.join(build_dir, sdk_tar_name)
|
||||
|
||||
# copy lib and install into sdk dir
|
||||
install_dir = osp.join(mmdeploy_dir, 'build/install/')
|
||||
_copy(install_dir, sdk_tar_dir)
|
||||
_copy(f'{mmdeploy_dir}/demo/python',
|
||||
f'{sdk_tar_dir}/example/python')
|
||||
_remove_if_exist(osp.join(sdk_tar_dir, 'example', 'build'))
|
||||
|
||||
# create sdk python api wheel
|
||||
# for linux
|
||||
python_api_lib_path = glob(
|
||||
osp.join(mmdeploy_dir, 'build/lib/mmdeploy_python.*.so'))
|
||||
# for windows
|
||||
python_api_lib_path += glob(
|
||||
osp.join(mmdeploy_dir, 'build/bin/*/mmdeploy_python.*.pyd'))
|
||||
num_libs = len(python_api_lib_path)
|
||||
if num_libs != 1:
|
||||
logging.info('find multiple mmdeploy_python libraries.')
|
||||
python_api_lib_path = python_api_lib_path[0]
|
||||
# build SDK Python API according to different python version
|
||||
for python_version in ['3.6', '3.7', '3.8', '3.9']:
|
||||
_version = version.parse(python_version)
|
||||
python_major, python_minor = _version.major, _version.minor
|
||||
|
||||
sdk_python_package_dir = osp.join(build_dir, '.mmdeploy_python')
|
||||
_copy(PACKAGING_DIR, sdk_python_package_dir)
|
||||
_copy(
|
||||
osp.join(mmdeploy_dir, 'mmdeploy', 'version.py'),
|
||||
osp.join(sdk_python_package_dir, 'mmdeploy_python',
|
||||
'version.py'))
|
||||
_copy(python_api_lib_path,
|
||||
osp.join(sdk_python_package_dir, 'mmdeploy_python'))
|
||||
sdk_wheel_dir = osp.abspath(osp.join(sdk_tar_dir, 'python'))
|
||||
bdist_cmd = _create_bdist_cmd(
|
||||
cfg, c_ext=True, dist_dir=sdk_wheel_dir)
|
||||
_call_command(bdist_cmd, sdk_python_package_dir)
|
||||
# create sdk python api wheel
|
||||
sdk_python_package_dir = osp.join(build_dir,
|
||||
'.mmdeploy_python')
|
||||
_copy(PACKAGING_DIR, sdk_python_package_dir)
|
||||
_copy(
|
||||
osp.join(mmdeploy_dir, 'mmdeploy', 'version.py'),
|
||||
osp.join(sdk_python_package_dir, 'mmdeploy_python',
|
||||
'version.py'),
|
||||
)
|
||||
|
||||
# remove temp package dir
|
||||
_remove_if_exist(sdk_python_package_dir)
|
||||
# build mmdeploy sdk python api
|
||||
python_executable = shutil.which('python')\
|
||||
.replace('mmdeploy-3.6', f'mmdeploy-{python_version}')
|
||||
python_api_lib_path = build_mmdeploy_python(
|
||||
python_executable, cfg, mmdeploy_dir)
|
||||
_copy(
|
||||
python_api_lib_path,
|
||||
osp.join(sdk_python_package_dir, 'mmdeploy_python'),
|
||||
)
|
||||
_remove_if_exist(osp.join(mmdeploy_dir, 'build_python'))
|
||||
|
||||
sdk_wheel_dir = osp.abspath(osp.join(sdk_tar_dir, 'python'))
|
||||
|
||||
bdist_cmd = (f'{python_executable} '
|
||||
f'setup.py bdist_wheel --plat-name '
|
||||
f'{PLATFORM_TAG} --python-tag '
|
||||
f'cp{python_major}{python_minor} '
|
||||
f'--dist-dir {sdk_wheel_dir}')
|
||||
_call_command(bdist_cmd, sdk_python_package_dir)
|
||||
|
||||
# remove temp package dir
|
||||
_remove_if_exist(sdk_python_package_dir)
|
||||
|
||||
logging.info('build finish.')
|
||||
|
||||
|
|
Loading…
Reference in New Issue