1{ config
2, stdenv
3, lib
4, fetchFromGitHub
5, cmake
6, gtest
7, doCheck ? true
8, autoAddDriverRunpath
9, cudaSupport ? config.cudaSupport
10, ncclSupport ? false
11, rLibrary ? false
12, cudaPackages
13, llvmPackages
14, R
15, rPackages
16}@inputs:
17
18assert ncclSupport -> (cudaSupport && !cudaPackages.nccl.meta.unsupported);
19# Disable regular tests when building the R package
20# because 1) the R package runs its own tests and
21# 2) the R package creates a different binary shared
22# object that isn't compatible with the regular CLI
23# tests.
24assert rLibrary -> doCheck != true;
25
26let
27 # This ensures xgboost gets the correct libstdc++ when
28 # built with cuda support. This may be removed once
29 # #226165 rewrites cudaStdenv
30 inherit (cudaPackages) backendStdenv;
31 stdenv = if cudaSupport then backendStdenv else inputs.stdenv;
32in
33
34stdenv.mkDerivation rec {
35 pnameBase = "xgboost";
36 # prefix with r when building the R library
37 # The R package build results in a special xgboost.so file
38 # that contains a subset of the .so file use for the CLI
39 # and python version. In general, the CRAN version from
40 # nixpkgs's r-modules should be used, but this non-standard
41 # build allows for enabling CUDA and NCCL support which aren't
42 # included in the CRAN release. Build with:
43 # nix-build -E "with (import $NIXPKGS{}); \
44 # let \
45 # xgb = xgboost.override{rLibrary = true; doCheck = false;}; \
46 # in \
47 # rWrapper.override{ packages = [ xgb ]; }"
48 pname = lib.optionalString rLibrary "r-" + pnameBase;
49 version = "2.0.3";
50
51 src = fetchFromGitHub {
52 owner = "dmlc";
53 repo = pnameBase;
54 rev = "v${version}";
55 fetchSubmodules = true;
56 hash = "sha256-LWco3A6zwdnAf8blU4qjW7PFEeZaTcJlVTwVrs7nwWM=";
57 };
58
59 nativeBuildInputs = [ cmake ]
60 ++ lib.optionals stdenv.isDarwin [ llvmPackages.openmp ]
61 ++ lib.optionals cudaSupport [ autoAddDriverRunpath ]
62 ++ lib.optionals rLibrary [ R ];
63
64 buildInputs = [ gtest ] ++ lib.optional cudaSupport cudaPackages.cudatoolkit
65 ++ lib.optional ncclSupport cudaPackages.nccl;
66
67 propagatedBuildInputs = lib.optionals rLibrary [
68 rPackages.data_table
69 rPackages.jsonlite
70 rPackages.Matrix
71 ];
72
73 cmakeFlags = lib.optionals doCheck [ "-DGOOGLE_TEST=ON" ]
74 ++ lib.optionals cudaSupport [
75 "-DUSE_CUDA=ON"
76 # Their CMakeLists.txt does not respect CUDA_HOST_COMPILER, instead using the CXX compiler.
77 # https://github.com/dmlc/xgboost/blob/ccf43d4ba0a94e2f0a3cc5a526197539ae46f410/CMakeLists.txt#L145
78 "-DCMAKE_C_COMPILER=${cudaPackages.backendStdenv.cc}/bin/gcc"
79 "-DCMAKE_CXX_COMPILER=${cudaPackages.backendStdenv.cc}/bin/g++"
80 ] ++ lib.optionals
81 (cudaSupport
82 && lib.versionAtLeast cudaPackages.cudatoolkit.version "11.4.0")
83 [ "-DBUILD_WITH_CUDA_CUB=ON" ]
84 ++ lib.optionals ncclSupport [ "-DUSE_NCCL=ON" ]
85 ++ lib.optionals rLibrary [ "-DR_LIB=ON" ];
86
87 preConfigure = lib.optionals rLibrary ''
88 substituteInPlace cmake/RPackageInstall.cmake.in --replace "CMD INSTALL" "CMD INSTALL -l $out/library"
89 export R_LIBS_SITE="$R_LIBS_SITE''${R_LIBS_SITE:+:}$out/library"
90 '';
91
92 inherit doCheck;
93
94 # By default, cmake build will run ctests with all checks enabled
95 # If we're building with cuda, we run ctest manually so that we can skip the GPU tests
96 checkPhase = lib.optionalString cudaSupport ''
97 ctest --force-new-ctest-process ${
98 lib.optionalString cudaSupport "-E TestXGBoostLib"
99 }
100 '';
101
102 # Disable finicky tests from dmlc core that fail in Hydra. XGboost team
103 # confirmed xgboost itself does not use this part of the dmlc code.
104 GTEST_FILTER =
105 let
106 # Upstream Issue: https://github.com/xtensor-stack/xsimd/issues/456
107 filteredTests = lib.optionals stdenv.hostPlatform.isDarwin [
108 "ThreadGroup.TimerThread"
109 "ThreadGroup.TimerThreadSimple"
110 ];
111 in
112 "-${builtins.concatStringsSep ":" filteredTests}";
113
114 installPhase =
115 let libname = "libxgboost${stdenv.hostPlatform.extensions.sharedLibrary}";
116 in ''
117 runHook preInstall
118 ''
119 # the R library option builds a completely different binary xgboost.so instead of
120 # libxgboost.so, which isn't full featured for python and CLI
121 + lib.optionalString rLibrary ''
122 mkdir -p $out/library
123 export R_LIBS_SITE="$out/library:$R_LIBS_SITE''${R_LIBS_SITE:+:}"
124 '' + ''
125 cmake --install .
126 cp -r ../rabit/include/rabit $out/include
127 runHook postInstall
128 '';
129
130 postFixup = lib.optionalString rLibrary ''
131 if test -e $out/nix-support/propagated-build-inputs; then
132 ln -s $out/nix-support/propagated-build-inputs $out/nix-support/propagated-user-env-packages
133 fi
134 '';
135
136 meta = with lib; {
137 description =
138 "Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library";
139 homepage = "https://github.com/dmlc/xgboost";
140 license = licenses.asl20;
141 mainProgram = "xgboost";
142 platforms = platforms.unix;
143 maintainers = with maintainers; [ abbradar nviets ];
144 };
145}