Skip to content

Commit 830c49b

Browse files
authored
Re-pin variable sized memory (#2599)
1 parent 0d6db97 commit 830c49b

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

lib/cudadrv/memory.jl

+14-4
Original file line numberDiff line numberDiff line change
@@ -659,9 +659,14 @@ end
659659

660660
const __pin_lock = ReentrantLock()
661661

662+
struct PinnedObject
663+
ref::WeakRef
664+
size::Int # memory size in bytes
665+
end
666+
662667
# - IdDict does not free the memory
663668
# - WeakRef dict does not unique the key by objectid
664-
const __pinned_objects = Dict{Tuple{CuContext,Ptr{Cvoid}}, WeakRef}()
669+
const __pinned_objects = Dict{Tuple{CuContext,Ptr{Cvoid}}, PinnedObject}()
665670

666671
function pin(a::AbstractArray)
667672
ctx = context()
@@ -670,10 +675,15 @@ function pin(a::AbstractArray)
670675
Base.@lock __pin_lock begin
671676
# only pin an object once per context
672677
key = (ctx, convert(Ptr{Nothing}, ptr))
673-
if haskey(__pinned_objects, key) && __pinned_objects[key].value !== nothing
674-
return nothing
678+
if haskey(__pinned_objects, key) && __pinned_objects[key].ref.value !== nothing
679+
if sizeof(a) == __pinned_objects[key].size
680+
return nothing
681+
else
682+
# if the object size has changed, unpin it first; it will be re-pinned with the new size
683+
__unpin(ptr, ctx)
684+
end
675685
end
676-
__pinned_objects[key] = WeakRef(a)
686+
__pinned_objects[key] = PinnedObject(WeakRef(a), sizeof(a))
677687
end
678688

679689
__pin(ptr, sizeof(a))

test/core/cudadrv.jl

+14
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,20 @@ if attribute(device(), CUDA.DEVICE_ATTRIBUTE_HOST_REGISTER_SUPPORTED) != 0
689689
dA = CUDA.rand(UInt8, 512)
690690
copyto!(dA, hA)
691691
copyto!(hA, dA)
692+
693+
# memory copies with resized pinned memory (used to fail with CUDA_ERROR_INVALID_VALUE)
694+
dA = rand(Float32, 100)
695+
hA = Array(dA)
696+
@test !CUDA.is_pinned(pointer(hA))
697+
for n 100:2000
698+
resize!(dA, n)
699+
resize!(hA, n)
700+
dA .= n
701+
CUDA.pin(hA)
702+
@test CUDA.is_pinned(pointer(hA))
703+
copyto!(hA, dA)
704+
copyto!(dA, hA)
705+
end
692706
end
693707

694708
end

0 commit comments

Comments
 (0)