[RPC] Update build support for cross compiling apps/cpp_rpc with OpenCL (#6229)
authorChris Sullivan <csullivan@octoml.ai>
Tue, 11 Aug 2020 07:47:01 +0000 (00:47 -0700)
committerGitHub <noreply@github.com>
Tue, 11 Aug 2020 07:47:01 +0000 (15:47 +0800)
* 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
apps/cpp_rpc/CMakeLists.txt
apps/cpp_rpc/Makefile [deleted file]
apps/cpp_rpc/README.md
cmake/config.cmake
cmake/modules/OpenCL.cmake
cmake/util/FindOpenCL.cmake [new file with mode: 0644]

index 1153300..1432c13 100644 (file)
@@ -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)
@@ -75,9 +76,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})
index 9888738..ad8ae14 100644 (file)
@@ -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 (file)
index 5cd87e9..0000000
+++ /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
index 6e50002..d073fca 100644 (file)
 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_output_dir>\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.
index ec2c503..fb4e2bd 100644 (file)
@@ -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)
 
index 9ed0d06..64ce3c3 100644 (file)
@@ -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 (file)
index 0000000..2510c01
--- /dev/null
@@ -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)