PoCL: math on 256-bit vectors returns garbage with the non-AVX x86 kernel libraries
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 28/100
Research direction
Start by reproducing with the MWE under POCL_KERNELLIB_NAME=sse2, then run the SIMD - 8 x Float32 and SIMD - 4 x Float64 sin/cos tests in test/intrinsics.jl. The issue points to where the vector-library mapping happens: PoCL's kernel library setup, or LLVM's ReplaceWithVeclib, which picks AVX2 _ZGVdN8v_sinf regardless of target features. Done means 256-bit results are correct on non-AVX libraries and AVX paths are unchanged.
Written by the indexing model from the issue text.
Description
On Linux x86, when PoCL uses one of its kernel libraries without AVX (sse2, ssse3 or sse41), math builtins on 256-bit vectors (Vec{8,Float32}, Vec{4,Float64}; float8/double4 in OpenCL C) return the correct lower half and garbage in the upper half. CPUs without AVX get these libraries; they include not just pre-2011 parts but also Atom/Celeron/Pentium Silver chips (e.g. Goldmont Plus, which gets sse41). On a machine with AVX the libraries can be forced with POCL_KERNELLIB_NAME:
using OpenCL, pocl_jll, SIMD
function kernel(out, x)
out[] = sin(x)
return
end
for (N, T) in ((4, Float32), (8, Float32), (16, Float32), (2, Float64), (4, Float64), (8, Float64))
x = Vec{N,T}(ntuple(i -> T(i) / 10, N))
out = CLArray{Vec{N,T},0}(undef)
@opencl kernel(out, x)
y = OpenCL.@allowscalar out[]
println(rpad("$N x $T", 12), all(y[i] ≈ sin(x[i]) for i in 1:N) ? "ok " : "WRONG", " ", y)
end
$ POCL_KERNELLIB_NAME=sse2 julia --project mwe.jl
4 x Float32 ok <4 x Float32>[0.09983342, 0.19866933, 0.29552022, 0.38941836]
8 x Float32 WRONG <8 x Float32>[0.09983342, 0.19866933, 0.29552022, 0.38941836, 0.0, 0.0, 0.0, 0.0]
16 x Float32ok ...
2 x Float64 ok <2 x Float64>[0.09983341664682815, 0.19866933079506122]
4 x Float64 WRONG <4 x Float64>[0.09983341664682815, 0.19866933079506122, 0.0, 0.0]
8 x Float64 ok ...
ssse3 and sse41 give the same result; avx, avx2 and the default library are fine. The OpenCL C path is affected too: with POCL_KERNELLIB_NAME=sse2, the SIMD - 8 x Float32 and SIMD - 4 x Float64 sin/cos tests in test/intrinsics.jl fail on both pocl and poclc.
Cause: the kernel is compiled for target-cpu=x86-64 with SSE2 features only, and sin on the vector stays an llvm.sin.v8f32 intrinsic. That intrinsic is then replaced with libmvec's AVX2 variant regardless of the target's features. The undefined symbols of the cached kernel objects:
4 x Float32: _ZGVbN4v_sinf (SSE)
8 x Float32: _ZGVdN8v_sinf (AVX2)
2 x Float64: _ZGVbN2v_sin (SSE)
4 x Float64: _ZGVdN4v_sin (AVX2)
Without AVX the caller passes and receives the <8 x float> in two XMM registers, while _ZGVdN8v_sinf uses YMM0, so only the lower half survives. On a CPU that really lacks AVX the call is invalid. The 512-bit vectors aren't mapped to the AVX-512 variants and work. With the avx library the same AVX2 variants are used, but that works because the ABI matches and glibc dispatches internally.
So the vector-library mapping needs to respect the target features, either in PoCL's setup of the vector library or in LLVM's ReplaceWithVeclib. I haven't checked which one, or whether PoCL main behaves differently. Windows has no vector library, so it's unaffected; I haven't tested macOS.
pocl_jll 7.2.2+3 (also 7.2.2+2), OpenCL.jl 0.10.12, Julia 1.13.1, Linux x86_64 (Zen 5).
- Dominant language
- Julia
- Stars
- 313
- Forks
- 50
- Avg merge
- 23h 33m
- Merged PRs (30d)
- 35
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from JuliaGPU/OpenCL.jl
-
Intel CPU runtime: reports half-precision atomic addition but lacks the atomic_add builtin for halfOpenDrivers Intel CPU upstream
Difficulty 4/5 1-2 days Newbie friendliness 55/100
Maintainers usually reply within 1 day
-
Drivers Intel CPU upstream
Difficulty 4/5 3-5 days Newbie friendliness 43/100
JuliaGPU/OpenCL.jl#559 · 1 comment ·
Maintainers usually reply within 1 day
-
Drivers Intel CPU upstream
Difficulty 4/5 3-5 days Newbie friendliness 35/100
JuliaGPU/OpenCL.jl#558 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
JuliaGPU/OpenCL.jl#550 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
Maintainers usually reply within 1 day
All issues in JuliaGPU/OpenCL.jl
Similar issues
-
code-review
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
JuliaNLSolvers/Optim.jl#1296 ·
-
OptimizationCUTEst jobs fail: gfortran not installed on the runnerPossibly taken @ChrisRackauckas-Claude claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
SciML/SciMLBenchmarks.jl#1946 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
JuliaSmoothOptimizers/NCL.jl#101 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 69/100