Skip to content

Commit bc34dfe

Browse files
committed
Give workgroup barriers their memory-fence flags
`barrier(0)` lowers to an `OpControlBarrier` with `SequentiallyConsistent` semantics but no storage-class bit, which the SPIR-V spec treats as ordering no memory. So shared-local (and global) writes are not guaranteed visible to other work-items after the barrier, which can silently drop updates (e.g. a workgroup local-atomic accumulation losing counts). Pass the appropriate fence flags so the barrier actually orders memory: `LOCAL_MEM_FENCE | GLOBAL_MEM_FENCE` for KA `@synchronize` (matching CUDA `__syncthreads`), and `LOCAL_MEM_FENCE` for the mapreduce reduce_group shared-memory tree.
1 parent 8d49d4a commit bc34dfe

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

src/mapreduce.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333
# perform a reduction
3434
d = 1
3535
while d < items
36-
barrier(0)
36+
# Fence local memory: `barrier(0)` lowers to an OpControlBarrier without the
37+
# WorkgroupMemory storage-class bit, which does not order the shared-local tree
38+
# accesses across the barrier. Fence local memory so each tree step sees the
39+
# previous step's `shared[]` writes.
40+
barrier(SPIRVIntrinsics.LOCAL_MEM_FENCE)
3741
index = 2 * d * (item-1) + 1
3842
@inbounds if index <= items
3943
other_val = if index + d <= items

src/oneAPIKernels.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,13 @@ end
214214
## Synchronization and Printing
215215

216216
@device_override @inline function KA.__synchronize()
217-
barrier(0)
217+
# Fence both local and global memory across the workgroup barrier, matching CUDA
218+
# `__syncthreads` semantics. `barrier(0)` lowers to `OpControlBarrier` with
219+
# `SequentiallyConsistent` but WITHOUT any storage-class bit, which the SPIR-V spec
220+
# treats as ordering *no* memory — so shared-local or global writes are not guaranteed
221+
# visible to other work-items after the barrier. `LOCAL_MEM_FENCE | GLOBAL_MEM_FENCE`
222+
# ORs in the WorkgroupMemory/CrossWorkgroupMemory fence bits.
223+
barrier(SPIRVIntrinsics.LOCAL_MEM_FENCE | SPIRVIntrinsics.GLOBAL_MEM_FENCE)
218224
end
219225

220226
@device_override @inline function KA.__print(args...)

0 commit comments

Comments
 (0)