Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[2.0] Add cpp-package #20131

Merged
merged 48 commits into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c0c4a0e
MXNet2.0: Add cpp-package
barry-jin Apr 6, 2021
b60808f
add tests
barry-jin Apr 8, 2021
ce056a0
switch to python3
barry-jin Apr 8, 2021
bc62d6b
update OpWrapperGenerator.py
barry-jin Apr 12, 2021
9fab1a9
Merge remote-tracking branch 'upstream/master' into cpp-package
barry-jin Apr 15, 2021
b6a16d9
test: test cpp-package on gpu
barry-jin Apr 15, 2021
0b90b83
test:update ci_test_cpp
barry-jin Apr 16, 2021
b3d121e
add softmaxoutput cuda support
barry-jin Apr 16, 2021
b3075a9
update build
barry-jin Apr 16, 2021
c6a40a2
update symbol
barry-jin Apr 17, 2021
64d1111
Revert "update symbol"
barry-jin Apr 17, 2021
b91d00e
update executor
barry-jin Apr 19, 2021
b12fb9a
update runtime_functions.sh
barry-jin Apr 19, 2021
43dc452
update cpp-package gpu build
barry-jin Apr 20, 2021
ec76a6c
update libcuda.so.1 sym link
barry-jin Apr 21, 2021
2271657
test: linked libraries
barry-jin Apr 22, 2021
1993a48
update
barry-jin Apr 22, 2021
b084c15
export LIBRARY_PATH
barry-jin Apr 22, 2021
fedef00
pack build/cpp-package/examples
barry-jin Apr 22, 2021
730d5eb
link libcuda.so.1
barry-jin Apr 22, 2021
21007f4
update jenkins
barry-jin Apr 22, 2021
e2aaec1
update dockerfile
barry-jin Apr 22, 2021
c06334b
turn on use_nvidia
barry-jin Apr 27, 2021
992d3d6
fix sanity
barry-jin Apr 27, 2021
8e4c0ba
fix build
barry-jin Apr 28, 2021
b1bd450
turn off use_nvidia
barry-jin Apr 29, 2021
64e2d16
update runtime_function.sh
barry-jin Apr 29, 2021
0ba0a4d
fix mlp
barry-jin Apr 29, 2021
7e9256a
fix gradient vanish
barry-jin Apr 30, 2021
f1ff96c
update cpp tests
barry-jin Apr 30, 2021
6540581
add more tests
barry-jin Apr 30, 2021
d055afd
add more tests
barry-jin Apr 30, 2021
cf104e5
turn on MXNET_USE_CPU
barry-jin Apr 30, 2021
ad4c370
fix sentiment inference
barry-jin Apr 30, 2021
887bb5a
fix cpu tests
barry-jin May 3, 2021
65c5d12
Revert "fix cpu tests"
barry-jin May 4, 2021
63fc6ad
update ci test
barry-jin May 4, 2021
1f20a20
update
barry-jin May 4, 2021
c6fc5cb
add back cpp doc
barry-jin May 4, 2021
d09dfec
add cross-compilation instructions
barry-jin May 5, 2021
f8350b3
add multi_threaded_inference_test
barry-jin May 7, 2021
f016683
update test script
barry-jin May 7, 2021
748941f
fix multithreaded docs
barry-jin May 7, 2021
d82e085
Update doc and add cpp-package sanity check
barry-jin May 10, 2021
605e7ac
fix sanity
barry-jin May 10, 2021
e49df4a
update
barry-jin May 10, 2021
6bddda2
update
barry-jin May 13, 2021
e9d8b45
add module api to amp list
barry-jin May 14, 2021
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
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ option(USE_JEMALLOC "Build with Jemalloc support" OFF)
option(USE_LIBJPEG_TURBO "Use libjpeg-turbo" OFF)
option(USE_DIST_KVSTORE "Build with DIST_KVSTORE support" OFF)
option(USE_PLUGINS_WARPCTC "Use WARPCTC Plugins" OFF)
option(USE_CPP_PACKAGE "Build C++ Package" OFF)
option(USE_MXNET_LIB_NAMING "Use MXNet library naming conventions." ON)
option(USE_GPROF "Compile with gprof (profiling) flag" OFF)
option(USE_VTUNE "Enable use of Intel Amplifier XE (VTune)" OFF) # one could set VTUNE_ROOT for search path
Expand Down Expand Up @@ -296,6 +297,10 @@ if(USE_ONEDNN)
set_target_properties(dnnl PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency
endif()

if(USE_CPP_PACKAGE)
add_definitions(-DMXNET_USE_CPP_PACKAGE=1)
endif()

if(USE_INTGEMM)
message(STATUS "Using intgemm")
add_subdirectory(3rdparty/intgemm EXCLUDE_FROM_ALL)
Expand Down Expand Up @@ -960,6 +965,11 @@ if(INSTALL_PYTHON_VERSIONS)
endforeach()
endif()

if(USE_CPP_PACKAGE)
add_subdirectory(cpp-package)
target_compile_definitions(mxnet PUBLIC MXNET_USE_CPP_PACKAGE=1)
endif()

if(NOT CMAKE_BUILD_TYPE STREQUAL "Distribution")
# Staticbuild applies linker version script to hide private symbols, breaking unit tests
add_subdirectory(tests)
Expand Down
16 changes: 15 additions & 1 deletion ci/docker/runtime_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -625,12 +625,16 @@ build_ubuntu_gpu_onednn_nocudnn() {
build_ubuntu_gpu() {
set -ex
cd /work/build
ln -s -f /usr/local/cuda/targets/x86_64-linux/lib/stubs/libcuda.so libcuda.so.1
export LIBRARY_PATH=${LIBRARY_PATH}:/work/build
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/work/build
leezu marked this conversation as resolved.
Show resolved Hide resolved
CC=gcc-7 CXX=g++-7 cmake \
-DCMAKE_BUILD_TYPE="RelWithDebInfo" \
-DUSE_CUDA=ON \
-DUSE_NVML=OFF \
-DMXNET_CUDA_ARCH="$CI_CMAKE_CUDA_ARCH" \
-DUSE_CUDNN=ON \
-DUSE_CPP_PACKAGE=ON \
-DUSE_BLAS=Open \
-DUSE_ONEDNN=OFF \
-DUSE_DIST_KVSTORE=ON \
Expand Down Expand Up @@ -707,7 +711,7 @@ sanity_license() {

sanity_cpp() {
set -ex
3rdparty/dmlc-core/scripts/lint.py mxnet cpp include src plugin tests --exclude_path src/operator/contrib/ctc_include include/onednn
3rdparty/dmlc-core/scripts/lint.py mxnet cpp include src plugin cpp-package tests --exclude_path src/operator/contrib/ctc_include include/onednn
}

sanity_python() {
Expand Down Expand Up @@ -878,6 +882,12 @@ unittest_centos7_gpu() {
pytest --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu/test_amp_init.py
}

integrationtest_ubuntu_cpp_package_gpu() {
set -ex
export DMLC_LOG_STACK_TRACE_DEPTH=10
cpp-package/tests/ci_test.sh
}

integrationtest_ubuntu_cpu_onnx() {
set -ex
export PYTHONPATH=./python/
Expand Down Expand Up @@ -1159,9 +1169,11 @@ build_docs() {
pushd docs/_build
tar -xzf jekyll-artifacts.tgz
python_doc_folder='html/api/python/docs'
api_folder='html/api'

# Python has it's own landing page/site so we don't put it in /docs/api
mkdir -p $python_doc_folder && tar -xzf python-artifacts.tgz --directory $python_doc_folder
mkdir -p $api_folder/cpp/docs/api && tar -xzf c-artifacts.tgz --directory $api_folder/cpp/docs/api

# check if .htaccess file exists
if [ ! -f "html/.htaccess" ]; then
Expand Down Expand Up @@ -1210,7 +1222,9 @@ build_docs_beta() {
pushd docs/_build
tar -xzf jekyll-artifacts.tgz
python_doc_folder="html/versions/$BRANCH/api/python/docs"
cpp_doc_folder="html/versions/$BRANCH/api/cpp/docs"
mkdir -p $python_doc_folder && tar -xzf python-artifacts.tgz --directory $python_doc_folder
mkdir -p $cpp_doc_folder && tar -xzf c-artifacts.tgz --directory $cpp_doc_folder
GZIP=-9 tar -zcvf beta_website.tgz -C html .
popd
}
Expand Down
40 changes: 37 additions & 3 deletions ci/jenkins/Jenkins_steps.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ mx_cmake_lib_cython = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so,
mx_cmake_lib_debug = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, build/tests/mxnet_unit_tests'
mx_onednn_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, example/extensions/lib_external_ops/build/libexternal_lib.so'
mx_tensorrt_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, lib/libnvonnxparser_runtime.so.0, lib/libnvonnxparser.so.0, lib/libonnx_proto.so, lib/libonnx.so'
mx_lib_cpp_examples = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, example/extensions/lib_external_ops/build/libexternal_lib.so, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so'
mx_lib_cpp_examples = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, example/extensions/lib_external_ops/build/libexternal_lib.so, build/cpp-package/example/*, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so'
mx_lib_cpp_examples_no_tvm_op = 'build/libmxnet.so, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so'
mx_lib_cpp_examples_cpu = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf'
mx_lib_cpp_examples_cpu = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/cpp-package/example/*'
mx_cd_lib = 'lib/libmxnet.so, licenses/*, lib/libgfortran.so.*, lib/libopenblas.so.0, include/onednn/oneapi/dnnl/dnnl_version.h, include/onednn/oneapi/dnnl/dnnl_config.h'


Expand Down Expand Up @@ -85,7 +85,7 @@ def compile_unix_cpu_openblas(lib_name) {
timeout(time: max_time, unit: 'MINUTES') {
utils.init_git()
utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_openblas', false)
utils.pack_lib(lib_name, mx_lib_cython, true)
utils.pack_lib(lib_name, mx_lib_cpp_examples, true)
}
}
}
Expand Down Expand Up @@ -846,6 +846,20 @@ def test_unix_distributed_kvstore_gpu(lib_name) {
}]
}

def test_unix_cpp_package_gpu(lib_name) {
return ['cpp-package GPU Makefile': {
node(NODE_LINUX_GPU_G4) {
ws('workspace/it-cpp-package-gpu') {
timeout(time: max_time, unit: 'MINUTES') {
utils.unpack_and_init(lib_name, mx_lib_cpp_examples)
utils.docker_run('ubuntu_gpu_cu111', 'integrationtest_ubuntu_cpp_package_gpu', true)
utils.publish_test_coverage()
}
}
}
}]
}

def test_centos7_python3_cpu(lib_name) {
return ['Python3: CentOS 7 CPU': {
node(NODE_LINUX_CPU) {
Expand Down Expand Up @@ -1048,6 +1062,23 @@ def docs_python(lib_name) {
}]
}

// Call this function from Jenkins to generate just the C and C++ API microsite artifacts.
def docs_c(lib_name) {
return ['C Docs': {
node(NODE_LINUX_CPU) {
ws('workspace/docs') {
timeout(time: max_time, unit: 'MINUTES') {
utils.unpack_and_init(lib_name, mx_lib, false)
utils.docker_run('ubuntu_cpu', 'build_c_docs', false)
if (should_pack_website()) {
utils.pack_lib('c-artifacts', 'docs/_build/c-artifacts.tgz', false)
}
}
}
}
}]
}


// Call this function from Jenkins to generate just the main website artifacts.
def docs_jekyll() {
Expand Down Expand Up @@ -1078,6 +1109,7 @@ def docs_prepare() {
utils.init_git()

unstash 'jekyll-artifacts'
unstash 'c-artifacts'
unstash 'python-artifacts'

utils.docker_run('ubuntu_cpu_jekyll', 'build_docs', false)
Expand All @@ -1104,6 +1136,7 @@ def docs_full_website() {
utils.init_git()

unstash 'jekyll-artifacts'
unstash 'c-artifacts'
unstash 'python-artifacts'

utils.docker_run('ubuntu_cpu_jekyll', 'build_docs', false)
Expand All @@ -1126,6 +1159,7 @@ def docs_prepare_beta() {
utils.init_git()

unstash 'jekyll-artifacts'
unstash 'c-artifacts'
unstash 'python-artifacts'

utils.docker_run('ubuntu_cpu_jekyll', 'build_docs_beta', false)
Expand Down
1 change: 1 addition & 0 deletions ci/jenkins/Jenkinsfile_unix_gpu
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ core_logic: {
custom_steps.test_unix_python3_gpu('gpu'),
custom_steps.test_unix_python3_onednn_gpu('onednn_gpu'),
custom_steps.test_unix_python3_onednn_nocudnn_gpu('onednn_gpu_nocudnn'),
custom_steps.test_unix_cpp_package_gpu('gpu'),
// TODO(szha): fix and reenable the hanging issue. tracked in #18098
// custom_steps.test_unix_distributed_kvstore_gpu('gpu'),
custom_steps.test_unix_byteps_gpu('gpu'),
Expand Down
1 change: 1 addition & 0 deletions ci/jenkins/Jenkinsfile_website_full
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ core_logic: {

utils.parallel_stage('Build Docs', [
custom_steps.docs_jekyll(),
custom_steps.docs_c('libmxnet'),
custom_steps.docs_python('libmxnet'),
])

Expand Down
1 change: 1 addition & 0 deletions ci/jenkins/Jenkinsfile_website_full_pr
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ core_logic: {
utils.parallel_stage('Build Docs', [
// Optimization would be to flag these not to stash if not previewing them
custom_steps.docs_jekyll(),
custom_steps.docs_c('libmxnet'),
custom_steps.docs_python('libmxnet'),
])

Expand Down
1 change: 1 addition & 0 deletions ci/jenkins/Jenkinsfile_website_nightly
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ core_logic: {

utils.parallel_stage('Build Docs', [
custom_steps.docs_jekyll(),
custom_steps.docs_c('libmxnet'),
custom_steps.docs_python('libmxnet'),
])

Expand Down
1 change: 1 addition & 0 deletions ci/jenkins/Jenkinsfile_website_version_artifacts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ core_logic: {

utils.parallel_stage('Build Docs', [
custom_steps.docs_jekyll(),
custom_steps.docs_c('libmxnet'),
custom_steps.docs_python('libmxnet'),
])

Expand Down
52 changes: 52 additions & 0 deletions cpp-package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.

cmake_minimum_required(VERSION 3.13)
project(mxnet_cpp C CXX)

add_library(mxnet_cpp INTERFACE)

set(CPP_PACKAGE_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include/)
target_include_directories(mxnet_cpp INTERFACE "${CPP_PACKAGE_INCLUDE_DIR}")
file(GLOB_RECURSE CPP_PACKAGE_HEADERS
"${CPP_PACKAGE_INCLUDE_DIR}/*.h"
"${CPP_PACKAGE_INCLUDE_DIR}/*.hpp")
set(CPP_PACKAGE_OP_H_HEADER ${CMAKE_CURRENT_LIST_DIR}/include/mxnet-cpp/op.h)
target_sources(mxnet_cpp INTERFACE ${CPP_PACKAGE_HEADERS} ${CPP_PACKAGE_OP_H_HEADER})
target_link_libraries(mxnet_cpp INTERFACE mxnet ${mxnet_LINKER_LIBS})

add_custom_target(
cpp_package_op_h ALL
BYPRODUCTS ${CPP_PACKAGE_OP_H_HEADER}
MAIN_DEPENDENCY mxnet
DEPENDS mxnet ${CMAKE_CURRENT_SOURCE_DIR}/scripts/OpWrapperGenerator.py
COMMAND echo "Running: OpWrapperGenerator.py"
COMMAND python3 OpWrapperGenerator.py $<TARGET_FILE:mxnet>
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts
)
add_dependencies(mxnet_cpp cpp_package_op_h)

if(MSVC)
target_compile_options(mxnet_cpp INTERFACE "/utf-8")
endif(MSVC)

if(BUILD_CPP_EXAMPLES)
add_subdirectory(example)
add_subdirectory(example/inference)
endif()

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
67 changes: 67 additions & 0 deletions cpp-package/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!--- Licensed to the Apache Software Foundation (ASF) under one -->
<!--- or more contributor license agreements. See the NOTICE file -->
<!--- distributed with this work for additional information -->
<!--- regarding copyright ownership. The ASF licenses this file -->
<!--- to you 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. -->

# MXNet - C++ API

The MXNet C++ Package provides C++ API bindings to the users of MXNet. Currently, these bindings are not available as standalone package.
The users of these bindings are required to build this package as mentioned below.

## Building C++ Package

The cpp-package directory contains the implementation of C++ API. As mentioned above, users are required to build this directory or package before using it.
**The cpp-package is built while building the MXNet shared library, *libmxnet.so*.**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason for that. cpp-package depends only on libmxnet.so C APIs. It would be better to keep a separate CMakeLists.txt for the cpp-package with the only requirement to find libmxnet.so. This implies removing the USE_CPP_PACKAGE in the main CMakeLists.txt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out. Let me update the documentation.


### Steps to build the C++ package:
1. Building the MXNet C++ package requires building MXNet from source.
2. Clone the MXNet GitHub repository **recursively** to ensure the code in submodules is available for building MXNet.
```
git clone --recursive https://github.com/apache/incubator-mxnet mxnet
```

3. Install the [recommended dependencies](https://mxnet.apache.org/versions/master/get_started/build_from_source.html#installing-mxnet's-recommended-dependencies) and [optional dependencies](https://mxnet.apache.org/versions/master/get_started/build_from_source.html#overview-of-optional-dependencies-and-optional-features) for building MXNet from source.
4. There is a configuration file for cmake, [config/*.cmake](<https://github.com/apache/incubator-mxnet/tree/master/config>) that contains all the compilation options. You can edit this file and set the appropriate options prior to running the **cmake** command.
5. Please refer to [cmake configuration files](https://github.com/apache/incubator-mxnet/blob/970a2cfbe77d09ee610fdd70afca1a93247cf4fb/config/linux_gpu.cmake#L18-L37) for more details on how to configure and compile MXNet.
6. For enabling the build of C++ Package, set the **-DUSE\_CPP\_PACKAGE = 1** in cmake options.

### Cross-Compilation steps:
1. Build the C++ package for the **host** platform to generate op.h file.
2. Remove the following line in [CMakeLists.txt](<https://github.com/apache/incubator-mxnet/blob/master/cpp-package/CMakeLists.txt#L15>).
```
COMMAND python OpWrapperGenerator.py $<TARGET_FILE:mxnet>
```
3. Re-configure cmake for cross-compilation to build the **target** C++ package.

## Usage

In order to consume the C++ API please follow the steps below.

1. Ensure that the MXNet shared library is built from source with the **USE\_CPP\_PACKAGE = 1**.
2. Include the [MxNetCpp.h](<https://github.com/apache/incubator-mxnet/blob/master/cpp-package/include/mxnet-cpp/MxNetCpp.h>) in the program that is going to consume MXNet C++ API.
```c++
#include <mxnet-cpp/MxNetCpp.h>
```
3. While building the program, ensure that the correct paths to the directories containing header files and MXNet shared library.
4. The program links the MXNet shared library dynamically. Hence the library needs to be accessible to the program during runtime. This can be achieved by including the path to the shared library in the environment variable **LD\_LIBRARY\_PATH** for Linux, Mac. and Ubuntu OS and **PATH** for Windows OS.


## Tutorial

A basic tutorial can be found at <https://mxnet.apache.org/api/cpp/docs/tutorials/basics>.

## Examples

The example directory contains examples for you to get started. Please build the MXNet C++ Package before building the examples.
Loading