1+ /*
2+ * Copyright (c) 2025 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+ #include < cuco/roaring_bitmap.cuh>
18+ #include < cuco/utility/traits.hpp>
19+
20+ #include < cuda/std/cstddef>
21+ #include < cuda/std/cstdint>
22+ #include < cuda/std/type_traits>
23+ #include < thrust/device_vector.h>
24+ #include < thrust/logical.h>
25+ #include < thrust/universal_vector.h>
26+
27+ #include < catch2/catch_test_macros.hpp>
28+
29+ #include < fstream>
30+ #include < string>
31+ #include < vector>
32+
33+ namespace {
34+ template <typename KeyType>
35+ bool check (std::string const & bitmap_file_path)
36+ {
37+ auto generate_keys = []() -> thrust::device_vector<KeyType> {
38+ if constexpr (cuda::std::is_same_v<KeyType, cuda::std::uint32_t >) {
39+ std::vector<cuda::std::uint32_t > keys;
40+ for (cuda::std::uint32_t k = 0 ; k < 100000 ; k += 1000 ) {
41+ keys.push_back (k);
42+ }
43+ for (int k = 100000 ; k < 200000 ; ++k) {
44+ keys.push_back (3 * k);
45+ }
46+ for (int k = 700000 ; k < 800000 ; ++k) {
47+ keys.push_back (k);
48+ }
49+ return thrust::device_vector<cuda::std::uint32_t >(keys.begin (), keys.end ());
50+ } else if constexpr (cuda::std::is_same_v<KeyType, cuda::std::uint64_t >) {
51+ std::vector<cuda::std::uint64_t > keys;
52+ for (cuda::std::uint64_t k = 0x00000ull ; k < 0x09000ull ; ++k) {
53+ keys.push_back (k);
54+ }
55+ for (cuda::std::uint64_t k = 0x0A000ull ; k < 0x10000ull ; ++k) {
56+ keys.push_back (k);
57+ }
58+ keys.push_back (0x20000ull );
59+ keys.push_back (0x20005ull );
60+ for (cuda::std::uint64_t i = 0 ; i < 0x10000ull ; i += 2ull ) {
61+ keys.push_back (0x80000ull + i);
62+ }
63+ return thrust::device_vector<cuda::std::uint64_t >(keys.begin (), keys.end ());
64+ } else {
65+ static_assert (cuco::dependent_false<KeyType>, " KeyType must be uint32_t or uint64_t" );
66+ return {};
67+ }
68+ };
69+
70+ std::ifstream file (bitmap_file_path, std::ios::binary);
71+ if (!file.is_open ()) { return false ; }
72+
73+ file.seekg (0 , std::ios::end);
74+ std::streamsize file_size = file.tellg ();
75+ file.seekg (0 , std::ios::beg);
76+
77+ thrust::universal_host_pinned_vector<cuda::std::byte> buffer (file_size);
78+
79+ file.read (reinterpret_cast <char *>(thrust::raw_pointer_cast (buffer.data ())), file_size);
80+ file.close ();
81+
82+ cuco::roaring_bitmap<KeyType> roaring_bitmap (thrust::raw_pointer_cast (buffer.data ()));
83+
84+ auto keys = generate_keys ();
85+ thrust::device_vector<bool > contained (keys.size (), false );
86+
87+ roaring_bitmap.contains (keys.begin (), keys.end (), contained.begin ());
88+
89+ bool const all_contained =
90+ thrust::all_of (contained.begin (), contained.end (), ::cuda::std::identity{});
91+ return all_contained;
92+ }
93+ } // namespace
94+
95+ TEST_CASE (" roaring_bitmap bulk contains from RoaringFormatSpec testdata" , " [roaring_bitmap]" )
96+ {
97+ #ifndef CUCO_ROARING_DATA_DIR
98+ SKIP (
99+ " CUCO_ROARING_DATA_DIR is not defined. Configure with -DCUCO_DOWNLOAD_ROARING_TESTDATA=ON to "
100+ " run this test." );
101+ #else
102+ std::string const data_dir = CUCO_ROARING_DATA_DIR;
103+
104+ SECTION (" 32-bit: bitmapwithoutruns.bin" )
105+ {
106+ std::string const path = data_dir + " /bitmapwithoutruns.bin" ;
107+ if (!std::ifstream (path).good ()) {
108+ std::string const msg = std::string (" Missing file: " ) + path;
109+ SKIP (msg.c_str ());
110+ }
111+ REQUIRE (check<cuda::std::uint32_t >(path));
112+ }
113+
114+ SECTION (" 32-bit: bitmapwithruns.bin" )
115+ {
116+ std::string const path = data_dir + " /bitmapwithruns.bin" ;
117+ if (!std::ifstream (path).good ()) {
118+ std::string const msg = std::string (" Missing file: " ) + path;
119+ SKIP (msg.c_str ());
120+ }
121+ REQUIRE (check<cuda::std::uint32_t >(path));
122+ }
123+
124+ SECTION (" 64-bit: portable_bitmap64.bin" )
125+ {
126+ std::string const path = data_dir + " /portable_bitmap64.bin" ;
127+ if (!std::ifstream (path).good ()) {
128+ std::string const msg = std::string (" Missing file: " ) + path;
129+ SKIP (msg.c_str ());
130+ }
131+ REQUIRE (check<cuda::std::uint64_t >(path));
132+ }
133+ #endif
134+ }
0 commit comments