diff --git a/src/device/array.jl b/src/device/array.jl index 24822656..75ba7908 100644 --- a/src/device/array.jl +++ b/src/device/array.jl @@ -325,7 +325,7 @@ function matmul_kernel(A, B, C) tile_A[local_i, local_j] = A[...] tile_B[local_i, local_j] = B[...] - barrier() # Synchronize workgroup + barrier(oneAPI.LOCAL_MEM_FENCE) # synchronize the workgroup, fencing local memory # Compute using local memory # ... diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 822b9b16..645db2cd 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -33,7 +33,11 @@ # perform a reduction d = 1 while d < items - barrier(0) + # Fence local memory: `barrier(0)` lowers to an OpControlBarrier without the + # WorkgroupMemory storage-class bit, which does not order the shared-local tree + # accesses across the barrier. Fence local memory so each tree step sees the + # previous step's `shared[]` writes. + barrier(SPIRVIntrinsics.LOCAL_MEM_FENCE) index = 2 * d * (item-1) + 1 @inbounds if index <= items other_val = if index + d <= items diff --git a/src/oneAPIKernels.jl b/src/oneAPIKernels.jl index 6e092397..bc6f3218 100644 --- a/src/oneAPIKernels.jl +++ b/src/oneAPIKernels.jl @@ -214,7 +214,13 @@ end ## Synchronization and Printing @device_override @inline function KA.__synchronize() - barrier(0) + # Fence both local and global memory across the workgroup barrier, matching CUDA + # `__syncthreads` semantics. `barrier(0)` lowers to `OpControlBarrier` with + # `SequentiallyConsistent` but WITHOUT any storage-class bit, which the SPIR-V spec + # treats as ordering *no* memory — so shared-local or global writes are not guaranteed + # visible to other work-items after the barrier. `LOCAL_MEM_FENCE | GLOBAL_MEM_FENCE` + # ORs in the WorkgroupMemory/CrossWorkgroupMemory fence bits. + barrier(SPIRVIntrinsics.LOCAL_MEM_FENCE | SPIRVIntrinsics.GLOBAL_MEM_FENCE) end @device_override @inline function KA.__print(args...)