Skip to content

Commit 8b4522d

Browse files
maleadtclaude
andauthored
PoCL 7.2: vectorize OpenCL math builtins via SLEEF_jll (libsleefgnuabi) (#14098)
Wire a vector-math library into the CPU kernel compiler so transcendental builtins (sin/exp/log/...) vectorize to packed _ZGV* calls, resolved at run time by the in-process JIT (dynamic, no redistributed .so beyond the SLEEF_jll dependency). - Bump pocl to e344b0f02c2c (adds a configurable libmvec SONAME for the JIT to dlopen, instead of the hardcoded libmvec.so.1, so it can use a shipped lib on musl/old-glibc). - common.jl: on x86_64 use LLVM's libmvec veclib (_ZGVdN*); on aarch64 use the SLEEF veclib (_ZGVnN*); point both at SLEEF's libsleefgnuabi (a drop-in libmvec-ABI lib). - Add a SLEEF_jll dependency on x86_64/aarch64 for Linux+FreeBSD -- the ELF targets where LLVM maps a veclib AND SLEEF_jll ships libsleefgnuabi (not macOS: no GNUABI on Mach-O; not Windows: no SLEEF_jll). Validated locally via OpenCL.jl: a transcendental kernel compiles to <8 x float> @llvm.sin.v8f32 and the object calls _ZGVdN8v_sinf, resolved against libsleefgnuabi, with correct results. NB: on AVX-512 hosts the work-item loop picks width 16, which LLVM's x86 veclib tables don't cover (max width 8), so math scalarizes there; AVX2 (8) and aarch64 NEON (4) get packed calls. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c48f1d2 commit 8b4522d

3 files changed

Lines changed: 42 additions & 16 deletions

File tree

P/pocl/common.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,29 @@ function build_script(standalone=false)
289289
CMAKE_FLAGS+=(-DHOST_COMPILER_SUPPORTS_FLOAT16:BOOL=OFF)
290290
fi
291291
292+
# Vectorize OpenCL math builtins (sin/exp/log/...) via a vector-math library. This is
293+
# gated to exactly where it can work: LLVM's TargetLibraryInfo only maps a veclib for
294+
# x86_64 (libmvec ABI, _ZGVdN*) and aarch64 (SLEEF ABI, _ZGVnN*), and SLEEF_jll only ships
295+
# the symbol-providing libsleefgnuabi on ELF targets -- Linux and FreeBSD (NOT macOS, which
296+
# has no GNUABI variant on Mach-O, and NOT Windows, where SLEEF_jll isn't built). The
297+
# in-process JIT dlopens it by SONAME at run time, so nothing is redistributed beyond the
298+
# SLEEF_jll dependency (added per-platform in build_tarballs.jl). Elsewhere there's no
299+
# veclib -> the kernel body still vectorizes, transcendentals stay scalar. NB: on AVX-512
300+
# hosts the work-item loop tends to pick width 16, which LLVM's x86 veclib tables don't
301+
# cover (they stop at width 8), so the math scalarizes there; AVX2 (width 8) and aarch64
302+
# NEON (width 4) get packed _ZGV* calls. (Separate from the always-on SLEEF kernel library,
303+
# ENABLE_SLEEF.)
304+
sleef_gnuabi="${prefix}/lib/libsleefgnuabi.so"
305+
if [[ "${target}" == x86_64-linux-* || "${target}" == x86_64-*freebsd* ]]; then
306+
CMAKE_FLAGS+=(-DENABLE_HOST_CPU_VECTORIZE_LIBMVEC:BOOL=ON)
307+
CMAKE_FLAGS+=(-DLIBMVEC="${sleef_gnuabi}")
308+
# libsleefgnuabi exports the required _ZGV* symbols; skip the (cross-unfriendly) probe.
309+
CMAKE_FLAGS+=(-DLIBMVEC_HAS_REQUIRED_SYMBOLS:BOOL=ON)
310+
elif [[ "${target}" == aarch64-linux-* || "${target}" == aarch64-*freebsd* ]]; then
311+
CMAKE_FLAGS+=(-DENABLE_HOST_CPU_VECTORIZE_SLEEF:BOOL=ON)
312+
CMAKE_FLAGS+=(-DLIBSLEEF="${sleef_gnuabi}")
313+
fi
314+
292315
# Link LLVM statically so that we don't have to worry about versioning the JLL against it
293316
CMAKE_FLAGS+=(-DSTATIC_LLVM:Bool=ON)
294317
# XXX: we add -pthread to the flags used to link libLLVM, so need that here too

P/pocl/pocl_next/build_tarballs.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ version = v"7.2.0"
2121
sources = [
2222
DirectorySource("./bundled"),
2323
GitSource("https://github.com/JuliaGPU/pocl",
24-
"88a7a839b58ff7f0e3720f58ed858eaf1480111b"),
24+
"e344b0f02c2c9f3680aa9ebc2fe13846783e8af1"),
2525
# vendored SPIR-V translator, built as a static library against our LLVM (see
2626
# common.jl); this commit is the LLVM-20.1-compatible revision (matches
2727
# LLVM_full_jll 20.1.2).
@@ -93,14 +93,15 @@ for platform in platforms
9393
platform_sources = deepcopy(sources)
9494
platform_dependencies = deepcopy(dependencies)
9595

96-
# for fp16, we need a vectorization library
97-
if arch(platform) in ["armv6l", "aarch64"]
98-
#push!(platform_dependencies, Dependency("SLEEF_jll"))
99-
# XXX: PoCL hard-codes the path to libsleef
100-
# `no such file or directory: '/opt/aarch64-linux-gnu/aarch64-linux-gnu/sys-root/usr/local/lib/libsleef.so'`
96+
# Vectorize OpenCL math builtins via SLEEF's libmvec-ABI / SLEEF compat library
97+
# (libsleefgnuabi), which the in-process JIT dlopens at run time (see common.jl for the
98+
# matching CMake flags). Gated to x86_64/aarch64 on the ELF OSes where LLVM maps a veclib
99+
# *and* SLEEF_jll ships libsleefgnuabi: Linux and FreeBSD (not macOS -- no GNUABI on
100+
# Mach-O -- and not Windows -- no SLEEF_jll). Static linking isn't used: the JIT resolves
101+
# _ZGV* symbols by dlopen, so a dynamic dependency is the natural fit.
102+
if (Sys.islinux(platform) || Sys.isfreebsd(platform)) && arch(platform) in ["x86_64", "aarch64"]
103+
push!(platform_dependencies, Dependency("SLEEF_jll"))
101104
end
102-
# TODO: libsvml for x86 (part of mkl)
103-
# TODO: libmvec as fallback (part of glibc 2.22+)
104105

105106
# On Windows we now link PoCL with the Clang/lld toolchain, but still build against this
106107
# GCC's MinGW sysroot and libstdc++, so its version must stay compatible with the

P/pocl/pocl_standalone/build_tarballs.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ version = v"7.2.0"
2525
sources = [
2626
DirectorySource("./bundled"),
2727
GitSource("https://github.com/JuliaGPU/pocl",
28-
"88a7a839b58ff7f0e3720f58ed858eaf1480111b"),
28+
"e344b0f02c2c9f3680aa9ebc2fe13846783e8af1"),
2929
# vendored SPIR-V translator, built as a static library against our LLVM (see
3030
# common.jl); this commit is the LLVM-20.1-compatible revision (matches
3131
# LLVM_full_jll 20.1.2).
@@ -96,14 +96,16 @@ for platform in platforms
9696
platform_sources = deepcopy(sources)
9797
platform_dependencies = deepcopy(dependencies)
9898

99-
# for fp16, we need a vectorization library
100-
if arch(platform) in ["armv6l", "aarch64"]
101-
#push!(platform_dependencies, Dependency("SLEEF_jll"))
102-
# XXX: PoCL hard-codes the path to libsleef
103-
# `no such file or directory: '/opt/aarch64-linux-gnu/aarch64-linux-gnu/sys-root/usr/local/lib/libsleef.so'`
99+
# Vectorize OpenCL math builtins via SLEEF's libmvec-ABI / SLEEF compat library
100+
# (libsleefgnuabi), which the in-process JIT dlopens at run time (see common.jl for the
101+
# matching CMake flags). Gated to x86_64/aarch64 on the ELF OSes where LLVM maps a veclib
102+
# *and* SLEEF_jll ships libsleefgnuabi: Linux and FreeBSD (not macOS -- no GNUABI on
103+
# Mach-O -- and not Windows -- no SLEEF_jll). Even though this is the "standalone"
104+
# (JLL-dependency-free in spirit) build, a dynamic SLEEF_jll dep is the natural fit: the
105+
# JIT resolves _ZGV* symbols by dlopen, not by static linking.
106+
if (Sys.islinux(platform) || Sys.isfreebsd(platform)) && arch(platform) in ["x86_64", "aarch64"]
107+
push!(platform_dependencies, Dependency("SLEEF_jll"))
104108
end
105-
# TODO: libsvml for x86 (part of mkl)
106-
# TODO: libmvec as fallback (part of glibc 2.22+)
107109

108110
# On Windows we now link PoCL with the Clang/lld toolchain, but still build against this
109111
# GCC's MinGW sysroot and libstdc++, so its version must stay compatible with the

0 commit comments

Comments
 (0)