Clang-tidy static analysis (#3222)
* Clang-tidy static analysis * Modernise checks * Google coding standard checks * Identifier renaming according to Google style
This commit is contained in:
@@ -23,22 +23,22 @@ namespace tree {
|
||||
|
||||
DMLC_REGISTRY_FILE_TAG(updater_gpu_hist);
|
||||
|
||||
typedef bst_gpair_precise gpair_sum_t;
|
||||
using GradientPairSumT = GradientPairPrecise;
|
||||
|
||||
template <int BLOCK_THREADS, typename reduce_t, typename temp_storage_t>
|
||||
__device__ gpair_sum_t ReduceFeature(const gpair_sum_t* begin,
|
||||
const gpair_sum_t* end,
|
||||
temp_storage_t* temp_storage) {
|
||||
__shared__ cub::Uninitialized<gpair_sum_t> uninitialized_sum;
|
||||
gpair_sum_t& shared_sum = uninitialized_sum.Alias();
|
||||
template <int BLOCK_THREADS, typename ReduceT, typename TempStorageT>
|
||||
__device__ GradientPairSumT ReduceFeature(const GradientPairSumT* begin,
|
||||
const GradientPairSumT* end,
|
||||
TempStorageT* temp_storage) {
|
||||
__shared__ cub::Uninitialized<GradientPairSumT> uninitialized_sum;
|
||||
GradientPairSumT& shared_sum = uninitialized_sum.Alias();
|
||||
|
||||
gpair_sum_t local_sum = gpair_sum_t();
|
||||
GradientPairSumT local_sum = GradientPairSumT();
|
||||
for (auto itr = begin; itr < end; itr += BLOCK_THREADS) {
|
||||
bool thread_active = itr + threadIdx.x < end;
|
||||
// Scan histogram
|
||||
gpair_sum_t bin = thread_active ? *(itr + threadIdx.x) : gpair_sum_t();
|
||||
GradientPairSumT bin = thread_active ? *(itr + threadIdx.x) : GradientPairSumT();
|
||||
|
||||
local_sum += reduce_t(temp_storage->sum_reduce).Reduce(bin, cub::Sum());
|
||||
local_sum += ReduceT(temp_storage->sum_reduce).Reduce(bin, cub::Sum());
|
||||
}
|
||||
|
||||
if (threadIdx.x == 0) {
|
||||
@@ -49,41 +49,41 @@ __device__ gpair_sum_t ReduceFeature(const gpair_sum_t* begin,
|
||||
return shared_sum;
|
||||
}
|
||||
|
||||
template <int BLOCK_THREADS, typename reduce_t, typename scan_t,
|
||||
typename max_reduce_t, typename temp_storage_t>
|
||||
__device__ void EvaluateFeature(int fidx, const gpair_sum_t* hist,
|
||||
template <int BLOCK_THREADS, typename ReduceT, typename scan_t,
|
||||
typename max_ReduceT, typename TempStorageT>
|
||||
__device__ void EvaluateFeature(int fidx, const GradientPairSumT* hist,
|
||||
const int* feature_segments, float min_fvalue,
|
||||
const float* gidx_fvalue_map,
|
||||
DeviceSplitCandidate* best_split,
|
||||
const DeviceNodeStats& node,
|
||||
const GPUTrainingParam& param,
|
||||
temp_storage_t* temp_storage, int constraint,
|
||||
TempStorageT* temp_storage, int constraint,
|
||||
const ValueConstraint& value_constraint) {
|
||||
int gidx_begin = feature_segments[fidx];
|
||||
int gidx_end = feature_segments[fidx + 1];
|
||||
|
||||
gpair_sum_t feature_sum = ReduceFeature<BLOCK_THREADS, reduce_t>(
|
||||
GradientPairSumT feature_sum = ReduceFeature<BLOCK_THREADS, ReduceT>(
|
||||
hist + gidx_begin, hist + gidx_end, temp_storage);
|
||||
|
||||
auto prefix_op = SumCallbackOp<gpair_sum_t>();
|
||||
auto prefix_op = SumCallbackOp<GradientPairSumT>();
|
||||
for (int scan_begin = gidx_begin; scan_begin < gidx_end;
|
||||
scan_begin += BLOCK_THREADS) {
|
||||
bool thread_active = scan_begin + threadIdx.x < gidx_end;
|
||||
|
||||
gpair_sum_t bin =
|
||||
thread_active ? hist[scan_begin + threadIdx.x] : gpair_sum_t();
|
||||
GradientPairSumT bin =
|
||||
thread_active ? hist[scan_begin + threadIdx.x] : GradientPairSumT();
|
||||
scan_t(temp_storage->scan).ExclusiveScan(bin, bin, cub::Sum(), prefix_op);
|
||||
|
||||
// Calculate gain
|
||||
gpair_sum_t parent_sum = gpair_sum_t(node.sum_gradients);
|
||||
GradientPairSumT parent_sum = GradientPairSumT(node.sum_gradients);
|
||||
|
||||
gpair_sum_t missing = parent_sum - feature_sum;
|
||||
GradientPairSumT missing = parent_sum - feature_sum;
|
||||
|
||||
bool missing_left = true;
|
||||
const float null_gain = -FLT_MAX;
|
||||
float gain = null_gain;
|
||||
if (thread_active) {
|
||||
gain = loss_chg_missing(bin, missing, parent_sum, node.root_gain, param,
|
||||
gain = LossChangeMissing(bin, missing, parent_sum, node.root_gain, param,
|
||||
constraint, value_constraint, missing_left);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ __device__ void EvaluateFeature(int fidx, const gpair_sum_t* hist,
|
||||
// Find thread with best gain
|
||||
cub::KeyValuePair<int, float> tuple(threadIdx.x, gain);
|
||||
cub::KeyValuePair<int, float> best =
|
||||
max_reduce_t(temp_storage->max_reduce).Reduce(tuple, cub::ArgMax());
|
||||
max_ReduceT(temp_storage->max_reduce).Reduce(tuple, cub::ArgMax());
|
||||
|
||||
__shared__ cub::KeyValuePair<int, float> block_max;
|
||||
if (threadIdx.x == 0) {
|
||||
@@ -107,11 +107,11 @@ __device__ void EvaluateFeature(int fidx, const gpair_sum_t* hist,
|
||||
float fvalue =
|
||||
gidx == gidx_begin ? min_fvalue : gidx_fvalue_map[gidx - 1];
|
||||
|
||||
gpair_sum_t left = missing_left ? bin + missing : bin;
|
||||
gpair_sum_t right = parent_sum - left;
|
||||
GradientPairSumT left = missing_left ? bin + missing : bin;
|
||||
GradientPairSumT right = parent_sum - left;
|
||||
|
||||
best_split->Update(gain, missing_left ? LeftDir : RightDir, fvalue, fidx,
|
||||
left, right, param);
|
||||
best_split->Update(gain, missing_left ? kLeftDir : kRightDir, fvalue, fidx,
|
||||
GradientPair(left), GradientPair(right), param);
|
||||
}
|
||||
__syncthreads();
|
||||
}
|
||||
@@ -119,17 +119,17 @@ __device__ void EvaluateFeature(int fidx, const gpair_sum_t* hist,
|
||||
|
||||
template <int BLOCK_THREADS>
|
||||
__global__ void evaluate_split_kernel(
|
||||
const gpair_sum_t* d_hist, int nidx, uint64_t n_features,
|
||||
const GradientPairSumT* d_hist, int nidx, uint64_t n_features,
|
||||
DeviceNodeStats nodes, const int* d_feature_segments,
|
||||
const float* d_fidx_min_map, const float* d_gidx_fvalue_map,
|
||||
GPUTrainingParam gpu_param, DeviceSplitCandidate* d_split,
|
||||
ValueConstraint value_constraint, int* d_monotonic_constraints) {
|
||||
typedef cub::KeyValuePair<int, float> ArgMaxT;
|
||||
typedef cub::BlockScan<gpair_sum_t, BLOCK_THREADS, cub::BLOCK_SCAN_WARP_SCANS>
|
||||
typedef cub::BlockScan<GradientPairSumT, BLOCK_THREADS, cub::BLOCK_SCAN_WARP_SCANS>
|
||||
BlockScanT;
|
||||
typedef cub::BlockReduce<ArgMaxT, BLOCK_THREADS> MaxReduceT;
|
||||
|
||||
typedef cub::BlockReduce<gpair_sum_t, BLOCK_THREADS> SumReduceT;
|
||||
typedef cub::BlockReduce<GradientPairSumT, BLOCK_THREADS> SumReduceT;
|
||||
|
||||
union TempStorage {
|
||||
typename BlockScanT::TempStorage scan;
|
||||
@@ -163,8 +163,8 @@ __global__ void evaluate_split_kernel(
|
||||
}
|
||||
|
||||
// Find a gidx value for a given feature otherwise return -1 if not found
|
||||
template <typename gidx_iter_t>
|
||||
__device__ int BinarySearchRow(bst_uint begin, bst_uint end, gidx_iter_t data,
|
||||
template <typename GidxIterT>
|
||||
__device__ int BinarySearchRow(bst_uint begin, bst_uint end, GidxIterT data,
|
||||
int fidx_begin, int fidx_end) {
|
||||
bst_uint previous_middle = UINT32_MAX;
|
||||
while (end != begin) {
|
||||
@@ -189,19 +189,19 @@ __device__ int BinarySearchRow(bst_uint begin, bst_uint end, gidx_iter_t data,
|
||||
}
|
||||
|
||||
struct DeviceHistogram {
|
||||
dh::bulk_allocator<dh::memory_type::DEVICE> ba;
|
||||
dh::dvec<gpair_sum_t> data;
|
||||
dh::BulkAllocator<dh::MemoryType::kDevice> ba;
|
||||
dh::DVec<GradientPairSumT> data;
|
||||
int n_bins;
|
||||
void Init(int device_idx, int max_nodes, int n_bins, bool silent) {
|
||||
this->n_bins = n_bins;
|
||||
ba.allocate(device_idx, silent, &data, size_t(max_nodes) * size_t(n_bins));
|
||||
ba.Allocate(device_idx, silent, &data, size_t(max_nodes) * size_t(n_bins));
|
||||
}
|
||||
|
||||
void Reset() { data.fill(gpair_sum_t()); }
|
||||
gpair_sum_t* GetHistPtr(int nidx) { return data.data() + nidx * n_bins; }
|
||||
void Reset() { data.Fill(GradientPairSumT()); }
|
||||
GradientPairSumT* GetHistPtr(int nidx) { return data.Data() + nidx * n_bins; }
|
||||
|
||||
void PrintNidx(int nidx) const {
|
||||
auto h_data = data.as_vector();
|
||||
auto h_data = data.AsVector();
|
||||
std::cout << "nidx " << nidx << ":\n";
|
||||
for (int i = n_bins * nidx; i < n_bins * (nidx + 1); i++) {
|
||||
std::cout << h_data[i] << " ";
|
||||
@@ -216,7 +216,7 @@ struct CalcWeightTrainParam {
|
||||
float reg_lambda;
|
||||
float max_delta_step;
|
||||
float learning_rate;
|
||||
__host__ __device__ CalcWeightTrainParam(const TrainParam& p)
|
||||
XGBOOST_DEVICE explicit CalcWeightTrainParam(const TrainParam& p)
|
||||
: min_child_weight(p.min_child_weight),
|
||||
reg_alpha(p.reg_alpha),
|
||||
reg_lambda(p.reg_lambda),
|
||||
@@ -240,19 +240,19 @@ struct DeviceShard {
|
||||
|
||||
int device_idx;
|
||||
int normalised_device_idx; // Device index counting from param.gpu_id
|
||||
dh::bulk_allocator<dh::memory_type::DEVICE> ba;
|
||||
dh::dvec<common::compressed_byte_t> gidx_buffer;
|
||||
dh::dvec<bst_gpair> gpair;
|
||||
dh::dvec2<bst_uint> ridx; // Row index relative to this shard
|
||||
dh::dvec2<int> position;
|
||||
dh::BulkAllocator<dh::MemoryType::kDevice> ba;
|
||||
dh::DVec<common::CompressedByteT> gidx_buffer;
|
||||
dh::DVec<GradientPair> gpair;
|
||||
dh::DVec2<bst_uint> ridx; // Row index relative to this shard
|
||||
dh::DVec2<int> position;
|
||||
std::vector<Segment> ridx_segments;
|
||||
dh::dvec<int> feature_segments;
|
||||
dh::dvec<float> gidx_fvalue_map;
|
||||
dh::dvec<float> min_fvalue;
|
||||
dh::dvec<int> monotone_constraints;
|
||||
dh::dvec<bst_float> prediction_cache;
|
||||
std::vector<bst_gpair> node_sum_gradients;
|
||||
dh::dvec<bst_gpair> node_sum_gradients_d;
|
||||
dh::DVec<int> feature_segments;
|
||||
dh::DVec<float> gidx_fvalue_map;
|
||||
dh::DVec<float> min_fvalue;
|
||||
dh::DVec<int> monotone_constraints;
|
||||
dh::DVec<bst_float> prediction_cache;
|
||||
std::vector<GradientPair> node_sum_gradients;
|
||||
dh::DVec<GradientPair> node_sum_gradients_d;
|
||||
common::CompressedIterator<uint32_t> gidx;
|
||||
int row_stride;
|
||||
bst_uint row_begin_idx; // The row offset for this shard
|
||||
@@ -311,8 +311,8 @@ struct DeviceShard {
|
||||
<< "Max leaves and max depth cannot both be unconstrained for "
|
||||
"gpu_hist.";
|
||||
int max_nodes =
|
||||
param.max_leaves > 0 ? param.max_leaves * 2 : n_nodes(param.max_depth);
|
||||
ba.allocate(device_idx, param.silent, &gidx_buffer, compressed_size_bytes,
|
||||
param.max_leaves > 0 ? param.max_leaves * 2 : MaxNodesDepth(param.max_depth);
|
||||
ba.Allocate(device_idx, param.silent, &gidx_buffer, compressed_size_bytes,
|
||||
&gpair, n_rows, &ridx, n_rows, &position, n_rows,
|
||||
&prediction_cache, n_rows, &node_sum_gradients_d, max_nodes,
|
||||
&feature_segments, gmat.cut->row_ptr.size(), &gidx_fvalue_map,
|
||||
@@ -328,11 +328,11 @@ struct DeviceShard {
|
||||
|
||||
// Compress gidx
|
||||
common::CompressedBufferWriter cbw(num_symbols);
|
||||
std::vector<common::compressed_byte_t> host_buffer(gidx_buffer.size());
|
||||
std::vector<common::CompressedByteT> host_buffer(gidx_buffer.Size());
|
||||
cbw.Write(host_buffer.data(), ellpack_matrix.begin(), ellpack_matrix.end());
|
||||
gidx_buffer = host_buffer;
|
||||
gidx =
|
||||
common::CompressedIterator<uint32_t>(gidx_buffer.data(), num_symbols);
|
||||
common::CompressedIterator<uint32_t>(gidx_buffer.Data(), num_symbols);
|
||||
|
||||
common::CompressedIterator<uint32_t> ci_host(host_buffer.data(),
|
||||
num_symbols);
|
||||
@@ -369,19 +369,19 @@ struct DeviceShard {
|
||||
}
|
||||
|
||||
// Reset values for each update iteration
|
||||
void Reset(HostDeviceVector<bst_gpair>* dh_gpair, int device) {
|
||||
void Reset(HostDeviceVector<GradientPair>* dh_gpair, int device) {
|
||||
auto begin = dh_gpair->tbegin(device);
|
||||
dh::safe_cuda(cudaSetDevice(device_idx));
|
||||
position.current_dvec().fill(0);
|
||||
position.CurrentDVec().Fill(0);
|
||||
std::fill(node_sum_gradients.begin(), node_sum_gradients.end(),
|
||||
bst_gpair());
|
||||
GradientPair());
|
||||
|
||||
thrust::sequence(ridx.current_dvec().tbegin(), ridx.current_dvec().tend());
|
||||
thrust::sequence(ridx.CurrentDVec().tbegin(), ridx.CurrentDVec().tend());
|
||||
|
||||
std::fill(ridx_segments.begin(), ridx_segments.end(), Segment(0, 0));
|
||||
ridx_segments.front() = Segment(0, ridx.size());
|
||||
ridx_segments.front() = Segment(0, ridx.Size());
|
||||
this->gpair.copy(begin + row_begin_idx, begin + row_end_idx);
|
||||
subsample_gpair(&gpair, param.subsample, row_begin_idx);
|
||||
SubsampleGradientPair(&gpair, param.subsample, row_begin_idx);
|
||||
hist.Reset();
|
||||
}
|
||||
|
||||
@@ -389,13 +389,13 @@ struct DeviceShard {
|
||||
auto segment = ridx_segments[nidx];
|
||||
auto d_node_hist = hist.GetHistPtr(nidx);
|
||||
auto d_gidx = gidx;
|
||||
auto d_ridx = ridx.current();
|
||||
auto d_gpair = gpair.data();
|
||||
auto d_ridx = ridx.Current();
|
||||
auto d_gpair = gpair.Data();
|
||||
auto row_stride = this->row_stride;
|
||||
auto null_gidx_value = this->null_gidx_value;
|
||||
auto n_elements = segment.Size() * row_stride;
|
||||
|
||||
dh::launch_n(device_idx, n_elements, [=] __device__(size_t idx) {
|
||||
dh::LaunchN(device_idx, n_elements, [=] __device__(size_t idx) {
|
||||
int ridx = d_ridx[(idx / row_stride) + segment.begin];
|
||||
int gidx = d_gidx[ridx * row_stride + idx % row_stride];
|
||||
|
||||
@@ -410,7 +410,7 @@ struct DeviceShard {
|
||||
auto d_node_hist_histogram = hist.GetHistPtr(nidx_histogram);
|
||||
auto d_node_hist_subtraction = hist.GetHistPtr(nidx_subtraction);
|
||||
|
||||
dh::launch_n(device_idx, hist.n_bins, [=] __device__(size_t idx) {
|
||||
dh::LaunchN(device_idx, hist.n_bins, [=] __device__(size_t idx) {
|
||||
d_node_hist_subtraction[idx] =
|
||||
d_node_hist_parent[idx] - d_node_hist_histogram[idx];
|
||||
});
|
||||
@@ -432,11 +432,11 @@ struct DeviceShard {
|
||||
auto d_left_count = temp_memory.Pointer<int64_t>();
|
||||
dh::safe_cuda(cudaMemset(d_left_count, 0, sizeof(int64_t)));
|
||||
auto segment = ridx_segments[nidx];
|
||||
auto d_ridx = ridx.current();
|
||||
auto d_position = position.current();
|
||||
auto d_ridx = ridx.Current();
|
||||
auto d_position = position.Current();
|
||||
auto d_gidx = gidx;
|
||||
auto row_stride = this->row_stride;
|
||||
dh::launch_n<1, 512>(
|
||||
dh::LaunchN<1, 512>(
|
||||
device_idx, segment.Size(), [=] __device__(bst_uint idx) {
|
||||
idx += segment.begin;
|
||||
auto ridx = d_ridx[idx];
|
||||
@@ -482,22 +482,22 @@ struct DeviceShard {
|
||||
|
||||
size_t temp_storage_bytes = 0;
|
||||
cub::DeviceRadixSort::SortPairs(
|
||||
nullptr, temp_storage_bytes, position.current() + segment.begin,
|
||||
position.other() + segment.begin, ridx.current() + segment.begin,
|
||||
nullptr, temp_storage_bytes, position.Current() + segment.begin,
|
||||
position.other() + segment.begin, ridx.Current() + segment.begin,
|
||||
ridx.other() + segment.begin, segment.Size(), min_bits, max_bits);
|
||||
|
||||
temp_memory.LazyAllocate(temp_storage_bytes);
|
||||
|
||||
cub::DeviceRadixSort::SortPairs(
|
||||
temp_memory.d_temp_storage, temp_memory.temp_storage_bytes,
|
||||
position.current() + segment.begin, position.other() + segment.begin,
|
||||
ridx.current() + segment.begin, ridx.other() + segment.begin,
|
||||
position.Current() + segment.begin, position.other() + segment.begin,
|
||||
ridx.Current() + segment.begin, ridx.other() + segment.begin,
|
||||
segment.Size(), min_bits, max_bits);
|
||||
dh::safe_cuda(cudaMemcpy(
|
||||
position.current() + segment.begin, position.other() + segment.begin,
|
||||
position.Current() + segment.begin, position.other() + segment.begin,
|
||||
segment.Size() * sizeof(int), cudaMemcpyDeviceToDevice));
|
||||
dh::safe_cuda(cudaMemcpy(
|
||||
ridx.current() + segment.begin, ridx.other() + segment.begin,
|
||||
ridx.Current() + segment.begin, ridx.other() + segment.begin,
|
||||
segment.Size() * sizeof(bst_uint), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
@@ -505,8 +505,8 @@ struct DeviceShard {
|
||||
dh::safe_cuda(cudaSetDevice(device_idx));
|
||||
if (!prediction_cache_initialised) {
|
||||
dh::safe_cuda(cudaMemcpy(
|
||||
prediction_cache.data(), &out_preds_d[row_begin_idx],
|
||||
prediction_cache.size() * sizeof(bst_float), cudaMemcpyDefault));
|
||||
prediction_cache.Data(), &out_preds_d[row_begin_idx],
|
||||
prediction_cache.Size() * sizeof(bst_float), cudaMemcpyDefault));
|
||||
}
|
||||
prediction_cache_initialised = true;
|
||||
|
||||
@@ -514,13 +514,13 @@ struct DeviceShard {
|
||||
|
||||
thrust::copy(node_sum_gradients.begin(), node_sum_gradients.end(),
|
||||
node_sum_gradients_d.tbegin());
|
||||
auto d_position = position.current();
|
||||
auto d_ridx = ridx.current();
|
||||
auto d_node_sum_gradients = node_sum_gradients_d.data();
|
||||
auto d_prediction_cache = prediction_cache.data();
|
||||
auto d_position = position.Current();
|
||||
auto d_ridx = ridx.Current();
|
||||
auto d_node_sum_gradients = node_sum_gradients_d.Data();
|
||||
auto d_prediction_cache = prediction_cache.Data();
|
||||
|
||||
dh::launch_n(
|
||||
device_idx, prediction_cache.size(), [=] __device__(int local_idx) {
|
||||
dh::LaunchN(
|
||||
device_idx, prediction_cache.Size(), [=] __device__(int local_idx) {
|
||||
int pos = d_position[local_idx];
|
||||
bst_float weight = CalcWeight(param_d, d_node_sum_gradients[pos]);
|
||||
d_prediction_cache[d_ridx[local_idx]] +=
|
||||
@@ -528,8 +528,8 @@ struct DeviceShard {
|
||||
});
|
||||
|
||||
dh::safe_cuda(cudaMemcpy(
|
||||
&out_preds_d[row_begin_idx], prediction_cache.data(),
|
||||
prediction_cache.size() * sizeof(bst_float), cudaMemcpyDefault));
|
||||
&out_preds_d[row_begin_idx], prediction_cache.Data(),
|
||||
prediction_cache.Size() * sizeof(bst_float), cudaMemcpyDefault));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -537,33 +537,32 @@ class GPUHistMaker : public TreeUpdater {
|
||||
public:
|
||||
struct ExpandEntry;
|
||||
|
||||
GPUHistMaker() : initialised(false), p_last_fmat_(nullptr) {}
|
||||
~GPUHistMaker() {}
|
||||
GPUHistMaker() : initialised_(false), p_last_fmat_(nullptr) {}
|
||||
void Init(
|
||||
const std::vector<std::pair<std::string, std::string>>& args) override {
|
||||
param.InitAllowUnknown(args);
|
||||
CHECK(param.n_gpus != 0) << "Must have at least one device";
|
||||
n_devices = param.n_gpus;
|
||||
param_.InitAllowUnknown(args);
|
||||
CHECK(param_.n_gpus != 0) << "Must have at least one device";
|
||||
n_devices_ = param_.n_gpus;
|
||||
|
||||
dh::check_compute_capability();
|
||||
dh::CheckComputeCapability();
|
||||
|
||||
if (param.grow_policy == TrainParam::kLossGuide) {
|
||||
qexpand_.reset(new ExpandQueue(loss_guide));
|
||||
if (param_.grow_policy == TrainParam::kLossGuide) {
|
||||
qexpand_.reset(new ExpandQueue(LossGuide));
|
||||
} else {
|
||||
qexpand_.reset(new ExpandQueue(depth_wise));
|
||||
qexpand_.reset(new ExpandQueue(DepthWise));
|
||||
}
|
||||
|
||||
monitor.Init("updater_gpu_hist", param.debug_verbose);
|
||||
monitor_.Init("updater_gpu_hist", param_.debug_verbose);
|
||||
}
|
||||
|
||||
void Update(HostDeviceVector<bst_gpair>* gpair, DMatrix* dmat,
|
||||
void Update(HostDeviceVector<GradientPair>* gpair, DMatrix* dmat,
|
||||
const std::vector<RegTree*>& trees) override {
|
||||
monitor.Start("Update", dList);
|
||||
GradStats::CheckInfo(dmat->info());
|
||||
monitor_.Start("Update", device_list_);
|
||||
GradStats::CheckInfo(dmat->Info());
|
||||
// rescale learning rate according to size of trees
|
||||
float lr = param.learning_rate;
|
||||
param.learning_rate = lr / trees.size();
|
||||
ValueConstraint::Init(¶m, dmat->info().num_col);
|
||||
float lr = param_.learning_rate;
|
||||
param_.learning_rate = lr / trees.size();
|
||||
ValueConstraint::Init(¶m_, dmat->Info().num_col_);
|
||||
// build tree
|
||||
try {
|
||||
for (size_t i = 0; i < trees.size(); ++i) {
|
||||
@@ -572,97 +571,97 @@ class GPUHistMaker : public TreeUpdater {
|
||||
} catch (const std::exception& e) {
|
||||
LOG(FATAL) << "GPU plugin exception: " << e.what() << std::endl;
|
||||
}
|
||||
param.learning_rate = lr;
|
||||
monitor.Stop("Update", dList);
|
||||
param_.learning_rate = lr;
|
||||
monitor_.Stop("Update", device_list_);
|
||||
}
|
||||
|
||||
void InitDataOnce(DMatrix* dmat) {
|
||||
info = &dmat->info();
|
||||
monitor.Start("Quantiles", dList);
|
||||
hmat_.Init(dmat, param.max_bin);
|
||||
info_ = &dmat->Info();
|
||||
monitor_.Start("Quantiles", device_list_);
|
||||
hmat_.Init(dmat, param_.max_bin);
|
||||
gmat_.cut = &hmat_;
|
||||
gmat_.Init(dmat);
|
||||
monitor.Stop("Quantiles", dList);
|
||||
n_bins = hmat_.row_ptr.back();
|
||||
monitor_.Stop("Quantiles", device_list_);
|
||||
n_bins_ = hmat_.row_ptr.back();
|
||||
|
||||
int n_devices = dh::n_devices(param.n_gpus, info->num_row);
|
||||
int n_devices = dh::NDevices(param_.n_gpus, info_->num_row_);
|
||||
|
||||
bst_uint row_begin = 0;
|
||||
bst_uint shard_size =
|
||||
std::ceil(static_cast<double>(info->num_row) / n_devices);
|
||||
std::ceil(static_cast<double>(info_->num_row_) / n_devices);
|
||||
|
||||
dList.resize(n_devices);
|
||||
device_list_.resize(n_devices);
|
||||
for (int d_idx = 0; d_idx < n_devices; ++d_idx) {
|
||||
int device_idx = (param.gpu_id + d_idx) % dh::n_visible_devices();
|
||||
dList[d_idx] = device_idx;
|
||||
int device_idx = (param_.gpu_id + d_idx) % dh::NVisibleDevices();
|
||||
device_list_[d_idx] = device_idx;
|
||||
}
|
||||
|
||||
reducer.Init(dList);
|
||||
reducer_.Init(device_list_);
|
||||
|
||||
// Partition input matrix into row segments
|
||||
std::vector<size_t> row_segments;
|
||||
shards.resize(n_devices);
|
||||
shards_.resize(n_devices);
|
||||
row_segments.push_back(0);
|
||||
for (int d_idx = 0; d_idx < n_devices; ++d_idx) {
|
||||
bst_uint row_end =
|
||||
std::min(static_cast<size_t>(row_begin + shard_size), info->num_row);
|
||||
std::min(static_cast<size_t>(row_begin + shard_size), info_->num_row_);
|
||||
row_segments.push_back(row_end);
|
||||
row_begin = row_end;
|
||||
}
|
||||
|
||||
// Create device shards
|
||||
omp_set_num_threads(shards.size());
|
||||
omp_set_num_threads(shards_.size());
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto cpu_thread_id = omp_get_thread_num();
|
||||
shards[cpu_thread_id] = std::unique_ptr<DeviceShard>(
|
||||
new DeviceShard(dList[cpu_thread_id], cpu_thread_id, gmat_,
|
||||
shards_[cpu_thread_id] = std::unique_ptr<DeviceShard>(
|
||||
new DeviceShard(device_list_[cpu_thread_id], cpu_thread_id, gmat_,
|
||||
row_segments[cpu_thread_id],
|
||||
row_segments[cpu_thread_id + 1], n_bins, param));
|
||||
row_segments[cpu_thread_id + 1], n_bins_, param_));
|
||||
}
|
||||
|
||||
p_last_fmat_ = dmat;
|
||||
initialised = true;
|
||||
initialised_ = true;
|
||||
}
|
||||
|
||||
void InitData(HostDeviceVector<bst_gpair>* gpair, DMatrix* dmat,
|
||||
void InitData(HostDeviceVector<GradientPair>* gpair, DMatrix* dmat,
|
||||
const RegTree& tree) {
|
||||
monitor.Start("InitDataOnce", dList);
|
||||
if (!initialised) {
|
||||
monitor_.Start("InitDataOnce", device_list_);
|
||||
if (!initialised_) {
|
||||
this->InitDataOnce(dmat);
|
||||
}
|
||||
monitor.Stop("InitDataOnce", dList);
|
||||
monitor_.Stop("InitDataOnce", device_list_);
|
||||
|
||||
column_sampler.Init(info->num_col, param);
|
||||
column_sampler_.Init(info_->num_col_, param_);
|
||||
|
||||
// Copy gpair & reset memory
|
||||
monitor.Start("InitDataReset", dList);
|
||||
omp_set_num_threads(shards.size());
|
||||
monitor_.Start("InitDataReset", device_list_);
|
||||
omp_set_num_threads(shards_.size());
|
||||
|
||||
// TODO(canonizer): make it parallel again once HostDeviceVector is
|
||||
// thread-safe
|
||||
for (int shard = 0; shard < shards.size(); ++shard)
|
||||
shards[shard]->Reset(gpair, param.gpu_id);
|
||||
monitor.Stop("InitDataReset", dList);
|
||||
for (int shard = 0; shard < shards_.size(); ++shard)
|
||||
shards_[shard]->Reset(gpair, param_.gpu_id);
|
||||
monitor_.Stop("InitDataReset", device_list_);
|
||||
}
|
||||
|
||||
void AllReduceHist(int nidx) {
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
auto d_node_hist = shard->hist.GetHistPtr(nidx);
|
||||
reducer.AllReduceSum(
|
||||
reducer_.AllReduceSum(
|
||||
shard->normalised_device_idx,
|
||||
reinterpret_cast<gpair_sum_t::value_t*>(d_node_hist),
|
||||
reinterpret_cast<gpair_sum_t::value_t*>(d_node_hist),
|
||||
n_bins * (sizeof(gpair_sum_t) / sizeof(gpair_sum_t::value_t)));
|
||||
reinterpret_cast<GradientPairSumT::ValueT*>(d_node_hist),
|
||||
reinterpret_cast<GradientPairSumT::ValueT*>(d_node_hist),
|
||||
n_bins_ * (sizeof(GradientPairSumT) / sizeof(GradientPairSumT::ValueT)));
|
||||
}
|
||||
|
||||
reducer.Synchronize();
|
||||
reducer_.Synchronize();
|
||||
}
|
||||
|
||||
void BuildHistLeftRight(int nidx_parent, int nidx_left, int nidx_right) {
|
||||
size_t left_node_max_elements = 0;
|
||||
size_t right_node_max_elements = 0;
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
left_node_max_elements = (std::max)(
|
||||
left_node_max_elements, shard->ridx_segments[nidx_left].Size());
|
||||
right_node_max_elements = (std::max)(
|
||||
@@ -677,13 +676,13 @@ class GPUHistMaker : public TreeUpdater {
|
||||
subtraction_trick_nidx = nidx_left;
|
||||
}
|
||||
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
shard->BuildHist(build_hist_nidx);
|
||||
}
|
||||
|
||||
this->AllReduceHist(build_hist_nidx);
|
||||
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
shard->SubtractionTrick(nidx_parent, build_hist_nidx,
|
||||
subtraction_trick_nidx);
|
||||
}
|
||||
@@ -692,12 +691,12 @@ class GPUHistMaker : public TreeUpdater {
|
||||
// Returns best loss
|
||||
std::vector<DeviceSplitCandidate> EvaluateSplits(
|
||||
const std::vector<int>& nidx_set, RegTree* p_tree) {
|
||||
auto columns = info->num_col;
|
||||
auto columns = info_->num_col_;
|
||||
std::vector<DeviceSplitCandidate> best_splits(nidx_set.size());
|
||||
std::vector<DeviceSplitCandidate> candidate_splits(nidx_set.size() *
|
||||
columns);
|
||||
// Use first device
|
||||
auto& shard = shards.front();
|
||||
auto& shard = shards_.front();
|
||||
dh::safe_cuda(cudaSetDevice(shard->device_idx));
|
||||
shard->temp_memory.LazyAllocate(sizeof(DeviceSplitCandidate) * columns *
|
||||
nidx_set.size());
|
||||
@@ -708,16 +707,16 @@ class GPUHistMaker : public TreeUpdater {
|
||||
// Use streams to process nodes concurrently
|
||||
for (auto i = 0; i < nidx_set.size(); i++) {
|
||||
auto nidx = nidx_set[i];
|
||||
DeviceNodeStats node(shard->node_sum_gradients[nidx], nidx, param);
|
||||
DeviceNodeStats node(shard->node_sum_gradients[nidx], nidx, param_);
|
||||
|
||||
const int BLOCK_THREADS = 256;
|
||||
evaluate_split_kernel<BLOCK_THREADS>
|
||||
<<<uint32_t(columns), BLOCK_THREADS, 0, streams[i]>>>(
|
||||
shard->hist.GetHistPtr(nidx), nidx, info->num_col, node,
|
||||
shard->feature_segments.data(), shard->min_fvalue.data(),
|
||||
shard->gidx_fvalue_map.data(), GPUTrainingParam(param),
|
||||
shard->hist.GetHistPtr(nidx), nidx, info_->num_col_, node,
|
||||
shard->feature_segments.Data(), shard->min_fvalue.Data(),
|
||||
shard->gidx_fvalue_map.Data(), GPUTrainingParam(param_),
|
||||
d_split + i * columns, node_value_constraints_[nidx],
|
||||
shard->monotone_constraints.data());
|
||||
shard->monotone_constraints.Data());
|
||||
}
|
||||
|
||||
dh::safe_cuda(
|
||||
@@ -730,9 +729,9 @@ class GPUHistMaker : public TreeUpdater {
|
||||
DeviceSplitCandidate nidx_best;
|
||||
for (auto fidx = 0; fidx < columns; fidx++) {
|
||||
auto& candidate = candidate_splits[i * columns + fidx];
|
||||
if (column_sampler.ColumnUsed(candidate.findex,
|
||||
if (column_sampler_.ColumnUsed(candidate.findex,
|
||||
p_tree->GetDepth(nidx))) {
|
||||
nidx_best.Update(candidate_splits[i * columns + fidx], param);
|
||||
nidx_best.Update(candidate_splits[i * columns + fidx], param_);
|
||||
}
|
||||
}
|
||||
best_splits[i] = nidx_best;
|
||||
@@ -743,34 +742,34 @@ class GPUHistMaker : public TreeUpdater {
|
||||
void InitRoot(RegTree* p_tree) {
|
||||
auto root_nidx = 0;
|
||||
// Sum gradients
|
||||
std::vector<bst_gpair> tmp_sums(shards.size());
|
||||
omp_set_num_threads(shards.size());
|
||||
std::vector<GradientPair> tmp_sums(shards_.size());
|
||||
omp_set_num_threads(shards_.size());
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto cpu_thread_id = omp_get_thread_num();
|
||||
auto& shard = shards[cpu_thread_id];
|
||||
auto& shard = shards_[cpu_thread_id];
|
||||
dh::safe_cuda(cudaSetDevice(shard->device_idx));
|
||||
tmp_sums[cpu_thread_id] = dh::sumReduction(
|
||||
shard->temp_memory, shard->gpair.data(), shard->gpair.size());
|
||||
tmp_sums[cpu_thread_id] = dh::SumReduction(
|
||||
shard->temp_memory, shard->gpair.Data(), shard->gpair.Size());
|
||||
}
|
||||
auto sum_gradient =
|
||||
std::accumulate(tmp_sums.begin(), tmp_sums.end(), bst_gpair_precise());
|
||||
std::accumulate(tmp_sums.begin(), tmp_sums.end(), GradientPair());
|
||||
|
||||
// Generate root histogram
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
shard->BuildHist(root_nidx);
|
||||
}
|
||||
|
||||
this->AllReduceHist(root_nidx);
|
||||
|
||||
// Remember root stats
|
||||
p_tree->stat(root_nidx).sum_hess = sum_gradient.GetHess();
|
||||
auto weight = CalcWeight(param, sum_gradient);
|
||||
p_tree->stat(root_nidx).base_weight = weight;
|
||||
(*p_tree)[root_nidx].set_leaf(param.learning_rate * weight);
|
||||
p_tree->Stat(root_nidx).sum_hess = sum_gradient.GetHess();
|
||||
auto weight = CalcWeight(param_, sum_gradient);
|
||||
p_tree->Stat(root_nidx).base_weight = weight;
|
||||
(*p_tree)[root_nidx].SetLeaf(param_.learning_rate * weight);
|
||||
|
||||
// Store sum gradients
|
||||
for (auto& shard : shards) {
|
||||
for (auto& shard : shards_) {
|
||||
shard->node_sum_gradients[root_nidx] = sum_gradient;
|
||||
}
|
||||
|
||||
@@ -785,14 +784,14 @@ class GPUHistMaker : public TreeUpdater {
|
||||
|
||||
void UpdatePosition(const ExpandEntry& candidate, RegTree* p_tree) {
|
||||
auto nidx = candidate.nid;
|
||||
auto left_nidx = (*p_tree)[nidx].cleft();
|
||||
auto right_nidx = (*p_tree)[nidx].cright();
|
||||
auto left_nidx = (*p_tree)[nidx].LeftChild();
|
||||
auto right_nidx = (*p_tree)[nidx].RightChild();
|
||||
|
||||
// convert floating-point split_pt into corresponding bin_id
|
||||
// split_cond = -1 indicates that split_pt is less than all known cut points
|
||||
auto split_gidx = -1;
|
||||
auto fidx = candidate.split.findex;
|
||||
auto default_dir_left = candidate.split.dir == LeftDir;
|
||||
auto default_dir_left = candidate.split.dir == kLeftDir;
|
||||
auto fidx_begin = hmat_.row_ptr[fidx];
|
||||
auto fidx_end = hmat_.row_ptr[fidx + 1];
|
||||
for (auto i = fidx_begin; i < fidx_end; ++i) {
|
||||
@@ -801,13 +800,13 @@ class GPUHistMaker : public TreeUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
auto is_dense = info->num_nonzero == info->num_row * info->num_col;
|
||||
auto is_dense = info_->num_nonzero_ == info_->num_row_ * info_->num_col_;
|
||||
|
||||
omp_set_num_threads(shards.size());
|
||||
omp_set_num_threads(shards_.size());
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto cpu_thread_id = omp_get_thread_num();
|
||||
shards[cpu_thread_id]->UpdatePosition(nidx, left_nidx, right_nidx, fidx,
|
||||
shards_[cpu_thread_id]->UpdatePosition(nidx, left_nidx, right_nidx, fidx,
|
||||
split_gidx, default_dir_left,
|
||||
is_dense, fidx_begin, fidx_end);
|
||||
}
|
||||
@@ -818,55 +817,55 @@ class GPUHistMaker : public TreeUpdater {
|
||||
RegTree& tree = *p_tree;
|
||||
tree.AddChilds(candidate.nid);
|
||||
auto& parent = tree[candidate.nid];
|
||||
parent.set_split(candidate.split.findex, candidate.split.fvalue,
|
||||
candidate.split.dir == LeftDir);
|
||||
tree.stat(candidate.nid).loss_chg = candidate.split.loss_chg;
|
||||
parent.SetSplit(candidate.split.findex, candidate.split.fvalue,
|
||||
candidate.split.dir == kLeftDir);
|
||||
tree.Stat(candidate.nid).loss_chg = candidate.split.loss_chg;
|
||||
|
||||
// Set up child constraints
|
||||
node_value_constraints_.resize(tree.GetNodes().size());
|
||||
GradStats left_stats(param);
|
||||
GradStats left_stats(param_);
|
||||
left_stats.Add(candidate.split.left_sum);
|
||||
GradStats right_stats(param);
|
||||
GradStats right_stats(param_);
|
||||
right_stats.Add(candidate.split.right_sum);
|
||||
node_value_constraints_[candidate.nid].SetChild(
|
||||
param, parent.split_index(), left_stats, right_stats,
|
||||
&node_value_constraints_[parent.cleft()],
|
||||
&node_value_constraints_[parent.cright()]);
|
||||
param_, parent.SplitIndex(), left_stats, right_stats,
|
||||
&node_value_constraints_[parent.LeftChild()],
|
||||
&node_value_constraints_[parent.RightChild()]);
|
||||
|
||||
// Configure left child
|
||||
auto left_weight =
|
||||
node_value_constraints_[parent.cleft()].CalcWeight(param, left_stats);
|
||||
tree[parent.cleft()].set_leaf(left_weight * param.learning_rate, 0);
|
||||
tree.stat(parent.cleft()).base_weight = left_weight;
|
||||
tree.stat(parent.cleft()).sum_hess = candidate.split.left_sum.GetHess();
|
||||
node_value_constraints_[parent.LeftChild()].CalcWeight(param_, left_stats);
|
||||
tree[parent.LeftChild()].SetLeaf(left_weight * param_.learning_rate, 0);
|
||||
tree.Stat(parent.LeftChild()).base_weight = left_weight;
|
||||
tree.Stat(parent.LeftChild()).sum_hess = candidate.split.left_sum.GetHess();
|
||||
|
||||
// Configure right child
|
||||
auto right_weight =
|
||||
node_value_constraints_[parent.cright()].CalcWeight(param, right_stats);
|
||||
tree[parent.cright()].set_leaf(right_weight * param.learning_rate, 0);
|
||||
tree.stat(parent.cright()).base_weight = right_weight;
|
||||
tree.stat(parent.cright()).sum_hess = candidate.split.right_sum.GetHess();
|
||||
node_value_constraints_[parent.RightChild()].CalcWeight(param_, right_stats);
|
||||
tree[parent.RightChild()].SetLeaf(right_weight * param_.learning_rate, 0);
|
||||
tree.Stat(parent.RightChild()).base_weight = right_weight;
|
||||
tree.Stat(parent.RightChild()).sum_hess = candidate.split.right_sum.GetHess();
|
||||
// Store sum gradients
|
||||
for (auto& shard : shards) {
|
||||
shard->node_sum_gradients[parent.cleft()] = candidate.split.left_sum;
|
||||
shard->node_sum_gradients[parent.cright()] = candidate.split.right_sum;
|
||||
for (auto& shard : shards_) {
|
||||
shard->node_sum_gradients[parent.LeftChild()] = candidate.split.left_sum;
|
||||
shard->node_sum_gradients[parent.RightChild()] = candidate.split.right_sum;
|
||||
}
|
||||
this->UpdatePosition(candidate, p_tree);
|
||||
}
|
||||
|
||||
void UpdateTree(HostDeviceVector<bst_gpair>* gpair, DMatrix* p_fmat,
|
||||
void UpdateTree(HostDeviceVector<GradientPair>* gpair, DMatrix* p_fmat,
|
||||
RegTree* p_tree) {
|
||||
// Temporarily store number of threads so we can change it back later
|
||||
int nthread = omp_get_max_threads();
|
||||
|
||||
auto& tree = *p_tree;
|
||||
|
||||
monitor.Start("InitData", dList);
|
||||
monitor_.Start("InitData", device_list_);
|
||||
this->InitData(gpair, p_fmat, *p_tree);
|
||||
monitor.Stop("InitData", dList);
|
||||
monitor.Start("InitRoot", dList);
|
||||
monitor_.Stop("InitData", device_list_);
|
||||
monitor_.Start("InitRoot", device_list_);
|
||||
this->InitRoot(p_tree);
|
||||
monitor.Stop("InitRoot", dList);
|
||||
monitor_.Stop("InitRoot", device_list_);
|
||||
|
||||
auto timestamp = qexpand_->size();
|
||||
auto num_leaves = 1;
|
||||
@@ -874,25 +873,25 @@ class GPUHistMaker : public TreeUpdater {
|
||||
while (!qexpand_->empty()) {
|
||||
auto candidate = qexpand_->top();
|
||||
qexpand_->pop();
|
||||
if (!candidate.IsValid(param, num_leaves)) continue;
|
||||
if (!candidate.IsValid(param_, num_leaves)) continue;
|
||||
// std::cout << candidate;
|
||||
monitor.Start("ApplySplit", dList);
|
||||
monitor_.Start("ApplySplit", device_list_);
|
||||
this->ApplySplit(candidate, p_tree);
|
||||
monitor.Stop("ApplySplit", dList);
|
||||
monitor_.Stop("ApplySplit", device_list_);
|
||||
num_leaves++;
|
||||
|
||||
auto left_child_nidx = tree[candidate.nid].cleft();
|
||||
auto right_child_nidx = tree[candidate.nid].cright();
|
||||
auto left_child_nidx = tree[candidate.nid].LeftChild();
|
||||
auto right_child_nidx = tree[candidate.nid].RightChild();
|
||||
|
||||
// Only create child entries if needed
|
||||
if (ExpandEntry::ChildIsValid(param, tree.GetDepth(left_child_nidx),
|
||||
if (ExpandEntry::ChildIsValid(param_, tree.GetDepth(left_child_nidx),
|
||||
num_leaves)) {
|
||||
monitor.Start("BuildHist", dList);
|
||||
monitor_.Start("BuildHist", device_list_);
|
||||
this->BuildHistLeftRight(candidate.nid, left_child_nidx,
|
||||
right_child_nidx);
|
||||
monitor.Stop("BuildHist", dList);
|
||||
monitor_.Stop("BuildHist", device_list_);
|
||||
|
||||
monitor.Start("EvaluateSplits", dList);
|
||||
monitor_.Start("EvaluateSplits", device_list_);
|
||||
auto splits =
|
||||
this->EvaluateSplits({left_child_nidx, right_child_nidx}, p_tree);
|
||||
qexpand_->push(ExpandEntry(left_child_nidx,
|
||||
@@ -901,7 +900,7 @@ class GPUHistMaker : public TreeUpdater {
|
||||
qexpand_->push(ExpandEntry(right_child_nidx,
|
||||
tree.GetDepth(right_child_nidx), splits[1],
|
||||
timestamp++));
|
||||
monitor.Stop("EvaluateSplits", dList);
|
||||
monitor_.Stop("EvaluateSplits", device_list_);
|
||||
}
|
||||
}
|
||||
// Reset omp num threads
|
||||
@@ -910,17 +909,17 @@ class GPUHistMaker : public TreeUpdater {
|
||||
|
||||
bool UpdatePredictionCache(
|
||||
const DMatrix* data, HostDeviceVector<bst_float>* p_out_preds) override {
|
||||
monitor.Start("UpdatePredictionCache", dList);
|
||||
if (shards.empty() || p_last_fmat_ == nullptr || p_last_fmat_ != data)
|
||||
monitor_.Start("UpdatePredictionCache", device_list_);
|
||||
if (shards_.empty() || p_last_fmat_ == nullptr || p_last_fmat_ != data)
|
||||
return false;
|
||||
|
||||
bst_float* out_preds_d = p_out_preds->ptr_d(param.gpu_id);
|
||||
bst_float* out_preds_d = p_out_preds->DevicePointer(param_.gpu_id);
|
||||
|
||||
#pragma omp parallel for schedule(static, 1)
|
||||
for (int shard = 0; shard < shards.size(); ++shard) {
|
||||
shards[shard]->UpdatePredictionCache(out_preds_d);
|
||||
for (int shard = 0; shard < shards_.size(); ++shard) {
|
||||
shards_[shard]->UpdatePredictionCache(out_preds_d);
|
||||
}
|
||||
monitor.Stop("UpdatePredictionCache", dList);
|
||||
monitor_.Stop("UpdatePredictionCache", device_list_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -933,7 +932,7 @@ class GPUHistMaker : public TreeUpdater {
|
||||
uint64_t timestamp)
|
||||
: nid(nid), depth(depth), split(split), timestamp(timestamp) {}
|
||||
bool IsValid(const TrainParam& param, int num_leaves) const {
|
||||
if (split.loss_chg <= rt_eps) return false;
|
||||
if (split.loss_chg <= kRtEps) return false;
|
||||
if (split.left_sum.GetHess() == 0 || split.right_sum.GetHess() == 0)
|
||||
return false;
|
||||
if (param.max_depth > 0 && depth == param.max_depth) return false;
|
||||
@@ -959,38 +958,38 @@ class GPUHistMaker : public TreeUpdater {
|
||||
}
|
||||
};
|
||||
|
||||
inline static bool depth_wise(ExpandEntry lhs, ExpandEntry rhs) {
|
||||
inline static bool DepthWise(ExpandEntry lhs, ExpandEntry rhs) {
|
||||
if (lhs.depth == rhs.depth) {
|
||||
return lhs.timestamp > rhs.timestamp; // favor small timestamp
|
||||
} else {
|
||||
return lhs.depth > rhs.depth; // favor small depth
|
||||
}
|
||||
}
|
||||
inline static bool loss_guide(ExpandEntry lhs, ExpandEntry rhs) {
|
||||
inline static bool LossGuide(ExpandEntry lhs, ExpandEntry rhs) {
|
||||
if (lhs.split.loss_chg == rhs.split.loss_chg) {
|
||||
return lhs.timestamp > rhs.timestamp; // favor small timestamp
|
||||
} else {
|
||||
return lhs.split.loss_chg < rhs.split.loss_chg; // favor large loss_chg
|
||||
}
|
||||
}
|
||||
TrainParam param;
|
||||
TrainParam param_;
|
||||
common::HistCutMatrix hmat_;
|
||||
common::GHistIndexMatrix gmat_;
|
||||
MetaInfo* info;
|
||||
bool initialised;
|
||||
int n_devices;
|
||||
int n_bins;
|
||||
MetaInfo* info_;
|
||||
bool initialised_;
|
||||
int n_devices_;
|
||||
int n_bins_;
|
||||
|
||||
std::vector<std::unique_ptr<DeviceShard>> shards;
|
||||
ColumnSampler column_sampler;
|
||||
std::vector<std::unique_ptr<DeviceShard>> shards_;
|
||||
ColumnSampler column_sampler_;
|
||||
typedef std::priority_queue<ExpandEntry, std::vector<ExpandEntry>,
|
||||
std::function<bool(ExpandEntry, ExpandEntry)>>
|
||||
ExpandQueue;
|
||||
std::unique_ptr<ExpandQueue> qexpand_;
|
||||
common::Monitor monitor;
|
||||
dh::AllReducer reducer;
|
||||
common::Monitor monitor_;
|
||||
dh::AllReducer reducer_;
|
||||
std::vector<ValueConstraint> node_value_constraints_;
|
||||
std::vector<int> dList;
|
||||
std::vector<int> device_list_;
|
||||
|
||||
DMatrix* p_last_fmat_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user