5#include "testing/testing.h"
22TEST(index_mask, IndicesToMask)
26 5, 100, 16383, 16384, 16385, 20000, 20001, 50000, 50001, 50002, 100000, 101000};
35TEST(index_mask, FromBitsManual)
39 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'1111'0010'0000;
50TEST(index_mask, FromBitsSimple)
59 EXPECT_FALSE(mask.contains(0));
60 EXPECT_FALSE(mask.contains(100));
63TEST(index_mask, FromBitsWithUniverse)
81TEST(index_mask, FromBitsSparse)
89 bit_vec[10'000].set();
90 bit_vec[10'002].set();
91 bit_vec[50'000].set();
92 bit_vec[70'000].set();
93 bit_vec[70'002].set();
94 bit_vec[70'004].set();
95 bit_vec[70'005].set();
114TEST(index_mask, FromBoolsSparse)
122 bools[10'000] =
true;
123 bools[10'002] =
true;
124 bools[50'000] =
true;
125 bools[70'000] =
true;
126 bools[70'002] =
true;
127 bools[70'004] =
true;
128 bools[70'005] =
true;
147TEST(index_mask, FromBitsAlternating)
167static BitVector<> build_bits_with_uniform_distribution(
const int bits_num,
168 const int set_bits_num,
171 if (set_bits_num > bits_num / 2) {
172 BitVector bit_vec = build_bits_with_uniform_distribution(bits_num, bits_num - set_bits_num);
179 while (counter < set_bits_num) {
180 const int i = rng.get_int32(
int(bits_num));
190static void benchmark_uniform_bit_distribution(
const int bits_num,
191 const int set_bits_num,
192 const int iterations)
194 const bool machine_readable =
true;
195 BitVector bit_vec = build_bits_with_uniform_distribution(bits_num, set_bits_num);
196 std::locale loc(
"en_US.UTF-8");
198 for ([[maybe_unused]]
const int64_t i : IndexRange(iterations)) {
199 IndexMaskMemory memory;
206 min_duration = std::min(min_duration, duration);
209 const double ms =
double(min_duration.count()) / 1'000'000.0;
210 if (machine_readable) {
211 std::cout << fmt::format(
"{},{:.6}\n", set_bits_num, ms);
214 std::cout << fmt::format(loc,
"{:15L} / {:L}: {:.4} ms\n", set_bits_num, bits_num, ms);
218TEST(index_mask, FromBitsBenchmark)
220 const int size = 100'000'000;
221 const int iterations = 5;
222 Vector<int> set_bit_nums;
223 set_bit_nums.append(0);
225 while (current < size / 2) {
226 set_bit_nums.append(current);
227 set_bit_nums.append(size - current);
228 current =
int(current * 1.3);
230 set_bit_nums.append(size);
231 std::sort(set_bit_nums.begin(), set_bit_nums.end());
233 for (
const int set_bit_num : set_bit_nums) {
234 benchmark_uniform_bit_distribution(size, set_bit_num, iterations);
245 const int size = rng.
get_int32(100'000) + 1;
246 const int set_bits = rng.
get_int32(size);
262 index = (index + 1) % size;
274 IndexRange(1), slice_half_size, 2, slice_half_size, memory),
283 universe,
BitSpan(inverted_bits).slice(slice), memory);
294 bit_vec[200].reset();
295 bit_vec[201].reset();
296 bit_vec[500].reset();
297 bit_vec[502].reset();
298 bit_vec[504].reset();
299 bit_vec[506].reset();
304 EXPECT_FALSE(mask.contains(5));
305 EXPECT_FALSE(mask.contains(200));
306 EXPECT_FALSE(mask.contains(201));
307 EXPECT_FALSE(mask.contains(500));
308 EXPECT_FALSE(mask.contains(502));
309 EXPECT_FALSE(mask.contains(504));
310 EXPECT_FALSE(mask.contains(506));
375TEST(index_mask, FromDifference)
399 EXPECT_TRUE(mask_difference.
is_empty());
403TEST(index_mask, FromIntersection)
427 EXPECT_TRUE(mask_intersection.
is_empty());
431TEST(index_mask, DefaultConstructor)
444 mask.foreach_range([&](
const IndexRange range) { ranges.append(range); });
457 EXPECT_TRUE(mask.to_range().has_value());
462 EXPECT_TRUE(mask.to_range().has_value());
467 EXPECT_FALSE(mask.to_range().has_value());
472 EXPECT_TRUE(mask.to_range().has_value());
519 test_range({0, 16384});
520 test_range({16320, 64});
521 test_range({16384, 64});
522 test_range({0, 100000});
523 test_range({100000, 100000});
524 test_range({688064, 64});
534 return range.contains(i);
542 return indices.contains(i);
546 mask.to_indices<
int64_t>(new_indices);
551TEST(index_mask, IndexIteratorConversionFuzzy)
558 for ([[maybe_unused]]
const int64_t j :
573 const int64_t new_index = mask.iterator_to_index(it);
583 EXPECT_EQ(sub_mask[it], indices[start + index]);
590 for (
const int64_t offset : {0, 1, 2, 100, 500}) {
591 const int64_t index_to_search = indices[index] + offset;
592 const bool contained = std::binary_search(indices.begin(), indices.end(), index_to_search);
593 const std::optional<RawMaskIterator> it = mask.find(index_to_search);
602TEST(index_mask, FromPredicateFuzzy)
614 return values.contains(
int(i));
617 for (
const int index : values) {
618 EXPECT_TRUE(mask.contains(index));
621 EXPECT_TRUE(values.contains(
int(index)));
634 mask.foreach_index([&](
const int64_t i) { EXPECT_FALSE(complement.
contains(i)); });
641 mask.foreach_index([&](
const int64_t i) { EXPECT_FALSE(complement.
contains(i)); });
648 mask.foreach_index([&](
const int64_t i) { EXPECT_FALSE(complement.
contains(i)); });
655 mask.foreach_index([&](
const int64_t i) { EXPECT_FALSE(complement.
contains(i)); });
659TEST(index_mask, ComplementFuzzy)
665 const int64_t universe_size = 110;
675 return values.contains(
int(i));
679 EXPECT_EQ(universe_size - mask.size(), complement.size());
680 complement.foreach_index([&](
const int64_t i) { EXPECT_FALSE(mask.contains(i)); });
681 mask.foreach_index([&](
const int64_t i) { EXPECT_FALSE(complement.contains(i)); });
685TEST(index_mask, OffsetIndexRangeFind)
688 auto result = mask.find(1);
689 EXPECT_TRUE(result.has_value());
690 EXPECT_EQ(mask.iterator_to_index(*result), 0);
694TEST(index_mask, FindLargerEqual)
700 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(0)), 0);
701 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(1)), 1);
702 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(2)), 2);
703 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(3)), 2);
704 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(4)), 3);
705 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(5)), 3);
706 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(6)), 3);
707 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(7)), 4);
708 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(10)), 4);
709 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(40)), 4);
710 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(49)), 4);
711 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(50)), 4);
712 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(60)), 14);
713 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(70)), 24);
714 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(99)), 53);
715 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(100)), 54);
716 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(1'000)), 54);
717 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(10'000)), 54);
718 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(50'000)), 54);
719 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(100'000)), 54);
720 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(100'001)), 55);
721 EXPECT_FALSE(mask.find_larger_equal(101'000).has_value());
725 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(0)), 0);
726 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(50)), 0);
727 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(9'999)), 0);
728 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(10'000)), 0);
729 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(10'001)), 1);
730 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(39'998)), 29'998);
731 EXPECT_EQ(mask.iterator_to_index(*mask.find_larger_equal(39'999)), 29'999);
732 EXPECT_FALSE(mask.find_larger_equal(40'000).has_value());
733 EXPECT_FALSE(mask.find_larger_equal(40'001).has_value());
734 EXPECT_FALSE(mask.find_larger_equal(100'000).has_value());
738TEST(index_mask, FindSmallerEqual)
744 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(0)), 0);
745 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(1)), 1);
746 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(2)), 1);
747 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(3)), 2);
748 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(4)), 2);
749 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(5)), 2);
750 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(6)), 3);
751 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(7)), 3);
752 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(10)), 3);
753 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(40)), 3);
754 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(49)), 3);
755 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(50)), 4);
756 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(60)), 14);
757 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(70)), 24);
758 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(99)), 53);
759 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(100)), 53);
760 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(1'000)), 53);
761 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(10'000)), 53);
762 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(50'000)), 53);
763 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(100'000)), 54);
764 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(100'001)), 55);
765 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(101'000)), 83);
769 EXPECT_FALSE(mask.find_smaller_equal(0).has_value());
770 EXPECT_FALSE(mask.find_smaller_equal(1).has_value());
771 EXPECT_FALSE(mask.find_smaller_equal(50).has_value());
772 EXPECT_FALSE(mask.find_smaller_equal(9'999).has_value());
773 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(10'000)), 0);
774 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(10'001)), 1);
775 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(39'998)), 29'998);
776 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(39'999)), 29'999);
777 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(40'000)), 29'999);
778 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(40'001)), 29'999);
779 EXPECT_EQ(mask.iterator_to_index(*mask.find_smaller_equal(100'000)), 29'999);
788 EXPECT_TRUE(mask.slice_content(
IndexRange(50, 10)).is_empty());
803 {4, 5, 100, 1'000, 10'000, 20'000, 25'000, 100'000}, memory);
818TEST(index_mask, EqualsRangeSelf)
831TEST(index_mask, EqualsRangeLarge)
838TEST(index_mask, EqualsRangeBegin)
845TEST(index_mask, EqualsRangeEnd)
852TEST(index_mask, NonEqualsRange)
856 EXPECT_NE(mask_a, mask_b);
880 EXPECT_NE(mask_a, mask_b);
883TEST(index_mask, NotEqualsRangeAndIndices)
891 EXPECT_NE(mask_a, mask_b);
896 if (a.size() !=
b.size()) {
899 for (
const int64_t i : a.index_range()) {
907TEST(index_mask, ZippedForeachSelf)
915 EXPECT_FALSE(segments.is_empty());
925 EXPECT_FALSE(segments.is_empty());
936 EXPECT_FALSE(segments.is_empty());
949 EXPECT_FALSE(segments.is_empty());
960TEST(index_mask, ZippedForeachSameSegments)
969 EXPECT_FALSE(segments.is_empty());
978 EXPECT_FALSE(segments.is_empty());
990 EXPECT_FALSE(segments.is_empty());
1003TEST(index_mask, ZippedForeachEqual)
1009 {{0, indices.take_front(5)}, {5, indices.take_front(5)}}, memory);
1011 {{0, indices.take_front(3)}, {3, indices.take_front(4)}, {7, indices.take_front(3)}},
1017 {3, indices.take_front(2)},
1018 {5, indices.take_front(2)},
1019 {7, indices.take_front(3)}};
1032TEST(index_mask, FromRepeatingEmpty)
1036 EXPECT_TRUE(mask.is_empty());
1039TEST(index_mask, FromRepeatingSingle)
1054TEST(index_mask, FromRepeatingMultiple)
1073TEST(index_mask, FromRepeatingRangeFromSingle)
1080TEST(index_mask, FromRepeatingRangeFromRange)
1088TEST(index_mask, FromRepeatingEverySecond)
1099TEST(index_mask, FromRepeatingMultipleRanges)
1122TEST(index_mask, FromRepeatingNoRepetitions)
1126 EXPECT_TRUE(mask.is_empty());
1164 EXPECT_TRUE(shifted_mask.
is_empty());
1208 EXPECT_TRUE(new_mask.is_empty());
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
typedef double(DMatrix)[4][4]
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static unsigned long seed
constexpr int64_t size() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
constexpr IndexRange index_range() const
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
void append(const T &value)
IndexMask slice_and_shift(IndexRange range, int64_t offset, IndexMaskMemory &memory) const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_every_nth(int64_t n, int64_t indices_num, const int64_t initial_offset, IndexMaskMemory &memory)
IndexMask slice_content(IndexRange range) const
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
static IndexMask from_repeating(const IndexMask &mask_to_repeat, int64_t repetitions, int64_t stride, int64_t initial_offset, IndexMaskMemory &memory)
static IndexMask from_union(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
IndexMask shift(const int64_t offset, IndexMaskMemory &memory) const
IndexMask slice(IndexRange range) const
static IndexMask from_intersection(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
int64_t iterator_to_index(const RawMaskIterator &it) const
static IndexMask from_segments(Span< IndexMaskSegment > segments, IndexMaskMemory &memory)
static IndexMask from_initializers(const Span< Initializer > initializers, IndexMaskMemory &memory)
bool contains(int64_t query_index) const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
RawMaskIterator index_to_iterator(int64_t index) const
static void foreach_segment_zipped(Span< IndexMask > masks, FunctionRef< bool(Span< IndexMaskSegment > segments)> fn)
static IndexMask from_difference(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void invert(BitSpanT &&data)
TEST(index_mask_expression, Union)
static bool mask_segments_equals(const IndexMaskSegment &a, const IndexMaskSegment &b)
static constexpr int64_t max_segment_size
const std::array< int16_t, max_segment_size > & get_static_indices_array()
std::chrono::nanoseconds Nanoseconds
Clock::time_point TimePoint
unsigned __int64 uint64_t