Skip to content

Commit 2038be6

Browse files
authored
Merge branch 'dmlc:release_3.1.0' into release_3.1.0
2 parents 338c7a5 + 2ac5944 commit 2038be6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+406
-266
lines changed

.github/workflows/cuda13.yml

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,21 @@ env:
1515
1616
jobs:
1717
build-cuda13:
18-
name: Build CUDA 13
18+
name: Build CUDA 13 wheel for ${{ matrix.arch }}
1919
runs-on:
2020
- runs-on=${{ github.run_id }}
21-
- runner=linux-amd64-cpu
22-
- tag=cuda13-build-cuda13
21+
- runner=${{ matrix.runner }}
22+
- tag=cuda13-build-cuda13-${{ matrix.arch }}
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
include:
27+
- arch: aarch64
28+
runner: linux-arm64-cpu
29+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8_aarch64
30+
- arch: x86_64
31+
runner: linux-amd64-cpu
32+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8
2333
steps:
2434
# Restart Docker daemon so that it recognizes the ephemeral disks
2535
- run: sudo systemctl restart docker
@@ -29,20 +39,31 @@ jobs:
2939
- name: Log into Docker registry (AWS ECR)
3040
run: bash ops/pipeline/login-docker-registry.sh
3141
- run: |
32-
bash ops/pipeline/build-cuda13.sh
42+
bash ops/pipeline/build-cuda13.sh ${{ matrix.image_repo }} ${{ matrix.arch }}
3343
- name: Stash files
3444
run: |
3545
python3 ops/pipeline/manage-artifacts.py upload \
3646
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
37-
--prefix cache/${{ github.run_id }}/build-cuda13 \
47+
--prefix cache/${{ github.run_id }}/build-cuda13-${{ matrix.arch }} \
3848
build/testxgboost ./xgboost python-package/dist/*.whl
49+
3950
test-cpp-cuda13:
40-
name: Google Test (C++) with CUDA 13
51+
name: Google Test (C++) with CUDA 13, arch ${{ matrix.arch }}
4152
needs: [build-cuda13]
4253
runs-on:
4354
- runs-on=${{ github.run_id }}
44-
- runner=linux-amd64-gpu
45-
- tag=cuda13-test-cpp-cuda13
55+
- runner=${{ matrix.runner }}
56+
- tag=cuda13-test-cpp-cuda13-${{ matrix.arch }}
57+
strategy:
58+
fail-fast: false
59+
matrix:
60+
include:
61+
- arch: aarch64
62+
runner: linux-arm64-gpu
63+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8_aarch64
64+
- arch: x86_64
65+
runner: linux-amd64-gpu
66+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8
4667
steps:
4768
# Restart Docker daemon so that it recognizes the ephemeral disks
4869
- run: sudo systemctl restart docker
@@ -55,19 +76,30 @@ jobs:
5576
run: |
5677
python3 ops/pipeline/manage-artifacts.py download \
5778
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
58-
--prefix cache/${{ github.run_id }}/build-cuda13 \
79+
--prefix cache/${{ github.run_id }}/build-cuda13-${{ matrix.arch }} \
5980
--dest-dir build \
6081
testxgboost
6182
chmod +x build/testxgboost
6283
- run: |
63-
bash ops/pipeline/test-cpp-cuda13.sh
84+
bash ops/pipeline/test-cpp-cuda13.sh ${{ matrix.image_repo }}
85+
6486
test-python-cuda13:
65-
name: Run Python tests with CUDA 13
87+
name: Run Python tests with CUDA 13, arch ${{ matrix.arch }}
6688
needs: [build-cuda13]
6789
runs-on:
6890
- runs-on=${{ github.run_id }}
69-
- runner=linux-amd64-gpu
70-
- tag=cuda13-test-python-cuda13
91+
- runner=${{ matrix.runner }}
92+
- tag=cuda13-test-python-cuda13-${{ matrix.arch }}
93+
strategy:
94+
fail-fast: false
95+
matrix:
96+
include:
97+
- arch: x86_64
98+
runner: linux-amd64-gpu
99+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8
100+
- arch: aarch64
101+
runner: linux-arm64-gpu
102+
image_repo: xgb-ci.gpu_build_cuda13_rockylinux8_aarch64
71103
steps:
72104
# Restart Docker daemon so that it recognizes the ephemeral disks
73105
- run: sudo systemctl restart docker
@@ -80,10 +112,10 @@ jobs:
80112
run: |
81113
python3 ops/pipeline/manage-artifacts.py download \
82114
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
83-
--prefix cache/${{ github.run_id }}/build-cuda13 \
115+
--prefix cache/${{ github.run_id }}/build-cuda13-${{ matrix.arch }} \
84116
--dest-dir wheelhouse \
85117
*.whl xgboost
86118
mv -v wheelhouse/xgboost .
87119
chmod +x ./xgboost
88120
- name: Run Python tests
89-
run: bash ops/pipeline/test-python-wheel-cuda13.sh
121+
run: bash ops/pipeline/test-python-wheel-cuda13.sh ${{ matrix.image_repo }}

.github/workflows/main.yml

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,21 @@ jobs:
3737
./xgboost
3838
3939
build-cuda:
40-
name: Build CUDA + manylinux_2_28_x86_64 wheel
40+
name: Build CUDA + manylinux_2_28_${{ matrix.arch }} wheel
4141
runs-on:
4242
- runs-on=${{ github.run_id }}
43-
- runner=linux-amd64-cpu
44-
- tag=main-build-cuda
43+
- runner=${{ matrix.runner }}
44+
- tag=main-build-cuda-${{ matrix.arch }}
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
include:
49+
- arch: aarch64
50+
runner: linux-arm64-cpu
51+
image_repo: xgb-ci.gpu_build_rockylinux8_aarch64
52+
- arch: x86_64
53+
runner: linux-amd64-cpu
54+
image_repo: xgb-ci.gpu_build_rockylinux8
4555
steps:
4656
# Restart Docker daemon so that it recognizes the ephemeral disks
4757
- run: sudo systemctl restart docker
@@ -51,12 +61,12 @@ jobs:
5161
- name: Log into Docker registry (AWS ECR)
5262
run: bash ops/pipeline/login-docker-registry.sh
5363
- run: |
54-
bash ops/pipeline/build-cuda.sh xgb-ci.gpu_build_rockylinux8 disable-rmm
64+
bash ops/pipeline/build-cuda.sh ${{ matrix.image_repo }} ${{ matrix.arch }} disable-rmm
5565
- name: Stash files
5666
run: |
5767
python3 ops/pipeline/manage-artifacts.py upload \
5868
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
59-
--prefix cache/${{ github.run_id }}/build-cuda \
69+
--prefix cache/${{ github.run_id }}/build-cuda-${{ matrix.arch }} \
6070
build/testxgboost ./xgboost python-package/dist/*.whl
6171
6272
build-cuda-with-rmm:
@@ -74,54 +84,14 @@ jobs:
7484
- name: Log into Docker registry (AWS ECR)
7585
run: bash ops/pipeline/login-docker-registry.sh
7686
- run: |
77-
bash ops/pipeline/build-cuda.sh xgb-ci.gpu_build_rockylinux8 enable-rmm
87+
bash ops/pipeline/build-cuda.sh xgb-ci.gpu_build_rockylinux8 x86_64 enable-rmm
7888
- name: Stash files
7989
run: |
8090
python3 ops/pipeline/manage-artifacts.py upload \
8191
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
8292
--prefix cache/${{ github.run_id }}/build-cuda-with-rmm \
8393
build/testxgboost
8494
85-
build-cuda-with-rmm-dev:
86-
name: Build CUDA with RMM (dev)
87-
runs-on:
88-
- runs-on=${{ github.run_id }}
89-
- runner=linux-amd64-cpu
90-
- tag=main-build-cuda-with-rmm-dev
91-
steps:
92-
# Restart Docker daemon so that it recognizes the ephemeral disks
93-
- run: sudo systemctl restart docker
94-
- uses: actions/checkout@v4
95-
with:
96-
submodules: "true"
97-
- name: Log into Docker registry (AWS ECR)
98-
run: bash ops/pipeline/login-docker-registry.sh
99-
- run: |
100-
bash ops/pipeline/build-cuda.sh \
101-
xgb-ci.gpu_build_rockylinux8_dev_ver enable-rmm
102-
103-
build-python-wheels-arm64:
104-
name: Build manylinux_2_28_aarch64 wheel
105-
runs-on:
106-
- runs-on=${{ github.run_id }}
107-
- runner=linux-arm64-cpu
108-
- tag=build-python-wheels-arm64
109-
steps:
110-
# Restart Docker daemon so that it recognizes the ephemeral disks
111-
- run: sudo systemctl restart docker
112-
- uses: actions/checkout@v4
113-
with:
114-
submodules: "true"
115-
- name: Log into Docker registry (AWS ECR)
116-
run: bash ops/pipeline/login-docker-registry.sh
117-
- run: bash ops/pipeline/build-python-wheels-arm64.sh
118-
- name: Stash files
119-
run: |
120-
python3 ops/pipeline/manage-artifacts.py upload \
121-
--s3-bucket ${{ env.RUNS_ON_S3_BUCKET_CACHE }} \
122-
--prefix cache/${{ github.run_id }}/build-python-wheels-arm64 \
123-
./xgboost python-package/dist/*.whl
124-
12595
build-python-wheels-cpu:
12696
name: Build CPU wheel for ${{ matrix.manylinux_target }}_${{ matrix.arch }}
12797
runs-on:
@@ -190,13 +160,20 @@ jobs:
190160
include:
191161
- suite: gpu
192162
runner: linux-amd64-gpu
193-
artifact_from: build-cuda
163+
image_repo: xgb-ci.gpu
164+
artifact_from: build-cuda-x86_64
165+
- suite: gpu
166+
runner: linux-arm64-gpu
167+
image_repo: xgb-ci.gpu_aarch64
168+
artifact_from: build-cuda-aarch64
194169
- suite: gpu-rmm
195170
runner: linux-amd64-gpu
171+
image_repo: xgb-ci.gpu
196172
artifact_from: build-cuda-with-rmm
197173
- suite: mgpu
198174
runner: linux-amd64-mgpu
199-
artifact_from: build-cuda
175+
image_repo: xgb-ci.gpu
176+
artifact_from: build-cuda-x86_64
200177
steps:
201178
# Restart Docker daemon so that it recognizes the ephemeral disks
202179
- run: sudo systemctl restart docker
@@ -213,11 +190,11 @@ jobs:
213190
--dest-dir build \
214191
testxgboost
215192
chmod +x build/testxgboost
216-
- run: bash ops/pipeline/test-cpp-gpu.sh ${{ matrix.suite }}
193+
- run: bash ops/pipeline/test-cpp-gpu.sh ${{ matrix.image_repo }} ${{ matrix.suite }}
217194

218195
test-python-wheel:
219196
name: Run Python tests (${{ matrix.description }})
220-
needs: [build-cuda, build-python-wheels-arm64]
197+
needs: [build-cuda]
221198
runs-on:
222199
- runs-on
223200
- runner=${{ matrix.runner }}
@@ -232,22 +209,27 @@ jobs:
232209
image_repo: xgb-ci.gpu
233210
suite: gpu
234211
runner: linux-amd64-gpu
235-
artifact_from: build-cuda
212+
artifact_from: build-cuda-x86_64
236213
- description: multiple-gpu
237214
image_repo: xgb-ci.gpu
238215
suite: mgpu
239216
runner: linux-amd64-mgpu
240-
artifact_from: build-cuda
217+
artifact_from: build-cuda-x86_64
241218
- description: cpu-amd64
242219
image_repo: xgb-ci.cpu
243220
suite: cpu
244221
runner: linux-amd64-cpu
245-
artifact_from: build-cuda
222+
artifact_from: build-cuda-x86_64
246223
- description: cpu-arm64
247224
image_repo: xgb-ci.manylinux_2_28_aarch64
248225
suite: cpu-arm64
249226
runner: linux-arm64-cpu
250-
artifact_from: build-python-wheels-arm64
227+
artifact_from: build-cuda-aarch64
228+
- description: gpu-arm64
229+
image_repo: xgb-ci.gpu_aarch64
230+
suite: gpu-arm64
231+
runner: linux-arm64-gpu
232+
artifact_from: build-cuda-aarch64
251233
steps:
252234
# Restart Docker daemon so that it recognizes the ephemeral disks
253235
- run: sudo systemctl restart docker

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ if(PLUGIN_SYCL)
44
string(REPLACE " -isystem ${CONDA_PREFIX}/include" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
55
endif()
66

7-
project(xgboost LANGUAGES CXX C VERSION 3.1.2)
7+
project(xgboost LANGUAGES CXX C VERSION 3.1.3)
88
include(cmake/Utils.cmake)
99
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
1010

R-package/DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: xgboost
22
Type: Package
33
Title: Extreme Gradient Boosting
4-
Version: 3.1.2.1
5-
Date: 2025-11-20
4+
Version: 3.1.3.1
5+
Date: 2026-01-05
66
Authors@R: c(
77
person("Tianqi", "Chen", role = c("aut"),
88
email = "[email protected]"),

R-package/R/utils.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ xgb.createFolds <- function(y, k) {
482482
#' \url{https://xgboost.readthedocs.io/en/latest/tutorials/saving_model.html}.
483483
#'
484484
#' @examples
485+
#' \dontshow{RhpcBLASctl::omp_set_num_threads(1)}
485486
#' data(agaricus.train, package = "xgboost")
486487
#'
487488
#' bst <- xgb.train(

R-package/R/xgb.Booster.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ xgb.get.handle <- function(object) {
252252
#' \url{https://arxiv.org/abs/1706.06060}
253253
#'
254254
#' @examples
255+
#' \dontshow{RhpcBLASctl::omp_set_num_threads(1)}
255256
#' ## binary classification:
256257
#'
257258
#' data(agaricus.train, package = "xgboost")

R-package/R/xgb.train.R

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,9 @@ xgb.train <- function(params = xgb.params(), data, nrounds, evals = list(),
338338
)
339339

340340
# the main loop for boosting iterations
341-
for (iteration in begin_iteration:end_iteration) {
341+
# FIX: Handle nrounds=0 to prevent 1:0 sequence and ensure 'iteration' is defined
342+
if (nrounds == 0) iteration <- end_iteration
343+
for (iteration in seq(from = begin_iteration, length.out = nrounds)) {
342344

343345
.execute.cb.before.iter(
344346
callbacks,
@@ -458,11 +460,11 @@ xgb.train <- function(params = xgb.params(), data, nrounds, evals = list(),
458460
#' See [Survival Analysis with Accelerated Failure Time](https://xgboost.readthedocs.io/en/latest/tutorials/aft_survival_analysis.html) for details.
459461
#' - `"multi:softmax"`: set XGBoost to do multiclass classification using the softmax objective, you also need to set num_class(number of classes)
460462
#' - `"multi:softprob"`: same as softmax, but output a vector of `ndata * nclass`, which can be further reshaped to `ndata * nclass` matrix. The result contains predicted probability of each data point belonging to each class.
461-
#' - `"rank:ndcg"`: Use LambdaMART to perform pair-wise ranking where [Normalized Discounted Cumulative Gain (NDCG)](https://en.wikipedia.org/wiki/NDCG) is maximized. This objective supports position debiasing for click data.
462-
#' - `"rank:map"`: Use LambdaMART to perform pair-wise ranking where [Mean Average Precision (MAP)](https://en.wikipedia.org/wiki/Mean_average_precision#Mean_average_precision) is maximized
463+
#' - `"rank:ndcg"`: Use LambdaMART to perform pair-wise ranking where the normalized discounted cumulative gain (NDCG) is maximized. This objective supports position debiasing for click data.
464+
#' - `"rank:map"`: Use LambdaMART to perform pair-wise ranking where the mean average precision (MAP) is maximized
463465
#' - `"rank:pairwise"`: Use LambdaRank to perform pair-wise ranking using the `ranknet` objective.
464-
#' - `"reg:gamma"`: gamma regression with log-link. Output is a mean of gamma distribution. It might be useful, e.g., for modeling insurance claims severity, or for any outcome that might be [gamma-distributed](https://en.wikipedia.org/wiki/Gamma_distribution#Occurrence_and_applications).
465-
#' - `"reg:tweedie"`: Tweedie regression with log-link. It might be useful, e.g., for modeling total loss in insurance, or for any outcome that might be [Tweedie-distributed](https://en.wikipedia.org/wiki/Tweedie_distribution#Occurrence_and_applications).
466+
#' - `"reg:gamma"`: gamma regression with log-link. Output is a mean of gamma distribution. It might be useful, e.g., for modeling insurance claims severity, or for any outcome that might be gamma-distributed.
467+
#' - `"reg:tweedie"`: Tweedie regression with log-link. It might be useful, e.g., for modeling total loss in insurance, or for any outcome that might be tweedie-distributed.
466468
#' @param verbosity (default=1)
467469
#' Verbosity of printing messages. Valid values are 0 (silent), 1 (warning), 2 (info), 3
468470
#' (debug). Sometimes XGBoost tries to change configurations based on heuristics, which
@@ -613,31 +615,31 @@ xgb.train <- function(params = xgb.params(), data, nrounds, evals = list(),
613615
#' - Evaluation metrics for validation data, a default metric will be assigned according to objective (rmse for regression, and logloss for classification, `mean average precision` for ``rank:map``, etc.)
614616
#' - User can add multiple evaluation metrics.
615617
#' - The choices are listed below:
616-
#' - `"rmse"`: [root mean square error](https://en.wikipedia.org/wiki/Root_mean_square_error)
618+
#' - `"rmse"`: root mean square error
617619
#' - `"rmsle"`: root mean square log error: \eqn{\sqrt{\frac{1}{N}[log(pred + 1) - log(label + 1)]^2}}. Default metric of `"reg:squaredlogerror"` objective. This metric reduces errors generated by outliers in dataset. But because `log` function is employed, `"rmsle"` might output `nan` when prediction value is less than -1. See `"reg:squaredlogerror"` for other requirements.
618-
#' - `"mae"`: [mean absolute error](https://en.wikipedia.org/wiki/Mean_absolute_error)
619-
#' - `"mape"`: [mean absolute percentage error](https://en.wikipedia.org/wiki/Mean_absolute_percentage_error)
620-
#' - `"mphe"`: [mean Pseudo Huber error](https://en.wikipedia.org/wiki/Huber_loss). Default metric of `"reg:pseudohubererror"` objective.
621-
#' - `"logloss"`: [negative log-likelihood](https://en.wikipedia.org/wiki/Log-likelihood)
620+
#' - `"mae"`: mean absolute error.
621+
#' - `"mape"`: mean absolute percentage error.
622+
#' - `"mphe"`: mean Pseudo Huber error. Default metric of `"reg:pseudohubererror"` objective.
623+
#' - `"logloss"`: negative log-likelihood.
622624
#' - `"error"`: Binary classification error rate. It is calculated as `#(wrong cases)/#(all cases)`. For the predictions, the evaluation will regard the instances with prediction value larger than 0.5 as positive instances, and the others as negative instances.
623625
#' - `"error@t"`: a different than 0.5 binary classification threshold value could be specified by providing a numerical value through 't'.
624626
#' - `"merror"`: Multiclass classification error rate. It is calculated as `#(wrong cases)/#(all cases)`.
625627
#' - `"mlogloss"`: [Multiclass logloss](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html).
626-
#' - `"auc"`: [Receiver Operating Characteristic Area under the Curve](https://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_the_curve).
628+
#' - `"auc"`: area under the receiver-operating characteristic curve.
627629
#' Available for classification and learning-to-rank tasks.
628630
#' - When used with binary classification, the objective should be `"binary:logistic"` or similar functions that work on probability.
629631
#' - When used with multi-class classification, objective should be `"multi:softprob"` instead of `"multi:softmax"`, as the latter doesn't output probability. Also the AUC is calculated by 1-vs-rest with reference class weighted by class prevalence.
630632
#' - When used with LTR task, the AUC is computed by comparing pairs of documents to count correctly sorted pairs. This corresponds to pairwise learning to rank. The implementation has some issues with average AUC around groups and distributed workers not being well-defined.
631633
#' - On a single machine the AUC calculation is exact. In a distributed environment the AUC is a weighted average over the AUC of training rows on each node - therefore, distributed AUC is an approximation sensitive to the distribution of data across workers. Use another metric in distributed environments if precision and reproducibility are important.
632634
#' - When input dataset contains only negative or positive samples, the output is `NaN`. The behavior is implementation defined, for instance, `scikit-learn` returns \eqn{0.5} instead.
633-
#' - `"aucpr"`: [Area under the PR curve](https://en.wikipedia.org/wiki/Precision_and_recall).
635+
#' - `"aucpr"`: area under the PR curve
634636
#' Available for classification and learning-to-rank tasks.
635637
#'
636638
#' After XGBoost 1.6, both of the requirements and restrictions for using `"aucpr"` in classification problem are similar to `"auc"`. For ranking task, only binary relevance label \eqn{y \in [0, 1]} is supported. Different from `"map"` (mean average precision), `"aucpr"` calculates the *interpolated* area under precision recall curve using continuous interpolation.
637639
#'
638640
#' - `"pre"`: Precision at \eqn{k}. Supports only learning to rank task.
639-
#' - `"ndcg"`: [Normalized Discounted Cumulative Gain](https://en.wikipedia.org/wiki/NDCG)
640-
#' - `"map"`: [Mean Average Precision](https://en.wikipedia.org/wiki/Mean_average_precision#Mean_average_precision)
641+
#' - `"ndcg"`: normalized discounted cumulative gain
642+
#' - `"map"`: mean average precision
641643
#'
642644
#' The `average precision` is defined as:
643645
#'

0 commit comments

Comments
 (0)