Skip to content

Commit 0eea880

Browse files
authored
Use philox for faster sampling on GPU. (#12223)
1 parent c78a218 commit 0eea880

4 files changed

Lines changed: 35 additions & 8 deletions

File tree

src/common/random.cu

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "algorithm.cuh" // for ArgSort
99
#include "cuda_context.cuh" // for CUDAContext
1010
#include "device_helpers.cuh"
11+
#include "random.cuh" // for DefaultRng, UniformRealDistribution
1112
#include "random.h"
1213
#include "xgboost/base.h" // for bst_feature_t
1314
#include "xgboost/context.h" // for Context
@@ -30,10 +31,9 @@ void WeightedSamplingWithoutReplacement(Context const *ctx, common::Span<bst_fea
3031
constexpr auto kEps = kRtEps; // avoid CUDA compilation error
3132
thrust::for_each_n(cuctx->CTP(), thrust::make_counting_iterator(0ul), array.size(),
3233
[=] XGBOOST_DEVICE(std::size_t i) {
33-
thrust::default_random_engine rng;
34-
rng.seed(seed);
34+
DefaultRng rng{seed};
3535
rng.discard(i);
36-
thrust::uniform_real_distribution<float> dist;
36+
UniformRealDistribution<float> dist;
3737

3838
auto w = std::max(weights[i], kEps);
3939
auto u = dist(rng);

src/common/random.cuh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2026, XGBoost Contributors
3+
*/
4+
#pragma once
5+
6+
#if __has_include(<cuda/std/random>)
7+
#define xgboost_HAS_CUDA_STD_RANDOM 1
8+
#include <cuda/std/random>
9+
#else
10+
#include <thrust/random.h>
11+
#endif
12+
13+
namespace xgboost::common::cuda_impl {
14+
#if defined(xgboost_HAS_CUDA_STD_RANDOM)
15+
using DefaultRng = cuda::std::philox4x64;
16+
template <typename T>
17+
using UniformRealDistribution = cuda::std::uniform_real_distribution<T>;
18+
#else
19+
using DefaultRng = thrust::default_random_engine;
20+
template <typename T>
21+
using UniformRealDistribution = thrust::uniform_real_distribution<T>;
22+
#endif
23+
} // namespace xgboost::common::cuda_impl
24+
25+
#if defined(xgboost_HAS_CUDA_STD_RANDOM)
26+
#undef xgboost_HAS_CUDA_STD_RANDOM
27+
#endif

src/tree/gpu_hist/sampler.cu

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
#include "../../common/cuda_context.cuh" // for CUDAContext
2727
#include "../../common/device_helpers.cuh" // for MakeTransformIterator
28-
#include "../../common/random.h"
29-
#include "../hist/sampler.h" // for kDefaultMvsLambda
28+
#include "../../common/random.cuh" // for DefaultRng, UniformRealDistribution
29+
#include "../hist/sampler.h" // for kDefaultMvsLambda
3030
#include "../param.h"
3131
#include "quantiser.cuh" // for GradientQuantiser
3232
#include "sampler.cuh"
@@ -38,8 +38,8 @@ class RandomWeight {
3838
explicit RandomWeight(std::size_t seed) : seed_(seed) {}
3939

4040
XGBOOST_DEVICE float operator()(std::size_t i) const {
41-
thrust::default_random_engine rng(seed_);
42-
thrust::uniform_real_distribution<float> dist;
41+
common::cuda_impl::DefaultRng rng{seed_};
42+
common::cuda_impl::UniformRealDistribution<float> dist;
4343
rng.discard(i);
4444
return dist(rng);
4545
}

tests/cpp/tree/test_gpu_hist.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ TEST(GpuHist, UniformSampling) {
7575
auto preds_h = preds.ConstHostVector();
7676
auto preds_sampling_h = preds_sampling.ConstHostVector();
7777
for (size_t i = 0; i < kRows; i++) {
78-
EXPECT_NEAR(preds_h[i], preds_sampling_h[i], 1e-8);
78+
EXPECT_NEAR(preds_h[i], preds_sampling_h[i], 1e-3);
7979
}
8080
}
8181

0 commit comments

Comments
 (0)