enable ROCm on latest XGBoost
This commit is contained in:
@@ -127,8 +127,8 @@ TEST(CpuPredictor, IterationRange) {
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, IterationRangeColmnSplit) {
|
||||
Context ctx;
|
||||
TestIterationRangeColumnSplit(&ctx);
|
||||
auto constexpr kWorldSize = 2;
|
||||
TestIterationRangeColumnSplit(kWorldSize, false);
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, ExternalMemory) {
|
||||
@@ -142,7 +142,7 @@ TEST(CpuPredictor, InplacePredict) {
|
||||
bst_row_t constexpr kRows{128};
|
||||
bst_feature_t constexpr kCols{64};
|
||||
Context ctx;
|
||||
auto gen = RandomDataGenerator{kRows, kCols, 0.5}.Device(ctx.gpu_id);
|
||||
auto gen = RandomDataGenerator{kRows, kCols, 0.5}.Device(ctx.Device());
|
||||
{
|
||||
HostDeviceVector<float> data;
|
||||
gen.GenerateDense(&data);
|
||||
@@ -226,23 +226,21 @@ TEST(CPUPredictor, GHistIndexTraining) {
|
||||
}
|
||||
|
||||
TEST(CPUPredictor, CategoricalPrediction) {
|
||||
Context ctx;
|
||||
TestCategoricalPrediction(&ctx, false);
|
||||
TestCategoricalPrediction(false, false);
|
||||
}
|
||||
|
||||
TEST(CPUPredictor, CategoricalPredictionColumnSplit) {
|
||||
Context ctx;
|
||||
TestCategoricalPredictionColumnSplit(&ctx);
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, TestCategoricalPrediction, false, true);
|
||||
}
|
||||
|
||||
TEST(CPUPredictor, CategoricalPredictLeaf) {
|
||||
Context ctx;
|
||||
TestCategoricalPredictLeaf(&ctx, false);
|
||||
TestCategoricalPredictLeaf(false, false);
|
||||
}
|
||||
|
||||
TEST(CPUPredictor, CategoricalPredictLeafColumnSplit) {
|
||||
Context ctx;
|
||||
TestCategoricalPredictLeafColumnSplit(&ctx);
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, TestCategoricalPredictLeaf, false, true);
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, UpdatePredictionCache) {
|
||||
@@ -256,8 +254,8 @@ TEST(CpuPredictor, LesserFeatures) {
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, LesserFeaturesColumnSplit) {
|
||||
Context ctx;
|
||||
TestPredictionWithLesserFeaturesColumnSplit(&ctx);
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, TestPredictionWithLesserFeaturesColumnSplit, false);
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, Sparse) {
|
||||
@@ -267,9 +265,9 @@ TEST(CpuPredictor, Sparse) {
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, SparseColumnSplit) {
|
||||
Context ctx;
|
||||
TestSparsePredictionColumnSplit(&ctx, 0.2);
|
||||
TestSparsePredictionColumnSplit(&ctx, 0.8);
|
||||
auto constexpr kWorldSize = 2;
|
||||
TestSparsePredictionColumnSplit(kWorldSize, false, 0.2);
|
||||
TestSparsePredictionColumnSplit(kWorldSize, false, 0.8);
|
||||
}
|
||||
|
||||
TEST(CpuPredictor, Multi) {
|
||||
|
||||
@@ -38,7 +38,7 @@ TEST(GPUPredictor, Basic) {
|
||||
auto dmat = RandomDataGenerator(n_row, n_col, 0).GenerateDMatrix();
|
||||
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Device())};
|
||||
gbm::GBTreeModel model = CreateTestModel(&mparam, &ctx);
|
||||
|
||||
// Test predict batch
|
||||
@@ -74,7 +74,7 @@ void VerifyBasicColumnSplit(std::array<std::vector<float>, 32> const& expected_r
|
||||
auto dmat = RandomDataGenerator(n_row, n_col, 0).GenerateDMatrix();
|
||||
std::unique_ptr<DMatrix> sliced{dmat->SliceCol(world_size, rank)};
|
||||
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Device())};
|
||||
gbm::GBTreeModel model = CreateTestModel(&mparam, &ctx);
|
||||
|
||||
// Test predict batch
|
||||
@@ -102,7 +102,7 @@ TEST_F(MGPUPredictorTest, BasicColumnSplit) {
|
||||
size_t n_row = i, n_col = i;
|
||||
auto dmat = RandomDataGenerator(n_row, n_col, 0).GenerateDMatrix();
|
||||
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(n_col, .5, 1, ctx.Device())};
|
||||
gbm::GBTreeModel model = CreateTestModel(&mparam, &ctx);
|
||||
|
||||
// Test predict batch
|
||||
@@ -123,8 +123,10 @@ TEST(GPUPredictor, EllpackBasic) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
for (size_t bins = 2; bins < 258; bins += 16) {
|
||||
size_t rows = bins * 16;
|
||||
auto p_m =
|
||||
RandomDataGenerator{rows, kCols, 0.0}.Bins(bins).Device(0).GenerateDeviceDMatrix(false);
|
||||
auto p_m = RandomDataGenerator{rows, kCols, 0.0}
|
||||
.Bins(bins)
|
||||
.Device(DeviceOrd::CUDA(0))
|
||||
.GenerateDeviceDMatrix(false);
|
||||
ASSERT_FALSE(p_m->PageExists<SparsePage>());
|
||||
TestPredictionFromGradientIndex<EllpackPage>(&ctx, rows, kCols, p_m);
|
||||
TestPredictionFromGradientIndex<EllpackPage>(&ctx, bins, kCols, p_m);
|
||||
@@ -136,11 +138,11 @@ TEST(GPUPredictor, EllpackTraining) {
|
||||
size_t constexpr kRows{128}, kCols{16}, kBins{64};
|
||||
auto p_ellpack = RandomDataGenerator{kRows, kCols, 0.0}
|
||||
.Bins(kBins)
|
||||
.Device(ctx.Ordinal())
|
||||
.Device(ctx.Device())
|
||||
.GenerateDeviceDMatrix(false);
|
||||
HostDeviceVector<float> storage(kRows * kCols);
|
||||
auto columnar =
|
||||
RandomDataGenerator{kRows, kCols, 0.0}.Device(ctx.Ordinal()).GenerateArrayInterface(&storage);
|
||||
RandomDataGenerator{kRows, kCols, 0.0}.Device(ctx.Device()).GenerateArrayInterface(&storage);
|
||||
auto adapter = data::CupyAdapter(columnar);
|
||||
std::shared_ptr<DMatrix> p_full{
|
||||
DMatrix::Create(&adapter, std::numeric_limits<float>::quiet_NaN(), 1)};
|
||||
@@ -155,7 +157,7 @@ TEST(GPUPredictor, ExternalMemoryTest) {
|
||||
|
||||
const int n_classes = 3;
|
||||
Context ctx = MakeCUDACtx(0);
|
||||
LearnerModelParam mparam{MakeMP(5, .5, n_classes, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(5, .5, n_classes, ctx.Device())};
|
||||
|
||||
gbm::GBTreeModel model = CreateTestModel(&mparam, &ctx, n_classes);
|
||||
std::vector<std::unique_ptr<DMatrix>> dmats;
|
||||
@@ -166,7 +168,7 @@ TEST(GPUPredictor, ExternalMemoryTest) {
|
||||
|
||||
for (const auto& dmat: dmats) {
|
||||
dmat->Info().base_margin_ = decltype(dmat->Info().base_margin_){
|
||||
{dmat->Info().num_row_, static_cast<size_t>(n_classes)}, 0};
|
||||
{dmat->Info().num_row_, static_cast<size_t>(n_classes)}, DeviceOrd::CUDA(0)};
|
||||
dmat->Info().base_margin_.Data()->Fill(0.5);
|
||||
PredictionCacheEntry out_predictions;
|
||||
gpu_predictor->InitOutPredictions(dmat->Info(), &out_predictions.predictions, model);
|
||||
@@ -185,7 +187,7 @@ TEST(GPUPredictor, InplacePredictCupy) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
size_t constexpr kRows{128}, kCols{64};
|
||||
RandomDataGenerator gen(kRows, kCols, 0.5);
|
||||
gen.Device(ctx.Ordinal());
|
||||
gen.Device(ctx.Device());
|
||||
HostDeviceVector<float> data;
|
||||
std::string interface_str = gen.GenerateArrayInterface(&data);
|
||||
std::shared_ptr<DMatrix> p_fmat{new data::DMatrixProxy};
|
||||
@@ -197,7 +199,7 @@ TEST(GPUPredictor, InplacePredictCuDF) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
size_t constexpr kRows{128}, kCols{64};
|
||||
RandomDataGenerator gen(kRows, kCols, 0.5);
|
||||
gen.Device(ctx.Ordinal());
|
||||
gen.Device(ctx.Device());
|
||||
std::vector<HostDeviceVector<float>> storage(kCols);
|
||||
auto interface_str = gen.GenerateColumnarArrayInterface(&storage);
|
||||
std::shared_ptr<DMatrix> p_fmat{new data::DMatrixProxy};
|
||||
@@ -210,6 +212,10 @@ TEST(GpuPredictor, LesserFeatures) {
|
||||
TestPredictionWithLesserFeatures(&ctx);
|
||||
}
|
||||
|
||||
TEST_F(MGPUPredictorTest, LesserFeaturesColumnSplit) {
|
||||
RunWithInMemoryCommunicator(world_size_, TestPredictionWithLesserFeaturesColumnSplit, true);
|
||||
}
|
||||
|
||||
// Very basic test of empty model
|
||||
TEST(GPUPredictor, ShapStump) {
|
||||
#if defined(XGBOOST_USE_CUDA)
|
||||
@@ -219,7 +225,7 @@ TEST(GPUPredictor, ShapStump) {
|
||||
#endif
|
||||
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
LearnerModelParam mparam{MakeMP(1, .5, 1, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(1, .5, 1, ctx.Device())};
|
||||
gbm::GBTreeModel model(&mparam, &ctx);
|
||||
|
||||
std::vector<std::unique_ptr<RegTree>> trees;
|
||||
@@ -245,7 +251,7 @@ TEST(GPUPredictor, ShapStump) {
|
||||
|
||||
TEST(GPUPredictor, Shap) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
LearnerModelParam mparam{MakeMP(1, .5, 1, ctx.Ordinal())};
|
||||
LearnerModelParam mparam{MakeMP(1, .5, 1, ctx.Device())};
|
||||
gbm::GBTreeModel model(&mparam, &ctx);
|
||||
|
||||
std::vector<std::unique_ptr<RegTree>> trees;
|
||||
@@ -278,19 +284,29 @@ TEST(GPUPredictor, IterationRange) {
|
||||
TestIterationRange(&ctx);
|
||||
}
|
||||
|
||||
TEST_F(MGPUPredictorTest, IterationRangeColumnSplit) {
|
||||
TestIterationRangeColumnSplit(world_size_, true);
|
||||
}
|
||||
|
||||
TEST(GPUPredictor, CategoricalPrediction) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
TestCategoricalPrediction(&ctx, false);
|
||||
TestCategoricalPrediction(true, false);
|
||||
}
|
||||
|
||||
TEST_F(MGPUPredictorTest, CategoricalPredictionColumnSplit) {
|
||||
RunWithInMemoryCommunicator(world_size_, TestCategoricalPrediction, true, true);
|
||||
}
|
||||
|
||||
TEST(GPUPredictor, CategoricalPredictLeaf) {
|
||||
auto ctx = MakeCUDACtx(0);
|
||||
TestCategoricalPredictLeaf(&ctx, false);
|
||||
TestCategoricalPredictLeaf(true, false);
|
||||
}
|
||||
|
||||
TEST_F(MGPUPredictorTest, CategoricalPredictionLeafColumnSplit) {
|
||||
RunWithInMemoryCommunicator(world_size_, TestCategoricalPredictLeaf, true, true);
|
||||
}
|
||||
|
||||
TEST(GPUPredictor, PredictLeafBasic) {
|
||||
size_t constexpr kRows = 5, kCols = 5;
|
||||
auto dmat = RandomDataGenerator(kRows, kCols, 0).Device(0).GenerateDMatrix();
|
||||
auto dmat = RandomDataGenerator(kRows, kCols, 0).Device(DeviceOrd::CUDA(0)).GenerateDMatrix();
|
||||
auto lparam = MakeCUDACtx(GPUIDX);
|
||||
std::unique_ptr<Predictor> gpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("gpu_predictor", &lparam));
|
||||
@@ -313,4 +329,9 @@ TEST(GPUPredictor, Sparse) {
|
||||
TestSparsePrediction(&ctx, 0.2);
|
||||
TestSparsePrediction(&ctx, 0.8);
|
||||
}
|
||||
|
||||
TEST_F(MGPUPredictorTest, SparseColumnSplit) {
|
||||
TestSparsePredictionColumnSplit(world_size_, true, 0.2);
|
||||
TestSparsePredictionColumnSplit(world_size_, true, 0.8);
|
||||
}
|
||||
} // namespace xgboost::predictor
|
||||
|
||||
@@ -34,7 +34,7 @@ TEST(Predictor, PredictionCache) {
|
||||
// Add a cache that is immediately expired.
|
||||
auto add_cache = [&]() {
|
||||
auto p_dmat = RandomDataGenerator(kRows, kCols, 0).GenerateDMatrix();
|
||||
container.Cache(p_dmat, Context::kCpuId);
|
||||
container.Cache(p_dmat, DeviceOrd::CPU());
|
||||
m = p_dmat.get();
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ void TestTrainingPrediction(Context const *ctx, size_t rows, size_t bins,
|
||||
void TestInplacePrediction(Context const *ctx, std::shared_ptr<DMatrix> x, bst_row_t rows,
|
||||
bst_feature_t cols) {
|
||||
std::size_t constexpr kClasses { 4 };
|
||||
auto gen = RandomDataGenerator{rows, cols, 0.5}.Device(ctx->gpu_id);
|
||||
auto gen = RandomDataGenerator{rows, cols, 0.5}.Device(ctx->Device());
|
||||
std::shared_ptr<DMatrix> m = gen.GenerateDMatrix(true, false, kClasses);
|
||||
|
||||
std::unique_ptr<Learner> learner {
|
||||
@@ -172,16 +172,6 @@ void VerifyPredictionWithLesserFeatures(Learner *learner, bst_row_t kRows,
|
||||
ASSERT_THROW({ learner->Predict(m_invalid, false, &prediction, 0, 0); }, dmlc::Error);
|
||||
}
|
||||
|
||||
void VerifyPredictionWithLesserFeaturesColumnSplit(Learner *learner, size_t rows,
|
||||
std::shared_ptr<DMatrix> m_test,
|
||||
std::shared_ptr<DMatrix> m_invalid) {
|
||||
auto const world_size = collective::GetWorldSize();
|
||||
auto const rank = collective::GetRank();
|
||||
std::shared_ptr<DMatrix> sliced_test{m_test->SliceCol(world_size, rank)};
|
||||
std::shared_ptr<DMatrix> sliced_invalid{m_invalid->SliceCol(world_size, rank)};
|
||||
|
||||
VerifyPredictionWithLesserFeatures(learner, rows, sliced_test, sliced_invalid);
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void TestPredictionWithLesserFeatures(Context const *ctx) {
|
||||
@@ -202,7 +192,7 @@ void TestPredictionDeviceAccess() {
|
||||
|
||||
HostDeviceVector<float> from_cpu;
|
||||
{
|
||||
ASSERT_EQ(from_cpu.DeviceIdx(), Context::kCpuId);
|
||||
ASSERT_TRUE(from_cpu.Device().IsCPU());
|
||||
Context cpu_ctx;
|
||||
learner->SetParam("device", cpu_ctx.DeviceName());
|
||||
learner->Predict(m_test, false, &from_cpu, 0, 0);
|
||||
@@ -216,7 +206,7 @@ void TestPredictionDeviceAccess() {
|
||||
Context cuda_ctx = MakeCUDACtx(0);
|
||||
learner->SetParam("device", cuda_ctx.DeviceName());
|
||||
learner->Predict(m_test, false, &from_cuda, 0, 0);
|
||||
ASSERT_EQ(from_cuda.DeviceIdx(), 0);
|
||||
ASSERT_EQ(from_cuda.Device(), DeviceOrd::CUDA(0));
|
||||
ASSERT_TRUE(from_cuda.DeviceCanWrite());
|
||||
ASSERT_FALSE(from_cuda.HostCanRead());
|
||||
}
|
||||
@@ -229,16 +219,24 @@ void TestPredictionDeviceAccess() {
|
||||
#endif // defined(XGBOOST_USE_CUDA)
|
||||
}
|
||||
|
||||
void TestPredictionWithLesserFeaturesColumnSplit(Context const *ctx) {
|
||||
size_t constexpr kRows = 256, kTrainCols = 256, kTestCols = 4, kIters = 4;
|
||||
auto m_train = RandomDataGenerator(kRows, kTrainCols, 0.5).GenerateDMatrix(true);
|
||||
auto learner = LearnerForTest(ctx, m_train, kIters);
|
||||
void TestPredictionWithLesserFeaturesColumnSplit(bool use_gpu) {
|
||||
auto const world_size = collective::GetWorldSize();
|
||||
auto const rank = collective::GetRank();
|
||||
|
||||
std::size_t constexpr kRows = 256, kTrainCols = 256, kTestCols = 4, kIters = 4;
|
||||
auto m_train = RandomDataGenerator(kRows, kTrainCols, 0.5).Seed(rank).GenerateDMatrix(true);
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(common::AllVisibleGPUs() == 1 ? 0 : rank);
|
||||
}
|
||||
auto learner = LearnerForTest(&ctx, m_train, kIters);
|
||||
auto m_test = RandomDataGenerator(kRows, kTestCols, 0.5).GenerateDMatrix(false);
|
||||
auto m_invalid = RandomDataGenerator(kRows, kTrainCols + 1, 0.5).GenerateDMatrix(false);
|
||||
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, VerifyPredictionWithLesserFeaturesColumnSplit,
|
||||
learner.get(), kRows, m_test, m_invalid);
|
||||
std::shared_ptr<DMatrix> sliced_test{m_test->SliceCol(world_size, rank)};
|
||||
std::shared_ptr<DMatrix> sliced_invalid{m_invalid->SliceCol(world_size, rank)};
|
||||
|
||||
VerifyPredictionWithLesserFeatures(learner.get(), kRows, sliced_test, sliced_invalid);
|
||||
}
|
||||
|
||||
void GBTreeModelForTest(gbm::GBTreeModel *model, uint32_t split_ind,
|
||||
@@ -260,7 +258,11 @@ void GBTreeModelForTest(gbm::GBTreeModel *model, uint32_t split_ind,
|
||||
model->CommitModelGroup(std::move(trees), 0);
|
||||
}
|
||||
|
||||
void TestCategoricalPrediction(Context const* ctx, bool is_column_split) {
|
||||
void TestCategoricalPrediction(bool use_gpu, bool is_column_split) {
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(common::AllVisibleGPUs() == 1 ? 0 : collective::GetRank());
|
||||
}
|
||||
size_t constexpr kCols = 10;
|
||||
PredictionCacheEntry out_predictions;
|
||||
|
||||
@@ -270,10 +272,10 @@ void TestCategoricalPrediction(Context const* ctx, bool is_column_split) {
|
||||
float left_weight = 1.3f;
|
||||
float right_weight = 1.7f;
|
||||
|
||||
gbm::GBTreeModel model(&mparam, ctx);
|
||||
gbm::GBTreeModel model(&mparam, &ctx);
|
||||
GBTreeModelForTest(&model, split_ind, split_cat, left_weight, right_weight);
|
||||
|
||||
std::unique_ptr<Predictor> predictor{CreatePredictorForTest(ctx)};
|
||||
std::unique_ptr<Predictor> predictor{CreatePredictorForTest(&ctx)};
|
||||
|
||||
std::vector<float> row(kCols);
|
||||
row[split_ind] = split_cat;
|
||||
@@ -303,12 +305,11 @@ void TestCategoricalPrediction(Context const* ctx, bool is_column_split) {
|
||||
ASSERT_EQ(out_predictions.predictions.HostVector()[0], left_weight + score);
|
||||
}
|
||||
|
||||
void TestCategoricalPredictionColumnSplit(Context const *ctx) {
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, TestCategoricalPrediction, ctx, true);
|
||||
}
|
||||
|
||||
void TestCategoricalPredictLeaf(Context const *ctx, bool is_column_split) {
|
||||
void TestCategoricalPredictLeaf(bool use_gpu, bool is_column_split) {
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(common::AllVisibleGPUs() == 1 ? 0 : collective::GetRank());
|
||||
}
|
||||
size_t constexpr kCols = 10;
|
||||
PredictionCacheEntry out_predictions;
|
||||
|
||||
@@ -319,10 +320,10 @@ void TestCategoricalPredictLeaf(Context const *ctx, bool is_column_split) {
|
||||
float left_weight = 1.3f;
|
||||
float right_weight = 1.7f;
|
||||
|
||||
gbm::GBTreeModel model(&mparam, ctx);
|
||||
gbm::GBTreeModel model(&mparam, &ctx);
|
||||
GBTreeModelForTest(&model, split_ind, split_cat, left_weight, right_weight);
|
||||
|
||||
std::unique_ptr<Predictor> predictor{CreatePredictorForTest(ctx)};
|
||||
std::unique_ptr<Predictor> predictor{CreatePredictorForTest(&ctx)};
|
||||
|
||||
std::vector<float> row(kCols);
|
||||
row[split_ind] = split_cat;
|
||||
@@ -347,15 +348,10 @@ void TestCategoricalPredictLeaf(Context const *ctx, bool is_column_split) {
|
||||
ASSERT_EQ(out_predictions.predictions.HostVector()[0], 1);
|
||||
}
|
||||
|
||||
void TestCategoricalPredictLeafColumnSplit(Context const *ctx) {
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, TestCategoricalPredictLeaf, ctx, true);
|
||||
}
|
||||
|
||||
void TestIterationRange(Context const* ctx) {
|
||||
size_t constexpr kRows = 1000, kCols = 20, kClasses = 4, kForest = 3, kIters = 10;
|
||||
auto dmat = RandomDataGenerator(kRows, kCols, 0)
|
||||
.Device(ctx->gpu_id)
|
||||
.Device(ctx->Device())
|
||||
.GenerateDMatrix(true, true, kClasses);
|
||||
auto learner = LearnerForTest(ctx, dmat, kIters, kForest);
|
||||
|
||||
@@ -411,15 +407,30 @@ void TestIterationRange(Context const* ctx) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
void VerifyIterationRangeColumnSplit(DMatrix *dmat, Learner *learner, Learner *sliced,
|
||||
void VerifyIterationRangeColumnSplit(bool use_gpu, Json const &ranged_model,
|
||||
Json const &sliced_model, std::size_t rows, std::size_t cols,
|
||||
std::size_t classes,
|
||||
std::vector<float> const &expected_margin_ranged,
|
||||
std::vector<float> const &expected_margin_sliced,
|
||||
std::vector<float> const &expected_leaf_ranged,
|
||||
std::vector<float> const &expected_leaf_sliced) {
|
||||
auto const world_size = collective::GetWorldSize();
|
||||
auto const rank = collective::GetRank();
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(common::AllVisibleGPUs() == 1 ? 0 : rank);
|
||||
}
|
||||
auto dmat = RandomDataGenerator(rows, cols, 0).GenerateDMatrix(true, true, classes);
|
||||
std::shared_ptr<DMatrix> Xy{dmat->SliceCol(world_size, rank)};
|
||||
|
||||
std::unique_ptr<Learner> learner{Learner::Create({Xy})};
|
||||
learner->SetParam("device", ctx.DeviceName());
|
||||
learner->LoadModel(ranged_model);
|
||||
|
||||
std::unique_ptr<Learner> sliced{Learner::Create({Xy})};
|
||||
sliced->SetParam("device", ctx.DeviceName());
|
||||
sliced->LoadModel(sliced_model);
|
||||
|
||||
HostDeviceVector<float> out_predt_sliced;
|
||||
HostDeviceVector<float> out_predt_ranged;
|
||||
|
||||
@@ -428,11 +439,15 @@ void VerifyIterationRangeColumnSplit(DMatrix *dmat, Learner *learner, Learner *s
|
||||
sliced->Predict(Xy, true, &out_predt_sliced, 0, 0, false, false, false, false, false);
|
||||
learner->Predict(Xy, true, &out_predt_ranged, 0, 3, false, false, false, false, false);
|
||||
auto const &h_sliced = out_predt_sliced.HostVector();
|
||||
auto const &h_range = out_predt_ranged.HostVector();
|
||||
ASSERT_EQ(h_sliced.size(), expected_margin_sliced.size());
|
||||
ASSERT_EQ(h_sliced, expected_margin_sliced);
|
||||
ASSERT_EQ(h_range.size(), expected_margin_ranged.size());
|
||||
ASSERT_EQ(h_range, expected_margin_ranged);
|
||||
auto const &h_ranged = out_predt_ranged.HostVector();
|
||||
EXPECT_EQ(h_sliced.size(), expected_margin_sliced.size());
|
||||
for (std::size_t i = 0; i < expected_margin_sliced.size(); ++i) {
|
||||
ASSERT_FLOAT_EQ(h_sliced[i], expected_margin_sliced[i]) << "rank " << rank << ", i " << i;
|
||||
}
|
||||
EXPECT_EQ(h_ranged.size(), expected_margin_ranged.size());
|
||||
for (std::size_t i = 0; i < expected_margin_ranged.size(); ++i) {
|
||||
ASSERT_FLOAT_EQ(h_ranged[i], expected_margin_ranged[i]) << "rank " << rank << ", i " << i;
|
||||
}
|
||||
}
|
||||
|
||||
// Leaf
|
||||
@@ -440,21 +455,27 @@ void VerifyIterationRangeColumnSplit(DMatrix *dmat, Learner *learner, Learner *s
|
||||
sliced->Predict(Xy, false, &out_predt_sliced, 0, 0, false, true, false, false, false);
|
||||
learner->Predict(Xy, false, &out_predt_ranged, 0, 3, false, true, false, false, false);
|
||||
auto const &h_sliced = out_predt_sliced.HostVector();
|
||||
auto const &h_range = out_predt_ranged.HostVector();
|
||||
ASSERT_EQ(h_sliced.size(), expected_leaf_sliced.size());
|
||||
ASSERT_EQ(h_sliced, expected_leaf_sliced);
|
||||
ASSERT_EQ(h_range.size(), expected_leaf_ranged.size());
|
||||
ASSERT_EQ(h_range, expected_leaf_ranged);
|
||||
auto const &h_ranged = out_predt_ranged.HostVector();
|
||||
EXPECT_EQ(h_sliced.size(), expected_leaf_sliced.size());
|
||||
for (std::size_t i = 0; i < expected_leaf_sliced.size(); ++i) {
|
||||
ASSERT_FLOAT_EQ(h_sliced[i], expected_leaf_sliced[i]) << "rank " << rank << ", i " << i;
|
||||
}
|
||||
EXPECT_EQ(h_ranged.size(), expected_leaf_ranged.size());
|
||||
for (std::size_t i = 0; i < expected_leaf_ranged.size(); ++i) {
|
||||
ASSERT_FLOAT_EQ(h_ranged[i], expected_leaf_ranged[i]) << "rank " << rank << ", i " << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void TestIterationRangeColumnSplit(Context const* ctx) {
|
||||
size_t constexpr kRows = 1000, kCols = 20, kClasses = 4, kForest = 3, kIters = 10;
|
||||
void TestIterationRangeColumnSplit(int world_size, bool use_gpu) {
|
||||
std::size_t constexpr kRows = 1000, kCols = 20, kClasses = 4, kForest = 3, kIters = 10;
|
||||
auto dmat = RandomDataGenerator(kRows, kCols, 0).GenerateDMatrix(true, true, kClasses);
|
||||
auto learner = LearnerForTest(ctx, dmat, kIters, kForest);
|
||||
|
||||
learner->SetParam("device", ctx->DeviceName());
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(0);
|
||||
}
|
||||
auto learner = LearnerForTest(&ctx, dmat, kIters, kForest);
|
||||
|
||||
bool bound = false;
|
||||
std::unique_ptr<Learner> sliced{learner->Slice(0, 3, 1, &bound)};
|
||||
@@ -476,9 +497,13 @@ void TestIterationRangeColumnSplit(Context const* ctx) {
|
||||
auto const &leaf_sliced = leaf_predt_sliced.HostVector();
|
||||
auto const &leaf_ranged = leaf_predt_ranged.HostVector();
|
||||
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, VerifyIterationRangeColumnSplit, dmat.get(),
|
||||
learner.get(), sliced.get(), margin_ranged, margin_sliced,
|
||||
Json ranged_model{Object{}};
|
||||
learner->SaveModel(&ranged_model);
|
||||
Json sliced_model{Object{}};
|
||||
sliced->SaveModel(&sliced_model);
|
||||
|
||||
RunWithInMemoryCommunicator(world_size, VerifyIterationRangeColumnSplit, use_gpu, ranged_model,
|
||||
sliced_model, kRows, kCols, kClasses, margin_ranged, margin_sliced,
|
||||
leaf_ranged, leaf_sliced);
|
||||
}
|
||||
|
||||
@@ -497,7 +522,7 @@ void TestSparsePrediction(Context const *ctx, float sparsity) {
|
||||
|
||||
if (ctx->IsCUDA()) {
|
||||
learner->SetParam("tree_method", "gpu_hist");
|
||||
learner->SetParam("gpu_id", std::to_string(ctx->gpu_id));
|
||||
learner->SetParam("device", ctx->Device().Name());
|
||||
}
|
||||
learner->Predict(Xy, false, &sparse_predt, 0, 0);
|
||||
|
||||
@@ -539,11 +564,20 @@ void TestSparsePrediction(Context const *ctx, float sparsity) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
void VerifySparsePredictionColumnSplit(DMatrix *dmat, Learner *learner,
|
||||
void VerifySparsePredictionColumnSplit(bool use_gpu, Json const &model, std::size_t rows,
|
||||
std::size_t cols, float sparsity,
|
||||
std::vector<float> const &expected_predt) {
|
||||
std::shared_ptr<DMatrix> sliced{
|
||||
dmat->SliceCol(collective::GetWorldSize(), collective::GetRank())};
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(common::AllVisibleGPUs() == 1 ? 0 : collective::GetRank());
|
||||
}
|
||||
auto Xy = RandomDataGenerator(rows, cols, sparsity).GenerateDMatrix(true);
|
||||
std::shared_ptr<DMatrix> sliced{Xy->SliceCol(collective::GetWorldSize(), collective::GetRank())};
|
||||
HostDeviceVector<float> sparse_predt;
|
||||
|
||||
std::unique_ptr<Learner> learner{Learner::Create({sliced})};
|
||||
learner->SetParam("device", ctx.DeviceName());
|
||||
learner->LoadModel(model);
|
||||
learner->Predict(sliced, false, &sparse_predt, 0, 0);
|
||||
|
||||
auto const &predt = sparse_predt.HostVector();
|
||||
@@ -554,10 +588,14 @@ void VerifySparsePredictionColumnSplit(DMatrix *dmat, Learner *learner,
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void TestSparsePredictionColumnSplit(Context const* ctx, float sparsity) {
|
||||
void TestSparsePredictionColumnSplit(int world_size, bool use_gpu, float sparsity) {
|
||||
Context ctx;
|
||||
if (use_gpu) {
|
||||
ctx = MakeCUDACtx(0);
|
||||
}
|
||||
size_t constexpr kRows = 512, kCols = 128, kIters = 4;
|
||||
auto Xy = RandomDataGenerator(kRows, kCols, sparsity).GenerateDMatrix(true);
|
||||
auto learner = LearnerForTest(ctx, Xy, kIters);
|
||||
auto learner = LearnerForTest(&ctx, Xy, kIters);
|
||||
|
||||
HostDeviceVector<float> sparse_predt;
|
||||
|
||||
@@ -567,12 +605,11 @@ void TestSparsePredictionColumnSplit(Context const* ctx, float sparsity) {
|
||||
learner.reset(Learner::Create({Xy}));
|
||||
learner->LoadModel(model);
|
||||
|
||||
learner->SetParam("device", ctx->DeviceName());
|
||||
learner->SetParam("device", ctx.DeviceName());
|
||||
learner->Predict(Xy, false, &sparse_predt, 0, 0);
|
||||
|
||||
auto constexpr kWorldSize = 2;
|
||||
RunWithInMemoryCommunicator(kWorldSize, VerifySparsePredictionColumnSplit, Xy.get(),
|
||||
learner.get(), sparse_predt.HostVector());
|
||||
RunWithInMemoryCommunicator(world_size, VerifySparsePredictionColumnSplit, use_gpu, model,
|
||||
kRows, kCols, sparsity, sparse_predt.HostVector());
|
||||
}
|
||||
|
||||
void TestVectorLeafPrediction(Context const *ctx) {
|
||||
@@ -583,7 +620,7 @@ void TestVectorLeafPrediction(Context const *ctx) {
|
||||
size_t constexpr kCols = 5;
|
||||
|
||||
LearnerModelParam mparam{static_cast<bst_feature_t>(kCols),
|
||||
linalg::Vector<float>{{0.5}, {1}, Context::kCpuId}, 1, 3,
|
||||
linalg::Vector<float>{{0.5}, {1}, DeviceOrd::CPU()}, 1, 3,
|
||||
MultiStrategy::kMultiOutputTree};
|
||||
|
||||
std::vector<std::unique_ptr<RegTree>> trees;
|
||||
|
||||
@@ -94,23 +94,19 @@ void TestPredictionWithLesserFeatures(Context const* ctx);
|
||||
|
||||
void TestPredictionDeviceAccess();
|
||||
|
||||
void TestCategoricalPrediction(Context const* ctx, bool is_column_split);
|
||||
void TestCategoricalPrediction(bool use_gpu, bool is_column_split);
|
||||
|
||||
void TestCategoricalPredictionColumnSplit(Context const* ctx);
|
||||
void TestPredictionWithLesserFeaturesColumnSplit(bool use_gpu);
|
||||
|
||||
void TestPredictionWithLesserFeaturesColumnSplit(Context const* ctx);
|
||||
|
||||
void TestCategoricalPredictLeaf(Context const* ctx, bool is_column_split);
|
||||
|
||||
void TestCategoricalPredictLeafColumnSplit(Context const* ctx);
|
||||
void TestCategoricalPredictLeaf(bool use_gpu, bool is_column_split);
|
||||
|
||||
void TestIterationRange(Context const* ctx);
|
||||
|
||||
void TestIterationRangeColumnSplit(Context const* ctx);
|
||||
void TestIterationRangeColumnSplit(int world_size, bool use_gpu);
|
||||
|
||||
void TestSparsePrediction(Context const* ctx, float sparsity);
|
||||
|
||||
void TestSparsePredictionColumnSplit(Context const* ctx, float sparsity);
|
||||
void TestSparsePredictionColumnSplit(int world_size, bool use_gpu, float sparsity);
|
||||
|
||||
void TestVectorLeafPrediction(Context const* ctx);
|
||||
} // namespace xgboost
|
||||
|
||||
Reference in New Issue
Block a user