From 17c8d30d00af723ea242f833382c42919d751f59 Mon Sep 17 00:00:00 2001 From: Yifan Zhao <yifanz16@illinois.edu> Date: Tue, 6 Apr 2021 03:57:55 -0500 Subject: [PATCH] CUDA is now optional; not having CUDA will disable all ApproxHPVM stuff --- hpvm/CMakeLists.txt | 30 ++++++++++----- hpvm/projects/CMakeLists.txt | 16 ++++---- hpvm/projects/hpvm-tensor-rt/CMakeLists.txt | 1 + hpvm/test/CMakeLists.txt | 12 +++--- hpvm/tools/hpvm-clang/CMakeLists.txt | 41 +++++++++++++++------ hpvm/tools/hpvm-clang/main.py.in | 18 ++++++--- 6 files changed, 78 insertions(+), 40 deletions(-) diff --git a/hpvm/CMakeLists.txt b/hpvm/CMakeLists.txt index 71e6de5999..abb85759a3 100644 --- a/hpvm/CMakeLists.txt +++ b/hpvm/CMakeLists.txt @@ -1,13 +1,25 @@ cmake_minimum_required(VERSION 3.18) -project(hpvm CUDA CXX) -get_filename_component( - CUDA_TOOLKIT_ROOT_DIR "${CMAKE_CUDA_COMPILER}/../.." ABSOLUTE -) # Set CUDA_TOOLKIT_ROOT_DIR by our own, to the parent folder of cuda nvcc -message(STATUS "CUDA Architecture: ${CMAKE_CUDA_ARCHITECTURES}") - -# find_package will use the auxillary cmake/Find*.cmake we provide -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -find_package(CUDNN 7 EXACT REQUIRED) # CUDNN_INCLUDE_PATH, CUDNN_LIBRARY_DIR and CUDNN::cudnn +project(hpvm CXX) + +include(CheckLanguage) +check_language(CUDA) +if(CMAKE_CUDA_COMPILER) + # Enable CUDA + set(HPVM_USE_CUDA 1) + enable_language(CUDA) + get_filename_component( + CUDA_TOOLKIT_ROOT_DIR "${CMAKE_CUDA_COMPILER}/../.." ABSOLUTE + ) # Set CUDA_TOOLKIT_ROOT_DIR by our own, to the parent folder of cuda nvcc + message(STATUS "CUDA Architecture: ${CMAKE_CUDA_ARCHITECTURES}") + + # find_package will use the auxillary cmake/Find*.cmake we provide + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + find_package(CUDNN 7 EXACT REQUIRED) # CUDNN_INCLUDE_PATH, CUDNN_LIBRARY_DIR and CUDNN::cudnn +else() + set(HPVM_USE_CUDA 0) + message(WARNING "CUDA is not found in this system; all ApproxHPVM features will be unavailable.") +endif() + find_package(OpenCL) # Defines ${OpenCL_INCLUDE_DIRS} and ${OpenCL_LIBRARY} if(${OpenCL_FOUND}) set(HPVM_USE_OPENCL 1) diff --git a/hpvm/projects/CMakeLists.txt b/hpvm/projects/CMakeLists.txt index 2a51c0b09e..4eaf1094e4 100644 --- a/hpvm/projects/CMakeLists.txt +++ b/hpvm/projects/CMakeLists.txt @@ -1,17 +1,15 @@ +# Add all entries automatically except hpvm-tensor-rt file(GLOB entries *) foreach(entry ${entries}) if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt) - if((NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/dragonegg) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxx) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxxabi) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libunwind) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/test-suite) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/parallel-libs) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/openmp) AND - (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/debuginfo-tests)) + if(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/hpvm-tensor-rt) get_filename_component(entry_name "${entry}" NAME) add_llvm_external_project(${entry_name}) endif() endif() endforeach(entry) + +# Add hpvm-tensor-rt only if CUDA is found (HPVM_USE_CUDA is set to 1) +if(HPVM_USE_CUDA) + add_llvm_external_project(hpvm-tensor-rt) +endif() diff --git a/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt b/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt index c448ce9c37..3f88dad2d0 100644 --- a/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt +++ b/hpvm/projects/hpvm-tensor-rt/CMakeLists.txt @@ -40,6 +40,7 @@ target_include_directories(soc_simulator PUBLIC soc_simulator/) find_package(OpenMP REQUIRED) # Provides ${OpenMP_CXX_FLAGS} and OpenMP::OpenMP_CXX # This will use the CUDA found by CUDA language support in the root CMake, # but it exports the CUDA::* targets (used below) so we can freely add libraries to link to. +# (If CUDA is unavailable then the higher-level CMakes will know to not compile this library at all.) find_package(CUDAToolkit REQUIRED) set( LINK_LIBS diff --git a/hpvm/test/CMakeLists.txt b/hpvm/test/CMakeLists.txt index 8b4185294f..e59e0959a3 100644 --- a/hpvm/test/CMakeLists.txt +++ b/hpvm/test/CMakeLists.txt @@ -6,9 +6,11 @@ set(CLANG_C ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clang) set(CLANG_CXX ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clang++) add_subdirectory(hpvm_pass) # Passes test suite -add_subdirectory(hpvm-tensor-rt) # Unit tests of tensor_runtime add_subdirectory(benchmarks) # HPVM benchmarks (no DNN) -add_subdirectory(dnn_benchmarks/hpvm-c) # HPVM-C DNN accuracy test suite -add_subdirectory(dnn_benchmarks/keras) # Keras frontend test suite -add_subdirectory(dnn_benchmarks/pytorch) # Torch frontend test suites (3 of them) -add_subdirectory(dnn_benchmarks/tensor-rt-src) # tensor_runtime DNN (build only, no tests) +if(HPVM_USE_CUDA) # Compile these only if CUDA exists. + add_subdirectory(hpvm-tensor-rt) # Unit tests of tensor_runtime + add_subdirectory(dnn_benchmarks/hpvm-c) # HPVM-C DNN accuracy test suite + add_subdirectory(dnn_benchmarks/keras) # Keras frontend test suite + add_subdirectory(dnn_benchmarks/pytorch) # Torch frontend test suites (3 of them) + add_subdirectory(dnn_benchmarks/tensor-rt-src) # tensor_runtime DNN (build only, no tests) +endif() diff --git a/hpvm/tools/hpvm-clang/CMakeLists.txt b/hpvm/tools/hpvm-clang/CMakeLists.txt index 3564b00d0a..fdd4de2557 100644 --- a/hpvm/tools/hpvm-clang/CMakeLists.txt +++ b/hpvm/tools/hpvm-clang/CMakeLists.txt @@ -7,18 +7,32 @@ # ---[ Define variables for main.py.in # main.py.in requires the following variables: # LLVM_PROJECT_DIR, LLVM_BUILD_DIR -# TRT_PATH, TRT_INCLUDE_DIRS, TRT_LINK_DIRS, TRT_LINK_LIBS -# DIRECT_LINK_LIBS, HPVM_USE_OPENCL (defined globally) +# INCLUDE_DIRS, LINK_DIRS, LINK_LIBS +# DIRECT_LINK_LIBS, HPVM_USE_OPENCL (defined globally), HPVM_HAS_TRT # AVAILABLE_PASSES, HPVM_RT_PATH set(LLVM_PROJECT_DIR ${CMAKE_SOURCE_DIR}) set(LLVM_BUILD_DIR ${CMAKE_BINARY_DIR}) +# CMake-dependency of hpvmpy: +set(DEPS hpvm-rt-bc clang opt llvm-link) -get_target_property(TRT_INCLUDE_DIRS tensor_runtime INCLUDE_DIRECTORIES) -get_target_property(TRT_LINK_DIRS tensor_runtime TRT_LINK_DIRS) -get_target_property(TRT_LINK_LIBS tensor_runtime TRT_LINK_LIBS) +# Don't do the following if tensor_runtime won't be compiled +# (which is due to CUDA not found). +if(TARGET tensor_runtime) + set(HPVM_HAS_TRT 1) # Has tensor runtime -set(DIRECT_LINK_LIBS "$<TARGET_FILE:tensor_runtime>") + get_target_property(TRT_INCLUDE_DIRS tensor_runtime INCLUDE_DIRECTORIES) + get_target_property(TRT_LINK_DIRS tensor_runtime TRT_LINK_DIRS) + get_target_property(TRT_LINK_LIBS tensor_runtime TRT_LINK_LIBS) + + list(APPEND INCLUDE_DIRS ${TRT_INCLUDE_DIRS}) + list(APPEND LINK_DIRS ${TRT_LINK_DIRS}) + list(APPEND LINK_LIBS ${TRT_LINK_LIBS}) + list(APPEND DIRECT_LINK_LIBS "$<TARGET_FILE:tensor_runtime>") + list(APPEND DEPS tensor_runtime) +else() + set(HPVM_HAS_TRT 0) # Doesn't have tensor runtime +endif() if(${HPVM_USE_OPENCL}) # We need to link to OpenCL libs when hpvm uses opencl # because OpenCL functions may be injected by the OpenCL pass. @@ -39,14 +53,20 @@ set( LLVMBuildDFG LLVMClearDFG LLVMDFG2LLVM_CPU - LLVMDFG2LLVM_CUDNN LLVMDFG2LLVM_OpenCL - LLVMDFG2LLVM_WrapperAPI - LLVMFuseHPVMTensorNodes LLVMGenHPVM - LLVMInPlaceDFGAnalysis LLVMLocalMem ) +if(TARGET tensor_runtime) + list( + APPEND AVAILABLE_PASSES + LLVMFuseHPVMTensorNodes + LLVMInPlaceDFGAnalysis + LLVMDFG2LLVM_CUDNN + LLVMDFG2LLVM_WrapperAPI + ) +endif() +list(APPEND DEPS ${AVAILABLE_PASSES}) # ---[ Create package folder structure # This sounds crazy but since main.py.in is generated into another file under build/ dir, @@ -69,7 +89,6 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.py INPUT ${CMAKE_CURRENT_B # Delibrately create an extra step of moving file # which is carried out at build time (as a target) # so we can set these dependencies on it. -set(DEPS tensor_runtime hpvm-rt-bc clang opt llvm-link ${AVAILABLE_PASSES}) add_custom_command( OUTPUT ${init_path} COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/main.py ${init_path} diff --git a/hpvm/tools/hpvm-clang/main.py.in b/hpvm/tools/hpvm-clang/main.py.in index f20bae4df9..0f240ad04f 100644 --- a/hpvm/tools/hpvm-clang/main.py.in +++ b/hpvm/tools/hpvm-clang/main.py.in @@ -10,11 +10,12 @@ HPVM_PROJECT_DIR = Path("@LLVM_PROJECT_DIR@") / "tools/hpvm" LLVM_BUILD_BIN = Path("@LLVM_BUILD_DIR@") / "bin" # Directories to include -TRT_INCLUDE_DIRS = "@TRT_INCLUDE_DIRS@".split(";") -TRT_LINK_DIRS = [Path(s) for s in "@TRT_LINK_DIRS@".split(";")] -TRT_LINK_LIBS = "@TRT_LINK_LIBS@".split(";") +INCLUDE_DIRS = "@INCLUDE_DIRS@".split(";") +LINK_DIRS = [Path(s) for s in "@LINK_DIRS@".split(";")] +LINK_LIBS = "@LINK_LIBS@".split(";") DIRECT_LINK_LIBS = "@DIRECT_LINK_LIBS@".split(";") HPVM_USE_OPENCL = int("@HPVM_USE_OPENCL@") +HPVM_HAS_TRT = int("@HPVM_HAS_TRT@") AVAILABLE_PASSES = "@AVAILABLE_PASSES@".split(";") HPVM_RT_PATH = "@HPVM_RT_PATH@" @@ -103,7 +104,7 @@ def hpvm_c_to_ll( is_cpp: bool = True, # otherwise is C std: str = None, # --std=c++11 ) -> List[str]: - includes = (extra_includes or []) + TRT_INCLUDE_DIRS + includes = (extra_includes or []) + INCLUDE_DIRS includes_s = [f"-I{path}" for path in includes] macros = [f"-D{macro}" for macro in (macros or [])] flags = [f"-f{flg}" for flg in (flags or [])] @@ -155,8 +156,8 @@ def _link_args(extra_link_dirs: List[PathLike], extra_link_libs: List[str]): lib = Path(lib) link_dirs.append(lib.parent) link_libs.append(lib.name) - link_dirs += TRT_LINK_DIRS - link_libs += TRT_LINK_LIBS + link_dirs += LINK_DIRS + link_libs += LINK_LIBS link_libnames = [drop_suffix(s) for s in link_libs] return link_dirs, link_libnames @@ -266,6 +267,11 @@ See option -b for that.""" parser.error(f"Language mode {args.x} not supported yet -- only c or c++") if not HPVM_USE_OPENCL and args.opencl: parser.error(f"OpenCL is disabled for this build of HPVM.") + if not HPVM_HAS_TRT and args.tensor_target: + parser.error( + "Tensor domain support is disabled for this build of HPVM; " + "please check your CMake warnings during compilation." + ) return args -- GitLab