Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] build sdk python api in standalone manner #810

Merged
merged 12 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/scripts/linux/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion .circleci/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/backend-snpe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
Expand Down
2 changes: 1 addition & 1 deletion cmake/MMDeployConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions csrc/mmdeploy/apis/c/mmdeploy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions csrc/mmdeploy/apis/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
2 changes: 2 additions & 0 deletions csrc/mmdeploy/apis/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ 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)

target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR})
install(DIRECTORY ${CMAKE_SOURCE_DIR}/demo/python/ DESTINATION example/python)
47 changes: 47 additions & 0 deletions tools/package_tools/README.md
Original file line number Diff line number Diff line change
@@ -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.
8 changes: 6 additions & 2 deletions tools/package_tools/configs/linux_x64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -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
8 changes: 5 additions & 3 deletions tools/package_tools/configs/windows_x64.yaml
Original file line number Diff line number Diff line change
@@ -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}"
Expand Down
121 changes: 84 additions & 37 deletions tools/package_tools/mmdeploy_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Dict

import yaml
from packaging import version

logger = logging.getLogger()
logger.setLevel(logging.INFO)
Expand Down Expand Up @@ -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} '
Expand Down Expand Up @@ -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())

lvhan028 marked this conversation as resolved.
Show resolved Hide resolved
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'
lvhan028 marked this conversation as resolved.
Show resolved Hide resolved
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.')
Expand All @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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)

Expand All @@ -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]

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)

# remove temp package dir
_remove_if_exist(sdk_python_package_dir)
# 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

# 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'),
)

# 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.')

Expand Down