Skip to content

Commit a784431

Browse files
committed
oneAPI: make in-process NEO discovery real, fix LD_LIBRARY_PATH comment
Setting ENV["LD_LIBRARY_PATH"] inside __init__ cannot affect the running process's dlopen search paths: glibc captures LD_LIBRARY_PATH once at process startup, so the stated purpose (letting libsycl's bundled ze_lib find NEO's libze_intel_gpu in-process) was never served for the current process — only for child processes that inherit the environment. dlopen the NEO driver by full path in __init__ so it is resident before libsycl loads; a later dlopen("libze_intel_gpu.so.1") by libsycl's bundled loader then resolves to it by soname without a path search. Keep extending LD_LIBRARY_PATH but correct the comment to say it only covers spawned worker processes. Verified oneMKL (which loads libsycl and needs NEO discovery) still works. Addresses PR_REVIEW.md finding #10.
1 parent 4374f68 commit a784431

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

src/oneAPI.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ using LLVM
1717
using LLVM.Interop
1818
using Core: LLVMPtr
1919

20+
import Libdl
21+
2022
# Load both SPIR-V codegen back-ends: GPUCompiler resolves the tool from the target's
2123
# `backend` field (`:khronos` -> translator, `:llvm` -> LLVM back-end) via a LazyModule that
2224
# looks the JLL up in `Base.loaded_modules`, so both must be loaded for either path to work.
@@ -144,9 +146,20 @@ function __init__()
144146
# ensure that the OpenCL loader finds the ICD files from our artifacts
145147
ENV["OCL_ICD_FILENAMES"] = oneL0.NEO_jll.libigdrcl
146148

147-
# ensure that libsycl's bundled ze_lib finds NEO's libze_intel_gpu via
148-
# path-based driver discovery (it does not reuse the JLL-loaded module).
149-
# Required when no system NEO is installed.
149+
# libsycl (loaded later for oneMKL) carries its own bundled Level Zero loader
150+
# that rediscovers the NEO driver by dlopen'ing it by soname rather than
151+
# reusing our JLL-loaded module. dlopen NEO here by full path so it is already
152+
# resident in this process before libsycl loads: a later
153+
# dlopen("libze_intel_gpu.so.1") then resolves to this module by soname without
154+
# needing a search path. Required when no system NEO is installed.
155+
Libdl.dlopen(oneL0.NEO_jll.libze_intel_gpu; throw_error = false)
156+
157+
# Extend LD_LIBRARY_PATH with the NEO directory as well. NOTE: this does NOT
158+
# affect the running process's own dlopen search — glibc captures
159+
# LD_LIBRARY_PATH once at startup — so it serves only *child* processes (e.g.
160+
# the multi-worker test suite) that inherit the environment and do their own
161+
# path-based driver discovery. In-process discovery is handled by the dlopen
162+
# above (and by ZE_ENABLE_ALT_DRIVERS, set in oneL0's __init__).
150163
neo_libdir = dirname(oneL0.NEO_jll.libze_intel_gpu)
151164
ld = get(ENV, "LD_LIBRARY_PATH", "")
152165
if !occursin(neo_libdir, ld)

0 commit comments

Comments
 (0)