diff --git a/docs/src/api/kernels.md b/docs/src/api/kernels.md index e82282eb..8a525fe7 100644 --- a/docs/src/api/kernels.md +++ b/docs/src/api/kernels.md @@ -37,7 +37,7 @@ used by `@oneapi`. Returns a callable kernel object. Convert arguments for kernel execution. This function is called for every argument passed to a kernel, allowing customization of argument conversion. By default, it converts `oneArray` -to `oneDeviceArray`. +to `oneDeviceArray`, and `ZePtr{T}` to `LLVMPtr{T,AS.CrossWorkgroup}`. ## Basic Kernel Example diff --git a/src/compiler/execution.jl b/src/compiler/execution.jl index b5b3a180..1ff3523f 100644 --- a/src/compiler/execution.jl +++ b/src/compiler/execution.jl @@ -158,8 +158,9 @@ struct KernelAdaptor end KernelAdaptor() = KernelAdaptor(nothing) -# convert oneAPI host pointers to device pointers -Adapt.adapt_storage(to::KernelAdaptor, p::ZePtr{T}) where {T} = reinterpret(Ptr{T}, p) +# device pointers are passed as global pointers; a plain `Ptr` is a private pointer in SPIR-V +Adapt.adapt_storage(to::KernelAdaptor, p::ZePtr{T}) where {T} = + reinterpret(LLVMPtr{T,AS.CrossWorkgroup}, p) # convert oneAPI host arrays to device arrays function Adapt.adapt_storage(to::KernelAdaptor, xs::oneArray{T,N}) where {T,N} diff --git a/test/execution.jl b/test/execution.jl index 2e52da33..0803023e 100644 --- a/test/execution.jl +++ b/test/execution.jl @@ -713,13 +713,28 @@ end if VERSION < v"1.12" a = oneArray(Float32[0]) - @oneapi kernel(pointer(a)) + @oneapi kernel(reinterpret(Ptr{Float32}, pointer(a))) @test Array(a) == [42] else @test_broken false end end +@testset "device pointer arguments" begin + # pointers to device memory are passed to kernels as global pointers; a plain `Ptr` + # would be a private pointer in SPIR-V, losing the store (#458) + function kernel(ptr, val) + unsafe_store!(ptr, val) + return + end + + for B in (oneL0.DeviceBuffer, oneL0.SharedBuffer, oneL0.HostBuffer) + a = oneVector{Int,B}([1]) + @oneapi kernel(pointer(a), 42) + @test Array(a) == [42] + end +end + ############################################################################################ # A chain of N live accumulators forces the register allocator to spill once N exceeds