50 using execution_space =
typename Device::execution_space;
53 static constexpr unsigned BIT_SCAN_REVERSE = 1u;
54 static constexpr unsigned MOVE_HINT_BACKWARD = 2u;
56 static constexpr unsigned BIT_SCAN_FORWARD_MOVE_HINT_FORWARD = 0
u;
57 static constexpr unsigned BIT_SCAN_REVERSE_MOVE_HINT_FORWARD =
59 static constexpr unsigned BIT_SCAN_FORWARD_MOVE_HINT_BACKWARD =
61 static constexpr unsigned BIT_SCAN_REVERSE_MOVE_HINT_BACKWARD =
62 BIT_SCAN_REVERSE | MOVE_HINT_BACKWARD;
68 enum :
unsigned { block_mask = block_size - 1u };
70 block_shift = Kokkos::Impl::integral_power_of_two(block_size)
78 m_last_block_mask(0
u),
79 m_blocks(
"Bitset", ((m_size + block_mask) >> block_shift)) {
80 for (
int i = 0, end =
static_cast<int>(m_size & block_mask);
i < end; ++
i) {
81 m_last_block_mask |= 1u <<
i;
85 KOKKOS_DEFAULTED_FUNCTION
88 KOKKOS_DEFAULTED_FUNCTION
91 KOKKOS_DEFAULTED_FUNCTION
94 KOKKOS_DEFAULTED_FUNCTION
97 KOKKOS_DEFAULTED_FUNCTION
102 KOKKOS_FORCEINLINE_FUNCTION
103 unsigned size()
const {
return m_size; }
108 Impl::BitsetCount<Bitset<Device> >
f(*
this);
115 Kokkos::deep_copy(m_blocks, ~0
u);
117 if (m_last_block_mask) {
119 Kokkos::Impl::DeepCopy<typename Device::memory_space, Kokkos::HostSpace>(
120 m_blocks.data() + (m_blocks.
extent(0) - 1u), &m_last_block_mask,
123 "Bitset::set: fence after clearing unused bits copying from "
130 void reset() { Kokkos::deep_copy(m_blocks, 0
u); }
134 void clear() { Kokkos::deep_copy(m_blocks, 0
u); }
138 KOKKOS_FORCEINLINE_FUNCTION
141 unsigned*
block_ptr = &m_blocks[
i >> block_shift];
142 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
151 KOKKOS_FORCEINLINE_FUNCTION
154 unsigned*
block_ptr = &m_blocks[
i >> block_shift];
155 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
164 KOKKOS_FORCEINLINE_FUNCTION
167#ifdef KOKKOS_ENABLE_SYCL
172 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
181 KOKKOS_FORCEINLINE_FUNCTION
188 KOKKOS_INLINE_FUNCTION
191 unsigned scan_direction = BIT_SCAN_FORWARD_MOVE_HINT_FORWARD)
const {
193 (
hint >> block_shift) < m_blocks.
extent(0) ? (
hint >> block_shift) : 0;
195#ifdef KOKKOS_ENABLE_SYCL
202 :
block & m_last_block_mask;
211 KOKKOS_INLINE_FUNCTION
214 unsigned scan_direction = BIT_SCAN_FORWARD_MOVE_HINT_FORWARD)
const {
217#ifdef KOKKOS_ENABLE_SYCL
224 :
~block & m_last_block_mask;
229 KOKKOS_INLINE_FUNCTION
constexpr bool is_allocated()
const {
230 return m_blocks.is_allocated();
234 KOKKOS_FORCEINLINE_FUNCTION
236 unsigned offset,
unsigned block,
237 unsigned scan_direction)
const {
241 result.second = update_hint(block_idx, offset, scan_direction);
244 scan_block((block_idx << block_shift), offset, block, scan_direction);
249 KOKKOS_FORCEINLINE_FUNCTION
250 unsigned scan_block(
unsigned block_start,
int offset,
unsigned block,
251 unsigned scan_direction)
const {
252 offset = !(scan_direction & BIT_SCAN_REVERSE)
254 : (offset + block_mask) & block_mask;
255 block = Impl::rotate_right(block, offset);
256 return (((!(scan_direction & BIT_SCAN_REVERSE)
257 ? Impl::bit_scan_forward(block)
258 : Impl::int_log2(block)) +
264 KOKKOS_FORCEINLINE_FUNCTION
265 unsigned update_hint(
long long block_idx,
unsigned offset,
266 unsigned scan_direction)
const {
267 block_idx += scan_direction & MOVE_HINT_BACKWARD ? -1 : 1;
268 block_idx = block_idx >= 0 ? block_idx : m_blocks.
extent(0) - 1;
270 block_idx < static_cast<long long>(m_blocks.
extent(0)) ? block_idx : 0;
272 return static_cast<unsigned>(block_idx) * block_size + offset;
277 unsigned m_last_block_mask;
278 View<unsigned*, Device, MemoryTraits<RandomAccess> > m_blocks;
281 template <
typename DDevice>
284 template <
typename DDevice>
285 friend class ConstBitset;
287 template <
typename Bitset>
288 friend struct Impl::BitsetCount;
290 template <
typename DstDevice,
typename SrcDevice>
291 friend void deep_copy(Bitset<DstDevice>& dst, Bitset<SrcDevice>
const& src);
293 template <
typename DstDevice,
typename SrcDevice>
294 friend void deep_copy(Bitset<DstDevice>& dst,
295 ConstBitset<SrcDevice>
const& src);