// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include // FNV-1a over a block of bytes. Not a cryptographic hash and does not need to be - it exists to // notice that the bytes behind a reused address changed, not to resist anyone. Its user is the // shared device-table cache (image_analysis/indexing/CudaSharedTables.h), which keys on it; it lives // here so the classes that own those tables can compute their own checksum once and hand it in. // // Run over eight interleaved lanes and fold them at the end. FNV's multiply is a loop-carried // dependency, so one lane retires a byte every few cycles however much memory bandwidth is going // spare; eight independent chains fill that latency. inline uint64_t TableChecksum(const void *data, size_t bytes) { constexpr uint64_t PRIME = 1099511628211ULL; constexpr size_t LANES = 8; const auto *p = static_cast(data); uint64_t h[LANES]; for (size_t l = 0; l < LANES; l++) h[l] = 1469598103934665603ULL + l; const size_t n = bytes / LANES * LANES; for (size_t i = 0; i < n; i += LANES) for (size_t l = 0; l < LANES; l++) { h[l] ^= p[i + l]; h[l] *= PRIME; } uint64_t out = 1469598103934665603ULL; for (size_t l = 0; l < LANES; l++) { out ^= h[l]; out *= PRIME; } for (size_t i = n; i < bytes; i++) { out ^= p[i]; out *= PRIME; } return out; }