lint half way
This commit is contained in:
parent
2ed40523ab
commit
0162bb7034
@ -1,11 +1,13 @@
|
||||
#ifndef XGBOOST_GBM_GBLINEAR_INL_HPP_
|
||||
#define XGBOOST_GBM_GBLINEAR_INL_HPP_
|
||||
/*!
|
||||
* Copyright by Contributors
|
||||
* \file gblinear-inl.hpp
|
||||
* \brief Implementation of Linear booster, with L1/L2 regularization: Elastic Net
|
||||
* the update rule is parallel coordinate descent (shotgun)
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_GBM_GBLINEAR_INL_HPP_
|
||||
#define XGBOOST_GBM_GBLINEAR_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@ -33,10 +35,10 @@ class GBLinear : public IGradBooster {
|
||||
model.param.SetParam(name, val);
|
||||
}
|
||||
}
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) {
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) { // NOLINT(*)
|
||||
model.LoadModel(fi);
|
||||
}
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const {
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const { // NOLINT(*)
|
||||
model.SaveModel(fo);
|
||||
}
|
||||
virtual void InitModel(void) {
|
||||
@ -92,7 +94,8 @@ class GBLinear : public IGradBooster {
|
||||
sum_hess += p.hess * v * v;
|
||||
}
|
||||
float &w = model[fid][gid];
|
||||
bst_float dw = static_cast<bst_float>(param.learning_rate * param.CalcDelta(sum_grad, sum_hess, w));
|
||||
bst_float dw = static_cast<bst_float>(param.learning_rate *
|
||||
param.CalcDelta(sum_grad, sum_hess, w));
|
||||
w += dw;
|
||||
// update grad value
|
||||
for (bst_uint j = 0; j < col.length; ++j) {
|
||||
@ -258,12 +261,12 @@ class GBLinear : public IGradBooster {
|
||||
std::fill(weight.begin(), weight.end(), 0.0f);
|
||||
}
|
||||
// save the model to file
|
||||
inline void SaveModel(utils::IStream &fo) const {
|
||||
inline void SaveModel(utils::IStream &fo) const { // NOLINT(*)
|
||||
fo.Write(¶m, sizeof(Param));
|
||||
fo.Write(weight);
|
||||
}
|
||||
// load model from file
|
||||
inline void LoadModel(utils::IStream &fi) {
|
||||
inline void LoadModel(utils::IStream &fi) { // NOLINT(*)
|
||||
utils::Assert(fi.Read(¶m, sizeof(Param)) != 0, "Load LinearBooster");
|
||||
fi.Read(&weight);
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
// Copyright by Contributors
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define NOMINMAX
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#ifndef XGBOOST_GBM_GBM_H_
|
||||
#define XGBOOST_GBM_GBM_H_
|
||||
/*!
|
||||
* Copyright by Contributors
|
||||
* \file gbm.h
|
||||
* \brief interface of gradient booster, that learns through gradient statistics
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_GBM_GBM_H_
|
||||
#define XGBOOST_GBM_GBM_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "../data.h"
|
||||
#include "../utils/io.h"
|
||||
#include "../utils/fmap.h"
|
||||
@ -29,13 +32,13 @@ class IGradBooster {
|
||||
* \param fi input stream
|
||||
* \param with_pbuffer whether the incoming data contains pbuffer
|
||||
*/
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) = 0;
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) = 0; // NOLINT(*)
|
||||
/*!
|
||||
* \brief save model to stream
|
||||
* \param fo output stream
|
||||
* \param with_pbuffer whether save out pbuffer
|
||||
*/
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const = 0;
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const = 0; // NOLINT(*)
|
||||
/*!
|
||||
* \brief initialize the model
|
||||
*/
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
#ifndef XGBOOST_GBM_GBTREE_INL_HPP_
|
||||
#define XGBOOST_GBM_GBTREE_INL_HPP_
|
||||
/*!
|
||||
* Copyright by Contributors
|
||||
* \file gbtree-inl.hpp
|
||||
* \brief gradient boosted tree implementation
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_GBM_GBTREE_INL_HPP_
|
||||
#define XGBOOST_GBM_GBTREE_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include "./gbm.h"
|
||||
#include "../utils/omp.h"
|
||||
#include "../tree/updater.h"
|
||||
@ -39,7 +42,7 @@ class GBTree : public IGradBooster {
|
||||
tparam.SetParam(name, val);
|
||||
if (trees.size() == 0) mparam.SetParam(name, val);
|
||||
}
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) {
|
||||
virtual void LoadModel(utils::IStream &fi, bool with_pbuffer) { // NOLINT(*)
|
||||
this->Clear();
|
||||
utils::Check(fi.Read(&mparam, sizeof(ModelParam)) != 0,
|
||||
"GBTree: invalid model file");
|
||||
@ -62,7 +65,7 @@ class GBTree : public IGradBooster {
|
||||
"GBTree: invalid model file");
|
||||
}
|
||||
}
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const {
|
||||
virtual void SaveModel(utils::IStream &fo, bool with_pbuffer) const { // NOLINT(*)
|
||||
utils::Assert(mparam.num_trees == static_cast<int>(trees.size()), "GBTree");
|
||||
if (with_pbuffer) {
|
||||
fo.Write(&mparam, sizeof(ModelParam));
|
||||
@ -196,7 +199,6 @@ class GBTree : public IGradBooster {
|
||||
thread_temp[i].Init(mparam.num_feature);
|
||||
}
|
||||
this->PredPath(p_fmat, info, out_preds, ntree_limit);
|
||||
|
||||
}
|
||||
virtual std::vector<std::string> DumpModel(const utils::FeatMap& fmap, int option) {
|
||||
std::vector<std::string> dump;
|
||||
@ -339,7 +341,7 @@ class GBTree : public IGradBooster {
|
||||
for (int j = 0; j < mparam.size_leaf_vector; ++j) {
|
||||
vec_psum[j] += trees[i]->leafvec(tid)[j];
|
||||
}
|
||||
if(--treeleft == 0) break;
|
||||
if (--treeleft == 0) break;
|
||||
}
|
||||
}
|
||||
p_feats->Drop(inst);
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
#ifndef XGBOOST_IO_IO_H_
|
||||
#define XGBOOST_IO_IO_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file io.h
|
||||
* \brief handles input data format of xgboost
|
||||
* I/O module handles a specific DMatrix format
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_IO_IO_H_
|
||||
#define XGBOOST_IO_IO_H_
|
||||
|
||||
#include "../data.h"
|
||||
#include "../learner/dmatrix.h"
|
||||
|
||||
@ -40,7 +42,6 @@ DataMatrix* LoadDataMatrix(const char *fname,
|
||||
* \param silent whether print message during saving
|
||||
*/
|
||||
void SaveDataMatrix(const DataMatrix &dmat, const char *fname, bool silent = false);
|
||||
|
||||
} // namespace io
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_IO_IO_H_
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_MODEL_H_
|
||||
#define XGBOOST_TREE_MODEL_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file model.h
|
||||
* \brief model structure for tree
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_MODEL_H_
|
||||
#define XGBOOST_TREE_MODEL_H_
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
@ -70,7 +72,7 @@ class TreeModel {
|
||||
/*! \brief tree node */
|
||||
class Node {
|
||||
public:
|
||||
Node(void) : sindex_(0) {}
|
||||
Node(void) : sindex_(0) {}
|
||||
/*! \brief index of left child */
|
||||
inline int cleft(void) const {
|
||||
return this->cleft_;
|
||||
@ -273,7 +275,7 @@ class TreeModel {
|
||||
return &leaf_vector[nid * param.size_leaf_vector];
|
||||
}
|
||||
/*! \brief get leaf vector given nid */
|
||||
inline const bst_float* leafvec(int nid) const{
|
||||
inline const bst_float* leafvec(int nid) const {
|
||||
if (leaf_vector.size() == 0) return NULL;
|
||||
return &leaf_vector[nid * param.size_leaf_vector];
|
||||
}
|
||||
@ -292,7 +294,7 @@ class TreeModel {
|
||||
* \brief load model from stream
|
||||
* \param fi input stream
|
||||
*/
|
||||
inline void LoadModel(utils::IStream &fi) {
|
||||
inline void LoadModel(utils::IStream &fi) { // NOLINT(*)
|
||||
utils::Check(fi.Read(¶m, sizeof(Param)) > 0,
|
||||
"TreeModel: wrong format");
|
||||
nodes.resize(param.num_nodes); stats.resize(param.num_nodes);
|
||||
@ -317,7 +319,7 @@ class TreeModel {
|
||||
* \brief save model to stream
|
||||
* \param fo output stream
|
||||
*/
|
||||
inline void SaveModel(utils::IStream &fo) const {
|
||||
inline void SaveModel(utils::IStream &fo) const { // NOLINT(*)
|
||||
utils::Assert(param.num_nodes == static_cast<int>(nodes.size()),
|
||||
"Tree::SaveModel");
|
||||
utils::Assert(param.num_nodes == static_cast<int>(stats.size()),
|
||||
@ -400,7 +402,7 @@ class TreeModel {
|
||||
}
|
||||
|
||||
private:
|
||||
void Dump(int nid, std::stringstream &fo,
|
||||
void Dump(int nid, std::stringstream &fo, // NOLINT(*)
|
||||
const utils::FeatMap& fmap, int depth, bool with_stats) {
|
||||
for (int i = 0; i < depth; ++i) {
|
||||
fo << '\t';
|
||||
@ -469,7 +471,7 @@ struct RTreeNodeStat {
|
||||
/*! \brief number of child that is leaf node known up to now */
|
||||
int leaf_child_cnt;
|
||||
/*! \brief print information of current stats to fo */
|
||||
inline void Print(std::stringstream &fo, bool is_leaf) const {
|
||||
inline void Print(std::stringstream &fo, bool is_leaf) const { // NOLINT(*)
|
||||
if (!is_leaf) {
|
||||
fo << ",gain=" << loss_chg << ",cover=" << sum_hess;
|
||||
} else {
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
#ifndef XGBOOST_TREE_PARAM_H_
|
||||
#define XGBOOST_TREE_PARAM_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file param.h
|
||||
* \brief training parameters, statistics used to support tree construction
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_PARAM_H_
|
||||
#define XGBOOST_TREE_PARAM_H_
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include "../data.h"
|
||||
|
||||
@ -244,7 +247,7 @@ struct GradStats {
|
||||
this->Add(b.sum_grad, b.sum_hess);
|
||||
}
|
||||
/*! \brief same as add, reduce is used in All Reduce */
|
||||
inline static void Reduce(GradStats &a, const GradStats &b) {
|
||||
inline static void Reduce(GradStats &a, const GradStats &b) { // NOLINT(*)
|
||||
a.Add(b);
|
||||
}
|
||||
/*! \brief set current value to a - b */
|
||||
@ -257,7 +260,7 @@ struct GradStats {
|
||||
return sum_hess == 0.0;
|
||||
}
|
||||
/*! \brief set leaf vector value based on statistics */
|
||||
inline void SetLeafVec(const TrainParam ¶m, bst_float *vec) const{
|
||||
inline void SetLeafVec(const TrainParam ¶m, bst_float *vec) const {
|
||||
}
|
||||
// constructor to allow inheritance
|
||||
GradStats(void) {}
|
||||
@ -324,7 +327,7 @@ struct CVGradStats : public GradStats {
|
||||
}
|
||||
}
|
||||
/*! \brief same as add, reduce is used in All Reduce */
|
||||
inline static void Reduce(CVGradStats &a, const CVGradStats &b) {
|
||||
inline static void Reduce(CVGradStats &a, const CVGradStats &b) { // NOLINT(*)
|
||||
a.Add(b);
|
||||
}
|
||||
/*! \brief set current value to a - b */
|
||||
@ -407,7 +410,7 @@ struct SplitEntry{
|
||||
}
|
||||
}
|
||||
/*! \brief same as update, used by AllReduce*/
|
||||
inline static void Reduce(SplitEntry &dst, const SplitEntry &src) {
|
||||
inline static void Reduce(SplitEntry &dst, const SplitEntry &src) { // NOLINT(*)
|
||||
dst.Update(src);
|
||||
}
|
||||
/*!\return feature index to split on */
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
// Copyright 2014 by Contributors
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define NOMINMAX
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_H_
|
||||
#define XGBOOST_TREE_UPDATER_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater.h
|
||||
* \brief interface to update the tree
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_H_
|
||||
#define XGBOOST_TREE_UPDATER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../data.h"
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_basemaker-inl.hpp
|
||||
* \brief implement a common tree constructor
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include "../sync/sync.h"
|
||||
#include "../utils/random.h"
|
||||
@ -60,8 +62,11 @@ class BaseMaker: public IUpdater {
|
||||
bst_float a = fminmax[fid * 2];
|
||||
bst_float b = fminmax[fid * 2 + 1];
|
||||
if (a == -std::numeric_limits<bst_float>::max()) return 0;
|
||||
if (-a == b) return 1;
|
||||
else return 2;
|
||||
if (-a == b) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
inline bst_float MaxValue(bst_uint fid) const {
|
||||
return fminmax[fid *2 + 1];
|
||||
@ -70,7 +75,7 @@ class BaseMaker: public IUpdater {
|
||||
std::vector<bst_uint> &findex = *p_findex;
|
||||
findex.clear();
|
||||
for (size_t i = 0; i < fminmax.size(); i += 2) {
|
||||
const bst_uint fid = static_cast<bst_uint>(i / 2);
|
||||
const bst_uint fid = static_cast<bst_uint>(i / 2);
|
||||
if (this->Type(fid) != 0) findex.push_back(fid);
|
||||
}
|
||||
unsigned n = static_cast<unsigned>(p * findex.size());
|
||||
@ -116,7 +121,7 @@ class BaseMaker: public IUpdater {
|
||||
}
|
||||
return nthread;
|
||||
}
|
||||
// ------class member helpers---------
|
||||
// ------class member helpers---------
|
||||
/*! \brief initialize temp data structure */
|
||||
inline void InitData(const std::vector<bst_gpair> &gpair,
|
||||
const IFMatrix &fmat,
|
||||
@ -124,7 +129,8 @@ class BaseMaker: public IUpdater {
|
||||
const RegTree &tree) {
|
||||
utils::Assert(tree.param.num_nodes == tree.param.num_roots,
|
||||
"TreeMaker: can only grow new tree");
|
||||
{// setup position
|
||||
{
|
||||
// setup position
|
||||
position.resize(gpair.size());
|
||||
if (root_index.size() == 0) {
|
||||
std::fill(position.begin(), position.end(), 0);
|
||||
@ -147,7 +153,8 @@ class BaseMaker: public IUpdater {
|
||||
}
|
||||
}
|
||||
}
|
||||
{// expand query
|
||||
{
|
||||
// expand query
|
||||
qexpand.reserve(256); qexpand.clear();
|
||||
for (int i = 0; i < tree.param.num_roots; ++i) {
|
||||
qexpand.push_back(i);
|
||||
@ -170,7 +177,7 @@ class BaseMaker: public IUpdater {
|
||||
this->UpdateNode2WorkIndex(tree);
|
||||
}
|
||||
// return decoded position
|
||||
inline int DecodePosition(bst_uint ridx) const{
|
||||
inline int DecodePosition(bst_uint ridx) const {
|
||||
const int pid = position[ridx];
|
||||
return pid < 0 ? ~pid : pid;
|
||||
}
|
||||
@ -189,7 +196,8 @@ class BaseMaker: public IUpdater {
|
||||
* \param p_fmat feature matrix needed for tree construction
|
||||
* \param tree the regression tree structure
|
||||
*/
|
||||
inline void ResetPositionCol(const std::vector<int> &nodes, IFMatrix *p_fmat, const RegTree &tree) {
|
||||
inline void ResetPositionCol(const std::vector<int> &nodes,
|
||||
IFMatrix *p_fmat, const RegTree &tree) {
|
||||
// set the positions in the nondefault
|
||||
this->SetNonDefaultPositionCol(nodes, p_fmat, tree);
|
||||
// set rest of instances to default position
|
||||
@ -252,7 +260,7 @@ class BaseMaker: public IUpdater {
|
||||
const int nid = this->DecodePosition(ridx);
|
||||
// go back to parent, correct those who are not default
|
||||
if (!tree[nid].is_leaf() && tree[nid].split_index() == fid) {
|
||||
if(fvalue < tree[nid].split_cond()) {
|
||||
if (fvalue < tree[nid].split_cond()) {
|
||||
this->SetEncodePosition(ridx, tree[nid].cleft());
|
||||
} else {
|
||||
this->SetEncodePosition(ridx, tree[nid].cright());
|
||||
@ -337,15 +345,16 @@ class BaseMaker: public IUpdater {
|
||||
return;
|
||||
}
|
||||
if (last_fvalue != fvalue) {
|
||||
double rmax = rmin + wmin;
|
||||
double rmax = rmin + wmin;
|
||||
if (rmax >= next_goal && sketch->temp.size != max_size) {
|
||||
if (sketch->temp.size == 0 || last_fvalue > sketch->temp.data[sketch->temp.size-1].value) {
|
||||
if (sketch->temp.size == 0 ||
|
||||
last_fvalue > sketch->temp.data[sketch->temp.size-1].value) {
|
||||
// push to sketch
|
||||
sketch->temp.data[sketch->temp.size] =
|
||||
utils::WXQuantileSketch<bst_float, bst_float>::
|
||||
Entry(static_cast<bst_float>(rmin),
|
||||
static_cast<bst_float>(rmax),
|
||||
static_cast<bst_float>(wmin), last_fvalue);
|
||||
static_cast<bst_float>(rmax),
|
||||
static_cast<bst_float>(wmin), last_fvalue);
|
||||
utils::Assert(sketch->temp.size < max_size,
|
||||
"invalid maximum size max_size=%u, stemp.size=%lu\n",
|
||||
max_size, sketch->temp.size);
|
||||
@ -353,15 +362,15 @@ class BaseMaker: public IUpdater {
|
||||
}
|
||||
if (sketch->temp.size == max_size) {
|
||||
next_goal = sum_total * 2.0f + 1e-5f;
|
||||
} else{
|
||||
} else {
|
||||
next_goal = static_cast<bst_float>(sketch->temp.size * sum_total / max_size);
|
||||
}
|
||||
} else {
|
||||
if (rmax >= next_goal) {
|
||||
rabit::TrackerPrintf("INFO: rmax=%g, sum_total=%g, next_goal=%g, size=%lu\n",
|
||||
rmax, sum_total, next_goal, sketch->temp.size);
|
||||
}
|
||||
}
|
||||
if (rmax >= next_goal) {
|
||||
rabit::TrackerPrintf("INFO: rmax=%g, sum_total=%g, next_goal=%g, size=%lu\n",
|
||||
rmax, sum_total, next_goal, sketch->temp.size);
|
||||
}
|
||||
}
|
||||
rmin = rmax;
|
||||
wmin = w;
|
||||
last_fvalue = fvalue;
|
||||
@ -375,13 +384,13 @@ class BaseMaker: public IUpdater {
|
||||
if (sketch->temp.size == 0 || last_fvalue > sketch->temp.data[sketch->temp.size-1].value) {
|
||||
utils::Assert(sketch->temp.size <= max_size,
|
||||
"Finalize: invalid maximum size, max_size=%u, stemp.size=%lu",
|
||||
sketch->temp.size, max_size );
|
||||
sketch->temp.size, max_size);
|
||||
// push to sketch
|
||||
sketch->temp.data[sketch->temp.size] =
|
||||
utils::WXQuantileSketch<bst_float, bst_float>::
|
||||
Entry(static_cast<bst_float>(rmin),
|
||||
static_cast<bst_float>(rmax),
|
||||
static_cast<bst_float>(wmin), last_fvalue);
|
||||
static_cast<bst_float>(rmax),
|
||||
static_cast<bst_float>(wmin), last_fvalue);
|
||||
++sketch->temp.size;
|
||||
}
|
||||
sketch->PushTemp();
|
||||
@ -415,4 +424,4 @@ class BaseMaker: public IUpdater {
|
||||
};
|
||||
} // namespace tree
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
#endif // XGBOOST_TREE_UPDATER_BASEMAKER_INL_HPP_
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_COLMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_COLMAKER_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_colmaker-inl.hpp
|
||||
* \brief use columnwise update to construct a tree
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_COLMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_COLMAKER_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
@ -114,10 +116,13 @@ class ColMaker: public IUpdater {
|
||||
// initialize temp data structure
|
||||
inline void InitData(const std::vector<bst_gpair> &gpair,
|
||||
const IFMatrix &fmat,
|
||||
const std::vector<unsigned> &root_index, const RegTree &tree) {
|
||||
utils::Assert(tree.param.num_nodes == tree.param.num_roots, "ColMaker: can only grow new tree");
|
||||
const std::vector<unsigned> &root_index,
|
||||
const RegTree &tree) {
|
||||
utils::Assert(tree.param.num_nodes == tree.param.num_roots,
|
||||
"ColMaker: can only grow new tree");
|
||||
const std::vector<bst_uint> &rowset = fmat.buffered_rowset();
|
||||
{// setup position
|
||||
{
|
||||
// setup position
|
||||
position.resize(gpair.size());
|
||||
if (root_index.size() == 0) {
|
||||
for (size_t i = 0; i < rowset.size(); ++i) {
|
||||
@ -127,7 +132,8 @@ class ColMaker: public IUpdater {
|
||||
for (size_t i = 0; i < rowset.size(); ++i) {
|
||||
const bst_uint ridx = rowset[i];
|
||||
position[ridx] = root_index[ridx];
|
||||
utils::Assert(root_index[ridx] < (unsigned)tree.param.num_roots, "root index exceed setting");
|
||||
utils::Assert(root_index[ridx] < (unsigned)tree.param.num_roots,
|
||||
"root index exceed setting");
|
||||
}
|
||||
}
|
||||
// mark delete for the deleted datas
|
||||
@ -154,11 +160,12 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
unsigned n = static_cast<unsigned>(param.colsample_bytree * feat_index.size());
|
||||
random::Shuffle(feat_index);
|
||||
//utils::Check(n > 0, "colsample_bytree is too small that no feature can be included");
|
||||
utils::Check(n > 0, "colsample_bytree=%g is too small that no feature can be included", param.colsample_bytree);
|
||||
utils::Check(n > 0, "colsample_bytree=%g is too small that no feature can be included",
|
||||
param.colsample_bytree);
|
||||
feat_index.resize(n);
|
||||
}
|
||||
{// setup temp space for each thread
|
||||
{
|
||||
// setup temp space for each thread
|
||||
#pragma omp parallel
|
||||
{
|
||||
this->nthread = omp_get_num_threads();
|
||||
@ -171,20 +178,25 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
snode.reserve(256);
|
||||
}
|
||||
{// expand query
|
||||
{
|
||||
// expand query
|
||||
qexpand_.reserve(256); qexpand_.clear();
|
||||
for (int i = 0; i < tree.param.num_roots; ++i) {
|
||||
qexpand_.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*! \brief initialize the base_weight, root_gain, and NodeEntry for all the new nodes in qexpand */
|
||||
/*!
|
||||
* \brief initialize the base_weight, root_gain,
|
||||
* and NodeEntry for all the new nodes in qexpand
|
||||
*/
|
||||
inline void InitNewNode(const std::vector<int> &qexpand,
|
||||
const std::vector<bst_gpair> &gpair,
|
||||
const IFMatrix &fmat,
|
||||
const BoosterInfo &info,
|
||||
const RegTree &tree) {
|
||||
{// setup statistics space for each tree node
|
||||
{
|
||||
// setup statistics space for each tree node
|
||||
for (size_t i = 0; i < stemp.size(); ++i) {
|
||||
stemp[i].resize(tree.param.num_nodes, ThreadEntry(param));
|
||||
}
|
||||
@ -280,7 +292,7 @@ class ColMaker: public IUpdater {
|
||||
ThreadEntry &e = stemp[tid][nid];
|
||||
float fsplit;
|
||||
if (tid != 0) {
|
||||
if(std::abs(stemp[tid - 1][nid].last_fvalue - e.first_fvalue) > rt_2eps) {
|
||||
if (std::abs(stemp[tid - 1][nid].last_fvalue - e.first_fvalue) > rt_2eps) {
|
||||
fsplit = (stemp[tid - 1][nid].last_fvalue - e.first_fvalue) * 0.5f;
|
||||
} else {
|
||||
continue;
|
||||
@ -290,16 +302,20 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
if (need_forward && tid != 0) {
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (c.sum_hess >= param.min_child_weight && e.stats.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
if (c.sum_hess >= param.min_child_weight &&
|
||||
e.stats.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, fsplit, false);
|
||||
}
|
||||
}
|
||||
if (need_backward) {
|
||||
tmp.SetSubstract(sum, e.stats);
|
||||
c.SetSubstract(snode[nid].stats, tmp);
|
||||
if (c.sum_hess >= param.min_child_weight && tmp.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(tmp.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
if (c.sum_hess >= param.min_child_weight &&
|
||||
tmp.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(tmp.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, fsplit, true);
|
||||
}
|
||||
}
|
||||
@ -308,8 +324,10 @@ class ColMaker: public IUpdater {
|
||||
tmp = sum;
|
||||
ThreadEntry &e = stemp[nthread-1][nid];
|
||||
c.SetSubstract(snode[nid].stats, tmp);
|
||||
if (c.sum_hess >= param.min_child_weight && tmp.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(tmp.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
if (c.sum_hess >= param.min_child_weight &&
|
||||
tmp.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(tmp.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, e.last_fvalue + rt_eps, true);
|
||||
}
|
||||
}
|
||||
@ -335,19 +353,25 @@ class ColMaker: public IUpdater {
|
||||
e.first_fvalue = fvalue;
|
||||
} else {
|
||||
// forward default right
|
||||
if (std::abs(fvalue - e.first_fvalue) > rt_2eps){
|
||||
if (std::abs(fvalue - e.first_fvalue) > rt_2eps) {
|
||||
if (need_forward) {
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (c.sum_hess >= param.min_child_weight && e.stats.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
if (c.sum_hess >= param.min_child_weight &&
|
||||
e.stats.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) -
|
||||
snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, (fvalue + e.first_fvalue) * 0.5f, false);
|
||||
}
|
||||
}
|
||||
if (need_backward) {
|
||||
cright.SetSubstract(e.stats_extra, e.stats);
|
||||
c.SetSubstract(snode[nid].stats, cright);
|
||||
if (c.sum_hess >= param.min_child_weight && cright.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(cright.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
if (c.sum_hess >= param.min_child_weight &&
|
||||
cright.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(cright.CalcGain(param) +
|
||||
c.CalcGain(param) -
|
||||
snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, (fvalue + e.first_fvalue) * 0.5f, true);
|
||||
}
|
||||
}
|
||||
@ -361,7 +385,7 @@ class ColMaker: public IUpdater {
|
||||
// update enumeration solution
|
||||
inline void UpdateEnumeration(int nid, bst_gpair gstats,
|
||||
float fvalue, int d_step, bst_uint fid,
|
||||
TStats &c, std::vector<ThreadEntry> &temp) {
|
||||
TStats &c, std::vector<ThreadEntry> &temp) { // NOLINT(*)
|
||||
// get the statistics of nid
|
||||
ThreadEntry &e = temp[nid];
|
||||
// test if first hit, this is fine, because we set 0 during init
|
||||
@ -370,10 +394,12 @@ class ColMaker: public IUpdater {
|
||||
e.last_fvalue = fvalue;
|
||||
} else {
|
||||
// try to find a split
|
||||
if (std::abs(fvalue - e.last_fvalue) > rt_2eps && e.stats.sum_hess >= param.min_child_weight) {
|
||||
if (std::abs(fvalue - e.last_fvalue) > rt_2eps &&
|
||||
e.stats.sum_hess >= param.min_child_weight) {
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (c.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, (fvalue + e.last_fvalue) * 0.5f, d_step == -1);
|
||||
}
|
||||
}
|
||||
@ -388,7 +414,7 @@ class ColMaker: public IUpdater {
|
||||
int d_step,
|
||||
bst_uint fid,
|
||||
const std::vector<bst_gpair> &gpair,
|
||||
std::vector<ThreadEntry> &temp) {
|
||||
std::vector<ThreadEntry> &temp) { // NOLINT(*)
|
||||
const std::vector<int> &qexpand = qexpand_;
|
||||
// clear all the temp statistics
|
||||
for (size_t j = 0; j < qexpand.size(); ++j) {
|
||||
@ -443,7 +469,8 @@ class ColMaker: public IUpdater {
|
||||
ThreadEntry &e = temp[nid];
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (e.stats.sum_hess >= param.min_child_weight && c.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
const float gap = std::abs(e.last_fvalue) + rt_eps;
|
||||
const float delta = d_step == +1 ? gap: -gap;
|
||||
e.best.Update(loss_chg, fid, e.last_fvalue + delta, d_step == -1);
|
||||
@ -458,7 +485,7 @@ class ColMaker: public IUpdater {
|
||||
bst_uint fid,
|
||||
const std::vector<bst_gpair> &gpair,
|
||||
const BoosterInfo &info,
|
||||
std::vector<ThreadEntry> &temp) {
|
||||
std::vector<ThreadEntry> &temp) { // NOLINT(*)
|
||||
// use cacheline aware optimization
|
||||
if (TStats::kSimpleStats != 0 && param.cache_opt != 0) {
|
||||
EnumerateSplitCacheOpt(begin, end, d_step, fid, gpair, temp);
|
||||
@ -471,7 +498,7 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
// left statistics
|
||||
TStats c(param);
|
||||
for(const ColBatch::Entry *it = begin; it != end; it += d_step) {
|
||||
for (const ColBatch::Entry *it = begin; it != end; it += d_step) {
|
||||
const bst_uint ridx = it->index;
|
||||
const int nid = position[ridx];
|
||||
if (nid < 0) continue;
|
||||
@ -485,10 +512,12 @@ class ColMaker: public IUpdater {
|
||||
e.last_fvalue = fvalue;
|
||||
} else {
|
||||
// try to find a split
|
||||
if (std::abs(fvalue - e.last_fvalue) > rt_2eps && e.stats.sum_hess >= param.min_child_weight) {
|
||||
if (std::abs(fvalue - e.last_fvalue) > rt_2eps &&
|
||||
e.stats.sum_hess >= param.min_child_weight) {
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (c.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
e.best.Update(loss_chg, fid, (fvalue + e.last_fvalue) * 0.5f, d_step == -1);
|
||||
}
|
||||
}
|
||||
@ -503,7 +532,8 @@ class ColMaker: public IUpdater {
|
||||
ThreadEntry &e = temp[nid];
|
||||
c.SetSubstract(snode[nid].stats, e.stats);
|
||||
if (e.stats.sum_hess >= param.min_child_weight && c.sum_hess >= param.min_child_weight) {
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) + c.CalcGain(param) - snode[nid].root_gain);
|
||||
bst_float loss_chg = static_cast<bst_float>(e.stats.CalcGain(param) +
|
||||
c.CalcGain(param) - snode[nid].root_gain);
|
||||
const float gap = std::abs(e.last_fvalue) + rt_eps;
|
||||
const float delta = d_step == +1 ? gap: -gap;
|
||||
e.best.Update(loss_chg, fid, e.last_fvalue + delta, d_step == -1);
|
||||
@ -585,7 +615,8 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
}
|
||||
// reset position of each data points after split is created in the tree
|
||||
inline void ResetPosition(const std::vector<int> &qexpand, IFMatrix *p_fmat, const RegTree &tree) {
|
||||
inline void ResetPosition(const std::vector<int> &qexpand,
|
||||
IFMatrix *p_fmat, const RegTree &tree) {
|
||||
// set the positions in the nondefault
|
||||
this->SetNonDefaultPosition(qexpand, p_fmat, tree);
|
||||
// set rest of instances to default position
|
||||
@ -655,7 +686,7 @@ class ColMaker: public IUpdater {
|
||||
const float fvalue = col[j].fvalue;
|
||||
// go back to parent, correct those who are not default
|
||||
if (!tree[nid].is_leaf() && tree[nid].split_index() == fid) {
|
||||
if(fvalue < tree[nid].split_cond()) {
|
||||
if (fvalue < tree[nid].split_cond()) {
|
||||
this->SetEncodePosition(ridx, tree[nid].cleft());
|
||||
} else {
|
||||
this->SetEncodePosition(ridx, tree[nid].cright());
|
||||
@ -667,7 +698,7 @@ class ColMaker: public IUpdater {
|
||||
}
|
||||
// utils to get/set position, with encoded format
|
||||
// return decoded position
|
||||
inline int DecodePosition(bst_uint ridx) const{
|
||||
inline int DecodePosition(bst_uint ridx) const {
|
||||
const int pid = position[ridx];
|
||||
return pid < 0 ? ~pid : pid;
|
||||
}
|
||||
@ -679,7 +710,7 @@ class ColMaker: public IUpdater {
|
||||
position[ridx] = nid;
|
||||
}
|
||||
}
|
||||
//--data fields--
|
||||
// --data fields--
|
||||
const TrainParam ¶m;
|
||||
// number of omp thread used during training
|
||||
int nthread;
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_DISTCOL_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_DISTCOL_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_distcol-inl.hpp
|
||||
* \brief beta distributed version that takes a sub-column
|
||||
* and construct a tree
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_DISTCOL_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_DISTCOL_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "../sync/sync.h"
|
||||
#include "../utils/bitmap.h"
|
||||
#include "../utils/io.h"
|
||||
@ -40,10 +44,11 @@ class DistColMaker : public ColMaker<TStats> {
|
||||
virtual const int* GetLeafPosition(void) const {
|
||||
return builder.GetLeafPosition();
|
||||
}
|
||||
|
||||
private:
|
||||
struct Builder : public ColMaker<TStats>::Builder {
|
||||
public:
|
||||
Builder(const TrainParam ¶m)
|
||||
explicit Builder(const TrainParam ¶m)
|
||||
: ColMaker<TStats>::Builder(param) {
|
||||
}
|
||||
inline void UpdatePosition(IFMatrix *p_fmat, const RegTree &tree) {
|
||||
@ -63,6 +68,7 @@ class DistColMaker : public ColMaker<TStats> {
|
||||
virtual const int* GetLeafPosition(void) const {
|
||||
return BeginPtr(this->position);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetNonDefaultPosition(const std::vector<int> &qexpand,
|
||||
IFMatrix *p_fmat, const RegTree &tree) {
|
||||
@ -142,7 +148,7 @@ class DistColMaker : public ColMaker<TStats> {
|
||||
}
|
||||
vec.push_back(this->snode[nid].best);
|
||||
}
|
||||
// TODO, lazy version
|
||||
// TODO(tqchen) lazy version
|
||||
// communicate best solution
|
||||
reducer.Allreduce(BeginPtr(vec), vec.size());
|
||||
// assign solution back
|
||||
@ -166,4 +172,4 @@ class DistColMaker : public ColMaker<TStats> {
|
||||
};
|
||||
} // namespace tree
|
||||
} // namespace xgboost
|
||||
#endif
|
||||
#endif // XGBOOST_TREE_UPDATER_DISTCOL_INL_HPP_
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_HISTMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_HISTMAKER_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_histmaker-inl.hpp
|
||||
* \brief use histogram counting to construct a tree
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_HISTMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_HISTMAKER_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "../sync/sync.h"
|
||||
@ -171,6 +173,7 @@ class HistMaker: public BaseMaker {
|
||||
const BoosterInfo &info,
|
||||
const std::vector <bst_uint> &fset,
|
||||
const RegTree &tree) = 0;
|
||||
|
||||
private:
|
||||
inline void EnumerateSplit(const HistUnit &hist,
|
||||
const TStats &node_sum,
|
||||
@ -187,7 +190,7 @@ class HistMaker: public BaseMaker {
|
||||
c.SetSubstract(node_sum, s);
|
||||
if (c.sum_hess >= param.min_child_weight) {
|
||||
double loss_chg = s.CalcGain(param) + c.CalcGain(param) - root_gain;
|
||||
if (best->Update((float)loss_chg, fid, hist.cut[i], false)) {
|
||||
if (best->Update(static_cast<float>(loss_chg), fid, hist.cut[i], false)) {
|
||||
*left_sum = s;
|
||||
}
|
||||
}
|
||||
@ -200,7 +203,7 @@ class HistMaker: public BaseMaker {
|
||||
c.SetSubstract(node_sum, s);
|
||||
if (c.sum_hess >= param.min_child_weight) {
|
||||
double loss_chg = s.CalcGain(param) + c.CalcGain(param) - root_gain;
|
||||
if (best->Update((float)loss_chg, fid, hist.cut[i-1], true)) {
|
||||
if (best->Update(static_cast<float>(loss_chg), fid, hist.cut[i-1], true)) {
|
||||
*left_sum = c;
|
||||
}
|
||||
}
|
||||
@ -219,19 +222,19 @@ class HistMaker: public BaseMaker {
|
||||
std::vector<TStats> left_sum(qexpand.size());
|
||||
bst_omp_uint nexpand = static_cast<bst_omp_uint>(qexpand.size());
|
||||
#pragma omp parallel for schedule(dynamic, 1)
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++ wid) {
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++wid) {
|
||||
const int nid = qexpand[wid];
|
||||
utils::Assert(node2workindex[nid] == static_cast<int>(wid),
|
||||
"node2workindex inconsistent");
|
||||
SplitEntry &best = sol[wid];
|
||||
TStats &node_sum = wspace.hset[0][num_feature + wid * (num_feature + 1)].data[0];
|
||||
for (size_t i = 0; i < fset.size(); ++ i) {
|
||||
for (size_t i = 0; i < fset.size(); ++i) {
|
||||
EnumerateSplit(this->wspace.hset[0][i + wid * (num_feature+1)],
|
||||
node_sum, fset[i], &best, &left_sum[wid]);
|
||||
}
|
||||
}
|
||||
// get the best result, we can synchronize the solution
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++ wid) {
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++wid) {
|
||||
const int nid = qexpand[wid];
|
||||
const SplitEntry &best = sol[wid];
|
||||
const TStats &node_sum = wspace.hset[0][num_feature + wid * (num_feature + 1)].data[0];
|
||||
@ -394,7 +397,8 @@ class CQHistMaker: public HistMaker<TStats> {
|
||||
#if __cplusplus >= 201103L
|
||||
auto lazy_get_summary = [&]()
|
||||
#endif
|
||||
{// get smmary
|
||||
{
|
||||
// get smmary
|
||||
thread_sketch.resize(this->get_nthread());
|
||||
// number of rows in
|
||||
const size_t nrows = p_fmat->buffered_rowset().size();
|
||||
@ -670,7 +674,7 @@ class QuantileHistMaker: public HistMaker<TStats> {
|
||||
}
|
||||
if (this->node2workindex[nid] < 0) {
|
||||
this->position[ridx] = ~nid;
|
||||
} else{
|
||||
} else {
|
||||
for (bst_uint j = 0; j < inst.length; ++j) {
|
||||
builder.AddBudget(inst[j].index, omp_get_thread_num());
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_prune-inl.hpp
|
||||
* \brief prune a tree given the statistics
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include "./param.h"
|
||||
#include "./updater.h"
|
||||
@ -37,9 +39,10 @@ class TreePruner: public IUpdater {
|
||||
param.learning_rate = lr;
|
||||
syncher.Update(gpair, p_fmat, info, trees);
|
||||
}
|
||||
|
||||
private:
|
||||
// try to prune off current leaf
|
||||
inline int TryPruneLeaf(RegTree &tree, int nid, int depth, int npruned) {
|
||||
inline int TryPruneLeaf(RegTree &tree, int nid, int depth, int npruned) { // NOLINT(*)
|
||||
if (tree[nid].is_root()) return npruned;
|
||||
int pid = tree[nid].parent();
|
||||
RegTree::NodeStat &s = tree.stat(pid);
|
||||
@ -54,7 +57,7 @@ class TreePruner: public IUpdater {
|
||||
}
|
||||
}
|
||||
/*! \brief do prunning of a tree */
|
||||
inline void DoPrune(RegTree &tree) {
|
||||
inline void DoPrune(RegTree &tree) { // NOLINT(*)
|
||||
int npruned = 0;
|
||||
// initialize auxiliary statistics
|
||||
for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_REFRESH_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_REFRESH_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_refresh-inl.hpp
|
||||
* \brief refresh the statistics and leaf value on the tree on the dataset
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_REFRESH_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_REFRESH_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include "../sync/sync.h"
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_SKMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_SKMAKER_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_skmaker-inl.hpp
|
||||
* \brief use approximation sketch to construct a tree,
|
||||
a refresh is needed to make the statistics exactly correct
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_SKMAKER_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_SKMAKER_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "../sync/sync.h"
|
||||
@ -81,7 +83,7 @@ class SketchMaker: public BaseMaker {
|
||||
double neg_grad;
|
||||
/*! \brief sum of hessian statistics */
|
||||
double sum_hess;
|
||||
explicit SKStats(void) {}
|
||||
SKStats(void) {}
|
||||
// constructor
|
||||
explicit SKStats(const TrainParam ¶m) {
|
||||
this->Clear();
|
||||
@ -123,7 +125,7 @@ class SketchMaker: public BaseMaker {
|
||||
sum_hess += b.sum_hess;
|
||||
}
|
||||
/*! \brief same as add, reduce is used in All Reduce */
|
||||
inline static void Reduce(SKStats &a, const SKStats &b) {
|
||||
inline static void Reduce(SKStats &a, const SKStats &b) { // NOLINT(*)
|
||||
a.Add(b);
|
||||
}
|
||||
/*! \brief set leaf vector value based on statistics */
|
||||
@ -217,7 +219,9 @@ class SketchMaker: public BaseMaker {
|
||||
for (size_t i = 0; i < this->qexpand.size(); ++i) {
|
||||
const int nid = this->qexpand[i];
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
sbuilder[3 * nid + k].sketch->Push(c[0].fvalue, static_cast<bst_float>(sbuilder[3 * nid + k].sum_total));
|
||||
sbuilder[3 * nid + k].sketch->Push(c[0].fvalue,
|
||||
static_cast<bst_float>(
|
||||
sbuilder[3 * nid + k].sum_total));
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -272,12 +276,12 @@ class SketchMaker: public BaseMaker {
|
||||
std::vector<SplitEntry> sol(qexpand.size());
|
||||
bst_omp_uint nexpand = static_cast<bst_omp_uint>(qexpand.size());
|
||||
#pragma omp parallel for schedule(dynamic, 1)
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++ wid) {
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++wid) {
|
||||
const int nid = qexpand[wid];
|
||||
utils::Assert(node2workindex[nid] == static_cast<int>(wid),
|
||||
"node2workindex inconsistent");
|
||||
SplitEntry &best = sol[wid];
|
||||
for (bst_uint fid = 0; fid < num_feature; ++ fid) {
|
||||
for (bst_uint fid = 0; fid < num_feature; ++fid) {
|
||||
unsigned base = (wid * p_tree->param.num_feature + fid) * 3;
|
||||
EnumerateSplit(summary_array[base + 0],
|
||||
summary_array[base + 1],
|
||||
@ -286,7 +290,7 @@ class SketchMaker: public BaseMaker {
|
||||
}
|
||||
}
|
||||
// get the best result, we can synchronize the solution
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++ wid) {
|
||||
for (bst_omp_uint wid = 0; wid < nexpand; ++wid) {
|
||||
const int nid = qexpand[wid];
|
||||
const SplitEntry &best = sol[wid];
|
||||
// set up the values
|
||||
@ -361,7 +365,8 @@ class SketchMaker: public BaseMaker {
|
||||
best->Update(static_cast<bst_float>(loss_chg), fid, fsplits[i], true);
|
||||
}
|
||||
}
|
||||
{// all including
|
||||
{
|
||||
// all including
|
||||
SKStats s = feat_sum, c;
|
||||
c.SetSubstract(node_sum, s);
|
||||
if (s.sum_hess >= param.min_child_weight &&
|
||||
@ -389,6 +394,6 @@ class SketchMaker: public BaseMaker {
|
||||
// per node, per feature sketch
|
||||
std::vector< utils::WXQuantileSketch<bst_float, bst_float> > sketchs;
|
||||
};
|
||||
} // tree
|
||||
} // xgboost
|
||||
#endif
|
||||
} // namespace tree
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_TREE_UPDATER_SKMAKER_INL_HPP_
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#ifndef XGBOOST_TREE_UPDATER_SYNC_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_SYNC_INL_HPP_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file updater_sync-inl.hpp
|
||||
* \brief synchronize the tree in all distributed nodes
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_TREE_UPDATER_SYNC_INL_HPP_
|
||||
#define XGBOOST_TREE_UPDATER_SYNC_INL_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include "../sync/sync.h"
|
||||
#include "./updater.h"
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
#ifndef XGBOOST_UTILS_CONFIG_H_
|
||||
#define XGBOOST_UTILS_CONFIG_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file config.h
|
||||
* \brief helper class to load in configures from file
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_CONFIG_H_
|
||||
#define XGBOOST_UTILS_CONFIG_H_
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#ifndef XGBOOST_UTILS_GROUP_DATA_H_
|
||||
#define XGBOOST_UTILS_GROUP_DATA_H_
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file group_data.h
|
||||
* \brief this file defines utils to group data by integer keys
|
||||
* Input: given input sequence (key,value), (k1,v1), (k2,v2)
|
||||
@ -12,6 +11,11 @@
|
||||
* The major algorithm is a two pass linear scan algorithm that requires two pass scan over the data
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_GROUP_DATA_H_
|
||||
#define XGBOOST_UTILS_GROUP_DATA_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*!
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
#ifndef XGBOOST_UTILS_IO_H
|
||||
#define XGBOOST_UTILS_IO_H
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file io.h
|
||||
* \brief general stream interface for serialization, I/O
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
|
||||
#ifndef XGBOOST_UTILS_IO_H_
|
||||
#define XGBOOST_UTILS_IO_H_
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "./utils.h"
|
||||
#include "../sync/sync.h"
|
||||
/*!
|
||||
* \file io.h
|
||||
* \brief general stream interface for serialization, I/O
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
// reuse the definitions of streams
|
||||
@ -23,7 +26,7 @@ typedef rabit::utils::MemoryBufferStream MemoryBufferStream;
|
||||
class FileStream : public ISeekStream {
|
||||
public:
|
||||
explicit FileStream(std::FILE *fp) : fp(fp) {}
|
||||
explicit FileStream(void) {
|
||||
FileStream(void) {
|
||||
this->fp = NULL;
|
||||
}
|
||||
virtual size_t Read(void *ptr, size_t size) {
|
||||
@ -33,7 +36,7 @@ class FileStream : public ISeekStream {
|
||||
std::fwrite(ptr, size, 1, fp);
|
||||
}
|
||||
virtual void Seek(size_t pos) {
|
||||
std::fseek(fp, static_cast<long>(pos), SEEK_SET);
|
||||
std::fseek(fp, static_cast<long>(pos), SEEK_SET); // NOLINT(*)
|
||||
}
|
||||
virtual size_t Tell(void) {
|
||||
return std::ftell(fp);
|
||||
@ -42,7 +45,7 @@ class FileStream : public ISeekStream {
|
||||
return std::feof(fp) != 0;
|
||||
}
|
||||
inline void Close(void) {
|
||||
if (fp != NULL){
|
||||
if (fp != NULL) {
|
||||
std::fclose(fp); fp = NULL;
|
||||
}
|
||||
}
|
||||
@ -52,6 +55,5 @@ class FileStream : public ISeekStream {
|
||||
};
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
|
||||
#include "./base64-inl.h"
|
||||
#endif
|
||||
#endif // XGBOOST_UTILS_IO_H_
|
||||
|
||||
@ -1,16 +1,17 @@
|
||||
#ifndef XGBOOST_UTILS_THREAD_H
|
||||
#define XGBOOST_UTILS_THREAD_H
|
||||
/*!
|
||||
* Copyright by Contributors
|
||||
* \file thread.h
|
||||
* \brief this header include the minimum necessary resource for multi-threading
|
||||
* \brief this header include the minimum necessary resource
|
||||
* for multi-threading that can be compiled in windows, linux, mac
|
||||
* \author Tianqi Chen
|
||||
* Acknowledgement: this file is adapted from SVDFeature project, by same author.
|
||||
* The MAC support part of this code is provided by Artemy Kolchinsky
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_THREAD_H_ // NOLINT(*)
|
||||
#define XGBOOST_UTILS_THREAD_H_ // NOLINT(*)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "utils.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include "../xgboost/utils.h"
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*! \brief simple semaphore used for synchronization */
|
||||
@ -18,27 +19,78 @@ class Semaphore {
|
||||
public :
|
||||
inline void Init(int init_val) {
|
||||
sem = CreateSemaphore(NULL, init_val, 10, NULL);
|
||||
utils::Assert(sem != NULL, "create Semaphore error");
|
||||
utils::Check(sem != NULL, "create Semaphore error");
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
CloseHandle(sem);
|
||||
}
|
||||
inline void Wait(void) {
|
||||
utils::Assert(WaitForSingleObject(sem, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject error");
|
||||
utils::Check(WaitForSingleObject(sem, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject error");
|
||||
}
|
||||
inline void Post(void) {
|
||||
utils::Assert(ReleaseSemaphore(sem, 1, NULL) != 0, "ReleaseSemaphore error");
|
||||
utils::Check(ReleaseSemaphore(sem, 1, NULL) != 0, "ReleaseSemaphore error");
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE sem;
|
||||
};
|
||||
|
||||
/*! \brief mutex under windows */
|
||||
class Mutex {
|
||||
public:
|
||||
inline void Init(void) {
|
||||
utils::Check(InitializeCriticalSectionAndSpinCount(&mutex, 0x00000400) != 0,
|
||||
"Mutex::Init fail");
|
||||
}
|
||||
inline void Lock(void) {
|
||||
EnterCriticalSection(&mutex);
|
||||
}
|
||||
inline void Unlock(void) {
|
||||
LeaveCriticalSection(&mutex);
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
DeleteCriticalSection(&mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
CRITICAL_SECTION mutex;
|
||||
};
|
||||
|
||||
// conditional variable that uses pthread
|
||||
class ConditionVariable {
|
||||
public:
|
||||
// initialize conditional variable
|
||||
inline void Init(void) {
|
||||
InitializeConditionVariable(&cond);
|
||||
}
|
||||
// destroy the thread
|
||||
inline void Destroy(void) {
|
||||
// DeleteConditionVariable(&cond);
|
||||
}
|
||||
// wait on the conditional variable
|
||||
inline void Wait(Mutex *mutex) {
|
||||
utils::Check(SleepConditionVariableCS(&cond, &(mutex->mutex), INFINITE) != 0,
|
||||
"ConditionVariable:Wait fail");
|
||||
}
|
||||
inline void Broadcast(void) {
|
||||
WakeAllConditionVariable(&cond);
|
||||
}
|
||||
inline void Signal(void) {
|
||||
WakeConditionVariable(&cond);
|
||||
}
|
||||
|
||||
private:
|
||||
CONDITION_VARIABLE cond;
|
||||
};
|
||||
|
||||
/*! \brief simple thread that wraps windows thread */
|
||||
class Thread {
|
||||
private:
|
||||
HANDLE thread_handle;
|
||||
unsigned thread_id;
|
||||
public:
|
||||
inline void Start(unsigned int __stdcall entry(void*), void *param) {
|
||||
inline void Start(unsigned int __stdcall entry(void*p), void *param) {
|
||||
thread_handle = (HANDLE)_beginthreadex(NULL, 0, entry, param, 0, &thread_id);
|
||||
}
|
||||
inline int Join(void) {
|
||||
@ -55,38 +107,40 @@ inline void ThreadExit(void *status) {
|
||||
} // namespace xgboost
|
||||
#else
|
||||
// thread interface using g++
|
||||
extern "C" {
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
}
|
||||
#include <errno.h>
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*!\brief semaphore class */
|
||||
class Semaphore {
|
||||
#ifdef __APPLE__
|
||||
|
||||
private:
|
||||
sem_t* semPtr;
|
||||
char sema_name[20];
|
||||
|
||||
private:
|
||||
inline void GenRandomString(char *s, const int len) {
|
||||
static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
|
||||
static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
for (int i = 0; i < len; ++i) {
|
||||
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
|
||||
}
|
||||
s[len] = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
inline void Init(int init_val) {
|
||||
sema_name[0]='/';
|
||||
sema_name[1]='s';
|
||||
sema_name[2]='e';
|
||||
sema_name[3]='/';
|
||||
sema_name[0] = '/';
|
||||
sema_name[1] = 's';
|
||||
sema_name[2] = 'e';
|
||||
sema_name[3] = '/';
|
||||
GenRandomString(&sema_name[4], 16);
|
||||
if((semPtr = sem_open(sema_name, O_CREAT, 0644, init_val)) == SEM_FAILED) {
|
||||
if ((semPtr = sem_open(sema_name, O_CREAT, 0644, init_val)) == SEM_FAILED) {
|
||||
perror("sem_open");
|
||||
exit(1);
|
||||
}
|
||||
utils::Assert(semPtr != NULL, "create Semaphore error");
|
||||
utils::Check(semPtr != NULL, "create Semaphore error");
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
if (sem_close(semPtr) == -1) {
|
||||
@ -105,51 +159,91 @@ class Semaphore {
|
||||
sem_post(semPtr);
|
||||
}
|
||||
#else
|
||||
|
||||
private:
|
||||
sem_t sem;
|
||||
|
||||
public:
|
||||
inline void Init(int init_val) {
|
||||
sem_init(&sem, 0, init_val);
|
||||
if (sem_init(&sem, 0, init_val) != 0) {
|
||||
utils::Error("Semaphore.Init:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
sem_destroy(&sem);
|
||||
if (sem_destroy(&sem) != 0) {
|
||||
utils::Error("Semaphore.Destroy:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Wait(void) {
|
||||
sem_wait(&sem);
|
||||
if (sem_wait(&sem) != 0) {
|
||||
utils::Error("Semaphore.Wait:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Post(void) {
|
||||
sem_post(&sem);
|
||||
if (sem_post(&sem) != 0) {
|
||||
utils::Error("Semaphore.Post:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// helper for c thread
|
||||
// used to strictly call c++ function from pthread
|
||||
struct ThreadContext {
|
||||
void *(*entry)(void*);
|
||||
void *param;
|
||||
};
|
||||
extern "C" {
|
||||
inline void *RunThreadContext(void *ctx_) {
|
||||
ThreadContext *ctx = reinterpret_cast<ThreadContext*>(ctx_);
|
||||
void *ret = (*ctx->entry)(ctx->param);
|
||||
delete ctx;
|
||||
return ret;
|
||||
// mutex that works with pthread
|
||||
class Mutex {
|
||||
public:
|
||||
inline void Init(void) {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
}
|
||||
inline void Lock(void) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
inline void Unlock(void) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
// conditional variable that uses pthread
|
||||
class ConditionVariable {
|
||||
public:
|
||||
// initialize conditional variable
|
||||
inline void Init(void) {
|
||||
pthread_cond_init(&cond, NULL);
|
||||
}
|
||||
// destroy the thread
|
||||
inline void Destroy(void) {
|
||||
pthread_cond_destroy(&cond);
|
||||
}
|
||||
// wait on the conditional variable
|
||||
inline void Wait(Mutex *mutex) {
|
||||
pthread_cond_wait(&cond, &(mutex->mutex));
|
||||
}
|
||||
inline void Broadcast(void) {
|
||||
pthread_cond_broadcast(&cond);
|
||||
}
|
||||
inline void Signal(void) {
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/*!\brief simple thread class */
|
||||
class Thread {
|
||||
private:
|
||||
pthread_t thread;
|
||||
|
||||
public :
|
||||
inline void Start(void *entry(void*), void *param) {
|
||||
inline void Start(void * entry(void*), void *param) { // NOLINT(*)
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
ThreadContext *ctx = new ThreadContext();
|
||||
ctx->entry = entry; ctx->param = param;
|
||||
pthread_create(&thread, &attr, RunThreadContext, ctx);
|
||||
pthread_create(&thread, &attr, entry, param);
|
||||
}
|
||||
inline int Join(void) {
|
||||
void *status;
|
||||
@ -159,9 +253,8 @@ class Thread {
|
||||
inline void ThreadExit(void *status) {
|
||||
pthread_exit(status);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
#define XGBOOST_THREAD_PREFIX void *
|
||||
#endif
|
||||
#endif
|
||||
#endif // Linux
|
||||
#endif // XGBOOST_UTILS_THREAD_H_ NOLINT(*)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user