You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PoCL drops the stores of a work-group when a value lives across a barrier inside a branch #548
PoCL miscompiles a barrier inside a branch when a work-item value computed before the barrier is used after it: a work-group in which that value differs between work-items stores nothing, not even from the work-items for which it holds. The barrier is valid OpenCL, since all work-items of a work-group take the same branch.
using OpenCL, pocl_jll
# In the last work-group only, a per-work-item value is computed before a barrier and used# after it. That work-group stores nothing.
src ="""kernel void k(global long *A, long n) { size_t I = get_global_id(0); if (get_group_id(0) == get_num_groups(0) - 1) { bool active = I < n; barrier(CLK_LOCAL_MEM_FENCE); if (active) A[I] = I + 1; } else { A[I] = I + 1; }}"""
prog = cl.Program(; source = src) |> cl.build!
kern = cl.Kernel(prog, "k")
n =37
A =CLArray(zeros(Int, 40))
clcall(kern, Tuple{CLPtr{Int}, Int}, A, n; global_size =40, local_size =8)
@showArray(A)[1:n]
Work-items 32–36 of the last work-group should have stored 33–37. Variants of the kernel above:
variant
result
as above
wrong
if (n > 0) around the barrier (all work-groups take it): the last work-group still stores nothing
wrong
int instead of long/size_t
wrong
I < n evaluated after the barrier instead of before it
correct
no branch around the barrier
correct
POCL_WORK_GROUP_METHOD=cbs
correct
built with -cl-opt-disable
correct
Also wrong with PoCL main (b3033f8d3), so it isn't fixed upstream yet. OpenCL.jl 0.10.12, pocl_jll 7.2.2+1 (LLVM 22.1.8), Ryzen 9 9950X.
This came up in KernelAbstractions.jl, when compiling each @kernel body twice, without and with bounds checks, and choosing per work-group which copy runs (an alternative to JuliaGPU/KernelAbstractions.jl#849). With @synchronize that puts a barrier under a group-dependent branch, and the partial last work-group then stored nothing.
Activity