Compare commits

...

25 Commits

Author SHA1 Message Date
Nan Zhu
15419d3fd9
[jvm-packages] update version of 1.1.0 branch (#6435) 2020-11-25 20:15:54 +08:00
Philip Hyunsu Cho
4e1fba261d [CI] Fix cuDF install; merge 'gpu' and 'cudf' test suite (#5814) 2020-07-15 12:13:27 -07:00
Hyunsu Cho
76d1b69664 Uninstall cuPy 2020-07-14 20:34:23 -07:00
Philip Hyunsu Cho
1bf42c817a [CI] Reduce load on Windows CI pipeline (#5892) 2020-07-14 19:56:38 -07:00
Philip Hyunsu Cho
9ac614fe61 [CI] Enforce daily budget in Jenkins CI (#5884)
* [CI] Throttle Jenkins CI

* Don't use Jenkins master instance
2020-07-14 19:56:18 -07:00
Philip Hyunsu Cho
d6d8be6519
Add explicit cast to pass 32-bit CRAN check (#5777) 2020-06-14 02:36:13 -07:00
Philip Hyunsu Cho
34408a7fdc
Release patch release 1.1.1 with faster CPU performance (#5732)
* Fix release degradation (#5720)

* fix release degradation, related to 5666

* less resizes

Co-authored-by: SHVETS, KIRILL <kirill.shvets@intel.com>

* Make 1.1.1 patch release

* Disable too-many-function-args pylint warning for predict()

* Fix Windows CI

* Remove cpplint

Co-authored-by: ShvetsKS <33296480+ShvetsKS@users.noreply.github.com>
Co-authored-by: SHVETS, KIRILL <kirill.shvets@intel.com>
2020-06-04 10:56:07 -07:00
Philip Hyunsu Cho
f9b246f5ee
Add pkgconfig to cmake (#5744) (#5748)
* Add pkgconfig to cmake

* Move xgboost.pc.in to cmake/

Co-authored-by: Peter Jung <peter@jung.ninja>
Co-authored-by: Peter Jung <peter.jung@heureka.cz>
Co-authored-by: Hyunsu Cho <chohyu01@cs.washington.edu>
2020-06-02 12:04:27 -07:00
Jiaming Yuan
8467880aeb
Fix loading old model. (#5724) (#5737)
* Add test.
2020-06-01 04:32:24 +08:00
Jiaming Yuan
e74560c86a
[CI] Backport Remove CUDA 9.0 from Windows CI. (#5674) (#5738)
* [CI] Remove CUDA 9.0 from Windows CI. (#5674)

* Remove CUDA 9.0 on Windows CI.

* Require cuda10 tag, to differentiate

Co-authored-by: Philip Hyunsu Cho <chohyu01@cs.washington.edu>

* Pylint.

Co-authored-by: Philip Hyunsu Cho <chohyu01@cs.washington.edu>
2020-05-31 21:35:00 +08:00
Hyunsu Cho
882b966536 [Doc] Fix typos in AFT tutorial 2020-05-27 03:09:46 -07:00
Philip Hyunsu Cho
115e4c3360 [R] Fix duplicated libomp.dylib error on Mac OSX (#5701) 2020-05-24 23:38:42 -07:00
Hyunsu Cho
f5d4fddafe Release 1.1.0 2020-05-17 00:26:22 -07:00
Jiaming Yuan
66690f3d07 Add JSON schema to model dump. (#5660) 2020-05-15 12:26:49 +08:00
Rory Mitchell
c42f533ae9 Resolve vector<bool>::iterator crash (#5642) 2020-05-11 18:14:41 +08:00
Philip Hyunsu Cho
751160b69c
Upgrade to CUDA 10.0 (#5649)
Co-authored-by: fis <jm.yuan@outlook.com>
2020-05-11 18:04:47 +08:00
Hyunsu Cho
8aaabce7c9 Make RC2 2020-05-04 09:11:38 -07:00
Philip Hyunsu Cho
14543176d1 Fix build on big endian CPUs (#5617)
* Fix build on big endian CPUs

* Clang-tidy
2020-05-04 09:09:22 -07:00
Jason E. Aten, Ph.D
afa6e086cc Clarify meaning of training parameter in XGBoosterPredict() (#5604)
Co-authored-by: Hyunsu Cho <chohyu01@cs.washington.edu>
Co-authored-by: Jiaming Yuan <jm.yuan@outlook.com>
2020-05-04 09:08:57 -07:00
Philip Hyunsu Cho
636ab6b522 Instruct Mac users to install libomp (#5606) 2020-05-04 09:08:25 -07:00
Philip Hyunsu Cho
6daa6ee4e0 [R] Address warnings to comply with CRAN submission policy (#5600)
* [R] Address warnings to comply with CRAN submission policy

* Include <xgboost/logging.h>
2020-05-04 09:08:16 -07:00
Philip Hyunsu Cho
4979991d5b [CI] Grant public read access to Mac OSX wheels (#5602) 2020-05-04 09:07:56 -07:00
Philip Hyunsu Cho
02faddc5f3 Fix compilation on Mac OSX High Sierra (10.13) (#5597)
* Fix compilation on Mac OSX High Sierra

* [CI] Build Mac OSX binary wheel using Travis CI
2020-05-04 09:07:29 -07:00
Jiaming Yuan
844d7c1d5b Set device in device dmatrix. (#5596) 2020-04-25 13:44:30 +08:00
Hyunsu Cho
3728855ce9 Make RC1 2020-04-24 13:56:54 -07:00
47 changed files with 400 additions and 210 deletions

View File

@ -6,7 +6,7 @@ os:
- linux - linux
- osx - osx
osx_image: xcode10.3 osx_image: xcode10.1
dist: bionic dist: bionic
# Use Build Matrix to do lint and build seperately # Use Build Matrix to do lint and build seperately
@ -21,6 +21,10 @@ env:
# cmake test # cmake test
- TASK=cmake_test - TASK=cmake_test
global:
- secure: "PR16i9F8QtNwn99C5NDp8nptAS+97xwDtXEJJfEiEVhxPaaRkOp0MPWhogCaK0Eclxk1TqkgWbdXFknwGycX620AzZWa/A1K3gAs+GrpzqhnPMuoBJ0Z9qxXTbSJvCyvMbYwVrjaxc/zWqdMU8waWz8A7iqKGKs/SqbQ3rO6v7c="
- secure: "dAGAjBokqm/0nVoLMofQni/fWIBcYSmdq4XvCBX1ZAMDsWnuOfz/4XCY6h2lEI1rVHZQ+UdZkc9PioOHGPZh5BnvE49/xVVWr9c4/61lrDOlkD01ZjSAeoV0fAZq+93V/wPl4QV+MM+Sem9hNNzFSbN5VsQLAiWCSapWsLdKzqA="
matrix: matrix:
exclude: exclude:
- os: linux - os: linux

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
project(xgboost LANGUAGES CXX C VERSION 1.1.0) project(xgboost LANGUAGES CXX C VERSION 1.1.1)
include(cmake/Utils.cmake) include(cmake/Utils.cmake)
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules") list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
cmake_policy(SET CMP0022 NEW) cmake_policy(SET CMP0022 NEW)
@ -57,6 +57,7 @@ address, leak, undefined and thread.")
## Plugins ## Plugins
option(PLUGIN_LZ4 "Build lz4 plugin" OFF) option(PLUGIN_LZ4 "Build lz4 plugin" OFF)
option(PLUGIN_DENSE_PARSER "Build dense parser plugin" OFF) option(PLUGIN_DENSE_PARSER "Build dense parser plugin" OFF)
option(ADD_PKGCONFIG "Add xgboost.pc into system." ON)
#-- Checks for building XGBoost #-- Checks for building XGBoost
if (USE_DEBUG_OUTPUT AND (NOT (CMAKE_BUILD_TYPE MATCHES Debug))) if (USE_DEBUG_OUTPUT AND (NOT (CMAKE_BUILD_TYPE MATCHES Debug)))
@ -274,3 +275,12 @@ endif (GOOGLE_TEST)
# replace /MD with /MT. See https://github.com/dmlc/xgboost/issues/4462 # replace /MD with /MT. See https://github.com/dmlc/xgboost/issues/4462
# for issues caused by mixing of /MD and /MT flags # for issues caused by mixing of /MD and /MT flags
msvc_use_static_runtime() 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)

30
Jenkinsfile vendored
View File

@ -31,13 +31,14 @@ pipeline {
// Build stages // Build stages
stages { stages {
stage('Jenkins Linux: Get sources') { stage('Jenkins Linux: Initialize') {
agent { label 'linux && cpu' } agent { label 'job_initializer' }
steps { steps {
script { script {
checkoutSrcs() checkoutSrcs()
commit_id = "${GIT_COMMIT}" commit_id = "${GIT_COMMIT}"
} }
sh 'python3 tests/jenkins_get_approval.py'
stash name: 'srcs' stash name: 'srcs'
milestone ordinal: 1 milestone ordinal: 1
} }
@ -48,7 +49,6 @@ pipeline {
script { script {
parallel ([ parallel ([
'clang-tidy': { ClangTidy() }, 'clang-tidy': { ClangTidy() },
'lint': { Lint() },
'sphinx-doc': { SphinxDoc() }, 'sphinx-doc': { SphinxDoc() },
'doxygen': { Doxygen() } 'doxygen': { Doxygen() }
]) ])
@ -64,7 +64,6 @@ pipeline {
'build-cpu': { BuildCPU() }, 'build-cpu': { BuildCPU() },
'build-cpu-rabit-mock': { BuildCPUMock() }, 'build-cpu-rabit-mock': { BuildCPUMock() },
'build-cpu-non-omp': { BuildCPUNonOmp() }, 'build-cpu-non-omp': { BuildCPUNonOmp() },
'build-gpu-cuda9.0': { BuildCUDA(cuda_version: '9.0') },
'build-gpu-cuda10.0': { BuildCUDA(cuda_version: '10.0') }, 'build-gpu-cuda10.0': { BuildCUDA(cuda_version: '10.0') },
'build-gpu-cuda10.1': { BuildCUDA(cuda_version: '10.1') }, 'build-gpu-cuda10.1': { BuildCUDA(cuda_version: '10.1') },
'build-jvm-packages': { BuildJVMPackages(spark_version: '2.4.3') }, 'build-jvm-packages': { BuildJVMPackages(spark_version: '2.4.3') },
@ -251,10 +250,10 @@ def BuildCUDA(args) {
${dockerRun} ${container_type} ${docker_binary} ${docker_args} bash -c "cd python-package && rm -rf dist/* && python setup.py bdist_wheel --universal" ${dockerRun} ${container_type} ${docker_binary} ${docker_args} bash -c "cd python-package && rm -rf dist/* && python setup.py bdist_wheel --universal"
${dockerRun} ${container_type} ${docker_binary} ${docker_args} python3 tests/ci_build/rename_whl.py python-package/dist/*.whl ${commit_id} manylinux2010_x86_64 ${dockerRun} ${container_type} ${docker_binary} ${docker_args} python3 tests/ci_build/rename_whl.py python-package/dist/*.whl ${commit_id} manylinux2010_x86_64
""" """
// Stash wheel for CUDA 9.0 target // Stash wheel for CUDA 10.0 target
if (args.cuda_version == '9.0') { if (args.cuda_version == '10.0') {
echo 'Stashing Python wheel...' echo 'Stashing Python wheel...'
stash name: 'xgboost_whl_cuda9', includes: 'python-package/dist/*.whl' stash name: 'xgboost_whl_cuda10', includes: 'python-package/dist/*.whl'
path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/" path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/"
s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', workingDir: 'python-package/dist', includePathPattern:'**/*.whl' s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', workingDir: 'python-package/dist', includePathPattern:'**/*.whl'
echo 'Stashing C++ test executable (testxgboost)...' echo 'Stashing C++ test executable (testxgboost)...'
@ -298,7 +297,7 @@ def BuildJVMDoc() {
def TestPythonCPU() { def TestPythonCPU() {
node('linux && cpu') { node('linux && cpu') {
unstash name: 'xgboost_whl_cuda9' unstash name: 'xgboost_whl_cuda10'
unstash name: 'srcs' unstash name: 'srcs'
unstash name: 'xgboost_cli' unstash name: 'xgboost_cli'
echo "Test Python CPU" echo "Test Python CPU"
@ -315,7 +314,7 @@ def TestPythonCPU() {
def TestPythonGPU(args) { def TestPythonGPU(args) {
nodeReq = (args.multi_gpu) ? 'linux && mgpu' : 'linux && gpu' nodeReq = (args.multi_gpu) ? 'linux && mgpu' : 'linux && gpu'
node(nodeReq) { node(nodeReq) {
unstash name: 'xgboost_whl_cuda9' unstash name: 'xgboost_whl_cuda10'
unstash name: 'srcs' unstash name: 'srcs'
echo "Test Python GPU: CUDA ${args.cuda_version}" echo "Test Python GPU: CUDA ${args.cuda_version}"
def container_type = "gpu" def container_type = "gpu"
@ -326,25 +325,12 @@ def TestPythonGPU(args) {
sh """ sh """
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh mgpu ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh mgpu
""" """
if (args.cuda_version != '9.0') {
echo "Running tests with cuDF..."
sh """
${dockerRun} cudf ${docker_binary} ${docker_args} tests/ci_build/test_python.sh mgpu-cudf
"""
}
} else { } else {
echo "Using a single GPU" echo "Using a single GPU"
sh """ sh """
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh gpu ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh gpu
""" """
if (args.cuda_version != '9.0') {
echo "Running tests with cuDF..."
sh """
${dockerRun} cudf ${docker_binary} ${docker_args} tests/ci_build/test_python.sh cudf
"""
} }
}
// For CUDA 10.0 target, run cuDF tests too
deleteDir() deleteDir()
} }
} }

View File

@ -12,13 +12,14 @@ pipeline {
agent none agent none
// Build stages // Build stages
stages { stages {
stage('Jenkins Win64: Get sources') { stage('Jenkins Win64: Initialize') {
agent { label 'win64 && build' } agent { label 'job_initializer' }
steps { steps {
script { script {
checkoutSrcs() checkoutSrcs()
commit_id = "${GIT_COMMIT}" commit_id = "${GIT_COMMIT}"
} }
sh 'python3 tests/jenkins_get_approval.py'
stash name: 'srcs' stash name: 'srcs'
milestone ordinal: 1 milestone ordinal: 1
} }
@ -28,7 +29,7 @@ pipeline {
steps { steps {
script { script {
parallel ([ parallel ([
'build-win64-cuda9.0': { BuildWin64() } 'build-win64-cuda10.0': { BuildWin64() }
]) ])
} }
milestone ordinal: 2 milestone ordinal: 2
@ -40,8 +41,6 @@ pipeline {
script { script {
parallel ([ parallel ([
'test-win64-cpu': { TestWin64CPU() }, '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') } 'test-win64-gpu-cuda10.1': { TestWin64GPU(cuda_target: 'cuda10_1') }
]) ])
} }
@ -67,7 +66,7 @@ def checkoutSrcs() {
} }
def BuildWin64() { def BuildWin64() {
node('win64 && build') { node('win64 && build && cuda10') {
unstash name: 'srcs' unstash name: 'srcs'
echo "Building XGBoost for Windows AMD64 target..." echo "Building XGBoost for Windows AMD64 target..."
bat "nvcc --version" bat "nvcc --version"
@ -139,7 +138,7 @@ def TestWin64GPU(args) {
""" """
echo "Installing Python dependencies..." echo "Installing Python dependencies..."
bat """ bat """
conda activate && conda upgrade scikit-learn pandas numpy conda activate && conda upgrade scikit-learn pandas numpy && python -m pip uninstall -y cupy-cuda100 cupy-cuda101 cupy-cuda102
""" """
echo "Running Python tests..." echo "Running Python tests..."
bat """ bat """

View File

@ -1,7 +1,7 @@
Package: xgboost Package: xgboost
Type: Package Type: Package
Title: Extreme Gradient Boosting Title: Extreme Gradient Boosting
Version: 1.1.0.1 Version: 1.1.1.1
Date: 2020-02-21 Date: 2020-02-21
Authors@R: c( Authors@R: c(
person("Tianqi", "Chen", role = c("aut"), person("Tianqi", "Chen", role = c("aut"),

2
R-package/configure vendored
View File

@ -2698,7 +2698,7 @@ fi
if test `uname -s` = "Darwin" if test `uname -s` = "Darwin"
then then
OPENMP_CXXFLAGS='-Xclang -fopenmp' OPENMP_CXXFLAGS='-Xclang -fopenmp'
OPENMP_LIB='/usr/local/lib/libomp.dylib' OPENMP_LIB='-lomp'
ac_pkg_openmp=no ac_pkg_openmp=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenMP will work in a package" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenMP will work in a package" >&5
$as_echo_n "checking whether OpenMP will work in a package... " >&6; } $as_echo_n "checking whether OpenMP will work in a package... " >&6; }

View File

@ -29,7 +29,7 @@ fi
if test `uname -s` = "Darwin" if test `uname -s` = "Darwin"
then then
OPENMP_CXXFLAGS='-Xclang -fopenmp' OPENMP_CXXFLAGS='-Xclang -fopenmp'
OPENMP_LIB='/usr/local/lib/libomp.dylib' OPENMP_LIB='-lomp'
ac_pkg_openmp=no ac_pkg_openmp=no
AC_MSG_CHECKING([whether OpenMP will work in a package]) AC_MSG_CHECKING([whether OpenMP will work in a package])
AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <omp.h>]], [[ return (omp_get_max_threads() <= 1); ]])]) AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <omp.h>]], [[ return (omp_get_max_threads() <= 1); ]])])

View File

@ -410,7 +410,7 @@ In some very specific cases, like when you want to pilot **XGBoost** from `caret
```{r saveLoadRBinVectorModel, message=F, warning=F} ```{r saveLoadRBinVectorModel, message=F, warning=F}
# save model to R's raw vector # save model to R's raw vector
rawVec <- xgb.save.raw(bst) rawVec <- xgb.serialize(bst)
# print class # print class
print(class(rawVec)) print(class(rawVec))

View File

@ -1 +1 @@
@xgboost_VERSION_MAJOR@.@xgboost_VERSION_MINOR@.@xgboost_VERSION_PATCH@-SNAPSHOT @xgboost_VERSION_MAJOR@.@xgboost_VERSION_MINOR@.@xgboost_VERSION_PATCH@

12
cmake/xgboost.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
version=@xgboost_VERSION@
exec_prefix=${prefix}/bin
libdir=${prefix}/lib
includedir=${prefix}/include
Name: xgboost
Description: XGBoost - Scalable and Flexible Gradient Boosting.
Version: ${version}
Cflags: -I${includedir}
Libs: -L${libdir} -lxgboost

55
doc/dump.schema Normal file
View File

@ -0,0 +1,55 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"split_node": {
"type": "object",
"properties": {
"nodeid": {
"type": "number",
"minimum": 0
},
"depth": {
"type": "number",
"minimum": 0
},
"yes": {
"type": "number",
"minimum": 0
},
"no": {
"type": "number",
"minimum": 0
},
"split": {
"type": "string"
},
"children": {
"type": "array",
"items": {
"oneOf": [
{"$ref": "#/definitions/split_node"},
{"$ref": "#/definitions/leaf_node"}
]
},
"maxItems": 2
}
},
"required": ["nodeid", "depth", "yes", "no", "split", "children"]
},
"leaf_node": {
"type": "object",
"properties": {
"nodeid": {
"type": "number",
"minimum": 0
},
"leaf": {
"type": "number"
}
},
"required": ["nodeid", "leaf"]
}
},
"type": "object",
"$ref": "#/definitions/split_node"
}

View File

@ -35,7 +35,7 @@ There are four kinds of censoring:
* **Uncensored**: the label is not censored and given as a single number. * **Uncensored**: the label is not censored and given as a single number.
* **Right-censored**: the label is of form :math:`[a, +\infty)`, where :math:`a` is the lower bound. * **Right-censored**: the label is of form :math:`[a, +\infty)`, where :math:`a` is the lower bound.
* **Left-censored**: the label is of form :math:`(-\infty, b]`, where :math:`b` is the upper bound. * **Left-censored**: the label is of form :math:`[0, b]`, where :math:`b` is the upper bound.
* **Interval-censored**: the label is of form :math:`[a, b]`, where :math:`a` and :math:`b` are the lower and upper bounds, respectively. * **Interval-censored**: the label is of form :math:`[a, b]`, where :math:`a` and :math:`b` are the lower and upper bounds, respectively.
Right-censoring is the most commonly used. Right-censoring is the most commonly used.
@ -83,7 +83,7 @@ Censoring type Interval form Lower bound finite? Upper bound finite?
================= ==================== =================== =================== ================= ==================== =================== ===================
Uncensored :math:`[a, a]` |tick| |tick| Uncensored :math:`[a, a]` |tick| |tick|
Right-censored :math:`[a, +\infty)` |tick| |cross| Right-censored :math:`[a, +\infty)` |tick| |cross|
Left-censored :math:`(-\infty, b]` |cross| |tick| Left-censored :math:`[0, b]` |tick| |tick|
Interval-censored :math:`[a, b]` |tick| |tick| Interval-censored :math:`[a, b]` |tick| |tick|
================= ==================== =================== =================== ================= ==================== =================== ===================
@ -102,7 +102,7 @@ Collect the lower bound numbers in one array (let's call it ``y_lower_bound``) a
# Associate ranged labels with the data matrix. # Associate ranged labels with the data matrix.
# This example shows each kind of censored labels. # This example shows each kind of censored labels.
# uncensored right left interval # uncensored right left interval
y_lower_bound = np.array([ 2.0, 3.0, -np.inf, 4.0]) y_lower_bound = np.array([ 2.0, 3.0, 0.0, 4.0])
y_upper_bound = np.array([ 2.0, +np.inf, 4.0, 5.0]) y_upper_bound = np.array([ 2.0, +np.inf, 4.0, 5.0])
dtrain.set_float_info('label_lower_bound', y_lower_bound) dtrain.set_float_info('label_lower_bound', y_lower_bound)
dtrain.set_float_info('label_upper_bound', y_upper_bound) dtrain.set_float_info('label_upper_bound', y_upper_bound)
@ -120,7 +120,7 @@ Collect the lower bound numbers in one array (let's call it ``y_lower_bound``) a
# Associate ranged labels with the data matrix. # Associate ranged labels with the data matrix.
# This example shows each kind of censored labels. # This example shows each kind of censored labels.
# uncensored right left interval # uncensored right left interval
y_lower_bound <- c( 2., 3., -Inf, 4.) y_lower_bound <- c( 2., 3., 0., 4.)
y_upper_bound <- c( 2., +Inf, 4., 5.) y_upper_bound <- c( 2., +Inf, 4., 5.)
setinfo(dtrain, 'label_lower_bound', y_lower_bound) setinfo(dtrain, 'label_lower_bound', y_lower_bound)
setinfo(dtrain, 'label_upper_bound', y_upper_bound) setinfo(dtrain, 'label_upper_bound', y_upper_bound)
@ -136,7 +136,7 @@ Now we are ready to invoke the training API:
'aft_loss_distribution_scale': 1.20, 'aft_loss_distribution_scale': 1.20,
'tree_method': 'hist', 'learning_rate': 0.05, 'max_depth': 2} 'tree_method': 'hist', 'learning_rate': 0.05, 'max_depth': 2}
bst = xgb.train(params, dtrain, num_boost_round=5, bst = xgb.train(params, dtrain, num_boost_round=5,
evals=[(dtrain, 'train'), (dvalid, 'valid')]) evals=[(dtrain, 'train')])
.. code-block:: r .. code-block:: r
:caption: R :caption: R

View File

@ -418,7 +418,14 @@ XGB_DLL int XGBoosterEvalOneIter(BoosterHandle handle,
* 4:output feature contributions to individual predictions * 4:output feature contributions to individual predictions
* \param ntree_limit limit number of trees used for prediction, this is only valid for boosted trees * \param ntree_limit limit number of trees used for prediction, this is only valid for boosted trees
* when the parameter is set to 0, we will use all the trees * when the parameter is set to 0, we will use all the trees
* \param training Whether the prediction value is used for training. * \param training Whether the prediction function is used as part of a training loop.
* Prediction can be run in 2 scenarios:
* 1. Given data matrix X, obtain prediction y_pred from the model.
* 2. Obtain the prediction for computing gradients. For example, DART booster performs dropout
* during training, and the prediction result will be different from the one obtained by normal
* inference step due to dropped trees.
* Set training=false for the first scenario. Set training=true for the second scenario.
* The second scenario applies when you are defining a custom objective function.
* \param out_len used to store length of returning result * \param out_len used to store length of returning result
* \param out_result used to set a pointer to array * \param out_result used to set a pointer to array
* \return 0 when success, -1 when failure happens * \return 0 when success, -1 when failure happens

View File

@ -9,6 +9,7 @@
#include <dmlc/base.h> #include <dmlc/base.h>
#include <dmlc/data.h> #include <dmlc/data.h>
#include <dmlc/serializer.h>
#include <rabit/rabit.h> #include <rabit/rabit.h>
#include <xgboost/base.h> #include <xgboost/base.h>
#include <xgboost/span.h> #include <xgboost/span.h>
@ -102,7 +103,7 @@ class MetaInfo {
/*! /*!
* \brief Validate all metainfo. * \brief Validate all metainfo.
*/ */
void Validate() const; void Validate(int32_t device) const;
MetaInfo Slice(common::Span<int32_t const> ridxs) const; MetaInfo Slice(common::Span<int32_t const> ridxs) const;
/*! /*!
@ -554,5 +555,21 @@ inline BatchSet<EllpackPage> DMatrix::GetBatches(const BatchParam& param) {
namespace dmlc { namespace dmlc {
DMLC_DECLARE_TRAITS(is_pod, xgboost::Entry, true); DMLC_DECLARE_TRAITS(is_pod, xgboost::Entry, true);
}
namespace serializer {
template <>
struct Handler<xgboost::Entry> {
inline static void Write(Stream* strm, const xgboost::Entry& data) {
strm->Write(data.index);
strm->Write(data.fvalue);
}
inline static bool Read(Stream* strm, xgboost::Entry* data) {
return strm->Read(&data->index) && strm->Read(&data->fvalue);
}
};
} // namespace serializer
} // namespace dmlc
#endif // XGBOOST_DATA_H_ #endif // XGBOOST_DATA_H_

View File

@ -30,6 +30,7 @@
#define XGBOOST_SPAN_H_ #define XGBOOST_SPAN_H_
#include <xgboost/base.h> #include <xgboost/base.h>
#include <xgboost/logging.h>
#include <cinttypes> // size_t #include <cinttypes> // size_t
#include <limits> // numeric_limits #include <limits> // numeric_limits
@ -85,9 +86,11 @@ namespace common {
} \ } \
} while (0); } while (0);
#ifdef __CUDA_ARCH__ #if defined(__CUDA_ARCH__)
#define SPAN_CHECK KERNEL_CHECK #define SPAN_CHECK KERNEL_CHECK
#else #elif defined(XGBOOST_STRICT_R_MODE) && XGBOOST_STRICT_R_MODE == 1 // R package
#define SPAN_CHECK CHECK // check from dmlc
#else // not CUDA, not R
#define SPAN_CHECK(cond) \ #define SPAN_CHECK(cond) \
do { \ do { \
if (XGBOOST_EXPECT(!(cond), false)) { \ if (XGBOOST_EXPECT(!(cond), false)) { \

View File

@ -6,6 +6,6 @@
#define XGBOOST_VER_MAJOR 1 #define XGBOOST_VER_MAJOR 1
#define XGBOOST_VER_MINOR 1 #define XGBOOST_VER_MINOR 1
#define XGBOOST_VER_PATCH 0 #define XGBOOST_VER_PATCH 1
#endif // XGBOOST_VERSION_CONFIG_H_ #endif // XGBOOST_VERSION_CONFIG_H_

View File

@ -6,7 +6,7 @@
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost-jvm_2.12</artifactId> <artifactId>xgboost-jvm_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>XGBoost JVM Package</name> <name>XGBoost JVM Package</name>
<description>JVM Package for XGBoost</description> <description>JVM Package for XGBoost</description>

View File

@ -6,10 +6,10 @@
<parent> <parent>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost-jvm_2.12</artifactId> <artifactId>xgboost-jvm_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</parent> </parent>
<artifactId>xgboost4j-example_2.12</artifactId> <artifactId>xgboost4j-example_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<build> <build>
<plugins> <plugins>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost4j-spark_${scala.binary.version}</artifactId> <artifactId>xgboost4j-spark_${scala.binary.version}</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.spark</groupId> <groupId>org.apache.spark</groupId>
@ -37,7 +37,7 @@
<dependency> <dependency>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost4j-flink_${scala.binary.version}</artifactId> <artifactId>xgboost4j-flink_${scala.binary.version}</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>

View File

@ -6,10 +6,10 @@
<parent> <parent>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost-jvm_2.12</artifactId> <artifactId>xgboost-jvm_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</parent> </parent>
<artifactId>xgboost4j-flink_2.12</artifactId> <artifactId>xgboost4j-flink_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost4j_${scala.binary.version}</artifactId> <artifactId>xgboost4j_${scala.binary.version}</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost-jvm_2.12</artifactId> <artifactId>xgboost-jvm_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</parent> </parent>
<artifactId>xgboost4j-spark_2.12</artifactId> <artifactId>xgboost4j-spark_2.12</artifactId>
<build> <build>
@ -24,7 +24,7 @@
<dependency> <dependency>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost4j_${scala.binary.version}</artifactId> <artifactId>xgboost4j_${scala.binary.version}</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.spark</groupId> <groupId>org.apache.spark</groupId>

View File

@ -6,10 +6,10 @@
<parent> <parent>
<groupId>ml.dmlc</groupId> <groupId>ml.dmlc</groupId>
<artifactId>xgboost-jvm_2.12</artifactId> <artifactId>xgboost-jvm_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
</parent> </parent>
<artifactId>xgboost4j_2.12</artifactId> <artifactId>xgboost4j_2.12</artifactId>
<version>1.1.0-SNAPSHOT</version> <version>1.1.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>

View File

@ -1 +1 @@
1.1.0-SNAPSHOT 1.1.1

View File

@ -159,8 +159,9 @@ def _load_lib():
'XGBoost Library ({}) could not be loaded.\n'.format(libname) + 'XGBoost Library ({}) could not be loaded.\n'.format(libname) +
'Likely causes:\n' + 'Likely causes:\n' +
' * OpenMP runtime is not installed ' + ' * OpenMP runtime is not installed ' +
'(vcomp140.dll or libgomp-1.dll for Windows, ' + '(vcomp140.dll or libgomp-1.dll for Windows, libomp.dylib for Mac OSX, ' +
'libgomp.so for UNIX-like OSes)\n' + 'libgomp.so for Linux and other UNIX-like OSes). Mac OSX users: Run ' +
'`brew install libomp` to install OpenMP runtime.\n' +
' * You are running 32-bit Python on a 64-bit OS\n' + ' * You are running 32-bit Python on a 64-bit OS\n' +
'Error message(s): {}\n'.format(os_error_list)) 'Error message(s): {}\n'.format(os_error_list))
lib.XGBGetLastError.restype = ctypes.c_char_p lib.XGBGetLastError.restype = ctypes.c_char_p
@ -1466,6 +1467,7 @@ class Booster(object):
self._validate_features(data) self._validate_features(data)
return self.eval_set([(data, name)], iteration) return self.eval_set([(data, name)], iteration)
# pylint: disable=too-many-function-args
def predict(self, def predict(self,
data, data,
output_margin=False, output_margin=False,
@ -1587,7 +1589,7 @@ class Booster(object):
ngroup = int(chunk_size / ((data.num_col() + 1) * ngroup = int(chunk_size / ((data.num_col() + 1) *
(data.num_col() + 1))) (data.num_col() + 1)))
if ngroup == 1: if ngroup == 1:
preds = preds.reshape(nrow, preds = preds.reshape(nrow, # pylint: disable=too-many-function-args
data.num_col() + 1, data.num_col() + 1,
data.num_col() + 1) data.num_col() + 1)
else: else:

View File

@ -181,7 +181,7 @@ XGB_DLL int XGDMatrixSliceDMatrixEx(DMatrixHandle handle,
<< "slice does not support group structure"; << "slice does not support group structure";
} }
DMatrix* dmat = static_cast<std::shared_ptr<DMatrix>*>(handle)->get(); DMatrix* dmat = static_cast<std::shared_ptr<DMatrix>*>(handle)->get();
*out = new std::shared_ptr<DMatrix>(dmat->Slice({idxset, len})); *out = new std::shared_ptr<DMatrix>(dmat->Slice({idxset, static_cast<std::size_t>(len)}));
API_END(); API_END();
} }
@ -426,7 +426,7 @@ XGB_DLL int XGBoosterPredict(BoosterHandle handle,
DMatrixHandle dmat, DMatrixHandle dmat,
int option_mask, int option_mask,
unsigned ntree_limit, unsigned ntree_limit,
int32_t training, int training,
xgboost::bst_ulong *len, xgboost::bst_ulong *len,
const bst_float **out_result) { const bst_float **out_result) {
API_BEGIN(); API_BEGIN();

View File

@ -82,14 +82,16 @@ template <typename BinIdxType>
class DenseColumn: public Column<BinIdxType> { class DenseColumn: public Column<BinIdxType> {
public: public:
DenseColumn(ColumnType type, common::Span<const BinIdxType> index, DenseColumn(ColumnType type, common::Span<const BinIdxType> index,
uint32_t index_base, uint32_t index_base, const std::vector<bool>& missing_flags,
const std::vector<bool>::const_iterator missing_flags) size_t feature_offset)
: Column<BinIdxType>(type, index, index_base), : Column<BinIdxType>(type, index, index_base),
missing_flags_(missing_flags) {} missing_flags_(missing_flags),
bool IsMissing(size_t idx) const { return missing_flags_[idx]; } feature_offset_(feature_offset) {}
bool IsMissing(size_t idx) const { return missing_flags_[feature_offset_ + idx]; }
private: private:
/* flags for missing values in dense columns */ /* flags for missing values in dense columns */
std::vector<bool>::const_iterator missing_flags_; const std::vector<bool>& missing_flags_;
size_t feature_offset_;
}; };
/*! \brief a collection of columns, with support for construction from /*! \brief a collection of columns, with support for construction from
@ -208,10 +210,8 @@ class ColumnMatrix {
column_size }; column_size };
std::unique_ptr<const Column<BinIdxType> > res; std::unique_ptr<const Column<BinIdxType> > res;
if (type_[fid] == ColumnType::kDenseColumn) { if (type_[fid] == ColumnType::kDenseColumn) {
std::vector<bool>::const_iterator column_iterator = missing_flags_.begin();
advance(column_iterator, feature_offset); // increment iterator to right position
res.reset(new DenseColumn<BinIdxType>(type_[fid], bin_index, index_base_[fid], res.reset(new DenseColumn<BinIdxType>(type_[fid], bin_index, index_base_[fid],
column_iterator)); missing_flags_, feature_offset));
} else { } else {
res.reset(new SparseColumn<BinIdxType>(type_[fid], bin_index, index_base_[fid], res.reset(new SparseColumn<BinIdxType>(type_[fid], bin_index, index_base_[fid],
{&row_ind_[feature_offset], column_size})); {&row_ind_[feature_offset], column_size}));

View File

@ -37,7 +37,7 @@ template <typename T>
void SaveScalarField(dmlc::Stream *strm, const std::string &name, void SaveScalarField(dmlc::Stream *strm, const std::string &name,
xgboost::DataType type, const T &field) { xgboost::DataType type, const T &field) {
strm->Write(name); strm->Write(name);
strm->Write(type); strm->Write(static_cast<uint8_t>(type));
strm->Write(true); // is_scalar=True strm->Write(true); // is_scalar=True
strm->Write(field); strm->Write(field);
} }
@ -47,7 +47,7 @@ void SaveVectorField(dmlc::Stream *strm, const std::string &name,
xgboost::DataType type, std::pair<uint64_t, uint64_t> shape, xgboost::DataType type, std::pair<uint64_t, uint64_t> shape,
const std::vector<T>& field) { const std::vector<T>& field) {
strm->Write(name); strm->Write(name);
strm->Write(type); strm->Write(static_cast<uint8_t>(type));
strm->Write(false); // is_scalar=False strm->Write(false); // is_scalar=False
strm->Write(shape.first); strm->Write(shape.first);
strm->Write(shape.second); strm->Write(shape.second);
@ -71,7 +71,9 @@ void LoadScalarField(dmlc::Stream* strm, const std::string& expected_name,
CHECK(strm->Read(&name)) << invalid; CHECK(strm->Read(&name)) << invalid;
CHECK_EQ(name, expected_name) CHECK_EQ(name, expected_name)
<< invalid << " Expected field: " << expected_name << ", got: " << name; << invalid << " Expected field: " << expected_name << ", got: " << name;
CHECK(strm->Read(&type)) << invalid; uint8_t type_val;
CHECK(strm->Read(&type_val)) << invalid;
type = static_cast<xgboost::DataType>(type_val);
CHECK(type == expected_type) CHECK(type == expected_type)
<< invalid << "Expected field of type: " << static_cast<int>(expected_type) << ", " << invalid << "Expected field of type: " << static_cast<int>(expected_type) << ", "
<< "got field type: " << static_cast<int>(type); << "got field type: " << static_cast<int>(type);
@ -91,7 +93,9 @@ void LoadVectorField(dmlc::Stream* strm, const std::string& expected_name,
CHECK(strm->Read(&name)) << invalid; CHECK(strm->Read(&name)) << invalid;
CHECK_EQ(name, expected_name) CHECK_EQ(name, expected_name)
<< invalid << " Expected field: " << expected_name << ", got: " << name; << invalid << " Expected field: " << expected_name << ", got: " << name;
CHECK(strm->Read(&type)) << invalid; uint8_t type_val;
CHECK(strm->Read(&type_val)) << invalid;
type = static_cast<xgboost::DataType>(type_val);
CHECK(type == expected_type) CHECK(type == expected_type)
<< invalid << "Expected field of type: " << static_cast<int>(expected_type) << ", " << invalid << "Expected field of type: " << static_cast<int>(expected_type) << ", "
<< "got field type: " << static_cast<int>(type); << "got field type: " << static_cast<int>(type);
@ -338,7 +342,7 @@ void MetaInfo::SetInfo(const char* key, const void* dptr, DataType dtype, size_t
} }
} }
void MetaInfo::Validate() const { void MetaInfo::Validate(int32_t device) const {
if (group_ptr_.size() != 0 && weights_.Size() != 0) { if (group_ptr_.size() != 0 && weights_.Size() != 0) {
CHECK_EQ(group_ptr_.size(), weights_.Size() + 1) CHECK_EQ(group_ptr_.size(), weights_.Size() + 1)
<< "Size of weights must equal to number of groups when ranking " << "Size of weights must equal to number of groups when ranking "
@ -350,30 +354,44 @@ void MetaInfo::Validate() const {
<< "Invalid group structure. Number of rows obtained from groups " << "Invalid group structure. Number of rows obtained from groups "
"doesn't equal to actual number of rows given by data."; "doesn't equal to actual number of rows given by data.";
} }
auto check_device = [device](HostDeviceVector<float> const &v) {
CHECK(v.DeviceIdx() == GenericParameter::kCpuId ||
device == GenericParameter::kCpuId ||
v.DeviceIdx() == device)
<< "Data is resided on a different device than `gpu_id`. "
<< "Device that data is on: " << v.DeviceIdx() << ", "
<< "`gpu_id` for XGBoost: " << device;
};
if (weights_.Size() != 0) { if (weights_.Size() != 0) {
CHECK_EQ(weights_.Size(), num_row_) CHECK_EQ(weights_.Size(), num_row_)
<< "Size of weights must equal to number of rows."; << "Size of weights must equal to number of rows.";
check_device(weights_);
return; return;
} }
if (labels_.Size() != 0) { if (labels_.Size() != 0) {
CHECK_EQ(labels_.Size(), num_row_) CHECK_EQ(labels_.Size(), num_row_)
<< "Size of labels must equal to number of rows."; << "Size of labels must equal to number of rows.";
check_device(labels_);
return; return;
} }
if (labels_lower_bound_.Size() != 0) { if (labels_lower_bound_.Size() != 0) {
CHECK_EQ(labels_lower_bound_.Size(), num_row_) CHECK_EQ(labels_lower_bound_.Size(), num_row_)
<< "Size of label_lower_bound must equal to number of rows."; << "Size of label_lower_bound must equal to number of rows.";
check_device(labels_lower_bound_);
return; return;
} }
if (labels_upper_bound_.Size() != 0) { if (labels_upper_bound_.Size() != 0) {
CHECK_EQ(labels_upper_bound_.Size(), num_row_) CHECK_EQ(labels_upper_bound_.Size(), num_row_)
<< "Size of label_upper_bound must equal to number of rows."; << "Size of label_upper_bound must equal to number of rows.";
check_device(labels_upper_bound_);
return; return;
} }
CHECK_LE(num_nonzero_, num_col_ * num_row_); CHECK_LE(num_nonzero_, num_col_ * num_row_);
if (base_margin_.Size() != 0) { if (base_margin_.Size() != 0) {
CHECK_EQ(base_margin_.Size() % num_row_, 0) CHECK_EQ(base_margin_.Size() % num_row_, 0)
<< "Size of base margin must be a multiple of number of rows."; << "Size of base margin must be a multiple of number of rows.";
check_device(base_margin_);
} }
} }

View File

@ -201,6 +201,7 @@ template <typename AdapterT>
DeviceDMatrix::DeviceDMatrix(AdapterT* adapter, float missing, int nthread, int max_bin) { DeviceDMatrix::DeviceDMatrix(AdapterT* adapter, float missing, int nthread, int max_bin) {
common::HistogramCuts cuts = common::HistogramCuts cuts =
common::AdapterDeviceSketch(adapter, max_bin, missing); common::AdapterDeviceSketch(adapter, max_bin, missing);
dh::safe_cuda(cudaSetDevice(adapter->DeviceIdx()));
auto& batch = adapter->Value(); auto& batch = adapter->Value();
// Work out how many valid entries we have in each row // Work out how many valid entries we have in each row
dh::caching_device_vector<size_t> row_counts(adapter->NumRows() + 1, 0); dh::caching_device_vector<size_t> row_counts(adapter->NumRows() + 1, 0);

View File

@ -99,6 +99,7 @@ void CopyDataRowMajor(AdapterT* adapter, common::Span<Entry> data,
// be supported in future. Does not currently support inferring row/column size // be supported in future. Does not currently support inferring row/column size
template <typename AdapterT> template <typename AdapterT>
SimpleDMatrix::SimpleDMatrix(AdapterT* adapter, float missing, int nthread) { SimpleDMatrix::SimpleDMatrix(AdapterT* adapter, float missing, int nthread) {
dh::safe_cuda(cudaSetDevice(adapter->DeviceIdx()));
CHECK(adapter->NumRows() != kAdapterUnknownSize); CHECK(adapter->NumRows() != kAdapterUnknownSize);
CHECK(adapter->NumColumns() != kAdapterUnknownSize); CHECK(adapter->NumColumns() != kAdapterUnknownSize);

View File

@ -689,15 +689,23 @@ class LearnerIO : public LearnerConfiguration {
warn_old_model = false; warn_old_model = false;
} }
if (mparam_.major_version >= 1) { if (mparam_.major_version < 1) {
learner_model_param_ = LearnerModelParam(mparam_,
obj_->ProbToMargin(mparam_.base_score));
} else {
// Before 1.0.0, base_score is saved as a transformed value, and there's no version // Before 1.0.0, base_score is saved as a transformed value, and there's no version
// attribute in the saved model. // attribute (saved a 0) in the saved model.
learner_model_param_ = LearnerModelParam(mparam_, mparam_.base_score); std::string multi{"multi:"};
if (!std::equal(multi.cbegin(), multi.cend(), tparam_.objective.cbegin())) {
HostDeviceVector<float> t;
t.HostVector().resize(1);
t.HostVector().at(0) = mparam_.base_score;
this->obj_->PredTransform(&t);
auto base_score = t.HostVector().at(0);
mparam_.base_score = base_score;
}
warn_old_model = true; warn_old_model = true;
} }
learner_model_param_ =
LearnerModelParam(mparam_, obj_->ProbToMargin(mparam_.base_score));
if (attributes_.find("objective") != attributes_.cend()) { if (attributes_.find("objective") != attributes_.cend()) {
auto obj_str = attributes_.at("objective"); auto obj_str = attributes_.at("objective");
auto j_obj = Json::Load({obj_str.c_str(), obj_str.size()}); auto j_obj = Json::Load({obj_str.c_str(), obj_str.size()});
@ -1052,7 +1060,7 @@ class LearnerImpl : public LearnerIO {
void ValidateDMatrix(DMatrix* p_fmat) const { void ValidateDMatrix(DMatrix* p_fmat) const {
MetaInfo const& info = p_fmat->Info(); MetaInfo const& info = p_fmat->Info();
info.Validate(); info.Validate(generic_parameters_.gpu_id);
auto const row_based_split = [this]() { auto const row_based_split = [this]() {
return tparam_.dsplit == DataSplitMode::kRow || return tparam_.dsplit == DataSplitMode::kRow ||

View File

@ -70,8 +70,7 @@ struct EvalAFT : public Metric {
double nloglik_sum = 0.0; double nloglik_sum = 0.0;
double weight_sum = 0.0; double weight_sum = 0.0;
#pragma omp parallel for default(none) \ #pragma omp parallel for \
firstprivate(nsize, is_null_weight, aft_loss_distribution_scale) \
shared(weights, y_lower, y_upper, yhat) reduction(+:nloglik_sum, weight_sum) shared(weights, y_lower, y_upper, yhat) reduction(+:nloglik_sum, weight_sum)
for (omp_ulong i = 0; i < nsize; ++i) { for (omp_ulong i = 0; i < nsize; ++i) {
// If weights are empty, data is unweighted so we use 1.0 everywhere // If weights are empty, data is unweighted so we use 1.0 everywhere

View File

@ -56,8 +56,7 @@ class AFTObj : public ObjFunction {
const omp_ulong nsize = static_cast<omp_ulong>(yhat.size()); const omp_ulong nsize = static_cast<omp_ulong>(yhat.size());
const float aft_loss_distribution_scale = param_.aft_loss_distribution_scale; const float aft_loss_distribution_scale = param_.aft_loss_distribution_scale;
#pragma omp parallel for default(none) \ #pragma omp parallel for \
firstprivate(nsize, is_null_weight, aft_loss_distribution_scale) \
shared(weights, y_lower, y_upper, yhat, gpair) shared(weights, y_lower, y_upper, yhat, gpair)
for (omp_ulong i = 0; i < nsize; ++i) { for (omp_ulong i = 0; i < nsize; ++i) {
// If weights are empty, data is unweighted so we use 1.0 everywhere // If weights are empty, data is unweighted so we use 1.0 everywhere
@ -74,7 +73,7 @@ class AFTObj : public ObjFunction {
// Trees give us a prediction in log scale, so exponentiate // Trees give us a prediction in log scale, so exponentiate
std::vector<bst_float> &preds = io_preds->HostVector(); std::vector<bst_float> &preds = io_preds->HostVector();
const long ndata = static_cast<long>(preds.size()); // NOLINT(*) const long ndata = static_cast<long>(preds.size()); // NOLINT(*)
#pragma omp parallel for default(none) firstprivate(ndata) shared(preds) #pragma omp parallel for shared(preds)
for (long j = 0; j < ndata; ++j) { // NOLINT(*) for (long j = 0; j < ndata; ++j) { // NOLINT(*)
preds[j] = std::exp(preds[j]); preds[j] = std::exp(preds[j]);
} }

View File

@ -41,10 +41,11 @@ struct RegLossParam : public XGBoostParameter<RegLossParam> {
template<typename Loss> template<typename Loss>
class RegLossObj : public ObjFunction { class RegLossObj : public ObjFunction {
protected: protected:
HostDeviceVector<int> label_correct_; HostDeviceVector<float> additional_input_;
public: public:
RegLossObj() = default; // 0 - label_correct flag, 1 - scale_pos_weight, 2 - is_null_weight
RegLossObj(): additional_input_(3) {}
void Configure(const std::vector<std::pair<std::string, std::string> >& args) override { void Configure(const std::vector<std::pair<std::string, std::string> >& args) override {
param_.UpdateAllowUnknown(args); param_.UpdateAllowUnknown(args);
@ -64,8 +65,7 @@ class RegLossObj : public ObjFunction {
size_t const ndata = preds.Size(); size_t const ndata = preds.Size();
out_gpair->Resize(ndata); out_gpair->Resize(ndata);
auto device = tparam_->gpu_id; auto device = tparam_->gpu_id;
label_correct_.Resize(1); additional_input_.HostVector().begin()[0] = 1; // Fill the label_correct flag
label_correct_.Fill(1);
bool is_null_weight = info.weights_.Size() == 0; bool is_null_weight = info.weights_.Size() == 0;
if (!is_null_weight) { if (!is_null_weight) {
@ -73,37 +73,39 @@ class RegLossObj : public ObjFunction {
<< "Number of weights should be equal to number of data points."; << "Number of weights should be equal to number of data points.";
} }
auto scale_pos_weight = param_.scale_pos_weight; auto scale_pos_weight = param_.scale_pos_weight;
common::Transform<>::Init( additional_input_.HostVector().begin()[1] = scale_pos_weight;
[=] XGBOOST_DEVICE(size_t _idx, additional_input_.HostVector().begin()[2] = is_null_weight;
common::Span<int> _label_correct,
common::Transform<>::Init([] XGBOOST_DEVICE(size_t _idx,
common::Span<float> _additional_input,
common::Span<GradientPair> _out_gpair, common::Span<GradientPair> _out_gpair,
common::Span<const bst_float> _preds, common::Span<const bst_float> _preds,
common::Span<const bst_float> _labels, common::Span<const bst_float> _labels,
common::Span<const bst_float> _weights) { common::Span<const bst_float> _weights) {
const float _scale_pos_weight = _additional_input[1];
const bool _is_null_weight = _additional_input[2];
bst_float p = Loss::PredTransform(_preds[_idx]); bst_float p = Loss::PredTransform(_preds[_idx]);
bst_float w = is_null_weight ? 1.0f : _weights[_idx]; bst_float w = _is_null_weight ? 1.0f : _weights[_idx];
bst_float label = _labels[_idx]; bst_float label = _labels[_idx];
if (label == 1.0f) { if (label == 1.0f) {
w *= scale_pos_weight; w *= _scale_pos_weight;
} }
if (!Loss::CheckLabel(label)) { if (!Loss::CheckLabel(label)) {
// If there is an incorrect label, the host code will know. // If there is an incorrect label, the host code will know.
_label_correct[0] = 0; _additional_input[0] = 0;
} }
_out_gpair[_idx] = GradientPair(Loss::FirstOrderGradient(p, label) * w, _out_gpair[_idx] = GradientPair(Loss::FirstOrderGradient(p, label) * w,
Loss::SecondOrderGradient(p, label) * w); Loss::SecondOrderGradient(p, label) * w);
}, },
common::Range{0, static_cast<int64_t>(ndata)}, device).Eval( common::Range{0, static_cast<int64_t>(ndata)}, device).Eval(
&label_correct_, out_gpair, &preds, &info.labels_, &info.weights_); &additional_input_, out_gpair, &preds, &info.labels_, &info.weights_);
// copy "label correct" flags back to host auto const flag = additional_input_.HostVector().begin()[0];
std::vector<int>& label_correct_h = label_correct_.HostVector();
for (auto const flag : label_correct_h) {
if (flag == 0) { if (flag == 0) {
LOG(FATAL) << Loss::LabelErrorMsg(); LOG(FATAL) << Loss::LabelErrorMsg();
} }
} }
}
public: public:
const char* DefaultEvalMetric() const override { const char* DefaultEvalMetric() const override {

View File

@ -68,20 +68,20 @@ class TreeGenerator {
return result; return result;
} }
virtual std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) { virtual std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) const {
return ""; return "";
} }
virtual std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) { virtual std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) const {
return ""; return "";
} }
virtual std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) { virtual std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) const {
return ""; return "";
} }
virtual std::string NodeStat(RegTree const& tree, int32_t nid) { virtual std::string NodeStat(RegTree const& tree, int32_t nid) const {
return ""; return "";
} }
virtual std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) = 0; virtual std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) const = 0;
virtual std::string SplitNode(RegTree const& tree, int32_t nid, uint32_t depth) { virtual std::string SplitNode(RegTree const& tree, int32_t nid, uint32_t depth) {
auto const split_index = tree[nid].SplitIndex(); auto const split_index = tree[nid].SplitIndex();
@ -110,7 +110,7 @@ class TreeGenerator {
return result; return result;
} }
virtual std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) = 0; virtual std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) const = 0;
virtual std::string BuildTree(RegTree const& tree, int32_t nid, uint32_t depth) = 0; virtual std::string BuildTree(RegTree const& tree, int32_t nid, uint32_t depth) = 0;
public: public:
@ -181,7 +181,7 @@ class TextGenerator : public TreeGenerator {
TextGenerator(FeatureMap const& fmap, std::string const& attrs, bool with_stats) : TextGenerator(FeatureMap const& fmap, std::string const& attrs, bool with_stats) :
TreeGenerator(fmap, with_stats) {} TreeGenerator(fmap, with_stats) {}
std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string kLeafTemplate = "{tabs}{nid}:leaf={leaf}{stats}"; static std::string kLeafTemplate = "{tabs}{nid}:leaf={leaf}{stats}";
static std::string kStatTemplate = ",cover={cover}"; static std::string kStatTemplate = ",cover={cover}";
std::string result = SuperT::Match( std::string result = SuperT::Match(
@ -195,7 +195,7 @@ class TextGenerator : public TreeGenerator {
return result; return result;
} }
std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kIndicatorTemplate = "{nid}:[{fname}] yes={yes},no={no}"; static std::string const kIndicatorTemplate = "{nid}:[{fname}] yes={yes},no={no}";
int32_t nyes = tree[nid].DefaultLeft() ? int32_t nyes = tree[nid].DefaultLeft() ?
tree[nid].RightChild() : tree[nid].LeftChild(); tree[nid].RightChild() : tree[nid].LeftChild();
@ -211,7 +211,7 @@ class TextGenerator : public TreeGenerator {
std::string SplitNodeImpl( std::string SplitNodeImpl(
RegTree const& tree, int32_t nid, std::string const& template_str, RegTree const& tree, int32_t nid, std::string const& template_str,
std::string cond, uint32_t depth) { std::string cond, uint32_t depth) const {
auto split_index = tree[nid].SplitIndex(); auto split_index = tree[nid].SplitIndex();
std::string const result = SuperT::Match( std::string const result = SuperT::Match(
template_str, template_str,
@ -226,7 +226,7 @@ class TextGenerator : public TreeGenerator {
return result; return result;
} }
std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kIntegerTemplate = static std::string const kIntegerTemplate =
"{tabs}{nid}:[{fname}<{cond}] yes={left},no={right},missing={missing}"; "{tabs}{nid}:[{fname}<{cond}] yes={left},no={right},missing={missing}";
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
@ -238,21 +238,21 @@ class TextGenerator : public TreeGenerator {
std::to_string(integer_threshold), depth); std::to_string(integer_threshold), depth);
} }
std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kQuantitiveTemplate = static std::string const kQuantitiveTemplate =
"{tabs}{nid}:[{fname}<{cond}] yes={left},no={right},missing={missing}"; "{tabs}{nid}:[{fname}<{cond}] yes={left},no={right},missing={missing}";
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
return SplitNodeImpl(tree, nid, kQuantitiveTemplate, SuperT::ToStr(cond), depth); return SplitNodeImpl(tree, nid, kQuantitiveTemplate, SuperT::ToStr(cond), depth);
} }
std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
static std::string const kNodeTemplate = static std::string const kNodeTemplate =
"{tabs}{nid}:[f{fname}<{cond}] yes={left},no={right},missing={missing}"; "{tabs}{nid}:[f{fname}<{cond}] yes={left},no={right},missing={missing}";
return SplitNodeImpl(tree, nid, kNodeTemplate, SuperT::ToStr(cond), depth); return SplitNodeImpl(tree, nid, kNodeTemplate, SuperT::ToStr(cond), depth);
} }
std::string NodeStat(RegTree const& tree, int32_t nid) override { std::string NodeStat(RegTree const& tree, int32_t nid) const override {
static std::string const kStatTemplate = ",gain={loss_chg},cover={sum_hess}"; static std::string const kStatTemplate = ",gain={loss_chg},cover={sum_hess}";
std::string const result = SuperT::Match( std::string const result = SuperT::Match(
kStatTemplate, kStatTemplate,
@ -297,7 +297,7 @@ class JsonGenerator : public TreeGenerator {
JsonGenerator(FeatureMap const& fmap, std::string attrs, bool with_stats) : JsonGenerator(FeatureMap const& fmap, std::string attrs, bool with_stats) :
TreeGenerator(fmap, with_stats) {} TreeGenerator(fmap, with_stats) {}
std::string Indent(uint32_t depth) { std::string Indent(uint32_t depth) const {
std::string result; std::string result;
for (uint32_t i = 0; i < depth + 1; ++i) { for (uint32_t i = 0; i < depth + 1; ++i) {
result += " "; result += " ";
@ -305,7 +305,7 @@ class JsonGenerator : public TreeGenerator {
return result; return result;
} }
std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kLeafTemplate = static std::string const kLeafTemplate =
R"L({ "nodeid": {nid}, "leaf": {leaf} {stat}})L"; R"L({ "nodeid": {nid}, "leaf": {leaf} {stat}})L";
static std::string const kStatTemplate = static std::string const kStatTemplate =
@ -321,11 +321,11 @@ class JsonGenerator : public TreeGenerator {
return result; return result;
} }
std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Indicator(RegTree const& tree, int32_t nid, uint32_t depth) const override {
int32_t nyes = tree[nid].DefaultLeft() ? int32_t nyes = tree[nid].DefaultLeft() ?
tree[nid].RightChild() : tree[nid].LeftChild(); tree[nid].RightChild() : tree[nid].LeftChild();
static std::string const kIndicatorTemplate = static std::string const kIndicatorTemplate =
R"ID( "nodeid": {nid}, "depth": {depth}, "split": "{fname}", "yes": {yes}, "no": {no}})ID"; R"ID( "nodeid": {nid}, "depth": {depth}, "split": "{fname}", "yes": {yes}, "no": {no})ID";
auto split_index = tree[nid].SplitIndex(); auto split_index = tree[nid].SplitIndex();
auto result = SuperT::Match( auto result = SuperT::Match(
kIndicatorTemplate, kIndicatorTemplate,
@ -337,8 +337,9 @@ class JsonGenerator : public TreeGenerator {
return result; return result;
} }
std::string SplitNodeImpl(RegTree const& tree, int32_t nid, std::string SplitNodeImpl(RegTree const &tree, int32_t nid,
std::string const& template_str, std::string cond, uint32_t depth) { std::string const &template_str, std::string cond,
uint32_t depth) const {
auto split_index = tree[nid].SplitIndex(); auto split_index = tree[nid].SplitIndex();
std::string const result = SuperT::Match( std::string const result = SuperT::Match(
template_str, template_str,
@ -353,7 +354,7 @@ class JsonGenerator : public TreeGenerator {
return result; return result;
} }
std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Integer(RegTree const& tree, int32_t nid, uint32_t depth) const override {
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
const bst_float floored = std::floor(cond); const bst_float floored = std::floor(cond);
const int32_t integer_threshold const int32_t integer_threshold
@ -367,7 +368,7 @@ class JsonGenerator : public TreeGenerator {
std::to_string(integer_threshold), depth); std::to_string(integer_threshold), depth);
} }
std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string Quantitive(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kQuantitiveTemplate = static std::string const kQuantitiveTemplate =
R"I( "nodeid": {nid}, "depth": {depth}, "split": "{fname}", )I" R"I( "nodeid": {nid}, "depth": {depth}, "split": "{fname}", )I"
R"I("split_condition": {cond}, "yes": {left}, "no": {right}, )I" R"I("split_condition": {cond}, "yes": {left}, "no": {right}, )I"
@ -376,7 +377,7 @@ class JsonGenerator : public TreeGenerator {
return SplitNodeImpl(tree, nid, kQuantitiveTemplate, SuperT::ToStr(cond), depth); return SplitNodeImpl(tree, nid, kQuantitiveTemplate, SuperT::ToStr(cond), depth);
} }
std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
static std::string const kNodeTemplate = static std::string const kNodeTemplate =
R"I( "nodeid": {nid}, "depth": {depth}, "split": {fname}, )I" R"I( "nodeid": {nid}, "depth": {depth}, "split": {fname}, )I"
@ -385,7 +386,7 @@ class JsonGenerator : public TreeGenerator {
return SplitNodeImpl(tree, nid, kNodeTemplate, SuperT::ToStr(cond), depth); return SplitNodeImpl(tree, nid, kNodeTemplate, SuperT::ToStr(cond), depth);
} }
std::string NodeStat(RegTree const& tree, int32_t nid) override { std::string NodeStat(RegTree const& tree, int32_t nid) const override {
static std::string kStatTemplate = static std::string kStatTemplate =
R"S(, "gain": {loss_chg}, "cover": {sum_hess})S"; R"S(, "gain": {loss_chg}, "cover": {sum_hess})S";
auto result = SuperT::Match( auto result = SuperT::Match(
@ -529,7 +530,7 @@ class GraphvizGenerator : public TreeGenerator {
protected: protected:
// Only indicator is different, so we combine all different node types into this // Only indicator is different, so we combine all different node types into this
// function. // function.
std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string PlainNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
auto split = tree[nid].SplitIndex(); auto split = tree[nid].SplitIndex();
auto cond = tree[nid].SplitCond(); auto cond = tree[nid].SplitCond();
static std::string const kNodeTemplate = static std::string const kNodeTemplate =
@ -563,7 +564,7 @@ class GraphvizGenerator : public TreeGenerator {
return result; return result;
}; };
std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) override { std::string LeafNode(RegTree const& tree, int32_t nid, uint32_t depth) const override {
static std::string const kLeafTemplate = static std::string const kLeafTemplate =
" {nid} [ label=\"leaf={leaf-value}\" {params}]\n"; " {nid} [ label=\"leaf={leaf-value}\" {params}]\n";
auto result = SuperT::Match(kLeafTemplate, { auto result = SuperT::Match(kLeafTemplate, {

View File

@ -1,37 +0,0 @@
ARG CUDA_VERSION
FROM nvidia/cuda:$CUDA_VERSION-runtime-ubuntu16.04
# Environment
ENV DEBIAN_FRONTEND noninteractive
SHELL ["/bin/bash", "-c"] # Use Bash as shell
# Install all basic requirements
RUN \
apt-get update && \
apt-get install -y wget unzip bzip2 libgomp1 build-essential && \
# Python
wget -O Miniconda3.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
bash Miniconda3.sh -b -p /opt/python
ENV PATH=/opt/python/bin:$PATH
# Create new Conda environment with cuDF, Dask, and cuPy
RUN \
conda create -n cudf_test -c rapidsai -c nvidia -c conda-forge -c defaults \
python=3.7 cudf cudatoolkit=$CUDA_VERSION dask dask-cuda dask-cudf cupy \
numpy pytest scipy scikit-learn pandas matplotlib wheel python-kubernetes urllib3 graphviz
ENV GOSU_VERSION 1.10
# Install lightweight sudo (not bound to TTY)
RUN set -ex; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-amd64" && \
chmod +x /usr/local/bin/gosu && \
gosu nobody true
# Default entry-point to use if running locally
# It will preserve attributes of created files
COPY entrypoint.sh /scripts/
WORKDIR /workspace
ENTRYPOINT ["/scripts/entrypoint.sh"]

View File

@ -3,6 +3,7 @@ FROM nvidia/cuda:$CUDA_VERSION-runtime-ubuntu16.04
# Environment # Environment
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND noninteractive
SHELL ["/bin/bash", "-c"] # Use Bash as shell
# Install all basic requirements # Install all basic requirements
RUN \ RUN \
@ -14,11 +15,11 @@ RUN \
ENV PATH=/opt/python/bin:$PATH ENV PATH=/opt/python/bin:$PATH
# Install Python packages # Create new Conda environment with cuDF, Dask, and cuPy
RUN \ RUN \
conda create -n gpu_test -c rapidsai -c nvidia -c conda-forge -c defaults \ conda create -n gpu_test -c rapidsai -c nvidia -c conda-forge -c defaults \
python=3.7 dask dask-cuda numpy pytest scipy scikit-learn pandas \ python=3.7 cudf=0.14 cudatoolkit=$CUDA_VERSION dask dask-cuda dask-cudf cupy \
matplotlib wheel python-kubernetes urllib3 graphviz numpy pytest scipy scikit-learn pandas matplotlib wheel python-kubernetes urllib3 graphviz
ENV GOSU_VERSION 1.10 ENV GOSU_VERSION 1.10

View File

@ -21,8 +21,6 @@ whl_path = sys.argv[1]
commit_id = sys.argv[2] commit_id = sys.argv[2]
platform_tag = sys.argv[3] platform_tag = sys.argv[3]
assert platform_tag in ['manylinux1_x86_64', 'manylinux2010_x86_64', 'win_amd64']
dirname, basename = os.path.dirname(whl_path), os.path.basename(whl_path) dirname, basename = os.path.dirname(whl_path), os.path.basename(whl_path)
with cd(dirname): with cd(dirname):

View File

@ -44,20 +44,6 @@ case "$suite" in
cd - cd -
;; ;;
cudf)
source activate cudf_test
install_xgboost
pytest -v -s -rxXs --fulltrace -m "not mgpu" \
tests/python-gpu/test_from_cudf.py tests/python-gpu/test_from_cupy.py \
tests/python-gpu/test_gpu_prediction.py
;;
mgpu-cudf)
source activate cudf_test
install_xgboost
pytest -v -s -rxXs --fulltrace -m "mgpu" tests/python-gpu/test_gpu_with_dask.py
;;
cpu) cpu)
install_xgboost install_xgboost
pytest -v -s --fulltrace tests/python pytest -v -s --fulltrace tests/python
@ -72,7 +58,7 @@ case "$suite" in
;; ;;
*) *)
echo "Usage: $0 {gpu|mgpu|cudf|cpu|cpu-py35}" echo "Usage: $0 {gpu|mgpu|cpu|cpu-py35}"
exit 1 exit 1
;; ;;
esac esac

View File

@ -149,9 +149,17 @@ TEST(MetaInfo, Validate) {
info.num_col_ = 3; info.num_col_ = 3;
std::vector<xgboost::bst_group_t> groups (11); std::vector<xgboost::bst_group_t> groups (11);
info.SetInfo("group", groups.data(), xgboost::DataType::kUInt32, 11); info.SetInfo("group", groups.data(), xgboost::DataType::kUInt32, 11);
EXPECT_THROW(info.Validate(), dmlc::Error); EXPECT_THROW(info.Validate(0), dmlc::Error);
std::vector<float> labels(info.num_row_ + 1); std::vector<float> labels(info.num_row_ + 1);
info.SetInfo("label", labels.data(), xgboost::DataType::kFloat32, info.num_row_ + 1); info.SetInfo("label", labels.data(), xgboost::DataType::kFloat32, info.num_row_ + 1);
EXPECT_THROW(info.Validate(), dmlc::Error); EXPECT_THROW(info.Validate(0), dmlc::Error);
#if defined(XGBOOST_USE_CUDA)
info.group_ptr_.clear();
labels.resize(info.num_row_);
info.SetInfo("label", labels.data(), xgboost::DataType::kFloat32, info.num_row_);
info.labels_.SetDevice(0);
EXPECT_THROW(info.Validate(1), dmlc::Error);
#endif // defined(XGBOOST_USE_CUDA)
} }

View File

@ -151,6 +151,10 @@ TEST(Tree, DumpJson) {
str = tree.DumpModel(fmap, false, "json"); str = tree.DumpModel(fmap, false, "json");
ASSERT_EQ(str.find("cover"), std::string::npos); ASSERT_EQ(str.find("cover"), std::string::npos);
auto j_tree = Json::Load({str.c_str(), str.size()});
ASSERT_EQ(get<Array>(j_tree["children"]).size(), 2);
} }
TEST(Tree, DumpText) { TEST(Tree, DumpText) {

View File

@ -0,0 +1,26 @@
import boto3
import json
lambda_client = boto3.client('lambda', region_name='us-west-2')
# Source code for the Lambda function is available at https://github.com/hcho3/xgboost-devops
r = lambda_client.invoke(
FunctionName='XGBoostCICostWatcher',
InvocationType='RequestResponse',
Payload='{}'.encode('utf-8')
)
payload = r['Payload'].read().decode('utf-8')
if 'FunctionError' in r:
msg = 'Error when invoking the Lambda function. Stack trace:\n'
error = json.loads(payload)
msg += f" {error['errorType']}: {error['errorMessage']}\n"
for trace in error['stackTrace']:
for line in trace.split('\n'):
msg += f' {line}\n'
raise RuntimeError(msg)
response = json.loads(payload)
if response['approved']:
print(f"Testing approved. Reason: {response['reason']}")
else:
raise RuntimeError(f"Testing rejected. Reason: {response['reason']}")

View File

@ -1,3 +1,4 @@
[pytest] [pytest]
markers = markers =
mgpu: Mark a test that requires multiple GPUs to run. mgpu: Mark a test that requires multiple GPUs to run.
ci: Mark a test that runs only on CI.

View File

@ -136,3 +136,14 @@ Arrow specification.'''
n = 100 n = 100
X = cp.random.random((n, 2)) X = cp.random.random((n, 2))
xgb.DeviceQuantileDMatrix(X.toDlpack()) xgb.DeviceQuantileDMatrix(X.toDlpack())
@pytest.mark.skipif(**tm.no_cupy())
@pytest.mark.mgpu
def test_specified_device(self):
import cupy as cp
cp.cuda.runtime.setDevice(0)
dtrain = dmatrix_from_cupy(
np.float32, xgb.DeviceQuantileDMatrix, np.nan)
with pytest.raises(xgb.core.XGBoostError):
xgb.train({'tree_method': 'gpu_hist', 'gpu_id': 1},
dtrain, num_boost_round=10)

View File

@ -12,25 +12,15 @@ rng = np.random.RandomState(1994)
class TestGPUBasicModels(unittest.TestCase): class TestGPUBasicModels(unittest.TestCase):
cputest = test_bm.TestModels() cputest = test_bm.TestModels()
def test_eta_decay_gpu_hist(self): def run_cls(self, X, y, deterministic):
self.cputest.run_eta_decay('gpu_hist')
def test_deterministic_gpu_hist(self):
kRows = 1000
kCols = 64
kClasses = 4
# Create large values to force rounding.
X = np.random.randn(kRows, kCols) * 1e4
y = np.random.randint(0, kClasses, size=kRows)
cls = xgb.XGBClassifier(tree_method='gpu_hist', cls = xgb.XGBClassifier(tree_method='gpu_hist',
deterministic_histogram=True, deterministic_histogram=deterministic,
single_precision_histogram=True) single_precision_histogram=True)
cls.fit(X, y) cls.fit(X, y)
cls.get_booster().save_model('test_deterministic_gpu_hist-0.json') cls.get_booster().save_model('test_deterministic_gpu_hist-0.json')
cls = xgb.XGBClassifier(tree_method='gpu_hist', cls = xgb.XGBClassifier(tree_method='gpu_hist',
deterministic_histogram=True, deterministic_histogram=deterministic,
single_precision_histogram=True) single_precision_histogram=True)
cls.fit(X, y) cls.fit(X, y)
cls.get_booster().save_model('test_deterministic_gpu_hist-1.json') cls.get_booster().save_model('test_deterministic_gpu_hist-1.json')
@ -40,7 +30,24 @@ class TestGPUBasicModels(unittest.TestCase):
with open('test_deterministic_gpu_hist-1.json', 'r') as fd: with open('test_deterministic_gpu_hist-1.json', 'r') as fd:
model_1 = fd.read() model_1 = fd.read()
assert hash(model_0) == hash(model_1)
os.remove('test_deterministic_gpu_hist-0.json') os.remove('test_deterministic_gpu_hist-0.json')
os.remove('test_deterministic_gpu_hist-1.json') os.remove('test_deterministic_gpu_hist-1.json')
return hash(model_0), hash(model_1)
def test_eta_decay_gpu_hist(self):
self.cputest.run_eta_decay('gpu_hist')
def test_deterministic_gpu_hist(self):
kRows = 1000
kCols = 64
kClasses = 4
# Create large values to force rounding.
X = np.random.randn(kRows, kCols) * 1e4
y = np.random.randint(0, kClasses, size=kRows) * 1e4
model_0, model_1 = self.run_cls(X, y, True)
assert model_0 == model_1
model_0, model_1 = self.run_cls(X, y, False)
assert model_0 != model_1

View File

@ -121,6 +121,7 @@ class TestGPUPredict(unittest.TestCase):
@pytest.mark.skipif(**tm.no_cupy()) @pytest.mark.skipif(**tm.no_cupy())
def test_inplace_predict_cupy(self): def test_inplace_predict_cupy(self):
import cupy as cp import cupy as cp
cp.cuda.runtime.setDevice(0)
rows = 1000 rows = 1000
cols = 10 cols = 10
cp_rng = cp.random.RandomState(1994) cp_rng = cp.random.RandomState(1994)

View File

@ -325,7 +325,7 @@ class TestModels(unittest.TestCase):
assert locale.getpreferredencoding(False) == loc assert locale.getpreferredencoding(False) == loc
@pytest.mark.skipif(**tm.no_json_schema()) @pytest.mark.skipif(**tm.no_json_schema())
def test_json_schema(self): def test_json_io_schema(self):
import jsonschema import jsonschema
model_path = 'test_json_schema.json' model_path = 'test_json_schema.json'
path = os.path.dirname( path = os.path.dirname(
@ -342,3 +342,35 @@ class TestModels(unittest.TestCase):
jsonschema.validate(instance=json_model(model_path, parameters), jsonschema.validate(instance=json_model(model_path, parameters),
schema=schema) schema=schema)
os.remove(model_path) os.remove(model_path)
@pytest.mark.skipif(**tm.no_json_schema())
def test_json_dump_schema(self):
import jsonschema
def validate_model(parameters):
X = np.random.random((100, 30))
y = np.random.randint(0, 4, size=(100,))
parameters['num_class'] = 4
m = xgb.DMatrix(X, y)
booster = xgb.train(parameters, m)
dump = booster.get_dump(dump_format='json')
for i in range(len(dump)):
jsonschema.validate(instance=json.loads(dump[i]),
schema=schema)
path = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
doc = os.path.join(path, 'doc', 'dump.schema')
with open(doc, 'r') as fd:
schema = json.load(fd)
parameters = {'tree_method': 'hist', 'booster': 'gbtree',
'objective': 'multi:softmax'}
validate_model(parameters)
parameters = {'tree_method': 'hist', 'booster': 'dart',
'objective': 'multi:softmax'}
validate_model(parameters)

View File

@ -4,6 +4,7 @@ import generate_models as gm
import json import json
import zipfile import zipfile
import pytest import pytest
import copy
def run_model_param_check(config): def run_model_param_check(config):
@ -124,6 +125,9 @@ def test_model_compatibility():
if name.startswith('xgboost-'): if name.startswith('xgboost-'):
booster = xgboost.Booster(model_file=path) booster = xgboost.Booster(model_file=path)
run_booster_check(booster, name) run_booster_check(booster, name)
# Do full serialization.
booster = copy.copy(booster)
run_booster_check(booster, name)
elif name.startswith('xgboost_scikit'): elif name.startswith('xgboost_scikit'):
run_scikit_model_check(name, path) run_scikit_model_check(name, path)
else: else:

View File

@ -23,18 +23,42 @@ if [ ${TASK} == "python_test" ]; then
mkdir build && cd build mkdir build && cd build
cmake .. -DUSE_OPENMP=ON -DCMAKE_VERBOSE_MAKEFILE=ON cmake .. -DUSE_OPENMP=ON -DCMAKE_VERBOSE_MAKEFILE=ON
make -j$(nproc) make -j$(nproc)
cd ..
echo "-------------------------------" echo "-------------------------------"
conda activate python3 conda activate python3
conda --version conda --version
python --version python --version
# Build binary wheel
cd ../python-package
python setup.py bdist_wheel
TAG=macosx_10_13_x86_64.macosx_10_14_x86_64.macosx_10_15_x86_64
python ../tests/ci_build/rename_whl.py dist/*.whl ${TRAVIS_COMMIT} ${TAG}
python -m pip install ./dist/xgboost-*-py3-none-${TAG}.whl
# Run unit tests
cd ..
python -m pip install graphviz pytest pytest-cov codecov python -m pip install graphviz pytest pytest-cov codecov
python -m pip install datatable python -m pip install datatable
python -m pip install numpy scipy pandas matplotlib scikit-learn dask[complete] python -m pip install numpy scipy pandas matplotlib scikit-learn dask[complete]
python -m pytest -v --fulltrace -s tests/python --cov=python-package/xgboost || exit -1 python -m pytest -v --fulltrace -s tests/python --cov=python-package/xgboost || exit -1
codecov codecov
# Deploy binary wheel to S3
python -m pip install awscli
if [ "${TRAVIS_PULL_REQUEST}" != "false" ]
then
S3_DEST="s3://xgboost-nightly-builds/PR-${TRAVIS_PULL_REQUEST}/"
else
if [ "${TRAVIS_BRANCH}" == "master" ]
then
S3_DEST="s3://xgboost-nightly-builds/"
elif [ -z "${TRAVIS_TAG}" ]
then
S3_DEST="s3://xgboost-nightly-builds/${TRAVIS_BRANCH}/"
fi
fi
python -m awscli s3 cp python-package/dist/*.whl "${S3_DEST}" --acl public-read || true
fi fi
if [ ${TASK} == "java_test" ]; then if [ ${TASK} == "java_test" ]; then