Skip to content

Commit

Permalink
Add global configuration (#6414)
Browse files Browse the repository at this point in the history
* Add management functions for global configuration: XGBSetGlobalConfig(), XGBGetGlobalConfig().
* Add Python interface: set_config(), get_config(), and config_context().
* Add unit tests for Python
* Add R interface: xgb.set.config(), xgb.get.config()
* Add unit tests for R

Co-authored-by: Jiaming Yuan <jm.yuan@outlook.com>
  • Loading branch information
hcho3 and trivialfis committed Dec 3, 2020
1 parent c2ba4fb commit fb56da5
Show file tree
Hide file tree
Showing 29 changed files with 639 additions and 88 deletions.
2 changes: 1 addition & 1 deletion R-package/DESCRIPTION
Expand Up @@ -53,7 +53,6 @@ Suggests:
testthat,
lintr,
igraph (>= 1.0.1),
jsonlite,
float,
crayon,
titanic
Expand All @@ -64,5 +63,6 @@ Imports:
methods,
data.table (>= 1.9.6),
magrittr (>= 1.5),
jsonlite (>= 1.0),
RoxygenNote: 7.1.1
SystemRequirements: GNU make, C++14
4 changes: 4 additions & 0 deletions R-package/NAMESPACE
Expand Up @@ -36,6 +36,7 @@ export(xgb.create.features)
export(xgb.cv)
export(xgb.dump)
export(xgb.gblinear.history)
export(xgb.get.config)
export(xgb.ggplot.deepness)
export(xgb.ggplot.importance)
export(xgb.ggplot.shap.summary)
Expand All @@ -52,6 +53,7 @@ export(xgb.plot.tree)
export(xgb.save)
export(xgb.save.raw)
export(xgb.serialize)
export(xgb.set.config)
export(xgb.train)
export(xgb.unserialize)
export(xgboost)
Expand All @@ -78,6 +80,8 @@ importFrom(graphics,lines)
importFrom(graphics,par)
importFrom(graphics,points)
importFrom(graphics,title)
importFrom(jsonlite,fromJSON)
importFrom(jsonlite,toJSON)
importFrom(magrittr,"%>%")
importFrom(stats,median)
importFrom(stats,predict)
Expand Down
38 changes: 38 additions & 0 deletions R-package/R/xgb.config.R
@@ -0,0 +1,38 @@
#' Global configuration consists of a collection of parameters that can be applied in the global
#' scope. See \url{https://xgboost.readthedocs.io/en/stable/parameter.html} for the full list of
#' parameters supported in the global configuration. Use \code{xgb.set.config} to update the
#' values of one or more global-scope parameters. Use \code{xgb.get.config} to fetch the current
#' values of all global-scope parameters (listed in
#' \url{https://xgboost.readthedocs.io/en/stable/parameter.html}).
#'
#' @rdname xgbConfig
#' @title Set and get global configuration
#' @name xgb.set.config, xgb.get.config
#' @export xgb.set.config xgb.get.config
#' @param ... List of parameters to be set, as keyword arguments
#' @return
#' \code{xgb.set.config} returns \code{TRUE} to signal success. \code{xgb.get.config} returns
#' a list containing all global-scope parameters and their values.
#'
#' @examples
#' # Set verbosity level to silent (0)
#' xgb.set.config(verbosity = 0)
#' # Now global verbosity level is 0
#' config <- xgb.get.config()
#' print(config$verbosity)
#' # Set verbosity level to warning (1)
#' xgb.set.config(verbosity = 1)
#' # Now global verbosity level is 1
#' config <- xgb.get.config()
#' print(config$verbosity)
xgb.set.config <- function(...) {
new_config <- list(...)
.Call(XGBSetGlobalConfig_R, jsonlite::toJSON(new_config, auto_unbox = TRUE))
return(TRUE)
}

#' @rdname xgbConfig
xgb.get.config <- function() {
config <- .Call(XGBGetGlobalConfig_R)
return(jsonlite::fromJSON(config))
}
2 changes: 2 additions & 0 deletions R-package/R/xgboost.R
Expand Up @@ -91,6 +91,8 @@ NULL
#' @importFrom data.table setkeyv
#' @importFrom data.table setnames
#' @importFrom magrittr %>%
#' @importFrom jsonlite fromJSON
#' @importFrom jsonlite toJSON
#' @importFrom utils object.size str tail
#' @importFrom stats predict
#' @importFrom stats median
Expand Down
39 changes: 39 additions & 0 deletions R-package/man/xgbConfig.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions R-package/src/init.c
Expand Up @@ -43,6 +43,8 @@ extern SEXP XGDMatrixNumRow_R(SEXP);
extern SEXP XGDMatrixSaveBinary_R(SEXP, SEXP, SEXP);
extern SEXP XGDMatrixSetInfo_R(SEXP, SEXP, SEXP);
extern SEXP XGDMatrixSliceDMatrix_R(SEXP, SEXP);
extern SEXP XGBSetGlobalConfig_R(SEXP);
extern SEXP XGBGetGlobalConfig_R();

static const R_CallMethodDef CallEntries[] = {
{"XGBoosterBoostOneIter_R", (DL_FUNC) &XGBoosterBoostOneIter_R, 4},
Expand Down Expand Up @@ -73,6 +75,8 @@ static const R_CallMethodDef CallEntries[] = {
{"XGDMatrixSaveBinary_R", (DL_FUNC) &XGDMatrixSaveBinary_R, 3},
{"XGDMatrixSetInfo_R", (DL_FUNC) &XGDMatrixSetInfo_R, 3},
{"XGDMatrixSliceDMatrix_R", (DL_FUNC) &XGDMatrixSliceDMatrix_R, 2},
{"XGBSetGlobalConfig_R", (DL_FUNC) &XGBSetGlobalConfig_R, 1},
{"XGBGetGlobalConfig_R", (DL_FUNC) &XGBGetGlobalConfig_R, 0},
{NULL, NULL, 0}
};

Expand Down
15 changes: 15 additions & 0 deletions R-package/src/xgboost_R.cc
Expand Up @@ -49,6 +49,21 @@ void _DMatrixFinalizer(SEXP ext) {
R_API_END();
}

SEXP XGBSetGlobalConfig_R(SEXP json_str) {
R_API_BEGIN();
CHECK_CALL(XGBSetGlobalConfig(CHAR(asChar(json_str))));
R_API_END();
return R_NilValue;
}

SEXP XGBGetGlobalConfig_R() {
const char* json_str;
R_API_BEGIN();
CHECK_CALL(XGBGetGlobalConfig(&json_str));
R_API_END();
return mkString(json_str);
}

SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
SEXP ret;
R_API_BEGIN();
Expand Down
13 changes: 13 additions & 0 deletions R-package/src/xgboost_R.h
Expand Up @@ -21,6 +21,19 @@
*/
XGB_DLL SEXP XGCheckNullPtr_R(SEXP handle);

/*!
* \brief Set global configuration
* \param json_str a JSON string representing the list of key-value pairs
* \return R_NilValue
*/
XGB_DLL SEXP XGBSetGlobalConfig_R(SEXP json_str);

/*!
* \brief Get global configuration
* \return JSON string
*/
XGB_DLL SEXP XGBGetGlobalConfig_R();

/*!
* \brief load a data matrix
* \param fname name of the content
Expand Down
2 changes: 1 addition & 1 deletion R-package/src/xgboost_custom.cc
Expand Up @@ -16,7 +16,7 @@ void CustomLogMessage::Log(const std::string& msg) {
namespace xgboost {
ConsoleLogger::~ConsoleLogger() {
if (cur_verbosity_ == LogVerbosity::kIgnore ||
cur_verbosity_ <= global_verbosity_) {
cur_verbosity_ <= GlobalVerbosity()) {
dmlc::CustomLogMessage::Log(log_stream_.str());
}
}
Expand Down
11 changes: 11 additions & 0 deletions R-package/tests/testthat/test_config.R
@@ -0,0 +1,11 @@
context('Test global configuration')

test_that('Global configuration works with verbosity', {
old_verbosity <- xgb.get.config()$verbosity
for (v in c(0, 1, 2, 3)) {
xgb.set.config(verbosity = v)
expect_equal(xgb.get.config()$verbosity, v)
}
xgb.set.config(verbosity = old_verbosity)
expect_equal(xgb.get.config()$verbosity, old_verbosity)
})
1 change: 1 addition & 0 deletions amalgamation/xgboost-all0.cc
Expand Up @@ -67,6 +67,7 @@
// global
#include "../src/learner.cc"
#include "../src/logging.cc"
#include "../src/global_config.cc"
#include "../src/common/common.cc"
#include "../src/common/random.cc"
#include "../src/common/charconv.cc"
Expand Down
7 changes: 7 additions & 0 deletions doc/parameter.rst
Expand Up @@ -16,6 +16,13 @@ Before running XGBoost, we must set three types of parameters: general parameter
:backlinks: none
:local:

********************
Global Configuration
********************
The following parameters can be set in the global scope, using ``xgb.config_context()`` (Python) or ``xgb.set.config()`` (R).

* ``verbosity``: Verbosity of printing messages. Valid values of 0 (silent), 1 (warning), 2 (info), and 3 (debug).

******************
General Parameters
******************
Expand Down
8 changes: 8 additions & 0 deletions doc/python/python_api.rst
Expand Up @@ -6,6 +6,14 @@ This page gives the Python API reference of xgboost, please also refer to Python
:backlinks: none
:local:

Global Configuration
--------------------
.. autofunction:: xgboost.config_context

.. autofunction:: xgboost.set_config

.. autofunction:: xgboost.get_config

Core Data Structure
-------------------
.. automodule:: xgboost.core
Expand Down
17 changes: 17 additions & 0 deletions include/xgboost/c_api.h
Expand Up @@ -63,6 +63,23 @@ XGB_DLL const char *XGBGetLastError(void);
*/
XGB_DLL int XGBRegisterLogCallback(void (*callback)(const char*));

/*!
* \brief Set global configuration (collection of parameters that apply globally). This function
* accepts the list of key-value pairs representing the global-scope parameters to be
* configured. The list of key-value pairs are passed in as a JSON string.
* \param json_str a JSON string representing the list of key-value pairs. The JSON object shall
* be flat: no value can be a JSON object or an array.
* \return 0 for success, -1 for failure
*/
XGB_DLL int XGBSetGlobalConfig(const char* json_str);

/*!
* \brief Get current global configuration (collection of parameters that apply globally).
* \param json_str pointer to received returned global configuration, represented as a JSON string.
* \return 0 for success, -1 for failure
*/
XGB_DLL int XGBGetGlobalConfig(const char** json_str);

/*!
* \brief load a data matrix
* \param fname the name of the file
Expand Down
30 changes: 30 additions & 0 deletions include/xgboost/global_config.h
@@ -0,0 +1,30 @@
/*!
* Copyright 2020 by Contributors
* \file global_config.h
* \brief Global configuration for XGBoost
* \author Hyunsu Cho
*/
#ifndef XGBOOST_GLOBAL_CONFIG_H_
#define XGBOOST_GLOBAL_CONFIG_H_

#include <xgboost/parameter.h>
#include <vector>
#include <string>

namespace xgboost {
class Json;

struct GlobalConfiguration : public XGBoostParameter<GlobalConfiguration> {
int verbosity;
DMLC_DECLARE_PARAMETER(GlobalConfiguration) {
DMLC_DECLARE_FIELD(verbosity)
.set_range(0, 3)
.set_default(1) // shows only warning
.describe("Flag to print out detailed breakdown of runtime.");
}
};

using GlobalConfigThreadLocalStore = dmlc::ThreadLocalStore<GlobalConfiguration>;
} // namespace xgboost

#endif // XGBOOST_GLOBAL_CONFIG_H_
5 changes: 2 additions & 3 deletions include/xgboost/json.h
Expand Up @@ -557,7 +557,6 @@ using String = JsonString;
using Null = JsonNull;

// Utils tailored for XGBoost.

template <typename Parameter>
Object ToJson(Parameter const& param) {
Object obj;
Expand All @@ -568,13 +567,13 @@ Object ToJson(Parameter const& param) {
}

template <typename Parameter>
void FromJson(Json const& obj, Parameter* param) {
Args FromJson(Json const& obj, Parameter* param) {
auto const& j_param = get<Object const>(obj);
std::map<std::string, std::string> m;
for (auto const& kv : j_param) {
m[kv.first] = get<String const>(kv.second);
}
param->UpdateAllowUnknown(m);
return param->UpdateAllowUnknown(m);
}
} // namespace xgboost
#endif // XGBOOST_JSON_H_
1 change: 0 additions & 1 deletion include/xgboost/learner.h
Expand Up @@ -45,7 +45,6 @@ struct XGBAPIThreadLocalEntry {
PredictionCacheEntry prediction_entry;
};


/*!
* \brief Learner class that does training and prediction.
* This is the user facing module of xgboost training.
Expand Down
17 changes: 1 addition & 16 deletions include/xgboost/logging.h
Expand Up @@ -13,6 +13,7 @@

#include <xgboost/base.h>
#include <xgboost/parameter.h>
#include <xgboost/global_config.h>

#include <sstream>
#include <map>
Expand All @@ -35,19 +36,6 @@ class BaseLogger {
std::ostringstream log_stream_;
};

// Parsing both silent and debug_verbose is to provide backward compatibility.
struct ConsoleLoggerParam : public XGBoostParameter<ConsoleLoggerParam> {
int verbosity;

DMLC_DECLARE_PARAMETER(ConsoleLoggerParam) {
DMLC_DECLARE_FIELD(verbosity)
.set_range(0, 3)
.set_default(1) // shows only warning
.describe("Flag to print out detailed breakdown of runtime.");
DMLC_DECLARE_ALIAS(verbosity, debug_verbose);
}
};

class ConsoleLogger : public BaseLogger {
public:
enum class LogVerbosity {
Expand All @@ -60,9 +48,6 @@ class ConsoleLogger : public BaseLogger {
using LV = LogVerbosity;

private:
static LogVerbosity global_verbosity_;
static ConsoleLoggerParam param_;

LogVerbosity cur_verbosity_;

public:
Expand Down
4 changes: 3 additions & 1 deletion python-package/xgboost/__init__.py
Expand Up @@ -17,6 +17,7 @@
from .sklearn import XGBModel, XGBClassifier, XGBRegressor, XGBRanker
from .sklearn import XGBRFClassifier, XGBRFRegressor
from .plotting import plot_importance, plot_tree, to_graphviz
from .config import set_config, get_config, config_context
except ImportError:
pass

Expand All @@ -29,4 +30,5 @@
'RabitTracker',
'XGBModel', 'XGBClassifier', 'XGBRegressor', 'XGBRanker',
'XGBRFClassifier', 'XGBRFRegressor',
'plot_importance', 'plot_tree', 'to_graphviz', 'dask']
'plot_importance', 'plot_tree', 'to_graphviz', 'dask',
'set_config', 'get_config', 'config_context']

0 comments on commit fb56da5

Please sign in to comment.