The test suite lives in tests/, with each test_*.cu compiled into its own executable.
Run the full suite with make test, which builds each binary under build/tests/ and executes them in sequence.
test_construction.cu— construct / destruct, move semantics, edge sizes (capacity == bucket_size, capacity below bucket_size), moved-from state behavior, andclear()returning the bucket array to the empty-byte pattern.test_combined.cu— end-to-end insert + get round-trips through the public API.test_get.cu—View::getin isolation. Pre-states are hand-built withIdentityHashso the probe sequence and home buckets are deterministic; the test then verifiesget's match / empty / richer-resident / wrap-around behavior.test_insert.cu—View::insertin isolation. Some tests use hand-computed expected layouts; all run a Robin Hood invariant scanner over the final state as a safety net. Covers the probe-cap failure path and concurrent same-key inserts.test_concurrency.cu— heavy parallel contention: adversarial displacement chains, many concurrent gets, mixed new / duplicate inserts, parallel saturation of the probe cap.test_randomized.cu— randomized stress. Uniform-key inserts at small (4 KB table) and gigabyte (1 GB table) scales; a sum-reduction stress test with random keys and deliberate duplicates whose expected per-key sum is computed on the host.
Three shared infrastructure headers:
tests/tests.cuh— theCUDA_CHECKpostfix error-check operator (expr >> CUDA_CHECK).tests/kernels.cuh— theTablealias (withdefault_hash), bulk insert/get host helpers, and end-to-end driver kernels. Used by the "combined" and construction tests.tests/isolated.cuh— theTestTablealias (withIdentityHashfor predictable home buckets), templatedrun_insert/run_get/run_get_one/run_insert_with_outcomes, theassert_robin_hood_invariantscanner, andset_state/read_statefor direct table-memory manipulation viaHashTable::data().
We use an identity hash function (IdentityHash) to facilitate isolated tests: with hash(K) = K, the home bucket of a key is fully predictable from its value, so we can construct any valid Robin Hood state with one cudaMemcpy and hand-predict the outcome of small insert sequences.
The randomized tests apply a bit-mixing function (the same fmix32 finalizer used by default_hash) as a permutation on sequential integers — this gives distinct random-looking keys without the slow host-side deduplication overhead that an unordered_set would require, which is what makes the gigabyte-scale tests run reasonably fast.
The test suite runs about 40 tests across ~1500 lines of test code (plus ~500 lines of shared test infrastructure under tests.cuh / kernels.cuh / isolated.cuh), against ~750 lines of library code under include/gpurhh/.
The high ratio is deliberate: this is a concurrent data structure, and the failure modes for concurrent CAS retries, displacement chains, and probe-cap interactions are subtle enough that we put significant effort into checking each path.