NV Hash-Map provides highly optimized CPU hash-maps and associative container implementations for NVIDIA and other CPUs. It is optimized for both NVIDIA and CPUs from other vendors.
NV Hash-Map provides optimized kernels to maximize hashmap lookup and insert performance on
- NVIDIA Grace [https://www.nvidia.com/en-us/data-center/grace-cpu],
- ARM64 CPUs that support the NEON or SVE instruction sets (i.e., armv8-a or newer, with up to 2048-bit register size), and
- x86 CPUs that support at least SSE2 (additional optimizations are enabled if SSE3 / SSE4 / AVX2 / AVX512 are available).
Further, NV Hash-Map provides C++-17 standard compatible fallback implentations that should be compile and runnable on every 64-bit little-endian CPU.
NV Hash-Map is a header-only library. However, to maximize performance we generate a configuration header file using CMake.
sudo apt-get update
sudo apt-get install -y cmake g++
export CC="gcc"
export CXX="g++"We are not aware of any compilation issues with gcc / g++ versions. Please file an issue if you come across a non-working configuration.
sudo apt-get update
sudo apt-get install -y cmake clang-20
export CC="clang-20"
export CXX="clang++-20"Assuming you start with a minimal Ubuntu docker image without any C++ compiler, you may need to register Clang as a the default alternative for /usr/lib/c++ to satisfy cmake:
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-16 100Known issues:
A LLVM AST parsing issues in clang++-17, clang++-18, and clang++-19 may prevent successful compilation in some distributions. The only wo workaround is to use compilers that do not have this bug. The problem has been made known to Clang team by myself. It has recently been marked as fixed. However, distributions are slow to acquire compiler updates. For Ubuntu, known compatible LLVM compilers are clang++-16 as shipped with Ubuntu 24.04, and clang++-20 as shipped with Ubuntu 25.04.
If targeting ARM64 (e.g., NVIDIA Grace):
sudo apt-get update
sudo apt-get install -y cmake g++-aarch64-linux-gnu
export CC="aarch64-linux-gnu-gcc"
export CXX="aarch64-linux-gnu-g++"If targeting x86/AMD64 (e.g., most Intel+AMD CPUs):
sudo apt-get update
sudo apt-get install -y cmake g++-x86-64-linux-gnu
export CC="x86_64-linux-gnu-gcc"
export CXX="x86_64-linux-gnu-g++"We are not aware of any compilation issues with gcc / g++ versions. Please file an issue if you come across a non-working configuration.
git clone https://github.com/NVIDIA/nvhashmap.git
cd nvhashmap
git submodule update --init --recursive
mkdir build
cd build
cmake -DNVHM_WANT_ALL=ON -DCMAKE_CXX_FLAGS="-march=armv9-a -mtune=neoverse-v2" ..git clone https://github.com/NVIDIA/nvhashmap.git
cd nvhashmap
git submodule update --init --recursive
mkdir build
cd build
cmake ..The cmake command will depend on the capabilties of your target. If you are compiling directly on your target machine, we will detect the capabilitites of your system and adjust the configuration automatically.
If the automatic process fails for you, or you want to compile cross-platform, you can toggle individual optimizations as follows.
General:
- When compiling on your target system, we strongly urge you to add
-DCMAKE_CXX_FLAGS="-march=native -mtune=native"when callingcmaketo ensure the compiler can generate the best possible code. - If you cross-compile, we cannot make any assumptions regarding your target hardware and will rely to compiler defaults. For optimal performance, you should set
-marchand-mtunevia-DCMAKE_CXX_FLAGS.
ARM64 specific:
-DNVHM_WANT_ALL=ONequivalent to setting all the following options toON.-DNVHM_WANT_NEON=ONenables ARM NEON codepath, which provides kernelsarm_kernel64_tandarm_kernel18_t(the NEON 128-bit kernel becomes thedefault_kernel_ton ARM64 targets).-DNVHM_WANT_SVE=ONenables ARM SVE codepath, which providesarm_sve_kernelX_tkernels, whereXis any power of 2 between[1, NVHM_WANT_SVE_MAX_BITS](if enabled, the SVE 128-bit SVE kernelarm_sve_kernel128_treplaces the 128-bit NEON kernel as thedefault_kernel_ton ARM64 targets).-DNVHM_WANT_SVE_MAX_BITS=<N>allows you specify the maximum SVE kernel size that can be used. If not specified, we will try to automatically determine and set this propertye on the build machine.
x86/AMD64 specific:
-DNVHM_WANT_ALL=ONequivalent to setting all the following options toON.-DNVHM_WANT_SSE2=ONenables x86 SSE2 codepath, which provides thex86_kernel128_tkernel (the SSE2 128-bit kernel becomes thedefault_kernel_ton x86/AMD64 targets).-DNVHM_WANT_SSE3=ONenables x86 SSE3 codepath, which enhandes the SSE2 kernel (also enablesNVHM_WANT_SSE2).-DNVHM_WANT_SSE4=ONenables x86 SSE4 codepath, which enhandes the SSE2 kernel (also enablesNVHM_WANT_SSE2).-DNVHM_WANT_AVX2=ONenables x86 AVX2 codepath, which provides the optionalx86_kernel256_tkernel (enabling this my also enhance the SSE kernel).-DNVHM_WANT_AVX512=ONenables x86 AVX-512 codepath, which provides the optionalx86_kernel512_tkernel (enabling this my also enhance the SSE2 and AVX2 kernels).-DNVHM_WANT_AVX_FVL=ONenhances SSE2, AVX2 and AVX512 kernels, if CPU supports the AVX-512 F and VL extensions.-DNVHM_WANT_AVX_BWVL=ONenhances SSE2, AVX2 and AVX512 kernels, if CPU supports the AVX-512 BW and VL extensions.-DNVHM_WANT_AVX_VBMI=ONenhances SSE2, AVX2 and AVX512 kernels, if CPU supports the AVX-512 VBMI extension.
Typically, you want to use NV Hash-Map from within your project. There are multiple ways to achieve this. For example, by adding it as a git submodule using, and then using add_subdirectory to execute the above configuration step as a nested cmake run. In this case you have to pass the previously discussed configuration options via the cmake environment.
An alternative, is to use the FetchContent plugin. In the following we provide a cmake-snippot that will download and make NV Hash-Map's headers available in your current cmake scope.
include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare(
nvhashmap
DOWNLOAD_COMMAND git clone
--branch main
--depth 1
--progress "https://github.com/NVIDIA/nvhashmap.git"
${CMAKE_BINARY_DIR}/_deps/nvhashmap-src
)
FetchContent_Populate(nvhashmap)
execute_process(WORKING_DIRECTORY ${nvhashmap_BINARY_DIR}
COMMAND cmake
-DCMAKE_BUILD_TYPE=Release
-DBUILD_TESTS=OFF
-DBUILD_BENCH=OFF
${nvhashmap_SOURCE_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
include_directories(
${nvhashmap_SOURCE_DIR}/include
${nvhashmap_BINARY_DIR}/include
)Assuming you have run cmake as discussed in the previous section, there is nothing you need to do
make -jTODO, for the moment src/benchmark.cpp provides a good example that shows how NV Hash-Map can be used and how it differs from std::unordered_map.
Actively maintained.
SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.