Go to the documentation of this file.
5 #ifndef XGBOOST_COMMON_BITFIELD_H_
6 #define XGBOOST_COMMON_BITFIELD_H_
16 #if defined(__CUDACC__)
17 #include <thrust/copy.h>
18 #include <thrust/device_ptr.h>
19 #include "device_helpers.cuh"
20 #endif // defined(__CUDACC__)
27 #if defined(__CUDACC__)
28 using BitFieldAtomicType =
unsigned long long;
30 __forceinline__ __device__ BitFieldAtomicType AtomicOr(BitFieldAtomicType* address,
31 BitFieldAtomicType val) {
32 BitFieldAtomicType old = *address, assumed;
35 old = atomicCAS(address, assumed, val | assumed);
36 }
while (assumed != old);
41 __forceinline__ __device__ BitFieldAtomicType AtomicAnd(BitFieldAtomicType* address,
42 BitFieldAtomicType val) {
43 BitFieldAtomicType old = *address, assumed;
46 old = atomicCAS(address, assumed, val & assumed);
47 }
while (assumed != old);
51 #endif // defined(__CUDACC__)
58 template <
typename VT,
typename Direction,
bool IsConst = false>
60 using value_type = std::conditional_t<IsConst, VT const, VT>;
74 static_assert(!std::is_signed<VT>::value,
"Must use unsiged type as underlying storage.");
103 #if defined(__CUDA_ARCH__)
105 auto tid = blockIdx.x * blockDim.x + threadIdx.x;
106 size_t min_size = min(bits_.
size(), rhs.bits_.
size());
107 if (tid < min_size) {
108 bits_[tid] |= rhs.bits_[tid];
114 size_t min_size = std::min(bits_.
size(), rhs.bits_.
size());
115 for (
size_t i = 0; i < min_size; ++i) {
116 bits_[i] |= rhs.bits_[i];
120 #endif // #if defined(__CUDA_ARCH__)
122 #if defined(__CUDA_ARCH__)
124 size_t min_size = min(bits_.
size(), rhs.bits_.
size());
125 auto tid = blockIdx.x * blockDim.x + threadIdx.x;
126 if (tid < min_size) {
127 bits_[tid] &= rhs.bits_[tid];
133 size_t min_size = std::min(bits_.
size(), rhs.bits_.
size());
134 for (
size_t i = 0; i < min_size; ++i) {
135 bits_[i] &= rhs.bits_[i];
139 #endif // defined(__CUDA_ARCH__)
141 #if defined(__CUDA_ARCH__)
143 Pos pos_v = Direction::Shift(
ToBitPos(pos));
146 using Type =
typename dh::detail::AtomicDispatcher<
sizeof(
value_type)>::Type;
147 atomicOr(
reinterpret_cast<Type *
>(&value), set_bit);
150 Pos pos_v = Direction::Shift(
ToBitPos(pos));
153 using Type =
typename dh::detail::AtomicDispatcher<
sizeof(
value_type)>::Type;
154 atomicAnd(
reinterpret_cast<Type *
>(&value), clear_bit);
158 Pos pos_v = Direction::Shift(
ToBitPos(pos));
164 Pos pos_v = Direction::Shift(
ToBitPos(pos));
169 #endif // defined(__CUDA_ARCH__)
172 pos_v = Direction::Shift(pos_v);
174 value_type const value = bits_[pos_v.int_pos];
177 return static_cast<bool>(result);
188 inline friend std::ostream &
190 os <<
"Bits " <<
"storage size: " << field.bits_.size() <<
"\n";
192 std::bitset<BitFieldContainer<VT, Direction, IsConst>::kValueSize> bset(field.bits_[i]);
200 template <
typename VT,
bool IsConst = false>
214 template <
typename VT>
217 using Pos =
typename Container::Pos;
234 #endif // XGBOOST_COMMON_BITFIELD_H_
XGBOOST_DEVICE pointer Data() const
Definition: bitfield.h:186
BitFieldContainer()=default
typename Container::value_type value_type
Definition: bitfield.h:204
value_type * pointer
Definition: bitfield.h:62
static XGBOOST_DEVICE Pos ToBitPos(index_type pos)
Definition: bitfield.h:77
static constexpr index_type kOne
Definition: bitfield.h:65
A non-owning type with auxiliary methods defined for manipulating bits.
Definition: bitfield.h:59
index_type bit_pos
Definition: bitfield.h:69
std::size_t index_type
Definition: span.h:427
XGBOOST_DEVICE common::Span< value_type > Bits()
Definition: bitfield.h:94
void Clear(index_type pos)
Definition: bitfield.h:163
BitFieldContainer & operator=(BitFieldContainer const &that)=default
index_type int_pos
Definition: bitfield.h:68
std::conditional_t< IsConst, VT const, VT > value_type
Definition: bitfield.h:60
Definition: bitfield.h:215
void Set(index_type pos)
Definition: bitfield.h:157
BitFieldContainer & operator&=(BitFieldContainer const &rhs)
Definition: bitfield.h:132
typename Container::Pos Pos
Definition: bitfield.h:217
XGBOOST_DEVICE bool Check(Pos pos_v) const
Definition: bitfield.h:171
static XGBOOST_DEVICE Pos Shift(Pos pos)
Definition: bitfield.h:220
typename Container::Pos Pos
Definition: bitfield.h:203
size_t index_type
Definition: bitfield.h:61
Definition: bitfield.h:201
XGBOOST_DEVICE T1 DivRoundUp(const T1 a, const T2 b)
Definition: common.h:86
XGBOOST_DEVICE bool Check(index_type pos) const
Definition: bitfield.h:179
static XGBOOST_DEVICE Pos Shift(Pos pos)
Definition: bitfield.h:206
Definition: bitfield.h:67
#define SPAN_LT(lhs, rhs)
Definition: span.h:124
static XGBOOST_DEVICE size_t ComputeStorageSize(index_type size)
Definition: bitfield.h:100
typename Container::value_type value_type
Definition: bitfield.h:218
static constexpr index_type kValueSize
Definition: bitfield.h:64
XGBOOST_DEVICE BitFieldContainer(BitFieldContainer const &other)
Definition: bitfield.h:90
constexpr XGBOOST_DEVICE index_type size() const __span_noexcept
Definition: span.h:553
constexpr XGBOOST_DEVICE pointer data() const __span_noexcept
Definition: span.h:548
BitFieldContainer & operator|=(BitFieldContainer const &rhs)
Definition: bitfield.h:113
XGBOOST_DEVICE size_t Size() const
Definition: bitfield.h:184
XGBOOST_DEVICE BitFieldContainer(common::Span< value_type > bits)
Definition: bitfield.h:89
XGBOOST_DEVICE common::Span< value_type const > Bits() const
Definition: bitfield.h:95
friend std::ostream & operator<<(std::ostream &os, BitFieldContainer< VT, Direction, IsConst > field)
Definition: bitfield.h:189
#define XGBOOST_DEVICE
Tag function as usable by device.
Definition: base.h:84
namespace of xgboost
Definition: base.h:110