diff --git a/.devcontainer/cuda11.8-gcc11/devcontainer.json b/.devcontainer/cuda11.8-gcc11/devcontainer.json
index 97ac85b23..606759c73 100644
--- a/.devcontainer/cuda11.8-gcc11/devcontainer.json
+++ b/.devcontainer/cuda11.8-gcc11/devcontainer.json
@@ -1,6 +1,6 @@
{
"shutdownAction": "stopContainer",
- "image": "rapidsai/devcontainers:24.06-cpp-gcc11-cuda11.8-ubuntu22.04",
+ "image": "rapidsai/devcontainers:24.10-cpp-gcc11-cuda11.8-ubuntu22.04",
"hostRequirements": {
"gpu": true
},
diff --git a/.devcontainer/cuda12.5-gcc12/devcontainer.json b/.devcontainer/cuda12.5-gcc12/devcontainer.json
new file mode 100644
index 000000000..3f562f865
--- /dev/null
+++ b/.devcontainer/cuda12.5-gcc12/devcontainer.json
@@ -0,0 +1,42 @@
+{
+ "shutdownAction": "stopContainer",
+ "image": "rapidsai/devcontainers:24.10-cpp-gcc12-cuda12.5-ubuntu22.04",
+ "hostRequirements": {
+ "gpu": true
+ },
+ "initializeCommand": [
+ "/bin/bash",
+ "-c",
+ "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}"
+ ],
+ "containerEnv": {
+ "SCCACHE_REGION": "us-east-2",
+ "SCCACHE_BUCKET": "rapids-sccache-devs",
+ "VAULT_HOST": "https://vault.ops.k8s.rapids.ai",
+ "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history",
+ "DEVCONTAINER_NAME": "cuda12.5-gcc12",
+ "CUCO_CUDA_VERSION": "12.5",
+ "CUCO_HOST_COMPILER": "gcc",
+ "CUCO_HOST_COMPILER_VERSION": "12"
+ },
+ "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}",
+ "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent",
+ "mounts": [
+ "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
+ "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
+ "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent"
+ ],
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "llvm-vs-code-extensions.vscode-clangd"
+ ],
+ "settings": {
+ "clangd.arguments": [
+ "--compile-commands-dir=${workspaceFolder}/build/latest"
+ ]
+ }
+ }
+ },
+ "name": "cuda12.5-gcc12"
+}
diff --git a/.devcontainer/cuda12.5-gcc13/devcontainer.json b/.devcontainer/cuda12.5-gcc13/devcontainer.json
new file mode 100644
index 000000000..01bbe927b
--- /dev/null
+++ b/.devcontainer/cuda12.5-gcc13/devcontainer.json
@@ -0,0 +1,42 @@
+{
+ "shutdownAction": "stopContainer",
+ "image": "rapidsai/devcontainers:24.10-cpp-gcc13-cuda12.5-ubuntu22.04",
+ "hostRequirements": {
+ "gpu": true
+ },
+ "initializeCommand": [
+ "/bin/bash",
+ "-c",
+ "mkdir -m 0755 -p ${localWorkspaceFolder}/.{aws,cache,config}"
+ ],
+ "containerEnv": {
+ "SCCACHE_REGION": "us-east-2",
+ "SCCACHE_BUCKET": "rapids-sccache-devs",
+ "VAULT_HOST": "https://vault.ops.k8s.rapids.ai",
+ "HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history",
+ "DEVCONTAINER_NAME": "cuda12.5-gcc13",
+ "CUCO_CUDA_VERSION": "12.5",
+ "CUCO_HOST_COMPILER": "gcc",
+ "CUCO_HOST_COMPILER_VERSION": "13"
+ },
+ "workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}",
+ "workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent",
+ "mounts": [
+ "source=${localWorkspaceFolder}/.aws,target=/home/coder/.aws,type=bind,consistency=consistent",
+ "source=${localWorkspaceFolder}/.cache,target=/home/coder/.cache,type=bind,consistency=consistent",
+ "source=${localWorkspaceFolder}/.config,target=/home/coder/.config,type=bind,consistency=consistent"
+ ],
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "llvm-vs-code-extensions.vscode-clangd"
+ ],
+ "settings": {
+ "clangd.arguments": [
+ "--compile-commands-dir=${workspaceFolder}/build/latest"
+ ]
+ }
+ }
+ },
+ "name": "cuda12.5-gcc13"
+}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 355d73995..01bbe927b 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,6 +1,6 @@
{
"shutdownAction": "stopContainer",
- "image": "rapidsai/devcontainers:24.06-cpp-gcc12-cuda12.4-ubuntu22.04",
+ "image": "rapidsai/devcontainers:24.10-cpp-gcc13-cuda12.5-ubuntu22.04",
"hostRequirements": {
"gpu": true
},
@@ -14,10 +14,10 @@
"SCCACHE_BUCKET": "rapids-sccache-devs",
"VAULT_HOST": "https://vault.ops.k8s.rapids.ai",
"HISTFILE": "${containerWorkspaceFolder}/.cache/._bash_history",
- "DEVCONTAINER_NAME": "cuda12.4-gcc12",
- "CUCO_CUDA_VERSION": "12.4",
+ "DEVCONTAINER_NAME": "cuda12.5-gcc13",
+ "CUCO_CUDA_VERSION": "12.5",
"CUCO_HOST_COMPILER": "gcc",
- "CUCO_HOST_COMPILER_VERSION": "12"
+ "CUCO_HOST_COMPILER_VERSION": "13"
},
"workspaceFolder": "/home/coder/${localWorkspaceFolderBasename}",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/coder/${localWorkspaceFolderBasename},type=bind,consistency=consistent",
@@ -38,5 +38,5 @@
}
}
},
- "name": "cuda12.4-gcc12"
+ "name": "cuda12.5-gcc13"
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b9e97e83..8de18db73 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,7 @@
cmake_minimum_required(VERSION 3.23.1 FATAL_ERROR)
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/CUCO_RAPIDS.cmake)
- file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-24.08/RAPIDS.cmake
+ file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-24.10/RAPIDS.cmake
${CMAKE_CURRENT_BINARY_DIR}/CUCO_RAPIDS.cmake)
endif()
include(${CMAKE_CURRENT_BINARY_DIR}/CUCO_RAPIDS.cmake)
diff --git a/README.md b/README.md
index 6b848f8d2..bc50aae02 100644
--- a/README.md
+++ b/README.md
@@ -206,8 +206,8 @@ We plan to add many GPU-accelerated, concurrent data structures to `cuCollection
#### Examples:
- [Host-bulk APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/host_bulk_example.cu) (see [live example in godbolt](https://godbolt.org/z/96re4zhjo))
- [Device-ref APIs for individual operations](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/device_ref_example.cu) (see [live example in godbolt](https://godbolt.org/z/7aKWdGTfx))
-- [One single storage for multiple sets](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/device_subsets_example.cu) (see [live example in godbolt](https://godbolt.org/z/sMfqGxdha))
-- [Using shared memory as storage](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/shared_memory_example.cu) (see [live example in godbolt](https://godbolt.org/z/zdTnbE1q5))
+- [One single storage for multiple sets](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/device_subsets_example.cu) (see [live example in godbolt](https://godbolt.org/z/7f9KW44P4))
+- [Using shared memory as storage](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/shared_memory_example.cu) (see [live example in godbolt](https://godbolt.org/z/Ws5c71T4z))
- [Using set as mapping table to handle large keys or indeterministic sentinels](https://github.com/NVIDIA/cuCollections/blob/dev/examples/static_set/mapping_table_example.cu) (see [live example in godbolt](https://godbolt.org/z/KfYo4nMss))
### `static_map`
@@ -234,12 +234,19 @@ We plan to add many GPU-accelerated, concurrent data structures to `cuCollection
#### Examples:
- [Host-bulk APIs (TODO)]()
-### `distinct_count_estimator`
+### `hyperloglog`
-`cuco::distinct_count_estimator` implements the well-established [HyperLogLog++ algorithm](https://static.googleusercontent.com/media/research.google.com/de//pubs/archive/40671.pdf) for approximating the count of distinct items in a multiset/stream.
+`cuco::hyperloglog` implements the well-established [HyperLogLog++ algorithm](https://static.googleusercontent.com/media/research.google.com/de//pubs/archive/40671.pdf) for approximating the count of distinct items in a multiset/stream.
#### Examples:
-- [Host-bulk APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/distinct_count_estimator/host_bulk_example.cu) (see [live example in godbolt](https://godbolt.org/z/sMfofM6qd))
-- [Device-ref APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/distinct_count_estimator/device_ref_example.cu) (see [live example in godbolt](https://godbolt.org/z/156T9ox7h))
+- [Host-bulk APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/hyperloglog/host_bulk_example.cu) (see [live example in godbolt](https://godbolt.org/z/G4qdcTezE))
+- [Device-ref APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/hyperloglog/device_ref_example.cu) (see [live example in godbolt](https://godbolt.org/z/n88713o4n))
+
+### `bloom_filter`
+
+`cuco::bloom_filter` implements a Blocked Bloom Filter for approximate set membership queries.
+
+#### Examples:
+- [Host-bulk APIs](https://github.com/NVIDIA/cuCollections/blob/dev/examples/bloom_filter/host_bulk_example.cu) (see [live example in godbolt](https://godbolt.org/z/EY7T5v5aE))
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
index b4d20083f..c4d4dbc37 100644
--- a/benchmarks/CMakeLists.txt
+++ b/benchmarks/CMakeLists.txt
@@ -35,7 +35,7 @@ function(ConfigureBench BENCH_NAME)
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/benchmarks")
target_include_directories(${BENCH_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}")
- target_compile_options(${BENCH_NAME} PRIVATE --expt-extended-lambda --expt-relaxed-constexpr -lineinfo)
+ target_compile_options(${BENCH_NAME} PRIVATE --expt-extended-lambda -lineinfo)
target_link_libraries(${BENCH_NAME} PRIVATE
nvbench::main
pthread
@@ -49,53 +49,59 @@ endfunction(ConfigureBench)
###################################################################################################
# - static_set benchmarks -------------------------------------------------------------------------
ConfigureBench(STATIC_SET_BENCH
- hash_table/static_set/contains_bench.cu
- hash_table/static_set/find_bench.cu
- hash_table/static_set/insert_bench.cu
- hash_table/static_set/retrieve_all_bench.cu
- hash_table/static_set/size_bench.cu
- hash_table/static_set/rehash_bench.cu)
+ static_set/contains_bench.cu
+ static_set/find_bench.cu
+ static_set/insert_bench.cu
+ static_set/retrieve_all_bench.cu
+ static_set/size_bench.cu
+ static_set/rehash_bench.cu)
###################################################################################################
# - static_map benchmarks -------------------------------------------------------------------------
ConfigureBench(STATIC_MAP_BENCH
- hash_table/static_map/insert_bench.cu
- hash_table/static_map/find_bench.cu
- hash_table/static_map/contains_bench.cu
- hash_table/static_map/erase_bench.cu
- hash_table/static_map/insert_or_apply_bench.cu)
+ static_map/insert_bench.cu
+ static_map/find_bench.cu
+ static_map/contains_bench.cu
+ static_map/erase_bench.cu
+ static_map/insert_or_apply_bench.cu)
###################################################################################################
# - static_multiset benchmarks --------------------------------------------------------------------
ConfigureBench(STATIC_MULTISET_BENCH
- hash_table/static_multiset/contains_bench.cu
- hash_table/static_multiset/retrieve_bench.cu
- hash_table/static_multiset/count_bench.cu
- hash_table/static_multiset/find_bench.cu
- hash_table/static_multiset/insert_bench.cu)
+ static_multiset/contains_bench.cu
+ static_multiset/retrieve_bench.cu
+ static_multiset/count_bench.cu
+ static_multiset/find_bench.cu
+ static_multiset/insert_bench.cu)
###################################################################################################
# - static_multimap benchmarks --------------------------------------------------------------------
ConfigureBench(STATIC_MULTIMAP_BENCH
- hash_table/static_multimap/insert_bench.cu
- hash_table/static_multimap/retrieve_bench.cu
- hash_table/static_multimap/query_bench.cu
- hash_table/static_multimap/count_bench.cu)
+ static_multimap/insert_bench.cu
+ static_multimap/retrieve_bench.cu
+ static_multimap/query_bench.cu
+ static_multimap/count_bench.cu)
###################################################################################################
# - dynamic_map benchmarks ------------------------------------------------------------------------
ConfigureBench(DYNAMIC_MAP_BENCH
- hash_table/dynamic_map/insert_bench.cu
- hash_table/dynamic_map/find_bench.cu
- hash_table/dynamic_map/contains_bench.cu
- hash_table/dynamic_map/erase_bench.cu)
+ dynamic_map/insert_bench.cu
+ dynamic_map/find_bench.cu
+ dynamic_map/contains_bench.cu
+ dynamic_map/erase_bench.cu)
###################################################################################################
# - hash function benchmarks ----------------------------------------------------------------------
-ConfigureBench(HASH_BENCH
- hash_bench.cu)
+ConfigureBench(HASH_FUNCTION_BENCH
+ hash_function/hash_function_bench.cu)
###################################################################################################
-# - distinct_count_estimator benchmarks -----------------------------------------------------------
-ConfigureBench(DISTINCT_COUNT_ESTIMATOR_BENCH
- distinct_count_estimator_bench.cu)
+# - hyperloglog benchmarks -----------------------------------------------------------
+ConfigureBench(HYPERLOGLOG_BENCH
+ hyperloglog/hyperloglog_bench.cu)
+
+###################################################################################################
+# - bloom_filter benchmarks -----------------------------------------------------------------------
+ConfigureBench(BLOOM_FILTER_BENCH
+ bloom_filter/add_bench.cu
+ bloom_filter/contains_bench.cu)
diff --git a/benchmarks/analysis/notebooks/StaticMultimap.ipynb b/benchmarks/analysis/notebooks/StaticMultimap.ipynb
deleted file mode 100644
index 0269c5690..000000000
--- a/benchmarks/analysis/notebooks/StaticMultimap.ipynb
+++ /dev/null
@@ -1,596 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Preparation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "# !pip install pandas\n",
- "# !pip install matplotlib\n",
- "\n",
- "# Import libraries\n",
- "import pandas as pd\n",
- "\n",
- "from Utils import *"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Global Parameters"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Specify the data path\n",
- "datafile = '../data/static-multimap-data.csv'\n",
- "\n",
- "output_keys = ['Benchmark', 'Label', 'Distribution', 'MatchingRate', 'Multiplicity', \\\n",
- " 'NumInputs', 'Occupancy', 'GPU Time (sec)', 'Elem/s (elem/sec)']"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Import Data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Read csv file\n",
- "rawdf = pd.read_csv(datafile)\n",
- "\n",
- "# Filter out skipped tests\n",
- "perfdf = rawdf[rawdf[\"Key\"] == rawdf[\"Value\"]].reset_index(drop=True)\n",
- "\n",
- "\n",
- "# Add labels\n",
- "perfdf['Label'] = perfdf[\"Key\"]\n",
- "perfdf.loc[perfdf['Distribution'].notnull(), 'Label'] += \"_\" + perfdf['Distribution']\n",
- "\n",
- "# Trim data frame for visualization\n",
- "perfdf = perfdf[output_keys]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Visualization Parameters"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "staic_multimap_insert_uniform_multiplicity\n",
- "staic_multimap_insert_occupancy\n",
- "staic_multimap_count_uniform_multiplicity\n",
- "staic_multimap_count_occupancy\n",
- "staic_multimap_retrieve_uniform_multiplicity\n",
- "staic_multimap_retrieve_occupancy\n",
- "staic_multimap_retrieve_matching_rate\n",
- "staic_multimap_query_uniform_multiplicity\n",
- "staic_multimap_query_occupancy\n",
- "staic_multimap_query_matching_rate\n",
- "staic_multimap_count_matching_rate\n"
- ]
- }
- ],
- "source": [
- "# Get benchmark list\n",
- "unique_bms = perfdf[\"Benchmark\"].unique()\n",
- "for it in unique_bms:\n",
- " print(it)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### `insert` performance by varying key muliplicities\n",
- "
\n",
- "- 100'000'000 insertions
\n",
- "- Fixed matching rate: 0.5
\n",
- "- Fixed occupancy: 0.8
\n",
- "- UNIFORM distribution
\n",
- "
"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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e6q+7xqZKJ9/Hjp0gFq17O/zz1ffvlu1asUXX3zBxIkT+eqrrxgwYAALFiwALFH++OOPTJ48mXXr1vHEE09Uupz69evzyiuvbPmilWfgwIFMnDiRiRMncsUVVwBw8cUXs8suuzB9+nSmT59Ox44d+eMf/7jlMbvuuisTJ05k8uTJzJs3jxdffHHLur333pv//ve/W+6PGDGCffbZp9LPpaqGD4e99oLate3v8OHVu//zzz+fa6+9lh9++IGxY8eyww47bFk3fvx4VqxYUeUy/P2sugcegEcfte80QNu28NhjtryqalyifP556NsXZs+2qvrs2Xa/upJlvXr1qF+/PgAbNmxgc1y9/7jjjkNEEBF69OjBvHnzKl1OnTp16Nu3L/fdd1+FH1tQUMCECRO4+eabtyy75ZZbGD9+PNOnTy+xbe3atenRowfz58/fsqxdu3asX7+exYsXo6q8++67HHvssZV+LlUxfDjceCM89JCdm3roIbtfXcny+++/p6ioiKOOOgqwmmajRo0A2LRpE9deey3//ve/q1yOv59VN3cudO0Ko0bB2WfDokXQpQssWFD1w++su9Y7mSuvhIkTy17/5ZewYUPJZWvXwsUXw+OPJ35MXh7cf3/qMcydO5fjjz+egoICBg4cSOvWrUusLyws5LnnnuOBKv7U9evXj27dunHdddeVu921117LnXfeCcBzzz3HzJkzycvLo3bt2lu2qV27Nnl5eUyZMoVu3bptWb5+/Xq++uqrrWI944wzeOmll9h3333p3r37lh+HMPTuvfWys86CSy+FO+6AbbeF/v2L1227LVx7LZxzDixdCmecUfKxY8akXva0adNo0qQJp512GjNnzuTII49kwIAB1K5dm4cffpiTTjqJVq1aVeZpbaWmvJ9hOeAAeOMN+OoreP11GDoU3noL8vPt6LEqalyNsnSSTLa8Mtq2bcukSZMoKCjgmWeeYfHixSXWX3rppRxyyCEcfPDBZe5DRJIu32677Tj//PO3nKcqS/yh2t57742qJtx//PLp06eTl5dH8+bNadeuXYkvG8BZZ53FSy+9xPDhwznnnHPKLT9MU6fC9tuXXLb99laLqA5FRUV8+umnDBo0iHHjxjFjxgyGDh3KggULeOmll7j88stT2o+/n+Hr3x+uuAJeeskqN8OG2dHiHXdUfd85V6NMVvPr0MEO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\n",
- "text/plain": [
- "