Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/compiler/compilation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,5 +322,18 @@ end
# link the SPIR-V bytes into a session-local `ZeKernel` on the given context and device.
function link_kernel(image::Vector{UInt8}, entry::String, ctx::ZeContext, dev::ZeDevice)
mod = ZeModule(ctx, dev, image)
kernels(mod)[entry]
kernel = kernels(mod)[entry]

# Kernels receive their arrays as `oneDeviceArray` structs, so to Level Zero every USM
# pointer they dereference is an indirect access. Without declaring that, the driver
# only maps the allocations we explicitly made resident, and a shared allocation that
# reuses the address of a freed (but never evicted) one isn't visible to the kernel:
# it reads zeros (JuliaGPU/oneAPI.jl#661). SYCL declares the same for all its kernels.
oneL0.indirect_access!(
kernel, oneL0.ZE_KERNEL_INDIRECT_ACCESS_FLAG_DEVICE |
oneL0.ZE_KERNEL_INDIRECT_ACCESS_FLAG_HOST |
oneL0.ZE_KERNEL_INDIRECT_ACCESS_FLAG_SHARED
)

return kernel
end
18 changes: 18 additions & 0 deletions test/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,24 @@ end
end
end

# https://github.com/JuliaGPU/oneAPI.jl/issues/661: kernels have to declare indirect access,
# or an allocation that reuses the address of a freed one isn't visible to them. Whether a
# reused shared allocation reads as zeros depends on allocator state, so churn through
# enough allocations (two live ones, freed in alternating order, plus collections of the
# reductions' outputs) to hit it reliably.
@testset "reusing freed $B allocations" for B in (oneL0.DeviceBuffer, oneL0.SharedBuffer, oneL0.HostBuffer)
results = map(1:100) do i
a = oneArray{Float32, 1, B}(fill(1.0f0, 1024))
b = oneArray{Float32, 1, B}(fill(2.0f0, 1024))
r = (sum(a), maximum(b))
oneAPI.unsafe_free!(isodd(i) ? a : b)
oneAPI.unsafe_free!(isodd(i) ? b : a)
i % 10 == 0 && GC.gc(false)
r
end
@test all(==((1024, 2)), results)
end

# https://github.com/JuliaGPU/CUDA.jl/issues/2191
@testset "preserving buffer types" begin
a = oneVector{Int,oneL0.SharedBuffer}([1])
Expand Down
Loading