De-duplicate GPU parameters. (#4454)

* Only define `gpu_id` and `n_gpus` in `LearnerTrainParam`
* Pass LearnerTrainParam through XGBoost vid factory method.
* Disable all GPU usage when GPU related parameters are not specified (fixes XGBoost choosing GPU over aggressively).
* Test learner train param io.
* Fix gpu pickling.
This commit is contained in:
Jiaming Yuan
2019-05-29 11:55:57 +08:00
committed by GitHub
parent a3fedbeaa8
commit c589eff941
69 changed files with 927 additions and 562 deletions

View File

@@ -0,0 +1,81 @@
/*!
* Copyright 2018 by Contributors
* \file enum_class_param.h
* \brief macro for using C++11 enum class as DMLC parameter
* \author Hyunsu Philip Cho
*/
#ifndef XGBOOST_ENUM_CLASS_PARAM_H_
#define XGBOOST_ENUM_CLASS_PARAM_H_
#include <dmlc/parameter.h>
#include <string>
#include <type_traits>
/*!
* \brief Specialization of FieldEntry for enum class (backed by int)
*
* Use this macro to use C++11 enum class as DMLC parameters
*
* Usage:
*
* \code{.cpp}
*
* // enum class must inherit from int type
* enum class Foo : int {
* kBar = 0, kFrog = 1, kCat = 2, kDog = 3
* };
*
* // This line is needed to prevent compilation error
* DECLARE_FIELD_ENUM_CLASS(Foo);
*
* // Now define DMLC parameter as usual;
* // enum classes can now be members.
* struct MyParam : dmlc::Parameter<MyParam> {
* Foo foo;
* DMLC_DECLARE_PARAMETER(MyParam) {
* DMLC_DECLARE_FIELD(foo)
* .set_default(Foo::kBar)
* .add_enum("bar", Foo::kBar)
* .add_enum("frog", Foo::kFrog)
* .add_enum("cat", Foo::kCat)
* .add_enum("dog", Foo::kDog);
* }
* };
*
* DMLC_REGISTER_PARAMETER(MyParam);
* \endcode
*/
#define DECLARE_FIELD_ENUM_CLASS(EnumClass) \
namespace dmlc { \
namespace parameter { \
template <> \
class FieldEntry<EnumClass> : public FieldEntry<int> { \
public: \
FieldEntry<EnumClass>() { \
static_assert( \
std::is_same<int, typename std::underlying_type<EnumClass>::type>::value, \
"enum class must be backed by int"); \
is_enum_ = true; \
} \
using Super = FieldEntry<int>; \
void Set(void *head, const std::string &value) const override { \
Super::Set(head, value); \
} \
inline FieldEntry<EnumClass>& add_enum(const std::string &key, EnumClass value) { \
Super::add_enum(key, static_cast<int>(value)); \
return *this; \
} \
inline FieldEntry<EnumClass>& set_default(const EnumClass& default_value) { \
default_value_ = static_cast<int>(default_value); \
has_default_ = true; \
return *this; \
} \
inline void Init(const std::string &key, void *head, EnumClass& ref) { /* NOLINT */ \
Super::Init(key, head, *reinterpret_cast<int*>(&ref)); \
} \
}; \
} /* namespace parameter */ \
} /* namespace dmlc */
#endif // XGBOOST_ENUM_CLASS_PARAM_H_

View File

@@ -9,15 +9,18 @@
#define XGBOOST_GBM_H_
#include <dmlc/registry.h>
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <xgboost/objective.h>
#include <xgboost/feature_map.h>
#include <xgboost/generic_parameters.h>
#include <vector>
#include <utility>
#include <string>
#include <functional>
#include <memory>
#include "./base.h"
#include "./data.h"
#include "./objective.h"
#include "./feature_map.h"
#include "../../src/common/host_device_vector.h"
namespace xgboost {
@@ -25,6 +28,9 @@ namespace xgboost {
* \brief interface of gradient boosting model.
*/
class GradientBooster {
protected:
LearnerTrainParam const* learner_param_;
public:
/*! \brief virtual destructor */
virtual ~GradientBooster() = default;
@@ -149,6 +155,7 @@ class GradientBooster {
*/
static GradientBooster* Create(
const std::string& name,
LearnerTrainParam const* gparam,
const std::vector<std::shared_ptr<DMatrix> >& cache_mats,
bst_float base_margin);
};

View File

@@ -0,0 +1,86 @@
/*!
* Copyright 2014-2019 by Contributors
* \file learner.cc
*/
#ifndef XGBOOST_GENERIC_PARAMETERS_H_
#define XGBOOST_GENERIC_PARAMETERS_H_
#include <dmlc/parameter.h>
#include <xgboost/enum_class_param.h>
namespace xgboost {
enum class TreeMethod : int {
kAuto = 0, kApprox = 1, kExact = 2, kHist = 3,
kGPUExact = 4, kGPUHist = 5
};
enum class DataSplitMode : int {
kAuto = 0, kCol = 1, kRow = 2
};
} // namespace xgboost
DECLARE_FIELD_ENUM_CLASS(xgboost::TreeMethod);
DECLARE_FIELD_ENUM_CLASS(xgboost::DataSplitMode);
namespace xgboost {
struct LearnerTrainParam : public dmlc::Parameter<LearnerTrainParam> {
// stored random seed
int seed;
// whether seed the PRNG each iteration
bool seed_per_iteration;
// data split mode, can be row, col, or none.
DataSplitMode dsplit;
// tree construction method
TreeMethod tree_method;
// number of threads to use if OpenMP is enabled
// if equals 0, use system default
int nthread;
// flag to disable default metric
int disable_default_eval_metric;
// primary device.
int gpu_id;
// number of devices to use, -1 implies using all available devices.
int n_gpus;
// declare parameters
DMLC_DECLARE_PARAMETER(LearnerTrainParam) {
DMLC_DECLARE_FIELD(seed).set_default(0).describe(
"Random number seed during training.");
DMLC_DECLARE_FIELD(seed_per_iteration)
.set_default(false)
.describe(
"Seed PRNG determnisticly via iterator number, "
"this option will be switched on automatically on distributed "
"mode.");
DMLC_DECLARE_FIELD(dsplit)
.set_default(DataSplitMode::kAuto)
.add_enum("auto", DataSplitMode::kAuto)
.add_enum("col", DataSplitMode::kCol)
.add_enum("row", DataSplitMode::kRow)
.describe("Data split mode for distributed training.");
DMLC_DECLARE_FIELD(tree_method)
.set_default(TreeMethod::kAuto)
.add_enum("auto", TreeMethod::kAuto)
.add_enum("approx", TreeMethod::kApprox)
.add_enum("exact", TreeMethod::kExact)
.add_enum("hist", TreeMethod::kHist)
.add_enum("gpu_exact", TreeMethod::kGPUExact)
.add_enum("gpu_hist", TreeMethod::kGPUHist)
.describe("Choice of tree construction method.");
DMLC_DECLARE_FIELD(nthread).set_default(0).describe(
"Number of threads to use.");
DMLC_DECLARE_FIELD(disable_default_eval_metric)
.set_default(0)
.describe("flag to disable default metric. Set to >0 to disable");
DMLC_DECLARE_FIELD(gpu_id)
.set_default(0)
.describe("The primary GPU device ordinal.");
DMLC_DECLARE_FIELD(n_gpus)
.set_default(0)
.set_lower_bound(-1)
.describe("Number of GPUs to use for multi-gpu algorithms.");
}
};
} // namespace xgboost
#endif // XGBOOST_GENERIC_PARAMETERS_H_

View File

@@ -1,5 +1,5 @@
/*!
* Copyright 2015 by Contributors
* Copyright 2015-2019 by Contributors
* \file learner.h
* \brief Learner interface that integrates objective, gbm and evaluation together.
* This is the user facing XGBoost training module.
@@ -9,15 +9,18 @@
#define XGBOOST_LEARNER_H_
#include <rabit/rabit.h>
#include <xgboost/base.h>
#include <xgboost/gbm.h>
#include <xgboost/metric.h>
#include <xgboost/objective.h>
#include <xgboost/generic_parameters.h>
#include <utility>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "./base.h"
#include "./gbm.h"
#include "./metric.h"
#include "./objective.h"
namespace xgboost {
/*!
@@ -144,6 +147,8 @@ class Learner : public rabit::Serializable {
* \return vector of attribute name strings.
*/
virtual std::vector<std::string> GetAttrNames() const = 0;
virtual LearnerTrainParam const& GetLearnerTrainParameter() const = 0;
/*!
* \return whether the model allow lazy checkpoint in rabit.
*/
@@ -195,6 +200,8 @@ class Learner : public rabit::Serializable {
std::unique_ptr<GradientBooster> gbm_;
/*! \brief The evaluation metrics used to evaluate the model. */
std::vector<std::unique_ptr<Metric> > metrics_;
/*! \brief Training parameter. */
LearnerTrainParam tparam_;
};
// implementation of inline functions.

View File

@@ -6,6 +6,7 @@
#include <dmlc/registry.h>
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <xgboost/generic_parameters.h>
#include <functional>
#include <string>
#include <utility>
@@ -18,6 +19,9 @@ namespace xgboost {
* \brief interface of linear updater
*/
class LinearUpdater {
protected:
LearnerTrainParam const* learner_param_;
public:
/*! \brief virtual destructor */
virtual ~LinearUpdater() = default;
@@ -45,7 +49,7 @@ class LinearUpdater {
* \brief Create a linear updater given name
* \param name Name of the linear updater.
*/
static LinearUpdater* Create(const std::string& name);
static LinearUpdater* Create(const std::string& name, LearnerTrainParam const*);
};
/*!

View File

@@ -8,13 +8,15 @@
#define XGBOOST_METRIC_H_
#include <dmlc/registry.h>
#include <xgboost/generic_parameters.h>
#include <xgboost/data.h>
#include <xgboost/base.h>
#include <vector>
#include <string>
#include <functional>
#include <utility>
#include "./data.h"
#include "./base.h"
#include "../../src/common/host_device_vector.h"
namespace xgboost {
@@ -23,6 +25,9 @@ namespace xgboost {
* This has nothing to do with training, but merely act as evaluation purpose.
*/
class Metric {
protected:
LearnerTrainParam const* tparam_;
public:
/*!
* \brief Configure the Metric with the specified parameters.
@@ -63,7 +68,7 @@ class Metric {
* and the name will be matched in the registry.
* \return the created metric.
*/
static Metric* Create(const std::string& name);
static Metric* Create(const std::string& name, LearnerTrainParam const* tparam);
};
/*!

View File

@@ -8,19 +8,24 @@
#define XGBOOST_OBJECTIVE_H_
#include <dmlc/registry.h>
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <xgboost/generic_parameters.h>
#include <vector>
#include <utility>
#include <string>
#include <functional>
#include "./data.h"
#include "./base.h"
#include "../../src/common/host_device_vector.h"
#include "../../src/common/host_device_vector.h"
namespace xgboost {
/*! \brief interface of objective function */
class ObjFunction {
protected:
LearnerTrainParam const* tparam_;
public:
/*! \brief virtual destructor */
virtual ~ObjFunction() = default;
@@ -77,9 +82,10 @@ class ObjFunction {
}
/*!
* \brief Create an objective function according to name.
* \param tparam Generic parameters.
* \param name Name of the objective.
*/
static ObjFunction* Create(const std::string& name);
static ObjFunction* Create(const std::string& name, LearnerTrainParam const* tparam);
};
// implementing configure.

View File

@@ -7,6 +7,7 @@
#pragma once
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <xgboost/generic_parameters.h>
#include <functional>
#include <memory>
@@ -38,6 +39,9 @@ namespace xgboost {
*/
class Predictor {
protected:
LearnerTrainParam const* learner_param_;
public:
virtual ~Predictor() = default;
@@ -170,7 +174,7 @@ class Predictor {
*
*/
static Predictor* Create(std::string name);
static Predictor* Create(std::string const& name, LearnerTrainParam const*);
protected:
/**

View File

@@ -1,5 +1,5 @@
/*!
* Copyright 2014 by Contributors
* Copyright 2014-2019 by Contributors
* \file tree_updater.h
* \brief General primitive for tree learning,
* Updating a collection of trees given the information.
@@ -9,13 +9,16 @@
#define XGBOOST_TREE_UPDATER_H_
#include <dmlc/registry.h>
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <xgboost/tree_model.h>
#include <xgboost/generic_parameters.h>
#include <functional>
#include <vector>
#include <utility>
#include <string>
#include "./base.h"
#include "./data.h"
#include "./tree_model.h"
#include "../../src/common/host_device_vector.h"
namespace xgboost {
@@ -23,6 +26,9 @@ namespace xgboost {
* \brief interface of tree update module, that performs update of a tree.
*/
class TreeUpdater {
protected:
LearnerTrainParam const* tparam_;
public:
/*! \brief virtual destructor */
virtual ~TreeUpdater() = default;
@@ -63,7 +69,7 @@ class TreeUpdater {
* \brief Create a tree updater given name
* \param name Name of the tree updater.
*/
static TreeUpdater* Create(const std::string& name);
static TreeUpdater* Create(const std::string& name, LearnerTrainParam const* tparam);
};
/*!