bit.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2022, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cassert>
20 #include <cuda/std/climits>
21 #include <cudf/types.hpp>
22 
28 namespace cudf {
29 namespace detail {
30 // @cond
31 // Work around a bug in NVRTC that fails to compile assert() in constexpr
32 // functions (fixed after CUDA 11.0)
33 #if defined __GNUC__
34 #define LIKELY(EXPR) __builtin_expect(!!(EXPR), 1)
35 #else
36 #define LIKELY(EXPR) (!!(EXPR))
37 #endif
38 
39 #ifdef NDEBUG
40 #define constexpr_assert(CHECK) static_cast<void>(0)
41 #else
42 #define constexpr_assert(CHECK) (LIKELY(CHECK) ? void(0) : [] { assert(!#CHECK); }())
43 #endif
44 // @endcond
45 
52 template <typename T>
53 constexpr CUDF_HOST_DEVICE inline std::size_t size_in_bits()
54 {
55  static_assert(CHAR_BIT == 8, "Size of a byte must be 8 bits.");
56  return sizeof(T) * CHAR_BIT;
57 }
58 } // namespace detail
59 
72 constexpr CUDF_HOST_DEVICE inline size_type word_index(size_type bit_index)
73 {
74  return bit_index / detail::size_in_bits<bitmask_type>();
75 }
76 
84 {
85  return bit_index % detail::size_in_bits<bitmask_type>();
86 }
87 
97 CUDF_HOST_DEVICE inline void set_bit_unsafe(bitmask_type* bitmask, size_type bit_index)
98 {
99  assert(nullptr != bitmask);
100  bitmask[word_index(bit_index)] |= (bitmask_type{1} << intra_word_index(bit_index));
101 }
102 
112 CUDF_HOST_DEVICE inline void clear_bit_unsafe(bitmask_type* bitmask, size_type bit_index)
113 {
114  assert(nullptr != bitmask);
115  bitmask[word_index(bit_index)] &= ~(bitmask_type{1} << intra_word_index(bit_index));
116 }
117 
126 CUDF_HOST_DEVICE inline bool bit_is_set(bitmask_type const* bitmask, size_type bit_index)
127 {
128  assert(nullptr != bitmask);
129  return bitmask[word_index(bit_index)] & (bitmask_type{1} << intra_word_index(bit_index));
130 }
131 
142 CUDF_HOST_DEVICE inline bool bit_value_or(bitmask_type const* bitmask,
143  size_type bit_index,
144  bool default_value)
145 {
146  return bitmask != nullptr ? bit_is_set(bitmask, bit_index) : default_value;
147 }
148 
158 {
159  constexpr_assert(0 <= n && n < static_cast<size_type>(detail::size_in_bits<bitmask_type>()));
160  return ((bitmask_type{1} << n) - 1);
161 }
162 
172 {
173  constexpr size_type word_size{detail::size_in_bits<bitmask_type>()};
174  constexpr_assert(0 <= n && n < word_size);
175  return ~((bitmask_type{1} << (word_size - n)) - 1);
176 }
177 
178 #ifdef __CUDACC__
179 
193 __device__ inline void set_bit(bitmask_type* bitmask, size_type bit_index)
194 {
195  assert(nullptr != bitmask);
196  atomicOr(&bitmask[word_index(bit_index)], (bitmask_type{1} << intra_word_index(bit_index)));
197 }
198 
211 __device__ inline void clear_bit(bitmask_type* bitmask, size_type bit_index)
212 {
213  assert(nullptr != bitmask);
214  atomicAnd(&bitmask[word_index(bit_index)], ~(bitmask_type{1} << intra_word_index(bit_index)));
215 }
216 #endif // end of group
218 } // namespace cudf
constexpr CUDF_HOST_DEVICE std::size_t size_in_bits()
Returns the number of bits the given type can hold.
Definition: bit.hpp:53
CUDF_HOST_DEVICE void set_bit_unsafe(bitmask_type *bitmask, size_type bit_index)
Sets the specified bit to 1
Definition: bit.hpp:97
constexpr CUDF_HOST_DEVICE size_type intra_word_index(size_type bit_index)
Returns the position within a word of the specified bit.
Definition: bit.hpp:83
constexpr CUDF_HOST_DEVICE size_type word_index(size_type bit_index)
Returns the index of the word containing the specified bit.
Definition: bit.hpp:72
constexpr CUDF_HOST_DEVICE bitmask_type set_least_significant_bits(size_type n)
Returns a bitmask word with the n least significant bits set.
Definition: bit.hpp:157
CUDF_HOST_DEVICE bool bit_value_or(bitmask_type const *bitmask, size_type bit_index, bool default_value)
optional-like interface to check if a specified bit of a bitmask is set.
Definition: bit.hpp:142
CUDF_HOST_DEVICE bool bit_is_set(bitmask_type const *bitmask, size_type bit_index)
Indicates whether the specified bit is set to 1
Definition: bit.hpp:126
constexpr CUDF_HOST_DEVICE bitmask_type set_most_significant_bits(size_type n)
Returns a bitmask word with the n most significant bits set.
Definition: bit.hpp:171
CUDF_HOST_DEVICE void clear_bit_unsafe(bitmask_type *bitmask, size_type bit_index)
Sets the specified bit to 0
Definition: bit.hpp:112
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:93
uint32_t bitmask_type
Bitmask type stored as 32-bit unsigned integer.
Definition: types.hpp:94
cuDF interfaces
Definition: aggregation.hpp:34
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:32