diff --git a/CMakeLists.txt b/CMakeLists.txt index bdaaa6661..23384f1b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ option(JVM_BINDINGS "Build JVM bindings" OFF) option(R_LIB "Build shared library for R package" OFF) ## Dev option(GOOGLE_TEST "Build google tests" OFF) +option(USE_DMLC_GTEST "Use google tests bundled with dmlc-core submodule (EXPERIMENTAL)" 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") ## CUDA @@ -55,6 +56,7 @@ endif (USE_SANITIZER) if (USE_CUDA) cmake_minimum_required(VERSION 3.12) + 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}") @@ -124,6 +126,10 @@ endif (JVM_BINDINGS) #-- CLI for xgboost add_executable(runxgboost ${PROJECT_SOURCE_DIR}/src/cli_main.cc ${XGBOOST_OBJ_SOURCES}) # For cli_main.cc only +if (USE_OPENMP) + find_package(OpenMP REQUIRED) + target_compile_options(runxgboost PRIVATE ${OpenMP_CXX_FLAGS}) +endif (USE_OPENMP) target_include_directories(runxgboost PRIVATE ${PROJECT_SOURCE_DIR}/include diff --git a/Jenkinsfile-win64 b/Jenkinsfile-win64 index 831f9154c..8da43d2e4 100644 --- a/Jenkinsfile-win64 +++ b/Jenkinsfile-win64 @@ -8,7 +8,7 @@ pipeline { // Build stages stages { stage('Jenkins Win64: Get sources') { - agent { label 'win64' } + agent { label 'win64 && build' } steps { script { checkoutSrcs() @@ -22,12 +22,26 @@ pipeline { steps { script { parallel ([ - 'build-win64': { BuildWin64() } + 'build-win64-cuda9.0': { BuildWin64() } ]) } milestone ordinal: 2 } } + stage('Jenkins Win64: Test') { + agent none + steps { + script { + parallel ([ + 'test-win64-cpu': { TestWin64CPU() }, + 'test-win64-gpu-cuda9.0': { TestWin64GPU(cuda_target: 'cuda9') }, + 'test-win64-gpu-cuda10.0': { TestWin64GPU(cuda_target: 'cuda10_0') }, + 'test-win64-gpu-cuda10.1': { TestWin64GPU(cuda_target: 'cuda10_1') } + ]) + } + milestone ordinal: 3 + } + } } } @@ -47,24 +61,74 @@ def checkoutSrcs() { } def BuildWin64() { - node('win64') { + node('win64 && build') { unstash name: 'srcs' echo "Building XGBoost for Windows AMD64 target..." + bat "nvcc --version" bat """ mkdir build cd build - cmake .. -G"Visual Studio 15 2017 Win64" -DUSE_CUDA=ON -DCMAKE_VERBOSE_MAKEFILE=ON + cmake .. -G"Visual Studio 15 2017 Win64" -DUSE_CUDA=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON """ bat """ cd build - "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe" xgboost.sln /m /p:Configuration=Release + "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe" xgboost.sln /m /p:Configuration=Release /nodeReuse:false """ bat """ cd python-package conda activate && python setup.py bdist_wheel --universal """ - stash name: 'xgboost_win_whl', includes: 'python-package/dist/*.whl' + echo "Insert vcomp140.dll (OpenMP runtime) into the wheel..." + bat """ + cd python-package\\dist + COPY /B ..\\..\\tests\\ci_build\\insert_vcomp140.py + conda activate && python insert_vcomp140.py *.whl + """ + echo 'Stashing Python wheel...' + stash name: 'xgboost_whl', includes: 'python-package/dist/*.whl' archiveArtifacts artifacts: "python-package/dist/*.whl", allowEmptyArchive: true + echo 'Stashing C++ test executable (testxgboost)...' + stash name: 'xgboost_cpp_tests', includes: 'build/testxgboost.exe' + deleteDir() + } +} + +def TestWin64CPU() { + node('win64 && cpu') { + unstash name: 'srcs' + unstash name: 'xgboost_whl' + echo "Test Win64 CPU" + echo "Installing Python wheel..." + bat "conda activate && (python -m pip uninstall -y xgboost || cd .)" + bat """ + conda activate && for /R %%i in (python-package\\dist\\*.whl) DO python -m pip install "%%i" + """ + echo "Running Python tests..." + bat "conda activate && python -m pytest -v -s --fulltrace tests\\python" + bat "conda activate && python -m pip uninstall -y xgboost" + deleteDir() + } +} + +def TestWin64GPU(args) { + node("win64 && gpu && ${args.cuda_target}") { + unstash name: 'srcs' + unstash name: 'xgboost_whl' + unstash name: 'xgboost_cpp_tests' + echo "Test Win64 GPU (${args.cuda_target})" + bat "nvcc --version" + echo "Running C++ tests..." + bat "build\\testxgboost.exe" + echo "Installing Python wheel..." + bat "conda activate && (python -m pip uninstall -y xgboost || cd .)" + bat """ + conda activate && for /R %%i in (python-package\\dist\\*.whl) DO python -m pip install "%%i" + """ + echo "Running Python tests..." + bat """ + conda activate && python -m pytest -v -s --fulltrace -m "(not slow) and (not mgpu)" tests\\python-gpu + """ + bat "conda activate && python -m pip uninstall -y xgboost" deleteDir() } } diff --git a/dmlc-core b/dmlc-core index c45451793..3943914ee 160000 --- a/dmlc-core +++ b/dmlc-core @@ -1 +1 @@ -Subproject commit c45451793caec59c06a71d4c0eed59a34601e7ea +Subproject commit 3943914eed66470bd010df581e29e4dca4f7df6f diff --git a/tests/ci_build/insert_vcomp140.py b/tests/ci_build/insert_vcomp140.py new file mode 100644 index 000000000..8093c36eb --- /dev/null +++ b/tests/ci_build/insert_vcomp140.py @@ -0,0 +1,18 @@ +import sys +import re +import zipfile +import glob + +if len(sys.argv) != 2: + print('Usage: {} [wheel]'.format(sys.argv[0])) + sys.exit(1) + +vcomp140_path = 'C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\14.0\\VC\\redist\\x64\\Microsoft.VC140.OpenMP\\vcomp140.dll' + +for wheel_path in sorted(glob.glob(sys.argv[1])): + m = re.search(r'xgboost-(.*)-py2.py3', wheel_path) + assert m + version = m.group(1) + + with zipfile.ZipFile(wheel_path, 'a') as f: + f.write(vcomp140_path, 'xgboost-{}.data/data/xgboost/vcomp140.dll'.format(version)) diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index eedbcd83b..b357a610f 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -1,4 +1,11 @@ -find_package(GTest REQUIRED) +if (USE_DMLC_GTEST) + if (NOT TARGET gtest) + message(FATAL_ERROR "USE_DMLC_GTEST=ON but dmlc-core didn't bundle gtest") + endif (NOT TARGET gtest) + set(GTEST_LIBRARIES gtest) +else (USE_DMLC_GTEST) + find_package(GTest REQUIRED) +endif (USE_DMLC_GTEST) file(GLOB_RECURSE TEST_SOURCES "*.cc") if (USE_CUDA) @@ -8,13 +15,16 @@ endif (USE_CUDA) add_executable(testxgboost ${TEST_SOURCES} ${XGBOOST_OBJ_SOURCES}) if (USE_CUDA) + # OpenMP is mandatory for CUDA + find_package(OpenMP REQUIRED) target_include_directories(testxgboost PRIVATE ${PROJECT_SOURCE_DIR}/cub/) target_compile_options(testxgboost PRIVATE $<$:--expt-extended-lambda> $<$:--expt-relaxed-constexpr> $<$:-lineinfo> - $<$:--std=c++11> + $<$>,$>:--std=c++11> + $<$:-Xcompiler=${OpenMP_CXX_FLAGS}> $<$:${GEN_CODE}>) target_compile_definitions(testxgboost PRIVATE -DXGBOOST_USE_CUDA=1)