20template<
typename ExprFn,
typename FirstBitSpanT,
typename... BitSpanT>
22 const FirstBitSpanT &first_arg,
23 const BitSpanT &...args)
25 const int64_t size = first_arg.size();
32 BitInt *first_data = first_arg.data();
33 const int64_t first_offset = first_arg.offset();
34 const int64_t full_ints_num = first_arg.full_ints_num();
38 first_data[i] = expr(first_data[i], args.data()[i]...);
41 if (
const int64_t final_bits = first_arg.final_bits_num()) {
42 const BitInt result = expr(first_data[full_ints_num] >> first_offset,
43 (args.data()[full_ints_num] >> args.offset())...);
45 first_data[full_ints_num] = ((result << first_offset) & mask) |
46 (first_data[full_ints_num] & ~mask);
53 const bool result = expr(
BitInt(first_arg[i].test()),
BitInt(args[i].test())...) != 0;
54 first_arg[i].set(result);
66template<
typename ExprFn,
typename FirstBitSpanT,
typename... BitSpanT>
67inline bool any_set_expr(ExprFn &&expr,
const FirstBitSpanT &first_arg,
const BitSpanT &...args)
69 const int64_t size = first_arg.size();
76 const BitInt *first_data = first_arg.data();
77 const int64_t full_ints_num = first_arg.full_ints_num();
81 if (expr(first_data[i], args.data()[i]...) != 0) {
86 if (
const int64_t final_bits = first_arg.final_bits_num()) {
87 const BitInt result = expr(first_data[full_ints_num] >> first_arg.offset(),
88 (args.data()[full_ints_num] >> args.offset())...);
90 if ((result & mask) != 0) {
116template<
typename ExprFn,
typename HandleFn,
typename FirstBitSpanT,
typename... BitSpanT>
119 const FirstBitSpanT &first_arg,
120 const BitSpanT &...args)
122 const int64_t size = first_arg.size();
129 const BitInt *first_data = first_arg.data();
130 const int64_t full_ints_num = first_arg.full_ints_num();
133 BitInt tmp = expr(first_data[int_i], args.data()[int_i]...);
136 static_assert(std::is_same_v<BitInt, uint64_t>);
138 handle(index + offset);
139 tmp &= ~mask_single_bit(index);
143 if (
const int64_t final_bits = first_arg.final_bits_num()) {
144 BitInt tmp = expr(first_data[full_ints_num] >> first_arg.offset(),
145 (args.data()[full_ints_num] >> args.offset())...) &
149 static_assert(std::is_same_v<BitInt, uint64_t>);
151 handle(index + offset);
152 tmp &= ~mask_single_bit(index);
170template<
typename ExprFn,
typename FirstBitSpanT,
typename... BitSpanT>
176template<
typename ExprFn,
typename FirstBitSpanT,
typename... BitSpanT>
177inline bool any_set_expr(ExprFn &&expr,
const FirstBitSpanT &first_arg,
const BitSpanT &...args)
182template<
typename ExprFn,
typename HandleFn,
typename FirstBitSpanT,
typename... BitSpanT>
185 const FirstBitSpanT &first_arg,
186 const BitSpanT &...args)
192template<
typename BitSpanT>
inline void invert(BitSpanT &&data)
197template<
typename FirstBitSpanT,
typename... BitSpanT>
198inline void inplace_or(FirstBitSpanT &first_arg,
const BitSpanT &...args)
203template<
typename FirstBitSpanT,
typename MaskBitSpanT,
typename... BitSpanT>
205 const MaskBitSpanT &mask,
206 const BitSpanT &...args)
209 [](
const BitInt a,
const BitInt mask,
const auto... x) {
return a | ((x | ...) &
mask); },
215template<
typename FirstBitSpanT,
typename... BitSpanT>
216inline void copy_from_or(FirstBitSpanT &first_arg,
const BitSpanT &...args)
219 [](
auto ,
auto... rest) {
return (rest | ...); }, first_arg, args...);
222template<
typename FirstBitSpanT,
typename... BitSpanT>
223inline void inplace_and(FirstBitSpanT &first_arg,
const BitSpanT &...args)
228template<
typename... BitSpanT>
234template<
typename... BitSpanT>
240template<
typename... BitSpanT>
246template<
typename... BitSpanT>
254 return any_set_expr([](
const auto... x) {
return (x & ...); }, args...);
257template<
typename BitSpanT>
inline bool any_bit_set(
const BitSpanT &arg)
264 return any_set_expr([](
const auto... x) {
return ~(x | ...); }, args...);
272template<
typename BitSpanT,
typename Fn>
inline void foreach_1_index(
const BitSpanT &data, Fn &&fn)
277template<
typename BitSpanT,
typename Fn>
inline void foreach_0_index(
const BitSpanT &data, Fn &&fn)
282template<
typename BitSpanT1,
typename BitSpanT2>
285 if (a.size() !=
b.size()) {
291template<
typename BitSpanT1,
typename BitSpanT2,
typename BitSpanT3>
MINLINE unsigned int bitscan_forward_uint64(unsigned long long a)
local_group_size(16, 16) .push_constant(Type b
ccl_device_inline float4 mask(const int4 mask, const float4 a)
bool any_set_expr(ExprFn &&expr, const FirstBitSpanT &first_arg, const BitSpanT &...args)
void foreach_1_index_expr(ExprFn &&expr, HandleFn &&handle, const FirstBitSpanT &first_arg, const BitSpanT &...args)
void mix_into_first_expr(ExprFn &&expr, const FirstBitSpanT &first_arg, const BitSpanT &...args)
void operator|=(MutableBitSpan first_arg, const BitSpanT &...args)
constexpr bool all_bounded_spans
bool has_common_set_bits(const BitSpanT &...args)
void inplace_or_masked(FirstBitSpanT &first_arg, const MaskBitSpanT &mask, const BitSpanT &...args)
T to_best_bit_span(const T &data)
bool has_common_unset_bits(const BitSpanT &...args)
static constexpr int64_t BitToIntIndexShift
void foreach_0_index(const BitSpanT &data, Fn &&fn)
bool any_bit_unset(const BitSpanT &arg)
void mix_into_first_expr(ExprFn &&expr, FirstBitSpanT &&first_arg, const BitSpanT &...args)
void operator&=(MutableBitSpan first_arg, const BitSpanT &...args)
bool any_bit_set(const BitSpanT &arg)
void inplace_or(FirstBitSpanT &first_arg, const BitSpanT &...args)
void inplace_and(FirstBitSpanT &first_arg, const BitSpanT &...args)
bool any_set_expr(ExprFn &&expr, const FirstBitSpanT &first_arg, const BitSpanT &...args)
void copy_from_or(FirstBitSpanT &first_arg, const BitSpanT &...args)
BitInt mask_first_n_bits(const int64_t n)
void foreach_1_index(const BitSpanT &data, Fn &&fn)
bool spans_equal(const BitSpanT1 &a, const BitSpanT2 &b)
BitInt mask_range_bits(const int64_t start, const int64_t size)
void invert(BitSpanT &&data)
void foreach_1_index_expr(ExprFn &&expr, HandleFn &&handle, const FirstBitSpanT &first_arg, const BitSpanT &...args)
bool spans_equal_masked(const BitSpanT1 &a, const BitSpanT2 &b, const BitSpanT3 &mask)