File: test_bitfield.cu

package info (click to toggle)
xgboost 3.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 13,796 kB
  • sloc: cpp: 67,502; python: 35,503; java: 4,676; ansic: 1,426; sh: 1,320; xml: 1,197; makefile: 204; javascript: 19
file content (84 lines) | stat: -rw-r--r-- 2,648 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
 * Copyright 2019-2023, XGBoost contributors
 */
#include <gtest/gtest.h>
#include <thrust/copy.h>
#include <thrust/device_vector.h>
#include <vector>
#include "../../../src/common/bitfield.h"
#include "../../../src/common/device_helpers.cuh"

namespace xgboost {

__global__ void TestSetKernel(LBitField64 bits) {
  auto tid = threadIdx.x + blockIdx.x * blockDim.x;
  if (tid < bits.Capacity()) {
    bits.Set(tid);
  }
}

TEST(BitField, StorageSize) {
  size_t constexpr kElements { 16 };
  size_t size = LBitField64::ComputeStorageSize(kElements);
  ASSERT_EQ(1, size);
  size = RBitField8::ComputeStorageSize(4);
  ASSERT_EQ(1, size);
  size = RBitField8::ComputeStorageSize(kElements);
  ASSERT_EQ(2, size);
}

TEST(BitField, GPUSet) {
  dh::device_vector<LBitField64::value_type> storage;
  uint32_t constexpr kBits = 128;
  storage.resize(128);
  auto bits = LBitField64(dh::ToSpan(storage));
  TestSetKernel<<<1, kBits>>>(bits);

  std::vector<LBitField64::value_type> h_storage(storage.size());
  thrust::copy(storage.begin(), storage.end(), h_storage.begin());
  LBitField64 outputs{
      common::Span<LBitField64::value_type>{h_storage.data(), h_storage.data() + h_storage.size()}};
  for (size_t i = 0; i < kBits; ++i) {
    ASSERT_TRUE(outputs.Check(i));
  }
}

namespace {
template <bool is_and, typename Op>
void TestGPULogic(Op op) {
  uint32_t constexpr kBits = 128;
  dh::device_vector<LBitField64::value_type> lhs_storage(kBits);
  dh::device_vector<LBitField64::value_type> rhs_storage(kBits);
  auto lhs = LBitField64(dh::ToSpan(lhs_storage));
  auto rhs = LBitField64(dh::ToSpan(rhs_storage));
  thrust::fill(lhs_storage.begin(), lhs_storage.end(), 0UL);
  thrust::fill(rhs_storage.begin(), rhs_storage.end(), ~static_cast<LBitField64::value_type>(0UL));
  dh::LaunchN(kBits, [=] __device__(auto) mutable { op(lhs, rhs); });

  std::vector<LBitField64::value_type> h_storage(lhs_storage.size());
  thrust::copy(lhs_storage.begin(), lhs_storage.end(), h_storage.begin());
  LBitField64 outputs{{h_storage.data(), h_storage.data() + h_storage.size()}};
  if (is_and) {
    for (size_t i = 0; i < kBits; ++i) {
      ASSERT_FALSE(outputs.Check(i));
    }
  } else {
    for (size_t i = 0; i < kBits; ++i) {
      ASSERT_TRUE(outputs.Check(i));
    }
  }
}

void TestGPUAnd() {
  TestGPULogic<true>([] XGBOOST_DEVICE(LBitField64 & lhs, LBitField64 const& rhs) { lhs &= rhs; });
}

void TestGPUOr() {
  TestGPULogic<false>([] XGBOOST_DEVICE(LBitField64 & lhs, LBitField64 const& rhs) { lhs |= rhs; });
}
}  // namespace

TEST(BitField, GPUAnd) { TestGPUAnd(); }

TEST(BitField, GPUOr) { TestGPUOr(); }
}  // namespace xgboost