Skip to content

Commit 8333a0b

Browse files
authored
Promote experimental::dynamic_map to cuco::dynamic_map (#794)
This PR promotes `cuco::experimental::dynamic_map` to `cuco::dynamic_map` and removes the legacy implementation. **Changes:** - Added `erase`, `find`, `contains`, `retrieve_all` methods - Added `size()`, `capacity()`, `load_factor()` getters - Added sentinel and hash function getters (`empty_key_sentinel()`, `erased_key_sentinel()`, `key_eq()`, `hash_function()`) - Updated all tests and benchmarks to use the new API - Added `insert_or_assign` Closes #732
1 parent 0b214c6 commit 8333a0b

19 files changed

+1725
-1600
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Similar to how [Thrust](https://github.com/thrust/thrust) and [CUB](https://gith
1515

1616
### Major Updates
1717

18+
__02/03/2026__ Modernized `dynamic_map`: promoted `cuco::experimental::dynamic_map` to `cuco::dynamic_map` and removed the legacy implementation
19+
1820
__01/30/2026__ Removed legacy `static_multimap` implementation and promoted `cuco::experimental::static_multimap` to `cuco::static_multimap`
1921

2022
__10/08/2025__ Changed `cuda_allocator` to stream-ordered, requiring `cuda::stream_ref` parameter in `allocate`/`deallocate`.
@@ -244,7 +246,7 @@ We plan to add many GPU-accelerated, concurrent data structures to `cuCollection
244246

245247
### `dynamic_map`
246248

247-
`cuco::dynamic_map` links together multiple `cuco::static_map`s to provide a hash table that can grow as key-value pairs are inserted. It currently only provides host-bulk APIs. See the Doxygen documentation in `dynamic_map.cuh` for more detailed information.
249+
`cuco::dynamic_map` links together multiple `cuco::static_map`s to provide a hash table that can grow as key-value pairs are inserted. It supports `insert`, `insert_or_assign`, `erase`, `find`, `contains`, and `retrieve_all` operations via host-bulk APIs with kernel-based implementations for optimal performance. See the Doxygen documentation in `dynamic_map.cuh` for more detailed information.
248250

249251
#### Examples:
250252
- [Host-bulk APIs (TODO)]()

benchmarks/dynamic_map/contains_bench.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023-2025, NVIDIA CORPORATION.
2+
* Copyright (c) 2023-2026, NVIDIA CORPORATION.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ std::enable_if_t<(sizeof(Key) == sizeof(Value)), void> dynamic_map_contains(
6262
state.add_element_count(num_keys);
6363

6464
state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) {
65-
map.contains(keys.begin(), keys.end(), result.begin(), {}, {}, launch.get_stream());
65+
map.contains(keys.begin(), keys.end(), result.begin(), {launch.get_stream()});
6666
});
6767
}
6868

benchmarks/dynamic_map/erase_bench.cu

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023-2025, NVIDIA CORPORATION.
2+
* Copyright (c) 2023-2026, NVIDIA CORPORATION.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -56,15 +56,14 @@ std::enable_if_t<(sizeof(Key) == sizeof(Value)), void> dynamic_map_erase(
5656

5757
state.exec(nvbench::exec_tag::sync | nvbench::exec_tag::timer,
5858
[&](nvbench::launch& launch, auto& timer) {
59-
// dynamic map with erase support
6059
cuco::dynamic_map<Key, Value> map{static_cast<size_t>(initial_size),
6160
cuco::empty_key<Key>{-1},
6261
cuco::empty_value<Value>{-1},
6362
cuco::erased_key<Key>{-2}};
64-
map.insert(pairs.begin(), pairs.end(), {}, {}, launch.get_stream());
63+
map.insert(pairs.begin(), pairs.end(), {launch.get_stream()});
6564

6665
timer.start();
67-
map.erase(keys.begin(), keys.end(), {}, {}, launch.get_stream());
66+
map.erase(keys.begin(), keys.end(), {launch.get_stream()});
6867
timer.stop();
6968
});
7069
}

benchmarks/dynamic_map/find_bench.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023-2025, NVIDIA CORPORATION.
2+
* Copyright (c) 2023-2026, NVIDIA CORPORATION.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ std::enable_if_t<(sizeof(Key) == sizeof(Value)), void> dynamic_map_find(
6262
state.add_element_count(num_keys);
6363

6464
state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) {
65-
map.find(keys.begin(), keys.end(), result.begin(), {}, {}, launch.get_stream());
65+
map.find(keys.begin(), keys.end(), result.begin(), {launch.get_stream()});
6666
});
6767
}
6868

benchmarks/dynamic_map/insert_bench.cu

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023-2025, NVIDIA CORPORATION.
2+
* Copyright (c) 2023-2026, NVIDIA CORPORATION.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -57,15 +57,12 @@ std::enable_if_t<(sizeof(Key) == sizeof(Value)), void> dynamic_map_insert(
5757

5858
state.exec(
5959
nvbench::exec_tag::sync | nvbench::exec_tag::timer, [&](nvbench::launch& launch, auto& timer) {
60-
cuco::dynamic_map<Key, Value> map{static_cast<size_t>(initial_size),
61-
cuco::empty_key<Key>{-1},
62-
cuco::empty_value<Value>{-1},
63-
{},
64-
launch.get_stream()};
60+
cuco::dynamic_map<Key, Value> map{
61+
static_cast<size_t>(initial_size), cuco::empty_key<Key>{-1}, cuco::empty_value<Value>{-1}};
6562

6663
timer.start();
6764
for (int64_t i = 0; i < num_keys; i += batch_size) {
68-
map.insert(pairs.begin() + i, pairs.begin() + i + batch_size, {}, {}, launch.get_stream());
65+
map.insert(pairs.begin() + i, pairs.begin() + i + batch_size, {launch.get_stream()});
6966
}
7067
timer.stop();
7168
});

benchmarks/dynamic_map/retrieve_all_bench.cu

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, NVIDIA CORPORATION.
2+
* Copyright (c) 2025-2026, NVIDIA CORPORATION.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,14 +53,14 @@ std::enable_if_t<(sizeof(Key) == sizeof(Value)), void> dynamic_map_retrieve_all(
5353
cuco::dynamic_map<Key, Value> map{
5454
static_cast<size_t>(initial_size), cuco::empty_key<Key>{-1}, cuco::empty_value<Value>{-1}};
5555
map.insert(pairs.begin(), pairs.end());
56-
// Prepare output buffers
57-
thrust::device_vector<Key> retrieved_keys(map.get_size());
58-
thrust::device_vector<Value> retrieved_values(map.get_size());
5956

60-
state.add_element_count(map.get_size());
57+
thrust::device_vector<Key> retrieved_keys(map.size());
58+
thrust::device_vector<Value> retrieved_values(map.size());
59+
60+
state.add_element_count(map.size());
6161

6262
state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) {
63-
map.retrieve_all(retrieved_keys.begin(), retrieved_values.begin(), launch.get_stream());
63+
map.retrieve_all(retrieved_keys.begin(), retrieved_values.begin(), {launch.get_stream()});
6464
});
6565
}
6666

0 commit comments

Comments
 (0)