Skip to content

Commit d9d2968

Browse files
committed
Fix run-container bitmaps without serialized offsets and add a minimal repro test
1 parent ff7cff7 commit d9d2968

File tree

2 files changed

+66
-7
lines changed

2 files changed

+66
-7
lines changed

include/cuco/detail/roaring_bitmap/roaring_bitmap_impl.cuh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,16 @@ class roaring_bitmap_impl<cuda::std::uint32_t> {
174174
__device__ bool contains_container(cuda::std::uint16_t lower, cuda::std::uint32_t index) const
175175
{
176176
cuda::std::uint32_t offset;
177-
cuda::std::byte const* offset_ptr =
178-
storage_ref_.container_offsets() + index * sizeof(cuda::std::uint32_t);
179-
if (offsets_aligned_) {
180-
offset = aligned_load<cuda::std::uint32_t>(offset_ptr);
177+
if (storage_ref_.metadata().offsets_in_serialized_data) {
178+
cuda::std::byte const* offset_ptr =
179+
storage_ref_.container_offsets() + index * sizeof(cuda::std::uint32_t);
180+
if (offsets_aligned_) {
181+
offset = aligned_load<cuda::std::uint32_t>(offset_ptr);
182+
} else {
183+
offset = misaligned_load<cuda::std::uint32_t>(offset_ptr);
184+
}
181185
} else {
182-
offset = misaligned_load<cuda::std::uint32_t>(offset_ptr);
186+
offset = storage_ref_.metadata().computed_offsets[index];
183187
}
184188
cuda::std::byte const* container = storage_ref_.data() + offset;
185189
if (storage_ref_.metadata().has_run and check_bit(storage_ref_.run_container_bitmap(), index)) {
@@ -381,4 +385,4 @@ class roaring_bitmap_impl<cuda::std::uint64_t> {
381385
storage_ref_type storage_ref_;
382386
};
383387

384-
} // namespace cuco::experimental::detail
388+
} // namespace cuco::experimental::detail

tests/roaring_bitmap/contains_test.cu

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
#include <cuda/std/cstdint>
2222
#include <cuda/std/type_traits>
2323
#include <thrust/device_vector.h>
24+
#include <thrust/host_vector.h>
2425
#include <thrust/logical.h>
2526
#include <thrust/universal_vector.h>
2627

2728
#include <catch2/catch_test_macros.hpp>
2829

30+
#include <cstring>
2931
#include <filesystem>
3032
#include <fstream>
3133
#include <string>
@@ -90,8 +92,61 @@ bool check(std::string const& bitmap_file_path)
9092
thrust::all_of(contained.begin(), contained.end(), ::cuda::std::identity{});
9193
return all_contained;
9294
}
95+
96+
std::vector<cuda::std::byte> make_run_container_no_offsets_bitmap()
97+
{
98+
std::vector<cuda::std::byte> bytes;
99+
auto append_u16 = [&bytes](cuda::std::uint16_t value) {
100+
bytes.push_back(static_cast<cuda::std::byte>(value & 0xFF));
101+
bytes.push_back(static_cast<cuda::std::byte>((value >> 8) & 0xFF));
102+
};
103+
auto append_u32 = [&bytes](cuda::std::uint32_t value) {
104+
bytes.push_back(static_cast<cuda::std::byte>(value & 0xFF));
105+
bytes.push_back(static_cast<cuda::std::byte>((value >> 8) & 0xFF));
106+
bytes.push_back(static_cast<cuda::std::byte>((value >> 16) & 0xFF));
107+
bytes.push_back(static_cast<cuda::std::byte>((value >> 24) & 0xFF));
108+
};
109+
110+
constexpr cuda::std::uint32_t serial_cookie = 12347;
111+
constexpr cuda::std::uint16_t key = 0;
112+
constexpr cuda::std::uint16_t card_minus_1 = 2; // card = 3
113+
constexpr cuda::std::uint16_t num_runs = 1;
114+
constexpr cuda::std::uint16_t run_start = 1;
115+
constexpr cuda::std::uint16_t run_length = 2; // 3 values total
116+
117+
append_u32(serial_cookie); // 1 container encoded in cookie
118+
bytes.push_back(static_cast<cuda::std::byte>(0x01)); // run container bitmap (1 byte)
119+
append_u16(key);
120+
append_u16(card_minus_1);
121+
append_u16(num_runs);
122+
append_u16(run_start);
123+
append_u16(run_length);
124+
125+
return bytes;
126+
}
93127
} // namespace
94128

129+
TEST_CASE("roaring_bitmap run container without offsets", "[roaring_bitmap]")
130+
{
131+
auto const bytes = make_run_container_no_offsets_bitmap();
132+
thrust::universal_host_pinned_vector<cuda::std::byte> buffer(bytes.size());
133+
std::memcpy(thrust::raw_pointer_cast(buffer.data()), bytes.data(), bytes.size());
134+
135+
cuco::experimental::roaring_bitmap<cuda::std::uint32_t> roaring_bitmap(
136+
thrust::raw_pointer_cast(buffer.data()));
137+
138+
thrust::device_vector<cuda::std::uint32_t> keys{1, 2, 3, 4};
139+
thrust::device_vector<bool> contained(keys.size(), false);
140+
141+
roaring_bitmap.contains(keys.begin(), keys.end(), contained.begin());
142+
143+
thrust::host_vector<bool> contained_h = contained;
144+
REQUIRE(contained_h[0]);
145+
REQUIRE(contained_h[1]);
146+
REQUIRE(contained_h[2]);
147+
REQUIRE_FALSE(contained_h[3]);
148+
}
149+
95150
TEST_CASE("roaring_bitmap bulk contains from RoaringFormatSpec testdata", "[roaring_bitmap]")
96151
{
97152
#ifndef CUCO_ROARING_DATA_DIR
@@ -131,4 +186,4 @@ TEST_CASE("roaring_bitmap bulk contains from RoaringFormatSpec testdata", "[roar
131186
REQUIRE(check<cuda::std::uint64_t>(path));
132187
}
133188
#endif
134-
}
189+
}

0 commit comments

Comments
 (0)