Skip to content

Commit

Permalink
Revert "Sketching from adapters (dmlc#5365)"
Browse files Browse the repository at this point in the history
This reverts commit a38e7bd.
  • Loading branch information
sriramch committed Mar 10, 2020
1 parent 987b241 commit 6a85632
Show file tree
Hide file tree
Showing 11 changed files with 605 additions and 761 deletions.
795 changes: 410 additions & 385 deletions src/common/hist_util.cu

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions src/common/hist_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,16 @@ class DenseCuts : public CutsBuilder {
void Build(DMatrix* p_fmat, uint32_t max_num_bins) override;
};


HistogramCuts DeviceSketch(int device, DMatrix* dmat, int max_bins,
size_t sketch_batch_num_elements = 10000000);

template <typename AdapterT>
HistogramCuts AdapterDeviceSketch(AdapterT* adapter, int num_bins,
float missing,
size_t sketch_batch_num_elements = 10000000);
// FIXME(trivialfis): Merge this into generic cut builder.
/*! \brief Builds the cut matrix on the GPU.
*
* \return The row stride across the entire dataset.
*/
size_t DeviceSketch(int device,
int max_bin,
int gpu_batch_nrows,
DMatrix* dmat,
HistogramCuts* hmat);

/*!
* \brief preprocessed global index matrix, in CSR format
Expand Down
1 change: 0 additions & 1 deletion src/data/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ namespace data {
constexpr size_t kAdapterUnknownSize = std::numeric_limits<size_t >::max();

struct COOTuple {
COOTuple() = default;
XGBOOST_DEVICE COOTuple(size_t row_idx, size_t column_idx, float value)
: row_idx(row_idx), column_idx(column_idx), value(value) {}

Expand Down
22 changes: 4 additions & 18 deletions src/data/ellpack_page.cu
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,6 @@ EllpackPageImpl::EllpackPageImpl(int device, EllpackInfo info, size_t n_rows) {
monitor_.StopCuda("InitCompressedData");
}

size_t GetRowStride(DMatrix* dmat) {
if (dmat->IsDense()) return dmat->Info().num_col_;

size_t row_stride = 0;
for (const auto& batch : dmat->GetBatches<SparsePage>()) {
const auto& row_offset = batch.offset.ConstHostVector();
for (auto i = 1ull; i < row_offset.size(); i++) {
row_stride = std::max(
row_stride, static_cast<size_t>(row_offset[i] - row_offset[i - 1]));
}
}
return row_stride;
}

// Construct an ELLPACK matrix in memory.
EllpackPageImpl::EllpackPageImpl(DMatrix* dmat, const BatchParam& param) {
monitor_.Init("ellpack_page");
Expand All @@ -101,13 +87,13 @@ EllpackPageImpl::EllpackPageImpl(DMatrix* dmat, const BatchParam& param) {

monitor_.StartCuda("Quantiles");
// Create the quantile sketches for the dmatrix and initialize HistogramCuts.
size_t row_stride = GetRowStride(dmat);
auto cuts = common::DeviceSketch(param.gpu_id, dmat, param.max_bin,
param.gpu_batch_nrows);
common::HistogramCuts hmat;
size_t row_stride =
common::DeviceSketch(param.gpu_id, param.max_bin, param.gpu_batch_nrows, dmat, &hmat);
monitor_.StopCuda("Quantiles");

monitor_.StartCuda("InitEllpackInfo");
InitInfo(param.gpu_id, dmat->IsDense(), row_stride, cuts);
InitInfo(param.gpu_id, dmat->IsDense(), row_stride, hmat);
monitor_.StopCuda("InitEllpackInfo");

monitor_.StartCuda("InitCompressedData");
Expand Down
22 changes: 4 additions & 18 deletions src/data/ellpack_page_source.cu
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,6 @@ const EllpackPage& EllpackPageSource::Value() const {
return impl_->Value();
}

size_t GetRowStride(DMatrix* dmat) {
if (dmat->IsDense()) return dmat->Info().num_col_;

size_t row_stride = 0;
for (const auto& batch : dmat->GetBatches<SparsePage>()) {
const auto& row_offset = batch.offset.ConstHostVector();
for (auto i = 1ull; i < row_offset.size(); i++) {
row_stride = std::max(
row_stride, static_cast<size_t>(row_offset[i] - row_offset[i - 1]));
}
}
return row_stride;
}

// Build the quantile sketch across the whole input data, then use the histogram cuts to compress
// each CSR page, and write the accumulated ELLPACK pages to disk.
EllpackPageSourceImpl::EllpackPageSourceImpl(DMatrix* dmat,
Expand All @@ -99,13 +85,13 @@ EllpackPageSourceImpl::EllpackPageSourceImpl(DMatrix* dmat,
dh::safe_cuda(cudaSetDevice(device_));

monitor_.StartCuda("Quantiles");
size_t row_stride = GetRowStride(dmat);
auto cuts = common::DeviceSketch(param.gpu_id, dmat, param.max_bin,
param.gpu_batch_nrows);
common::HistogramCuts hmat;
size_t row_stride =
common::DeviceSketch(device_, param.max_bin, param.gpu_batch_nrows, dmat, &hmat);
monitor_.StopCuda("Quantiles");

monitor_.StartCuda("CreateEllpackInfo");
ellpack_info_ = EllpackInfo(device_, dmat->IsDense(), row_stride, cuts, &ba_);
ellpack_info_ = EllpackInfo(device_, dmat->IsDense(), row_stride, hmat, &ba_);
monitor_.StopCuda("CreateEllpackInfo");

monitor_.StartCuda("WriteEllpackPages");
Expand Down
105 changes: 105 additions & 0 deletions tests/cpp/common/test_gpu_hist_util.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <dmlc/filesystem.h>
#include <gtest/gtest.h>

#include <algorithm>
#include <cmath>


#include <thrust/device_vector.h>
#include <thrust/iterator/counting_iterator.h>

#include "xgboost/c_api.h"

#include "../../../src/common/device_helpers.cuh"
#include "../../../src/common/hist_util.h"

#include "../helpers.h"

namespace xgboost {
namespace common {

void TestDeviceSketch(bool use_external_memory) {
// create the data
int nrows = 10001;
std::shared_ptr<xgboost::DMatrix> *dmat = nullptr;

size_t num_cols = 1;
dmlc::TemporaryDirectory tmpdir;
std::string file = tmpdir.path + "/big.libsvm";
if (use_external_memory) {
auto sp_dmat = CreateSparsePageDMatrix(nrows * 3, 128UL, file); // 3 entries/row
dmat = new std::shared_ptr<xgboost::DMatrix>(std::move(sp_dmat));
num_cols = 5;
} else {
std::vector<float> test_data(nrows);
auto count_iter = thrust::make_counting_iterator(0);
// fill in reverse order
std::copy(count_iter, count_iter + nrows, test_data.rbegin());

// create the DMatrix
DMatrixHandle dmat_handle;
XGDMatrixCreateFromMat(test_data.data(), nrows, 1, -1,
&dmat_handle);
dmat = static_cast<std::shared_ptr<xgboost::DMatrix> *>(dmat_handle);
}

int device{0};
int max_bin{20};
int gpu_batch_nrows{0};

// find quantiles on the CPU
HistogramCuts hmat_cpu;
hmat_cpu.Build((*dmat).get(), max_bin);

// find the cuts on the GPU
HistogramCuts hmat_gpu;
size_t row_stride = DeviceSketch(device, max_bin, gpu_batch_nrows, dmat->get(), &hmat_gpu);

// compare the row stride with the one obtained from the dmatrix
bst_row_t expected_row_stride = 0;
for (const auto &batch : dmat->get()->GetBatches<xgboost::SparsePage>()) {
const auto &offset_vec = batch.offset.ConstHostVector();
for (int i = 1; i <= offset_vec.size() -1; ++i) {
expected_row_stride = std::max(expected_row_stride, offset_vec[i] - offset_vec[i-1]);
}
}

ASSERT_EQ(expected_row_stride, row_stride);

// compare the cuts
double eps = 1e-2;
ASSERT_EQ(hmat_gpu.MinValues().size(), num_cols);
ASSERT_EQ(hmat_gpu.Ptrs().size(), num_cols + 1);
ASSERT_EQ(hmat_gpu.Values().size(), hmat_cpu.Values().size());
ASSERT_LT(fabs(hmat_cpu.MinValues()[0] - hmat_gpu.MinValues()[0]), eps * nrows);
for (int i = 0; i < hmat_gpu.Values().size(); ++i) {
ASSERT_LT(fabs(hmat_cpu.Values()[i] - hmat_gpu.Values()[i]), eps * nrows);
}

// Determinstic
size_t constexpr kRounds { 100 };
for (size_t r = 0; r < kRounds; ++r) {
HistogramCuts new_sketch;
DeviceSketch(device, max_bin, gpu_batch_nrows, dmat->get(), &new_sketch);
ASSERT_EQ(hmat_gpu.Values().size(), new_sketch.Values().size());
for (size_t i = 0; i < hmat_gpu.Values().size(); ++i) {
ASSERT_EQ(hmat_gpu.Values()[i], new_sketch.Values()[i]);
}
for (size_t i = 0; i < hmat_gpu.MinValues().size(); ++i) {
ASSERT_EQ(hmat_gpu.MinValues()[i], new_sketch.MinValues()[i]);
}
}

delete dmat;
}

TEST(gpu_hist_util, DeviceSketch) {
TestDeviceSketch(false);
}

TEST(gpu_hist_util, DeviceSketch_ExternalMemory) {
TestDeviceSketch(true);
}

} // namespace common
} // namespace xgboost
26 changes: 4 additions & 22 deletions tests/cpp/common/test_hist_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -261,25 +261,7 @@ TEST(hist_util, DenseCutsAccuracyTest) {
HistogramCuts cuts;
DenseCuts dense(&cuts);
dense.Build(dmat.get(), num_bins);
ValidateCuts(cuts, dmat.get(), num_bins);
}
}
}

TEST(hist_util, DenseCutsAccuracyTestWeights) {
int bin_sizes[] = {2, 16, 256, 512};
int sizes[] = {100, 1000, 1500};
int num_columns = 5;
for (auto num_rows : sizes) {
auto x = GenerateRandom(num_rows, num_columns);
auto dmat = GetDMatrixFromData(x, num_rows, num_columns);
auto w = GenerateRandomWeights(num_rows);
dmat->Info().weights_.HostVector() = w;
for (auto num_bins : bin_sizes) {
HistogramCuts cuts;
DenseCuts dense(&cuts);
dense.Build(dmat.get(), num_bins);
ValidateCuts(cuts, dmat.get(), num_bins);
ValidateCuts(cuts, x, num_rows, num_columns, num_bins);
}
}
}
Expand All @@ -297,7 +279,7 @@ TEST(hist_util, DenseCutsExternalMemory) {
HistogramCuts cuts;
DenseCuts dense(&cuts);
dense.Build(dmat.get(), num_bins);
ValidateCuts(cuts, dmat.get(), num_bins);
ValidateCuts(cuts, x, num_rows, num_columns, num_bins);
}
}
}
Expand All @@ -313,7 +295,7 @@ TEST(hist_util, SparseCutsAccuracyTest) {
HistogramCuts cuts;
SparseCuts sparse(&cuts);
sparse.Build(dmat.get(), num_bins);
ValidateCuts(cuts, dmat.get(), num_bins);
ValidateCuts(cuts, x, num_rows, num_columns, num_bins);
}
}
}
Expand Down Expand Up @@ -353,7 +335,7 @@ TEST(hist_util, SparseCutsExternalMemory) {
HistogramCuts cuts;
SparseCuts dense(&cuts);
dense.Build(dmat.get(), num_bins);
ValidateCuts(cuts, dmat.get(), num_bins);
ValidateCuts(cuts, x, num_rows, num_columns, num_bins);
}
}
}
Expand Down
Loading

0 comments on commit 6a85632

Please sign in to comment.