Remove omp_get_max_threads (#7608)

This is the one last PR for removing omp global variable.

* Add context object to the `DMatrix`.  This bridges `DMatrix` with https://github.com/dmlc/xgboost/issues/7308 .
* Require context to be available at the construction time of booster.
* Add `n_threads` support for R csc DMatrix constructor.
* Remove `omp_get_max_threads` in R glue code.
* Remove threading utilities that rely on omp global variable.
This commit is contained in:
Jiaming Yuan
2022-01-28 16:09:22 +08:00
committed by GitHub
parent 028bdc1740
commit 81210420c6
31 changed files with 195 additions and 211 deletions

View File

@@ -14,15 +14,7 @@
namespace xgboost {
namespace common {
size_t GetNThreads() {
size_t nthreads;
#pragma omp parallel
{
#pragma omp master
nthreads = omp_get_num_threads();
}
return nthreads;
}
size_t GetNThreads() { return common::OmpGetNumThreads(0); }
template <typename GradientSumT>
void ParallelGHistBuilderReset() {

View File

@@ -590,10 +590,8 @@ TEST(Json, DISABLED_RoundTripExhaustive) {
}
};
int64_t int32_max = static_cast<int64_t>(std::numeric_limits<uint32_t>::max());
#pragma omp parallel for schedule(static)
for (int64_t i = 0; i <= int32_max; ++i) {
test(static_cast<uint32_t>(i));
}
GenericParameter ctx;
common::ParallelFor(int32_max, ctx.Threads(), [&](auto i) { test(static_cast<uint32_t>(i)); });
}
TEST(Json, TypedArray) {

View File

@@ -88,22 +88,5 @@ TEST(ParallelFor2dNonUniform, Test) {
omp_set_num_threads(old);
}
#if defined(_OPENMP)
TEST(OmpSetNumThreads, Basic) {
auto nthreads = 2;
auto orgi = OmpSetNumThreads(&nthreads);
ASSERT_EQ(omp_get_max_threads(), 2);
nthreads = 0;
OmpSetNumThreads(&nthreads);
ASSERT_EQ(omp_get_max_threads(), omp_get_num_procs());
nthreads = 1;
OmpSetNumThreads(&nthreads);
nthreads = 0;
OmpSetNumThreads(&nthreads);
ASSERT_EQ(omp_get_max_threads(), omp_get_num_procs());
omp_set_num_threads(orgi);
}
#endif // defined(_OPENMP)
} // namespace common
} // namespace xgboost

View File

@@ -506,8 +506,9 @@ std::unique_ptr<DMatrix> CreateSparsePageDMatrixWithRC(
return dmat;
}
gbm::GBTreeModel CreateTestModel(LearnerModelParam const* param, size_t n_classes) {
gbm::GBTreeModel model(param);
gbm::GBTreeModel CreateTestModel(LearnerModelParam const* param, GenericParameter const* ctx,
size_t n_classes) {
gbm::GBTreeModel model(param, ctx);
for (size_t i = 0; i < n_classes; ++i) {
std::vector<std::unique_ptr<RegTree>> trees;

View File

@@ -357,7 +357,8 @@ std::unique_ptr<DMatrix> CreateSparsePageDMatrixWithRC(
size_t n_rows, size_t n_cols, size_t page_size, bool deterministic,
const dmlc::TemporaryDirectory& tempdir = dmlc::TemporaryDirectory());
gbm::GBTreeModel CreateTestModel(LearnerModelParam const* param, size_t n_classes = 1);
gbm::GBTreeModel CreateTestModel(LearnerModelParam const* param, GenericParameter const* ctx,
size_t n_classes = 1);
std::unique_ptr<GradientBooster> CreateTrainedGBM(
std::string name, Args kwargs, size_t kRows, size_t kCols,

View File

@@ -25,7 +25,9 @@ TEST(CpuPredictor, Basic) {
param.base_score = 0.0;
param.num_output_group = 1;
gbm::GBTreeModel model = CreateTestModel(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx);
auto dmat = RandomDataGenerator(kRows, kCols, 0).GenerateDMatrix();
@@ -106,7 +108,9 @@ TEST(CpuPredictor, ExternalMemory) {
param.num_feature = dmat->Info().num_col_;
param.num_output_group = 1;
gbm::GBTreeModel model = CreateTestModel(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx);
// Test predict batch
PredictionCacheEntry out_predictions;

View File

@@ -38,7 +38,9 @@ TEST(GPUPredictor, Basic) {
param.num_output_group = 1;
param.base_score = 0.5;
gbm::GBTreeModel model = CreateTestModel(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx);
// Test predict batch
PredictionCacheEntry gpu_out_predictions;
@@ -100,7 +102,9 @@ TEST(GPUPredictor, ExternalMemoryTest) {
param.num_output_group = n_classes;
param.base_score = 0.5;
gbm::GBTreeModel model = CreateTestModel(&param, n_classes);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx, n_classes);
std::vector<std::unique_ptr<DMatrix>> dmats;
dmats.push_back(CreateSparsePageDMatrix(400));
@@ -167,11 +171,17 @@ TEST(GpuPredictor, LesserFeatures) {
// Very basic test of empty model
TEST(GPUPredictor, ShapStump) {
cudaSetDevice(0);
LearnerModelParam param;
param.num_feature = 1;
param.num_output_group = 1;
param.base_score = 0.5;
gbm::GBTreeModel model(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model(&param, &ctx);
std::vector<std::unique_ptr<RegTree>> trees;
trees.push_back(std::unique_ptr<RegTree>(new RegTree));
model.CommitModel(std::move(trees), 0);
@@ -197,7 +207,12 @@ TEST(GPUPredictor, Shap) {
param.num_feature = 1;
param.num_output_group = 1;
param.base_score = 0.5;
gbm::GBTreeModel model(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model(&param, &ctx);
std::vector<std::unique_ptr<RegTree>> trees;
trees.push_back(std::unique_ptr<RegTree>(new RegTree));
trees[0]->ExpandNode(0, 0, 0.5, true, 1.0, -1.0, 1.0, 0.0, 5.0, 2.0, 3.0);
@@ -249,7 +264,9 @@ TEST(GPUPredictor, PredictLeafBasic) {
param.base_score = 0.0;
param.num_output_group = 1;
gbm::GBTreeModel model = CreateTestModel(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx);
HostDeviceVector<float> leaf_out_predictions;
gpu_predictor->PredictLeaf(dmat.get(), &leaf_out_predictions, model);

View File

@@ -214,10 +214,11 @@ void TestCategoricalPrediction(std::string name) {
float left_weight = 1.3f;
float right_weight = 1.7f;
gbm::GBTreeModel model(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model(&param, &ctx);
GBTreeModelForTest(&model, split_ind, split_cat, left_weight, right_weight);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{{"gpu_id", "0"}});
std::unique_ptr<Predictor> predictor{Predictor::Create(name.c_str(), &ctx)};
@@ -257,13 +258,14 @@ void TestCategoricalPredictLeaf(StringView name) {
float left_weight = 1.3f;
float right_weight = 1.7f;
gbm::GBTreeModel model(&param);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model(&param, &ctx);
GBTreeModelForTest(&model, split_ind, split_cat, left_weight, right_weight);
GenericParameter runtime;
runtime.gpu_id = 0;
std::unique_ptr<Predictor> predictor{
Predictor::Create(name.c_str(), &runtime)};
ctx.gpu_id = 0;
std::unique_ptr<Predictor> predictor{Predictor::Create(name.c_str(), &ctx)};
std::vector<float> row(kCols);
row[split_ind] = split_cat;

View File

@@ -23,7 +23,9 @@ void TestPredictionFromGradientIndex(std::string name, size_t rows, size_t cols,
std::unique_ptr<Predictor>(Predictor::Create(name, &lparam));
predictor->Configure({});
gbm::GBTreeModel model = CreateTestModel(&param, kClasses);
GenericParameter ctx;
ctx.UpdateAllowUnknown(Args{});
gbm::GBTreeModel model = CreateTestModel(&param, &ctx, kClasses);
{
auto p_precise = RandomDataGenerator(rows, cols, 0).GenerateDMatrix();

View File

@@ -1,5 +1,5 @@
/*!
* Copyright 2017-2020 XGBoost contributors
* Copyright 2017-2022 by XGBoost contributors
*/
#include <gtest/gtest.h>
#include <vector>
@@ -284,27 +284,27 @@ TEST(Learner, GPUConfiguration) {
learner->SetParams({Arg{"booster", "gblinear"},
Arg{"updater", "gpu_coord_descent"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, 0);
ASSERT_EQ(learner->Ctx()->gpu_id, 0);
}
{
std::unique_ptr<Learner> learner {Learner::Create(mat)};
learner->SetParams({Arg{"tree_method", "gpu_hist"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, 0);
ASSERT_EQ(learner->Ctx()->gpu_id, 0);
}
{
std::unique_ptr<Learner> learner {Learner::Create(mat)};
learner->SetParams({Arg{"tree_method", "gpu_hist"},
Arg{"gpu_id", "-1"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, 0);
ASSERT_EQ(learner->Ctx()->gpu_id, 0);
}
{
// with CPU algorithm
std::unique_ptr<Learner> learner {Learner::Create(mat)};
learner->SetParams({Arg{"tree_method", "hist"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, -1);
ASSERT_EQ(learner->Ctx()->gpu_id, -1);
}
{
// with CPU algorithm, but `gpu_id` takes priority
@@ -312,7 +312,7 @@ TEST(Learner, GPUConfiguration) {
learner->SetParams({Arg{"tree_method", "hist"},
Arg{"gpu_id", "0"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, 0);
ASSERT_EQ(learner->Ctx()->gpu_id, 0);
}
{
// With CPU algorithm but GPU Predictor, this is to simulate when
@@ -322,7 +322,7 @@ TEST(Learner, GPUConfiguration) {
learner->SetParams({Arg{"tree_method", "hist"},
Arg{"predictor", "gpu_predictor"}});
learner->UpdateOneIter(0, p_dmat);
ASSERT_EQ(learner->GetGenericParameter().gpu_id, 0);
ASSERT_EQ(learner->Ctx()->gpu_id, 0);
}
}
#endif // defined(XGBOOST_USE_CUDA)