Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

PoCL: math on 256-bit vectors returns garbage with the non-AVX x86 kernel libraries

Open
#552 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
28/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
c
Domain
compilers

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from JuliaGPU/OpenCL.jl

All issues in JuliaGPU/OpenCL.jl

Similar issues

More Julia issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.