76 using execution_space = Device;
79 enum { BIT_SCAN_REVERSE = 1u };
80 enum { MOVE_HINT_BACKWARD = 2u };
83 BIT_SCAN_FORWARD_MOVE_HINT_FORWARD = 0
u,
84 BIT_SCAN_REVERSE_MOVE_HINT_FORWARD = BIT_SCAN_REVERSE,
85 BIT_SCAN_FORWARD_MOVE_HINT_BACKWARD = MOVE_HINT_BACKWARD,
86 BIT_SCAN_REVERSE_MOVE_HINT_BACKWARD = BIT_SCAN_REVERSE | MOVE_HINT_BACKWARD
91 enum { block_mask = block_size - 1u };
92 enum { block_shift = Kokkos::Impl::integral_power_of_two(block_size) };
99 m_last_block_mask(0
u),
100 m_blocks(
"Bitset", ((m_size + block_mask) >> block_shift)) {
101 for (
int i = 0, end =
static_cast<int>(m_size & block_mask);
i < end; ++
i) {
102 m_last_block_mask |= 1u <<
i;
106 KOKKOS_DEFAULTED_FUNCTION
109 KOKKOS_DEFAULTED_FUNCTION
112 KOKKOS_DEFAULTED_FUNCTION
115 KOKKOS_DEFAULTED_FUNCTION
118 KOKKOS_DEFAULTED_FUNCTION
123 KOKKOS_FORCEINLINE_FUNCTION
124 unsigned size()
const {
return m_size; }
129 Impl::BitsetCount<Bitset<Device> >
f(*
this);
136 Kokkos::deep_copy(m_blocks, ~0
u);
138 if (m_last_block_mask) {
141 Kokkos::Impl::DeepCopy<
typename execution_space::memory_space,
144 &m_last_block_mask,
sizeof(
unsigned));
150 void reset() { Kokkos::deep_copy(m_blocks, 0
u); }
154 void clear() { Kokkos::deep_copy(m_blocks, 0
u); }
158 KOKKOS_FORCEINLINE_FUNCTION
161 unsigned*
block_ptr = &m_blocks[
i >> block_shift];
162 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
171 KOKKOS_FORCEINLINE_FUNCTION
174 unsigned*
block_ptr = &m_blocks[
i >> block_shift];
175 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
184 KOKKOS_FORCEINLINE_FUNCTION
188 const unsigned mask = 1u <<
static_cast<int>(
i & block_mask);
197 KOKKOS_FORCEINLINE_FUNCTION
204 KOKKOS_INLINE_FUNCTION
207 unsigned scan_direction = BIT_SCAN_FORWARD_MOVE_HINT_FORWARD)
const {
209 (
hint >> block_shift) < m_blocks.
extent(0) ? (
hint >> block_shift) : 0;
214 :
block & m_last_block_mask;
223 KOKKOS_INLINE_FUNCTION
226 unsigned scan_direction = BIT_SCAN_FORWARD_MOVE_HINT_FORWARD)
const {
232 :
~block & m_last_block_mask;
237 KOKKOS_INLINE_FUNCTION
constexpr bool is_allocated()
const {
238 return m_blocks.is_allocated();
242 KOKKOS_FORCEINLINE_FUNCTION
244 unsigned offset,
unsigned block,
245 unsigned scan_direction)
const {
249 result.second = update_hint(block_idx, offset, scan_direction);
252 scan_block((block_idx << block_shift), offset, block, scan_direction);
257 KOKKOS_FORCEINLINE_FUNCTION
258 unsigned scan_block(
unsigned block_start,
int offset,
unsigned block,
259 unsigned scan_direction)
const {
260 offset = !(scan_direction & BIT_SCAN_REVERSE)
262 : (offset + block_mask) & block_mask;
263 block = Impl::rotate_right(block, offset);
264 return (((!(scan_direction & BIT_SCAN_REVERSE)
265 ? Impl::bit_scan_forward(block)
266 : ::Kokkos::log2(block)) +
272 KOKKOS_FORCEINLINE_FUNCTION
273 unsigned update_hint(
long long block_idx,
unsigned offset,
274 unsigned scan_direction)
const {
275 block_idx += scan_direction & MOVE_HINT_BACKWARD ? -1 : 1;
276 block_idx = block_idx >= 0 ? block_idx : m_blocks.
extent(0) - 1;
278 block_idx < static_cast<long long>(m_blocks.
extent(0)) ? block_idx : 0;
280 return static_cast<unsigned>(block_idx) * block_size + offset;
285 unsigned m_last_block_mask;
286 View<unsigned*, execution_space, MemoryTraits<RandomAccess> > m_blocks;
289 template <
typename DDevice>
292 template <
typename DDevice>
293 friend class ConstBitset;
295 template <
typename Bitset>
296 friend struct Impl::BitsetCount;
298 template <
typename DstDevice,
typename SrcDevice>
299 friend void deep_copy(Bitset<DstDevice>& dst, Bitset<SrcDevice>
const& src);
301 template <
typename DstDevice,
typename SrcDevice>
302 friend void deep_copy(Bitset<DstDevice>& dst,
303 ConstBitset<SrcDevice>
const& src);