Use quantised gradients in gpu_hist histograms (#8246)
This commit is contained in:
@@ -196,72 +196,4 @@ TEST(DeviceHelpers, ArgSort) {
|
||||
thrust::greater<size_t>{}));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Atomic add as type cast for test.
|
||||
XGBOOST_DEV_INLINE int64_t atomicAdd(int64_t *dst, int64_t src) { // NOLINT
|
||||
uint64_t* u_dst = reinterpret_cast<uint64_t*>(dst);
|
||||
uint64_t u_src = *reinterpret_cast<uint64_t*>(&src);
|
||||
uint64_t ret = ::atomicAdd(u_dst, u_src);
|
||||
return *reinterpret_cast<int64_t*>(&ret);
|
||||
}
|
||||
}
|
||||
|
||||
void TestAtomicAdd() {
|
||||
size_t n_elements = 1024;
|
||||
dh::device_vector<int64_t> result_a(1, 0);
|
||||
auto d_result_a = result_a.data().get();
|
||||
|
||||
dh::device_vector<int64_t> result_b(1, 0);
|
||||
auto d_result_b = result_b.data().get();
|
||||
|
||||
/**
|
||||
* Test for simple inputs
|
||||
*/
|
||||
std::vector<int64_t> h_inputs(n_elements);
|
||||
for (size_t i = 0; i < h_inputs.size(); ++i) {
|
||||
h_inputs[i] = (i % 2 == 0) ? i : -i;
|
||||
}
|
||||
dh::device_vector<int64_t> inputs(h_inputs);
|
||||
auto d_inputs = inputs.data().get();
|
||||
|
||||
dh::LaunchN(n_elements, [=] __device__(size_t i) {
|
||||
dh::AtomicAdd64As32(d_result_a, d_inputs[i]);
|
||||
atomicAdd(d_result_b, d_inputs[i]);
|
||||
});
|
||||
ASSERT_EQ(result_a[0], result_b[0]);
|
||||
|
||||
/**
|
||||
* Test for positive values that don't fit into 32 bit integer.
|
||||
*/
|
||||
thrust::fill(inputs.begin(), inputs.end(),
|
||||
(std::numeric_limits<uint32_t>::max() / 2));
|
||||
thrust::fill(result_a.begin(), result_a.end(), 0);
|
||||
thrust::fill(result_b.begin(), result_b.end(), 0);
|
||||
dh::LaunchN(n_elements, [=] __device__(size_t i) {
|
||||
dh::AtomicAdd64As32(d_result_a, d_inputs[i]);
|
||||
atomicAdd(d_result_b, d_inputs[i]);
|
||||
});
|
||||
ASSERT_EQ(result_a[0], result_b[0]);
|
||||
ASSERT_GT(result_a[0], std::numeric_limits<uint32_t>::max());
|
||||
CHECK_EQ(thrust::reduce(inputs.begin(), inputs.end(), int64_t(0)), result_a[0]);
|
||||
|
||||
/**
|
||||
* Test for negative values that don't fit into 32 bit integer.
|
||||
*/
|
||||
thrust::fill(inputs.begin(), inputs.end(),
|
||||
(std::numeric_limits<int32_t>::min() / 2));
|
||||
thrust::fill(result_a.begin(), result_a.end(), 0);
|
||||
thrust::fill(result_b.begin(), result_b.end(), 0);
|
||||
dh::LaunchN(n_elements, [=] __device__(size_t i) {
|
||||
dh::AtomicAdd64As32(d_result_a, d_inputs[i]);
|
||||
atomicAdd(d_result_b, d_inputs[i]);
|
||||
});
|
||||
ASSERT_EQ(result_a[0], result_b[0]);
|
||||
ASSERT_LT(result_a[0], std::numeric_limits<int32_t>::min());
|
||||
CHECK_EQ(thrust::reduce(inputs.begin(), inputs.end(), int64_t(0)), result_a[0]);
|
||||
}
|
||||
|
||||
TEST(AtomicAdd, Int64) {
|
||||
TestAtomicAdd();
|
||||
}
|
||||
} // namespace xgboost
|
||||
|
||||
Reference in New Issue
Block a user