From 6705b17c345a802de73277b1677bf369186a9929 Mon Sep 17 00:00:00 2001 From: Chris Sullivan Date: Tue, 11 Aug 2020 00:47:01 -0700 Subject: [PATCH] [RPC] Update build support for cross compiling apps/cpp_rpc with OpenCL (#6229) * Standardize support for building and cross compiling apps/cpp_rpc. * Add cmake coverage for building the C++ RPC server binary and update documentation. * Add support for linking against custom OpenCL SDK employing a custom find_opencl macro. This can be useful when cross compiling with a custom OpenCL device driver. * Update OpenCL related documentation. * Add embedded linux build instructions to apps/cpp_rpc/README.md and ensure pthread is linked against when OS=Linux is defined. Remove outdated apps/cpp_rpc/Makefile. --- CMakeLists.txt | 4 +-- apps/cpp_rpc/CMakeLists.txt | 12 +++++++ apps/cpp_rpc/Makefile | 53 ---------------------------- apps/cpp_rpc/README.md | 44 +++++++++++++++-------- cmake/config.cmake | 8 +++++ cmake/modules/OpenCL.cmake | 6 ++-- cmake/util/FindOpenCL.cmake | 70 +++++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 73 deletions(-) delete mode 100644 apps/cpp_rpc/Makefile create mode 100644 cmake/util/FindOpenCL.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fa3c2b4b4ad0d..512c8f44e53b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(tvm C CXX) # Utility functions include(cmake/util/Util.cmake) include(cmake/util/FindCUDA.cmake) +include(cmake/util/FindOpenCL.cmake) include(cmake/util/FindVulkan.cmake) include(cmake/util/FindLLVM.cmake) include(cmake/util/FindROCM.cmake) @@ -77,9 +78,6 @@ tvm_option(USE_TARGET_ONNX "Build with ONNX Codegen support" OFF) tvm_option(USE_ARM_COMPUTE_LIB "Build with Arm Compute Library" OFF) tvm_option(USE_ARM_COMPUTE_LIB_GRAPH_RUNTIME "Build with Arm Compute Library graph runtime" OFF) -if(USE_CPP_RPC AND UNIX) - message(FATAL_ERROR "USE_CPP_RPC is only supported with WIN32. Use the Makefile for non-Windows.") -endif() # include directories include_directories(${CMAKE_INCLUDE_PATH}) diff --git a/apps/cpp_rpc/CMakeLists.txt b/apps/cpp_rpc/CMakeLists.txt index 98887381c068b..ad8ae14884989 100644 --- a/apps/cpp_rpc/CMakeLists.txt +++ b/apps/cpp_rpc/CMakeLists.txt @@ -17,6 +17,18 @@ if(WIN32) target_compile_definitions(tvm_rpc PUBLIC -DNOMINMAX) endif() +if (OS) + if (OS STREQUAL "Linux") + set_property(TARGET tvm_rpc PROPERTY LINK_FLAGS -lpthread) + endif() +endif() + +if(USE_OPENCL) + if (ANDROID_ABI) + set_property(TARGET tvm_rpc PROPERTY LINK_FLAGS -fuse-ld=gold) + endif() +endif() + target_include_directories( tvm_rpc PUBLIC "../../include" diff --git a/apps/cpp_rpc/Makefile b/apps/cpp_rpc/Makefile deleted file mode 100644 index 5cd87e929223a..0000000000000 --- a/apps/cpp_rpc/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# 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. - -# Makefile to compile RPC Server. -TVM_ROOT=$(shell cd ../..; pwd) -DMLC_CORE=${TVM_ROOT}/3rdparty/dmlc-core -TVM_RUNTIME_DIR?= -OS?= - -# Android can not link pthrad, but Linux need. -ifeq ($(OS), Linux) -LINK_PTHREAD=-lpthread -else -LINK_PTHREAD= -endif - -PKG_CFLAGS = -std=c++14 -O2 -fPIC -Wall\ - -I${TVM_ROOT}/include\ - -I${DMLC_CORE}/include\ - -I${TVM_ROOT}/3rdparty/dlpack/include - -PKG_LDFLAGS = -L$(TVM_RUNTIME_DIR) $(LINK_PTHREAD) -ltvm_runtime -ldl -Wl,-R$(TVM_RUNTIME_DIR) - -ifeq ($(USE_GLOG), 1) - PKG_CFLAGS += -DDMLC_USE_GLOG=1 - PKG_LDFLAGS += -lglog -endif - -.PHONY: clean all - -all: tvm_rpc - -# Build rule for all in one TVM package library -tvm_rpc: *.cc - @mkdir -p $(@D) - $(CXX) $(PKG_CFLAGS) -o $@ $(filter-out win32_process.cc, $(filter %.cc %.o %.a, $^)) $(PKG_LDFLAGS) - -clean: - -rm -f tvm_rpc \ No newline at end of file diff --git a/apps/cpp_rpc/README.md b/apps/cpp_rpc/README.md index 6e50002cf4cad..d073fca819219 100644 --- a/apps/cpp_rpc/README.md +++ b/apps/cpp_rpc/README.md @@ -19,24 +19,38 @@ This folder contains a simple recipe to make RPC server in c++. ## Usage (Non-Windows) -- Build tvm runtime -- Make the rpc executable [Makefile](Makefile). - `make CXX=/path/to/cross compiler g++/ TVM_RUNTIME_DIR=/path/to/tvm runtime library directory/ OS=Linux` - if you want to compile it for embedded Linux, you should add `OS=Linux`. - if the target os is Android, you doesn't need to pass OS argument. - You could cross compile the TVM runtime like this: -``` - cd tvm - mkdir arm_runtime - cp cmake/config.cmake arm_runtime - cd arm_runtime - cmake .. -DCMAKE_CXX_COMPILER="/path/to/cross compiler g++/" - make runtime +- Configure the tvm cmake build with `config.cmake` ensuring that `USE_CPP_RPC` is set to `ON` in the config. +- If cross compiling for Android, add the following options to the cmake config or specify them when invoking cmake: +``` + # Whether to build the C++ RPC server binary + set(USE_CPP_RPC ON) + # Path to the Android NDK cmake toolchain + set(CMAKE_TOOLCHAIN_FILE $ENV{ANDROID_NDK}/build/cmake/android.toolchain.cmake) + # The Android ABI and platform to target + set(ANDROID_ABI "arm64-v8a") + set(ANDROID_PLATFORM android-28) + ``` +- Similarly, if cross compiling for embedded Linux add the following options to cmake config: +``` + # Needed to ensure pthread is linked + set(OS Linux) + # Path to the desired C++ cross compiler + set(CMAKE_CXX_COMPILER /path/to/cross/compiler/executable) +``` +- If linking against a custom device OpenCL library is needed, in the config specify the path to the OpenCL SDK containing the include/CL headers and lib/ or lib64/libOpenCL.so: +``` + set(USE_OPENCL /path/to/opencl-sdk) +``` + +- From within the configured tvm build directory, compile `tvm_runtime` and the `tvm_rpc` server: +``` + cd $TVM_ROOT/build + make -jN tvm_runtime tvm_rpc ``` - Use `./tvm_rpc server` to start the RPC server ## Usage (Windows) -- Build tvm with the argument -DUSE_CPP_RPC +- Configure the tvm cmake build with `config.cmake` ensuring that `USE_CPP_RPC` is set to `ON` in the config. - Install [LLVM pre-build binaries](https://releases.llvm.org/download.html), making sure to select the option to add it to the PATH. - Verify Python 3.6 or newer is installed and in the PATH. - Use `\tvm_rpc.exe` to start the RPC server @@ -59,4 +73,4 @@ Command line usage ``` ## Note -Currently support is only there for Linux / Android / Windows environment and proxy mode doesn't be supported currently. +Currently support is only there for Linux / Android / Windows environment and proxy mode isn't supported currently. diff --git a/cmake/config.cmake b/cmake/config.cmake index 47f20372e906e..b7b9de8d0b08e 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -63,6 +63,11 @@ set(USE_SDACCEL OFF) set(USE_AOCL OFF) # Whether enable OpenCL runtime +# +# Possible values: +# - ON: enable OpenCL with cmake's auto search +# - OFF: disable OpenCL +# - /path/to/opencl-sdk: use specific path to opencl-sdk set(USE_OPENCL OFF) # Whether enable Metal runtime @@ -96,6 +101,9 @@ set(RUST_SGX_SDK "/path/to/rust-sgx-sdk") # Whether enable RPC runtime set(USE_RPC ON) +# Whether to build the C++ RPC server binary +set(USE_CPP_RPC OFF) + # Whether embed stackvm into the runtime set(USE_STACKVM_RUNTIME OFF) diff --git a/cmake/modules/OpenCL.cmake b/cmake/modules/OpenCL.cmake index 9ed0d0660f2b5..64ce3c3d38101 100644 --- a/cmake/modules/OpenCL.cmake +++ b/cmake/modules/OpenCL.cmake @@ -16,7 +16,7 @@ # under the License. # OPENCL Module -find_package(OpenCL QUIET) +find_opencl(${USE_OPENCL}) if(OpenCL_FOUND) # always set the includedir when cuda is available @@ -49,7 +49,9 @@ else() endif(USE_AOCL) if(USE_OPENCL) - find_package(OpenCL REQUIRED) + if (NOT OpenCL_FOUND) + find_package(OpenCL REQUIRED) + endif() message(STATUS "Build with OpenCL support") file(GLOB RUNTIME_OPENCL_SRCS src/runtime/opencl/*.cc) list(APPEND TVM_RUNTIME_LINKER_LIBS ${OpenCL_LIBRARIES}) diff --git a/cmake/util/FindOpenCL.cmake b/cmake/util/FindOpenCL.cmake new file mode 100644 index 0000000000000..2510c01a1bec6 --- /dev/null +++ b/cmake/util/FindOpenCL.cmake @@ -0,0 +1,70 @@ +# 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. + +####################################################### +# Enhanced version of find OpenCL. +# +# Usage: +# find_opencl(${USE_OPENCL}) +# +# - When USE_OPENCL=ON, use auto search +# - When USE_OPENCL=/path/to/opencl-sdk-path, use the sdk. +# Can be useful when cross compiling and cannot rely on +# CMake to provide the correct library as part of the +# requested toolchain. +# +# Provide variables: +# +# - OpenCL_FOUND +# - OpenCL_INCLUDE_DIRS +# - OpenCL_LIBRARIES +# + +macro(find_opencl use_opencl) + set(__use_opencl ${use_opencl}) + if(IS_DIRECTORY ${__use_opencl}) + set(__opencl_sdk ${__use_opencl}) + message(STATUS "Custom OpenCL SDK PATH=" ${__use_opencl}) + elseif(IS_DIRECTORY $ENV{OPENCL_SDK}) + set(__opencl_sdk $ENV{OPENCL_SDK}) + else() + set(__opencl_sdk "") + endif() + + if(__opencl_sdk) + set(OpenCL_INCLUDE_DIRS ${__opencl_sdk}/include) + if (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY STREQUAL "ONLY") + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) + endif() + find_library(OpenCL_LIBRARIES NAMES OpenCL PATHS ${__opencl_sdk}/lib ${__opencl_sdk}/lib64) + if(OpenCL_LIBRARIES) + set(OpenCL_FOUND TRUE) + endif() + endif(__opencl_sdk) + + # No user provided OpenCL include/libs found + if(NOT OpenCL_FOUND) + if(__use_opencl STREQUAL "ON") + find_package(OpenCL QUIET) + endif() + endif() + + if(OpenCL_FOUND) + message(STATUS "OpenCL_INCLUDE_DIRS=" ${OpenCL_INCLUDE_DIRS}) + message(STATUS "OpenCL_LIBRARIES=" ${OpenCL_LIBRARIES}) + endif(OpenCL_FOUND) +endmacro(find_opencl)