Hello,
I’m encountering unexpected behavior when reading/writing a global RWStructuredBuffer inside an OptiX anyhit program, and I’m not sure if this is intended or a bug.
I’m implementing a per-ray max-heap (stored in a global RWStructuredBuffer t_distances passed as a launch parameter) to keep the max_iters closest hits. Writes happen in anyhit until the buffer is full. Then buffer is heapified and subsequent hits are heap inserted into the heap. Raygen performs heapsort and integration.
The issue is that reads from the buffer inside anyhit sometimes return 0 even after a confirmed write, while the same logic works correctly in raygen (heapify happens there if max_iters hit are not reached).
For example,
///////////////////////////////////////
// Inside the anyhit kernel
///////////////////////////////////////
uint hit_count = get_payload0();
for (int n = 0; n < 2; n++)
{
float t = ts[n];
// Skip entry if behind ray start
if (n == 0 && t <= cur_t) continue;
if (hit_count < max_iters) // Simple insertion on the hit_count idx
{
// Fill phase
if (r_ind == 107860) // just a debug ray that visually had issues
{
if (hit_count > 0) // avoid hitting illegal memory
printf("before setting %d [%d]~%f [%d]~%f\n",
n, hit_count, t_distances[r_ind + hit_count * num_rays],
hit_count - 1, t_distances[r_ind + (hit_count - 1) * num_rays]);
}
t_distances[r_ind + hit_count * num_rays] = t;
if (r_ind == 107860) // just a debug ray that visually had issues
{
if (hit_count > 0) // avoid hitting illegal memory
printf("after setting %d [%d]~%f [%d]~%f\n",
n, hit_count, t_distances[r_ind + hit_count * num_rays],
hit_count - 1, t_distances[r_ind + (hit_count - 1) * num_rays]);
}
hit_count++;
set_payload0(hit_count);
// Once full, build heap in O(N)
if (hit_count == max_iters)
{
heapify(r_ind, num_rays, max_iters);
}
}
else // Heap insert
{
if (t < t_distances[r_ind])
{
heap_replace_root(...);
}
}
}
The (truncated) print output is the following:
before setting 0 [2]~0.000000 [1]~1.329237
after setting 0 [2]~1.475692 [1]~1.329237
before setting 1 [3]~0.000000 [2]~0.000000
after setting 1 [3]~1.697015 [2]~0.000000
before setting 0 [4]~0.000000 [3]~1.697015
after setting 0 [4]~1.435285 [3]~1.697015
It looks like some writes are not visible to subsequent reads within the same ray, in a weird pattern. A similar behaviour is present inside heapify, causing the bug. I launch one thread per ray, so it’s not a race condition. Also, I’ve triple checked that I’m not accidentally accessing illegal memory.
Could this be due to caching, memory visibility rules that I ignored, or restrictions on global memory access in anyhit programs?
My setup is:
- CUDA 12.8
- RTX Pro 5000 Blackwell
- Optix 9.1
- Slang 2026.5.1
Thanks in advance!
Panagiotis