From f01186ecab8d5ec8c1d87d95165584b2e76a46c3 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 19 Aug 2026 21:57:48 +0200 Subject: [PATCH] Synchronize pageable host uploads Level Zero memory copies read their host source when the queued command executes, but Array uploads returned after submission and only preserved the source through that submission. A temporary source could therefore be collected and its storage reused before a delayed copy ran, silently corrupting device data. Synchronize the task-local queue inside the GC preserve region so pageable host memory remains valid until the upload completes. This deliberately makes Array-to-device copies synchronous, matching the existing device-to-Array behavior. --- src/array.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/array.jl b/src/array.jl index 6fdeaef6..4c805403 100644 --- a/src/array.jl +++ b/src/array.jl @@ -445,11 +445,17 @@ Base.copyto!(dest::oneDenseArray{T}, src::oneDenseArray{T}) where {T} = function Base.unsafe_copyto!(ctx::ZeContext, dev::ZeDevice, dest::oneDenseArray{T}, doffs, src::Array{T}, soffs, n) where T - GC.@preserve src dest unsafe_copyto!(ctx, dev, pointer(dest, doffs), pointer(src, soffs), n) + GC.@preserve src dest begin + unsafe_copyto!(ctx, dev, pointer(dest, doffs), pointer(src, soffs), n) + + # Keep pageable host memory alive until the queued copy completes. + synchronize(global_queue(ctx, dev)) + end if Base.isbitsunion(T) # copy selector bytes error("oneArray does not yet support isbits-union arrays") end + return dest end