Note that when cub inside CUDA is being used, XGBoost performs checks on input size instead of using internal cub function to accept inputs larger than maximum integer.
354 lines
13 KiB
CMake
354 lines
13 KiB
CMake
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
|
project(xgboost LANGUAGES CXX C VERSION 1.6.0)
|
|
include(cmake/Utils.cmake)
|
|
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
|
|
cmake_policy(SET CMP0022 NEW)
|
|
cmake_policy(SET CMP0079 NEW)
|
|
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
|
cmake_policy(SET CMP0063 NEW)
|
|
|
|
if ((${CMAKE_VERSION} VERSION_GREATER 3.13) OR (${CMAKE_VERSION} VERSION_EQUAL 3.13))
|
|
cmake_policy(SET CMP0077 NEW)
|
|
endif ((${CMAKE_VERSION} VERSION_GREATER 3.13) OR (${CMAKE_VERSION} VERSION_EQUAL 3.13))
|
|
|
|
message(STATUS "CMake version ${CMAKE_VERSION}")
|
|
|
|
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
|
message(FATAL_ERROR "GCC version must be at least 5.0!")
|
|
endif()
|
|
|
|
include(${xgboost_SOURCE_DIR}/cmake/FindPrefetchIntrinsics.cmake)
|
|
find_prefetch_intrinsics()
|
|
include(${xgboost_SOURCE_DIR}/cmake/Version.cmake)
|
|
write_version()
|
|
set_default_configuration_release()
|
|
|
|
#-- Options
|
|
## User options
|
|
option(BUILD_C_DOC "Build documentation for C APIs using Doxygen." OFF)
|
|
option(USE_OPENMP "Build with OpenMP support." ON)
|
|
option(BUILD_STATIC_LIB "Build static library" OFF)
|
|
option(FORCE_SHARED_CRT "Build with dynamic CRT on Windows (/MD)" OFF)
|
|
option(RABIT_BUILD_MPI "Build MPI" OFF)
|
|
## Bindings
|
|
option(JVM_BINDINGS "Build JVM bindings" OFF)
|
|
option(R_LIB "Build shared library for R package" OFF)
|
|
## Dev
|
|
option(USE_DEBUG_OUTPUT "Dump internal training results like gradients and predictions to stdout.
|
|
Should only be used for debugging." OFF)
|
|
option(FORCE_COLORED_OUTPUT "Force colored output from compilers, useful when ninja is used instead of make." OFF)
|
|
option(ENABLE_ALL_WARNINGS "Enable all compiler warnings. Only effective for GCC/Clang" OFF)
|
|
option(LOG_CAPI_INVOCATION "Log all C API invocations for debugging" OFF)
|
|
option(GOOGLE_TEST "Build google tests" OFF)
|
|
option(USE_DMLC_GTEST "Use google tests bundled with dmlc-core submodule" OFF)
|
|
option(USE_DEVICE_DEBUG "Generate CUDA device debug info." OFF)
|
|
option(USE_NVTX "Build with cuda profiling annotations. Developers only." OFF)
|
|
set(NVTX_HEADER_DIR "" CACHE PATH "Path to the stand-alone nvtx header")
|
|
option(RABIT_MOCK "Build rabit with mock" OFF)
|
|
option(HIDE_CXX_SYMBOLS "Build shared library and hide all C++ symbols" OFF)
|
|
## CUDA
|
|
option(USE_CUDA "Build with GPU acceleration" OFF)
|
|
option(USE_NCCL "Build with NCCL to enable distributed GPU support." OFF)
|
|
option(BUILD_WITH_SHARED_NCCL "Build with shared NCCL library." OFF)
|
|
option(BUILD_WITH_CUDA_CUB "Build with cub in CUDA installation" OFF)
|
|
set(GPU_COMPUTE_VER "" CACHE STRING
|
|
"Semicolon separated list of compute versions to be built against, e.g. '35;61'")
|
|
## Copied From dmlc
|
|
option(USE_HDFS "Build with HDFS support" OFF)
|
|
option(USE_AZURE "Build with AZURE support" OFF)
|
|
option(USE_S3 "Build with S3 support" OFF)
|
|
## Sanitizers
|
|
option(USE_SANITIZER "Use santizer flags" OFF)
|
|
option(SANITIZER_PATH "Path to sanitizes.")
|
|
set(ENABLED_SANITIZERS "address" "leak" CACHE STRING
|
|
"Semicolon separated list of sanitizer names. E.g 'address;leak'. Supported sanitizers are
|
|
address, leak, undefined and thread.")
|
|
## Plugins
|
|
option(PLUGIN_DENSE_PARSER "Build dense parser plugin" OFF)
|
|
option(PLUGIN_RMM "Build with RAPIDS Memory Manager (RMM)" OFF)
|
|
## TODO: 1. Add check if DPC++ compiler is used for building
|
|
option(PLUGIN_UPDATER_ONEAPI "DPC++ updater" OFF)
|
|
option(ADD_PKGCONFIG "Add xgboost.pc into system." ON)
|
|
|
|
#-- Checks for building XGBoost
|
|
if (USE_DEBUG_OUTPUT AND (NOT (CMAKE_BUILD_TYPE MATCHES Debug)))
|
|
message(SEND_ERROR "Do not enable `USE_DEBUG_OUTPUT' with release build.")
|
|
endif (USE_DEBUG_OUTPUT AND (NOT (CMAKE_BUILD_TYPE MATCHES Debug)))
|
|
if (USE_NCCL AND NOT (USE_CUDA))
|
|
message(SEND_ERROR "`USE_NCCL` must be enabled with `USE_CUDA` flag.")
|
|
endif (USE_NCCL AND NOT (USE_CUDA))
|
|
if (USE_DEVICE_DEBUG AND NOT (USE_CUDA))
|
|
message(SEND_ERROR "`USE_DEVICE_DEBUG` must be enabled with `USE_CUDA` flag.")
|
|
endif (USE_DEVICE_DEBUG AND NOT (USE_CUDA))
|
|
if (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
|
message(SEND_ERROR "Build XGBoost with -DUSE_NCCL=ON to enable BUILD_WITH_SHARED_NCCL.")
|
|
endif (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
|
if (JVM_BINDINGS AND R_LIB)
|
|
message(SEND_ERROR "`R_LIB' is not compatible with `JVM_BINDINGS' as they both have customized configurations.")
|
|
endif (JVM_BINDINGS AND R_LIB)
|
|
if (R_LIB AND GOOGLE_TEST)
|
|
message(WARNING "Some C++ unittests will fail with `R_LIB` enabled,
|
|
as R package redirects some functions to R runtime implementation.")
|
|
endif (R_LIB AND GOOGLE_TEST)
|
|
if (USE_AVX)
|
|
message(SEND_ERROR "The option 'USE_AVX' is deprecated as experimental AVX features have been removed from XGBoost.")
|
|
endif (USE_AVX)
|
|
if (PLUGIN_LZ4)
|
|
message(SEND_ERROR "The option 'PLUGIN_LZ4' is removed from XGBoost.")
|
|
endif (PLUGIN_LZ4)
|
|
if (PLUGIN_RMM AND NOT (USE_CUDA))
|
|
message(SEND_ERROR "`PLUGIN_RMM` must be enabled with `USE_CUDA` flag.")
|
|
endif (PLUGIN_RMM AND NOT (USE_CUDA))
|
|
if (PLUGIN_RMM AND NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
|
message(SEND_ERROR "`PLUGIN_RMM` must be used with GCC or Clang compiler.")
|
|
endif (PLUGIN_RMM AND NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
|
if (PLUGIN_RMM AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
|
message(SEND_ERROR "`PLUGIN_RMM` must be used with Linux.")
|
|
endif (PLUGIN_RMM AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
|
if (ENABLE_ALL_WARNINGS)
|
|
if ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
|
message(SEND_ERROR "ENABLE_ALL_WARNINGS is only available for Clang and GCC.")
|
|
endif ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
|
endif (ENABLE_ALL_WARNINGS)
|
|
if (BUILD_STATIC_LIB AND (R_LIB OR JVM_BINDINGS))
|
|
message(SEND_ERROR "Cannot build a static library libxgboost.a when R or JVM packages are enabled.")
|
|
endif (BUILD_STATIC_LIB AND (R_LIB OR JVM_BINDINGS))
|
|
if (PLUGIN_RMM AND (NOT BUILD_WITH_CUDA_CUB))
|
|
message(SEND_ERROR "Cannot build with RMM using cub submodule.")
|
|
endif (PLUGIN_RMM AND (NOT BUILD_WITH_CUDA_CUB))
|
|
|
|
#-- Sanitizer
|
|
if (USE_SANITIZER)
|
|
include(cmake/Sanitizer.cmake)
|
|
enable_sanitizers("${ENABLED_SANITIZERS}")
|
|
endif (USE_SANITIZER)
|
|
|
|
if (USE_CUDA)
|
|
set(USE_OPENMP ON CACHE BOOL "CUDA requires OpenMP" FORCE)
|
|
# `export CXX=' is ignored by CMake CUDA.
|
|
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
|
|
message(STATUS "Configured CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
|
|
|
|
enable_language(CUDA)
|
|
if (${CMAKE_CUDA_COMPILER_VERSION} VERSION_LESS 10.1)
|
|
message(FATAL_ERROR "CUDA version must be at least 10.1!")
|
|
endif()
|
|
set(GEN_CODE "")
|
|
format_gencode_flags("${GPU_COMPUTE_VER}" GEN_CODE)
|
|
add_subdirectory(${PROJECT_SOURCE_DIR}/gputreeshap)
|
|
|
|
if ((${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 11.4) AND (NOT BUILD_WITH_CUDA_CUB))
|
|
set(BUILD_WITH_CUDA_CUB ON)
|
|
endif ()
|
|
endif (USE_CUDA)
|
|
|
|
if (FORCE_COLORED_OUTPUT AND (CMAKE_GENERATOR STREQUAL "Ninja") AND
|
|
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
|
|
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")))
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
|
endif()
|
|
|
|
find_package(Threads REQUIRED)
|
|
|
|
if (USE_OPENMP)
|
|
if (APPLE)
|
|
# Require CMake 3.16+ on Mac OSX, as previous versions of CMake had trouble locating
|
|
# OpenMP on Mac. See https://github.com/dmlc/xgboost/pull/5146#issuecomment-568312706
|
|
cmake_minimum_required(VERSION 3.16)
|
|
endif (APPLE)
|
|
find_package(OpenMP REQUIRED)
|
|
endif (USE_OPENMP)
|
|
|
|
if (USE_NCCL)
|
|
find_package(Nccl REQUIRED)
|
|
endif (USE_NCCL)
|
|
|
|
# dmlc-core
|
|
msvc_use_static_runtime()
|
|
if (FORCE_SHARED_CRT)
|
|
set(DMLC_FORCE_SHARED_CRT ON)
|
|
endif ()
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/dmlc-core)
|
|
|
|
if (MSVC)
|
|
if (TARGET dmlc_unit_tests)
|
|
target_compile_options(dmlc_unit_tests PRIVATE
|
|
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
|
endif (TARGET dmlc_unit_tests)
|
|
endif (MSVC)
|
|
|
|
# rabit
|
|
add_subdirectory(rabit)
|
|
if (RABIT_BUILD_MPI)
|
|
find_package(MPI REQUIRED)
|
|
endif (RABIT_BUILD_MPI)
|
|
|
|
# core xgboost
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/src)
|
|
target_link_libraries(objxgboost PUBLIC dmlc)
|
|
|
|
# Exports some R specific definitions and objects
|
|
if (R_LIB)
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/R-package)
|
|
endif (R_LIB)
|
|
|
|
# This creates its own shared library `xgboost4j'.
|
|
if (JVM_BINDINGS)
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/jvm-packages)
|
|
endif (JVM_BINDINGS)
|
|
|
|
# Plugin
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/plugin)
|
|
|
|
#-- library
|
|
if (BUILD_STATIC_LIB)
|
|
add_library(xgboost STATIC)
|
|
else (BUILD_STATIC_LIB)
|
|
add_library(xgboost SHARED)
|
|
endif (BUILD_STATIC_LIB)
|
|
target_link_libraries(xgboost PRIVATE objxgboost)
|
|
target_include_directories(xgboost
|
|
INTERFACE
|
|
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
|
|
#-- End shared library
|
|
|
|
#-- CLI for xgboost
|
|
add_executable(runxgboost ${xgboost_SOURCE_DIR}/src/cli_main.cc)
|
|
target_link_libraries(runxgboost PRIVATE objxgboost)
|
|
target_include_directories(runxgboost
|
|
PRIVATE
|
|
${xgboost_SOURCE_DIR}/include
|
|
${xgboost_SOURCE_DIR}/dmlc-core/include
|
|
${xgboost_SOURCE_DIR}/rabit/include
|
|
)
|
|
set_target_properties(runxgboost PROPERTIES OUTPUT_NAME xgboost)
|
|
#-- End CLI for xgboost
|
|
|
|
# Common setup for all targets
|
|
foreach(target xgboost objxgboost dmlc runxgboost)
|
|
xgboost_target_properties(${target})
|
|
xgboost_target_link_libraries(${target})
|
|
xgboost_target_defs(${target})
|
|
endforeach()
|
|
|
|
if (JVM_BINDINGS)
|
|
xgboost_target_properties(xgboost4j)
|
|
xgboost_target_link_libraries(xgboost4j)
|
|
xgboost_target_defs(xgboost4j)
|
|
endif (JVM_BINDINGS)
|
|
|
|
set_output_directory(runxgboost ${xgboost_SOURCE_DIR})
|
|
set_output_directory(xgboost ${xgboost_SOURCE_DIR}/lib)
|
|
# Ensure these two targets do not build simultaneously, as they produce outputs with conflicting names
|
|
add_dependencies(xgboost runxgboost)
|
|
|
|
#-- Installing XGBoost
|
|
if (R_LIB)
|
|
include(cmake/RPackageInstallTargetSetup.cmake)
|
|
set_target_properties(xgboost PROPERTIES PREFIX "")
|
|
if (APPLE)
|
|
set_target_properties(xgboost PROPERTIES SUFFIX ".so")
|
|
endif (APPLE)
|
|
setup_rpackage_install_target(xgboost "${CMAKE_CURRENT_BINARY_DIR}/R-package-install")
|
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/dummy_inst")
|
|
endif (R_LIB)
|
|
if (MINGW)
|
|
set_target_properties(xgboost PROPERTIES PREFIX "")
|
|
endif (MINGW)
|
|
|
|
if (BUILD_C_DOC)
|
|
include(cmake/Doc.cmake)
|
|
run_doxygen()
|
|
endif (BUILD_C_DOC)
|
|
|
|
include(CPack)
|
|
|
|
include(GNUInstallDirs)
|
|
# Install all headers. Please note that currently the C++ headers does not form an "API".
|
|
install(DIRECTORY ${xgboost_SOURCE_DIR}/include/xgboost
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
|
|
# Install libraries. If `xgboost` is a static lib, specify `objxgboost` also, to avoid the
|
|
# following error:
|
|
#
|
|
# > install(EXPORT ...) includes target "xgboost" which requires target "objxgboost" that is not
|
|
# > in any export set.
|
|
#
|
|
# https://github.com/dmlc/xgboost/issues/6085
|
|
if (BUILD_STATIC_LIB)
|
|
set(INSTALL_TARGETS xgboost runxgboost objxgboost dmlc)
|
|
else (BUILD_STATIC_LIB)
|
|
set(INSTALL_TARGETS xgboost runxgboost)
|
|
endif (BUILD_STATIC_LIB)
|
|
|
|
install(TARGETS ${INSTALL_TARGETS}
|
|
EXPORT XGBoostTargets
|
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
INCLUDES DESTINATION ${LIBLEGACY_INCLUDE_DIRS})
|
|
install(EXPORT XGBoostTargets
|
|
FILE XGBoostTargets.cmake
|
|
NAMESPACE xgboost::
|
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
|
|
|
include(CMakePackageConfigHelpers)
|
|
configure_package_config_file(
|
|
${CMAKE_CURRENT_LIST_DIR}/cmake/xgboost-config.cmake.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/cmake/xgboost-config.cmake
|
|
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
|
write_basic_package_version_file(
|
|
${CMAKE_BINARY_DIR}/cmake/xgboost-config-version.cmake
|
|
VERSION ${XGBOOST_VERSION}
|
|
COMPATIBILITY AnyNewerVersion)
|
|
install(
|
|
FILES
|
|
${CMAKE_BINARY_DIR}/cmake/xgboost-config.cmake
|
|
${CMAKE_BINARY_DIR}/cmake/xgboost-config-version.cmake
|
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
|
|
|
#-- Test
|
|
if (GOOGLE_TEST)
|
|
enable_testing()
|
|
# Unittests.
|
|
add_executable(testxgboost)
|
|
target_link_libraries(testxgboost PRIVATE objxgboost)
|
|
xgboost_target_properties(testxgboost)
|
|
xgboost_target_link_libraries(testxgboost)
|
|
xgboost_target_defs(testxgboost)
|
|
|
|
add_subdirectory(${xgboost_SOURCE_DIR}/tests/cpp)
|
|
|
|
add_test(
|
|
NAME TestXGBoostLib
|
|
COMMAND testxgboost
|
|
WORKING_DIRECTORY ${xgboost_BINARY_DIR})
|
|
# CLI tests
|
|
configure_file(
|
|
${xgboost_SOURCE_DIR}/tests/cli/machine.conf.in
|
|
${xgboost_BINARY_DIR}/tests/cli/machine.conf
|
|
@ONLY)
|
|
add_test(
|
|
NAME TestXGBoostCLI
|
|
COMMAND runxgboost ${xgboost_BINARY_DIR}/tests/cli/machine.conf
|
|
WORKING_DIRECTORY ${xgboost_BINARY_DIR})
|
|
set_tests_properties(TestXGBoostCLI
|
|
PROPERTIES
|
|
PASS_REGULAR_EXPRESSION ".*test-rmse:0.087.*")
|
|
endif (GOOGLE_TEST)
|
|
|
|
# For MSVC: Call msvc_use_static_runtime() once again to completely
|
|
# replace /MD with /MT. See https://github.com/dmlc/xgboost/issues/4462
|
|
# for issues caused by mixing of /MD and /MT flags
|
|
msvc_use_static_runtime()
|
|
|
|
# Add xgboost.pc
|
|
if (ADD_PKGCONFIG)
|
|
configure_file(${xgboost_SOURCE_DIR}/cmake/xgboost.pc.in ${xgboost_BINARY_DIR}/xgboost.pc @ONLY)
|
|
|
|
install(
|
|
FILES ${xgboost_BINARY_DIR}/xgboost.pc
|
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
|
endif (ADD_PKGCONFIG)
|