Quick fix for memory leak in CPU Hist. (#5153)
Closes https://github.com/dmlc/xgboost/issues/3579 . * Don't use map.
This commit is contained in:
parent
018df6004e
commit
04db125699
@ -41,7 +41,6 @@ void QuantileHistMaker::Configure(const Args& args) {
|
|||||||
}
|
}
|
||||||
pruner_->Configure(args);
|
pruner_->Configure(args);
|
||||||
param_.UpdateAllowUnknown(args);
|
param_.UpdateAllowUnknown(args);
|
||||||
is_gmat_initialized_ = false;
|
|
||||||
|
|
||||||
// initialise the split evaluator
|
// initialise the split evaluator
|
||||||
if (!spliteval_) {
|
if (!spliteval_) {
|
||||||
@ -54,12 +53,14 @@ void QuantileHistMaker::Configure(const Args& args) {
|
|||||||
void QuantileHistMaker::Update(HostDeviceVector<GradientPair> *gpair,
|
void QuantileHistMaker::Update(HostDeviceVector<GradientPair> *gpair,
|
||||||
DMatrix *dmat,
|
DMatrix *dmat,
|
||||||
const std::vector<RegTree *> &trees) {
|
const std::vector<RegTree *> &trees) {
|
||||||
if (is_gmat_initialized_ == false) {
|
if (dmat != p_last_dmat_ || is_gmat_initialized_ == false) {
|
||||||
gmat_.Init(dmat, static_cast<uint32_t>(param_.max_bin));
|
gmat_.Init(dmat, static_cast<uint32_t>(param_.max_bin));
|
||||||
column_matrix_.Init(gmat_, param_.sparse_threshold);
|
column_matrix_.Init(gmat_, param_.sparse_threshold);
|
||||||
if (param_.enable_feature_grouping > 0) {
|
if (param_.enable_feature_grouping > 0) {
|
||||||
gmatb_.Init(gmat_, column_matrix_, param_);
|
gmatb_.Init(gmat_, column_matrix_, param_);
|
||||||
}
|
}
|
||||||
|
// A proper solution is puting cut matrix in DMatrix, see:
|
||||||
|
// https://github.com/dmlc/xgboost/issues/5143
|
||||||
is_gmat_initialized_ = true;
|
is_gmat_initialized_ = true;
|
||||||
}
|
}
|
||||||
// rescale learning rate according to size of trees
|
// rescale learning rate according to size of trees
|
||||||
@ -72,12 +73,14 @@ void QuantileHistMaker::Update(HostDeviceVector<GradientPair> *gpair,
|
|||||||
param_,
|
param_,
|
||||||
std::move(pruner_),
|
std::move(pruner_),
|
||||||
std::unique_ptr<SplitEvaluator>(spliteval_->GetHostClone()),
|
std::unique_ptr<SplitEvaluator>(spliteval_->GetHostClone()),
|
||||||
int_constraint_));
|
int_constraint_, dmat));
|
||||||
}
|
}
|
||||||
for (auto tree : trees) {
|
for (auto tree : trees) {
|
||||||
builder_->Update(gmat_, gmatb_, column_matrix_, gpair, dmat, tree);
|
builder_->Update(gmat_, gmatb_, column_matrix_, gpair, dmat, tree);
|
||||||
}
|
}
|
||||||
param_.learning_rate = lr;
|
param_.learning_rate = lr;
|
||||||
|
|
||||||
|
p_last_dmat_ = dmat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuantileHistMaker::UpdatePredictionCache(
|
bool QuantileHistMaker::UpdatePredictionCache(
|
||||||
@ -508,12 +511,8 @@ void QuantileHistMaker::Builder::InitData(const GHistIndexMatrix& gmat,
|
|||||||
data_layout_ = kSparseData;
|
data_layout_ = kSparseData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
// store a pointer to the tree
|
||||||
// store a pointer to the tree
|
p_last_tree_ = &tree;
|
||||||
p_last_tree_ = &tree;
|
|
||||||
// store a pointer to training data
|
|
||||||
p_last_fmat_ = &fmat;
|
|
||||||
}
|
|
||||||
if (data_layout_ == kDenseDataOneBased) {
|
if (data_layout_ == kDenseDataOneBased) {
|
||||||
column_sampler_.Init(info.num_col_, param_.colsample_bynode, param_.colsample_bylevel,
|
column_sampler_.Init(info.num_col_, param_.colsample_bynode, param_.colsample_bylevel,
|
||||||
param_.colsample_bytree, true);
|
param_.colsample_bytree, true);
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "xgboost/data.h"
|
||||||
#include "xgboost/json.h"
|
#include "xgboost/json.h"
|
||||||
#include "constraints.h"
|
#include "constraints.h"
|
||||||
#include "./param.h"
|
#include "./param.h"
|
||||||
@ -80,7 +81,7 @@ using xgboost::common::Column;
|
|||||||
/*! \brief construct a tree using quantized feature values */
|
/*! \brief construct a tree using quantized feature values */
|
||||||
class QuantileHistMaker: public TreeUpdater {
|
class QuantileHistMaker: public TreeUpdater {
|
||||||
public:
|
public:
|
||||||
QuantileHistMaker() : is_gmat_initialized_{ false } {}
|
QuantileHistMaker() {}
|
||||||
void Configure(const Args& args) override;
|
void Configure(const Args& args) override;
|
||||||
|
|
||||||
void Update(HostDeviceVector<GradientPair>* gpair,
|
void Update(HostDeviceVector<GradientPair>* gpair,
|
||||||
@ -112,7 +113,8 @@ class QuantileHistMaker: public TreeUpdater {
|
|||||||
GHistIndexBlockMatrix gmatb_;
|
GHistIndexBlockMatrix gmatb_;
|
||||||
// column accessor
|
// column accessor
|
||||||
ColumnMatrix column_matrix_;
|
ColumnMatrix column_matrix_;
|
||||||
bool is_gmat_initialized_;
|
DMatrix const* p_last_dmat_ {nullptr};
|
||||||
|
bool is_gmat_initialized_ {false};
|
||||||
|
|
||||||
// data structure
|
// data structure
|
||||||
struct NodeEntry {
|
struct NodeEntry {
|
||||||
@ -136,10 +138,11 @@ class QuantileHistMaker: public TreeUpdater {
|
|||||||
explicit Builder(const TrainParam& param,
|
explicit Builder(const TrainParam& param,
|
||||||
std::unique_ptr<TreeUpdater> pruner,
|
std::unique_ptr<TreeUpdater> pruner,
|
||||||
std::unique_ptr<SplitEvaluator> spliteval,
|
std::unique_ptr<SplitEvaluator> spliteval,
|
||||||
FeatureInteractionConstraintHost int_constraints_)
|
FeatureInteractionConstraintHost int_constraints_,
|
||||||
|
DMatrix const* fmat)
|
||||||
: param_(param), pruner_(std::move(pruner)),
|
: param_(param), pruner_(std::move(pruner)),
|
||||||
spliteval_(std::move(spliteval)), interaction_constraints_{int_constraints_},
|
spliteval_(std::move(spliteval)), interaction_constraints_{int_constraints_},
|
||||||
p_last_tree_(nullptr), p_last_fmat_(nullptr) {
|
p_last_tree_(nullptr), p_last_fmat_(fmat) {
|
||||||
builder_monitor_.Init("Quantile::Builder");
|
builder_monitor_.Init("Quantile::Builder");
|
||||||
}
|
}
|
||||||
// update one tree, growing
|
// update one tree, growing
|
||||||
@ -313,7 +316,7 @@ class QuantileHistMaker: public TreeUpdater {
|
|||||||
|
|
||||||
// back pointers to tree and data matrix
|
// back pointers to tree and data matrix
|
||||||
const RegTree* p_last_tree_;
|
const RegTree* p_last_tree_;
|
||||||
const DMatrix* p_last_fmat_;
|
DMatrix const* const p_last_fmat_;
|
||||||
|
|
||||||
using ExpandQueue =
|
using ExpandQueue =
|
||||||
std::priority_queue<ExpandEntry, std::vector<ExpandEntry>,
|
std::priority_queue<ExpandEntry, std::vector<ExpandEntry>,
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "../../../src/tree/param.h"
|
#include "../../../src/tree/param.h"
|
||||||
#include "../../../src/tree/updater_quantile_hist.h"
|
#include "../../../src/tree/updater_quantile_hist.h"
|
||||||
#include "../../../src/tree/split_evaluator.h"
|
#include "../../../src/tree/split_evaluator.h"
|
||||||
|
#include "xgboost/data.h"
|
||||||
|
|
||||||
namespace xgboost {
|
namespace xgboost {
|
||||||
namespace tree {
|
namespace tree {
|
||||||
@ -26,8 +27,9 @@ class QuantileHistMock : public QuantileHistMaker {
|
|||||||
BuilderMock(const TrainParam& param,
|
BuilderMock(const TrainParam& param,
|
||||||
std::unique_ptr<TreeUpdater> pruner,
|
std::unique_ptr<TreeUpdater> pruner,
|
||||||
std::unique_ptr<SplitEvaluator> spliteval,
|
std::unique_ptr<SplitEvaluator> spliteval,
|
||||||
FeatureInteractionConstraintHost int_constraint)
|
FeatureInteractionConstraintHost int_constraint,
|
||||||
: RealImpl(param, std::move(pruner), std::move(spliteval), std::move(int_constraint)) {}
|
DMatrix const* fmat)
|
||||||
|
: RealImpl(param, std::move(pruner), std::move(spliteval), std::move(int_constraint), fmat) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void TestInitData(const GHistIndexMatrix& gmat,
|
void TestInitData(const GHistIndexMatrix& gmat,
|
||||||
@ -236,13 +238,14 @@ class QuantileHistMock : public QuantileHistMaker {
|
|||||||
cfg_{args} {
|
cfg_{args} {
|
||||||
QuantileHistMaker::Configure(args);
|
QuantileHistMaker::Configure(args);
|
||||||
spliteval_->Init(¶m_);
|
spliteval_->Init(¶m_);
|
||||||
|
dmat_ = CreateDMatrix(kNRows, kNCols, 0.8, 3);
|
||||||
builder_.reset(
|
builder_.reset(
|
||||||
new BuilderMock(
|
new BuilderMock(
|
||||||
param_,
|
param_,
|
||||||
std::move(pruner_),
|
std::move(pruner_),
|
||||||
std::unique_ptr<SplitEvaluator>(spliteval_->GetHostClone()),
|
std::unique_ptr<SplitEvaluator>(spliteval_->GetHostClone()),
|
||||||
int_constraint_));
|
int_constraint_,
|
||||||
dmat_ = CreateDMatrix(kNRows, kNCols, 0.8, 3);
|
dmat_->get()));
|
||||||
}
|
}
|
||||||
~QuantileHistMock() override { delete dmat_; }
|
~QuantileHistMock() override { delete dmat_; }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user