diff --git a/src/pocl/pocl.jl b/src/pocl/pocl.jl index a752e86f0..371390949 100644 --- a/src/pocl/pocl.jl +++ b/src/pocl/pocl.jl @@ -174,6 +174,12 @@ function Adapt.adapt_storage(to::KernelAdaptor, xs::Array{T, N}) where {T, N} return CLDeviceArray{T, N, AS.CrossWorkgroup}(size(xs), reinterpret(LLVMPtr{T, AS.CrossWorkgroup}, ptr), maxsize) end +# VERSION >= v"1.11" +@static if isdefined(Core, :Memory) + # wrapping `Memory` in an `Array` doesn't copy it + Adapt.adapt_storage(to::KernelAdaptor, xs::Memory) = adapt(to, Base.wrap(Array, xs, length(xs))) +end + import KernelInterface include("backend.jl") import .POCLKernels: POCLBackend diff --git a/test/runtests.jl b/test/runtests.jl index cf61bf306..a12ca5028 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -794,6 +794,34 @@ end end end +# `Memory` belongs to the POCL back-end too, so kernels take it like an `Array` +@kernel function add_one_memory!(B, @Const(A)) + i = @index(Global) + @inbounds B[i] = coalesce(A[i], 0) + 1 +end +# VERSION >= v"1.11" +@static if isdefined(Core, :Memory) + @testset "POCL Memory arguments" begin + A = Memory{Int32}(undef, 5) + A .= 1:5 + B = Memory{Float32}(undef, 5) + add_one_memory!(POCLBackend())(B, A; ndrange = 5) + synchronize(POCLBackend()) + @test B == 2:6 + + C = zeros(Int32, 3) + add_one_memory!(POCLBackend())(C, view(A, 2:4); ndrange = 3) + synchronize(POCLBackend()) + @test C == 3:5 + + U = Memory{Union{Missing, Int32}}(undef, 4) + U .= [1, missing, 3, missing] + add_one_memory!(POCLBackend())(C, U; ndrange = 3) + synchronize(POCLBackend()) + @test C == [2, 1, 4] + end +end + # a struct with a union field is not isbits, but is stored inline with its own selector struct UnionField x::Union{Int, Float32}