Clean up after removing gpu_exact. (#4777)
* Removed unused functions. * Removed unused parameters. * Move ValueConstraints into constraints.cuh since it's now only used in GPU_Hist.
This commit is contained in:
parent
b9b57f2289
commit
c81238b5c4
@ -1,5 +1,7 @@
|
|||||||
/*!
|
/*!
|
||||||
* Copyright 2019 XGBoost contributors
|
* Copyright 2019 XGBoost contributors
|
||||||
|
*
|
||||||
|
* \file Various constraints used in GPU_Hist.
|
||||||
*/
|
*/
|
||||||
#ifndef XGBOOST_TREE_CONSTRAINTS_H_
|
#ifndef XGBOOST_TREE_CONSTRAINTS_H_
|
||||||
#define XGBOOST_TREE_CONSTRAINTS_H_
|
#define XGBOOST_TREE_CONSTRAINTS_H_
|
||||||
@ -16,6 +18,75 @@
|
|||||||
|
|
||||||
namespace xgboost {
|
namespace xgboost {
|
||||||
|
|
||||||
|
// This class implements monotonic constraints, L1, L2 regularization.
|
||||||
|
struct ValueConstraint {
|
||||||
|
double lower_bound;
|
||||||
|
double upper_bound;
|
||||||
|
XGBOOST_DEVICE ValueConstraint()
|
||||||
|
: lower_bound(-std::numeric_limits<double>::max()),
|
||||||
|
upper_bound(std::numeric_limits<double>::max()) {}
|
||||||
|
inline static void Init(tree::TrainParam *param, unsigned num_feature) {
|
||||||
|
param->monotone_constraints.resize(num_feature, 0);
|
||||||
|
}
|
||||||
|
template <typename ParamT>
|
||||||
|
XGBOOST_DEVICE inline double CalcWeight(const ParamT ¶m, tree::GradStats stats) const {
|
||||||
|
double w = xgboost::tree::CalcWeight(param, stats);
|
||||||
|
if (w < lower_bound) {
|
||||||
|
return lower_bound;
|
||||||
|
}
|
||||||
|
if (w > upper_bound) {
|
||||||
|
return upper_bound;
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParamT>
|
||||||
|
XGBOOST_DEVICE inline double CalcGain(const ParamT ¶m, tree::GradStats stats) const {
|
||||||
|
return tree::CalcGainGivenWeight<ParamT, float>(param, stats.sum_grad, stats.sum_hess,
|
||||||
|
CalcWeight(param, stats));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParamT>
|
||||||
|
XGBOOST_DEVICE inline double CalcSplitGain(const ParamT ¶m, int constraint,
|
||||||
|
tree::GradStats left, tree::GradStats right) const {
|
||||||
|
const double negative_infinity = -std::numeric_limits<double>::infinity();
|
||||||
|
double wleft = CalcWeight(param, left);
|
||||||
|
double wright = CalcWeight(param, right);
|
||||||
|
double gain =
|
||||||
|
tree::CalcGainGivenWeight<ParamT, float>(param, left.sum_grad, left.sum_hess, wleft) +
|
||||||
|
tree::CalcGainGivenWeight<ParamT, float>(param, right.sum_grad, right.sum_hess, wright);
|
||||||
|
if (constraint == 0) {
|
||||||
|
return gain;
|
||||||
|
} else if (constraint > 0) {
|
||||||
|
return wleft <= wright ? gain : negative_infinity;
|
||||||
|
} else {
|
||||||
|
return wleft >= wright ? gain : negative_infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetChild(const tree::TrainParam ¶m, bst_uint split_index,
|
||||||
|
tree::GradStats left, tree::GradStats right, ValueConstraint *cleft,
|
||||||
|
ValueConstraint *cright) {
|
||||||
|
int c = param.monotone_constraints.at(split_index);
|
||||||
|
*cleft = *this;
|
||||||
|
*cright = *this;
|
||||||
|
if (c == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double wleft = CalcWeight(param, left);
|
||||||
|
double wright = CalcWeight(param, right);
|
||||||
|
double mid = (wleft + wright) / 2;
|
||||||
|
CHECK(!std::isnan(mid));
|
||||||
|
if (c < 0) {
|
||||||
|
cleft->lower_bound = mid;
|
||||||
|
cright->upper_bound = mid;
|
||||||
|
} else {
|
||||||
|
cleft->upper_bound = mid;
|
||||||
|
cright->lower_bound = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Feature interaction constraints built for GPU Hist updater.
|
// Feature interaction constraints built for GPU Hist updater.
|
||||||
struct FeatureInteractionConstraint {
|
struct FeatureInteractionConstraint {
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -62,8 +62,6 @@ struct TrainParam : public dmlc::Parameter<TrainParam> {
|
|||||||
float sketch_eps;
|
float sketch_eps;
|
||||||
// accuracy of sketch
|
// accuracy of sketch
|
||||||
float sketch_ratio;
|
float sketch_ratio;
|
||||||
// leaf vector size
|
|
||||||
int size_leaf_vector;
|
|
||||||
// option for parallelization
|
// option for parallelization
|
||||||
int parallel_option;
|
int parallel_option;
|
||||||
// option to open cacheline optimization
|
// option to open cacheline optimization
|
||||||
@ -176,10 +174,6 @@ struct TrainParam : public dmlc::Parameter<TrainParam> {
|
|||||||
.set_lower_bound(0.0f)
|
.set_lower_bound(0.0f)
|
||||||
.set_default(2.0f)
|
.set_default(2.0f)
|
||||||
.describe("EXP Param: Sketch accuracy related parameter of approximate algorithm.");
|
.describe("EXP Param: Sketch accuracy related parameter of approximate algorithm.");
|
||||||
DMLC_DECLARE_FIELD(size_leaf_vector)
|
|
||||||
.set_lower_bound(0)
|
|
||||||
.set_default(0)
|
|
||||||
.describe("Size of leaf vectors, reserved for vector trees");
|
|
||||||
DMLC_DECLARE_FIELD(parallel_option)
|
DMLC_DECLARE_FIELD(parallel_option)
|
||||||
.set_default(0)
|
.set_default(0)
|
||||||
.describe("Different types of parallelization algorithm.");
|
.describe("Different types of parallelization algorithm.");
|
||||||
@ -240,10 +234,6 @@ struct TrainParam : public dmlc::Parameter<TrainParam> {
|
|||||||
inline bool NeedPrune(double loss_chg, int depth) const {
|
inline bool NeedPrune(double loss_chg, int depth) const {
|
||||||
return loss_chg < this->min_split_loss;
|
return loss_chg < this->min_split_loss;
|
||||||
}
|
}
|
||||||
/*! \brief whether we can split with current hessian */
|
|
||||||
inline bool CannotSplit(double sum_hess, int depth) const {
|
|
||||||
return sum_hess < this->min_child_weight * 2.0;
|
|
||||||
}
|
|
||||||
/*! \brief maximum sketch size */
|
/*! \brief maximum sketch size */
|
||||||
inline unsigned MaxSketchSize() const {
|
inline unsigned MaxSketchSize() const {
|
||||||
auto ret = static_cast<unsigned>(sketch_ratio / sketch_eps);
|
auto ret = static_cast<unsigned>(sketch_ratio / sketch_eps);
|
||||||
@ -400,75 +390,6 @@ struct GradStats {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(trivialfis): Remove this class.
|
|
||||||
struct ValueConstraint {
|
|
||||||
double lower_bound;
|
|
||||||
double upper_bound;
|
|
||||||
XGBOOST_DEVICE ValueConstraint()
|
|
||||||
: lower_bound(-std::numeric_limits<double>::max()),
|
|
||||||
upper_bound(std::numeric_limits<double>::max()) {}
|
|
||||||
inline static void Init(TrainParam *param, unsigned num_feature) {
|
|
||||||
param->monotone_constraints.resize(num_feature, 0);
|
|
||||||
}
|
|
||||||
template <typename ParamT>
|
|
||||||
XGBOOST_DEVICE inline double CalcWeight(const ParamT ¶m, GradStats stats) const {
|
|
||||||
double w = xgboost::tree::CalcWeight(param, stats);
|
|
||||||
if (w < lower_bound) {
|
|
||||||
return lower_bound;
|
|
||||||
}
|
|
||||||
if (w > upper_bound) {
|
|
||||||
return upper_bound;
|
|
||||||
}
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamT>
|
|
||||||
XGBOOST_DEVICE inline double CalcGain(const ParamT ¶m, GradStats stats) const {
|
|
||||||
return CalcGainGivenWeight<ParamT, float>(param, stats.sum_grad, stats.sum_hess,
|
|
||||||
CalcWeight(param, stats));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParamT>
|
|
||||||
XGBOOST_DEVICE inline double CalcSplitGain(const ParamT ¶m, int constraint,
|
|
||||||
GradStats left, GradStats right) const {
|
|
||||||
const double negative_infinity = -std::numeric_limits<double>::infinity();
|
|
||||||
double wleft = CalcWeight(param, left);
|
|
||||||
double wright = CalcWeight(param, right);
|
|
||||||
double gain =
|
|
||||||
CalcGainGivenWeight<ParamT, float>(param, left.sum_grad, left.sum_hess, wleft) +
|
|
||||||
CalcGainGivenWeight<ParamT, float>(param, right.sum_grad, right.sum_hess, wright);
|
|
||||||
if (constraint == 0) {
|
|
||||||
return gain;
|
|
||||||
} else if (constraint > 0) {
|
|
||||||
return wleft <= wright ? gain : negative_infinity;
|
|
||||||
} else {
|
|
||||||
return wleft >= wright ? gain : negative_infinity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetChild(const TrainParam ¶m, bst_uint split_index,
|
|
||||||
GradStats left, GradStats right, ValueConstraint *cleft,
|
|
||||||
ValueConstraint *cright) {
|
|
||||||
int c = param.monotone_constraints.at(split_index);
|
|
||||||
*cleft = *this;
|
|
||||||
*cright = *this;
|
|
||||||
if (c == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double wleft = CalcWeight(param, left);
|
|
||||||
double wright = CalcWeight(param, right);
|
|
||||||
double mid = (wleft + wright) / 2;
|
|
||||||
CHECK(!std::isnan(mid));
|
|
||||||
if (c < 0) {
|
|
||||||
cleft->lower_bound = mid;
|
|
||||||
cright->upper_bound = mid;
|
|
||||||
} else {
|
|
||||||
cleft->upper_bound = mid;
|
|
||||||
cright->lower_bound = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief statistics that is helpful to store
|
* \brief statistics that is helpful to store
|
||||||
* and represent a split solution for the tree
|
* and represent a split solution for the tree
|
||||||
|
|||||||
@ -69,7 +69,7 @@ struct GPUTrainingParam {
|
|||||||
max_delta_step(param.max_delta_step) {}
|
max_delta_step(param.max_delta_step) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
using NodeIdT = int;
|
using NodeIdT = int32_t;
|
||||||
|
|
||||||
/** used to assign default id to a Node */
|
/** used to assign default id to a Node */
|
||||||
static const int kUnusedNode = -1;
|
static const int kUnusedNode = -1;
|
||||||
@ -88,8 +88,9 @@ enum DefaultDirection {
|
|||||||
struct DeviceSplitCandidate {
|
struct DeviceSplitCandidate {
|
||||||
float loss_chg;
|
float loss_chg;
|
||||||
DefaultDirection dir;
|
DefaultDirection dir;
|
||||||
float fvalue;
|
|
||||||
int findex;
|
int findex;
|
||||||
|
float fvalue;
|
||||||
|
|
||||||
GradientPair left_sum;
|
GradientPair left_sum;
|
||||||
GradientPair right_sum;
|
GradientPair right_sum;
|
||||||
|
|
||||||
@ -107,10 +108,10 @@ struct DeviceSplitCandidate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XGBOOST_DEVICE void Update(float loss_chg_in, DefaultDirection dir_in,
|
XGBOOST_DEVICE void Update(float loss_chg_in, DefaultDirection dir_in,
|
||||||
float fvalue_in, int findex_in,
|
float fvalue_in, int findex_in,
|
||||||
GradientPair left_sum_in,
|
GradientPair left_sum_in,
|
||||||
GradientPair right_sum_in,
|
GradientPair right_sum_in,
|
||||||
const GPUTrainingParam& param) {
|
const GPUTrainingParam& param) {
|
||||||
if (loss_chg_in > loss_chg &&
|
if (loss_chg_in > loss_chg &&
|
||||||
left_sum_in.GetHess() >= param.min_child_weight &&
|
left_sum_in.GetHess() >= param.min_child_weight &&
|
||||||
right_sum_in.GetHess() >= param.min_child_weight) {
|
right_sum_in.GetHess() >= param.min_child_weight) {
|
||||||
@ -214,76 +215,14 @@ struct SumCallbackOp {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename GradientPairT>
|
|
||||||
XGBOOST_DEVICE inline float DeviceCalcLossChange(const GPUTrainingParam& param,
|
|
||||||
const GradientPairT& left,
|
|
||||||
const GradientPairT& parent_sum,
|
|
||||||
const float& parent_gain) {
|
|
||||||
GradientPairT right = parent_sum - left;
|
|
||||||
float left_gain = CalcGain(param, left.GetGrad(), left.GetHess());
|
|
||||||
float right_gain = CalcGain(param, right.GetGrad(), right.GetHess());
|
|
||||||
return left_gain + right_gain - parent_gain;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Total number of nodes in tree, given depth
|
// Total number of nodes in tree, given depth
|
||||||
XGBOOST_DEVICE inline int MaxNodesDepth(int depth) {
|
XGBOOST_DEVICE inline int MaxNodesDepth(int depth) {
|
||||||
return (1 << (depth + 1)) - 1;
|
return (1 << (depth + 1)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of nodes at this level of the tree
|
|
||||||
XGBOOST_DEVICE inline int MaxNodesLevel(int depth) { return 1 << depth; }
|
|
||||||
|
|
||||||
// Whether a node is currently being processed at current depth
|
|
||||||
XGBOOST_DEVICE inline bool IsNodeActive(int nidx, int depth) {
|
|
||||||
return nidx >= MaxNodesDepth(depth - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XGBOOST_DEVICE inline int ParentNodeIdx(int nidx) { return (nidx - 1) / 2; }
|
|
||||||
|
|
||||||
XGBOOST_DEVICE inline int LeftChildNodeIdx(int nidx) {
|
|
||||||
return nidx * 2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
XGBOOST_DEVICE inline int RightChildNodeIdx(int nidx) {
|
|
||||||
return nidx * 2 + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
XGBOOST_DEVICE inline bool IsLeftChild(int nidx) {
|
|
||||||
return nidx % 2 == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy gpu dense representation of tree to xgboost sparse representation
|
|
||||||
inline void Dense2SparseTree(RegTree* p_tree,
|
|
||||||
common::Span<DeviceNodeStats> nodes,
|
|
||||||
const TrainParam& param) {
|
|
||||||
RegTree& tree = *p_tree;
|
|
||||||
std::vector<DeviceNodeStats> h_nodes(nodes.size());
|
|
||||||
dh::safe_cuda(cudaMemcpy(h_nodes.data(), nodes.data(),
|
|
||||||
nodes.size() * sizeof(DeviceNodeStats),
|
|
||||||
cudaMemcpyDeviceToHost));
|
|
||||||
|
|
||||||
int nid = 0;
|
|
||||||
for (int gpu_nid = 0; gpu_nid < h_nodes.size(); gpu_nid++) {
|
|
||||||
const DeviceNodeStats& n = h_nodes[gpu_nid];
|
|
||||||
if (!n.IsUnused() && !n.IsLeaf()) {
|
|
||||||
tree.ExpandNode(nid, n.fidx, n.fvalue, n.dir == kLeftDir, n.weight, 0.0f,
|
|
||||||
0.0f, n.root_gain, n.sum_gradients.GetHess());
|
|
||||||
tree.Stat(nid).loss_chg = n.root_gain;
|
|
||||||
tree.Stat(nid).base_weight = n.weight;
|
|
||||||
tree.Stat(nid).sum_hess = n.sum_gradients.GetHess();
|
|
||||||
nid++;
|
|
||||||
} else if (n.IsLeaf()) {
|
|
||||||
tree[nid].SetLeaf(n.weight * param.learning_rate);
|
|
||||||
tree.Stat(nid).sum_hess = n.sum_gradients.GetHess();
|
|
||||||
nid++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Random
|
* Random
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct BernoulliRng {
|
struct BernoulliRng {
|
||||||
float p;
|
float p;
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user