Skip to content

Commit 056a526

Browse files
authored
Always inspect the task-local context when verifying before freeing. (#1462)
For some reason, the thread-bound context can become desynchronized from the task-local one. Generally we don't notice this, because we prefix every API call with a call that synchronizes both. Here, however, we explicitly didn't to avoid initializing the state as that was thought to cause the kind of initialization that may have to yield (which is unsupported when done so from a finalizer). However, just creating the task local state shouldn't result in yield, only creating a stream does, like querying `active_state` as was done before #1383.
1 parent dc8a11e commit 056a526

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

lib/cufft/fft.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ abstract type CuFFTPlan{T<:cufftNumber, K, inplace} <: Plan{T} end
2525
Base.convert(::Type{cufftHandle}, p::CuFFTPlan) = p.handle
2626

2727
function CUDA.unsafe_free!(plan::CuFFTPlan, stream::CuStream=stream())
28+
# verify that the caller has switched contexts
29+
if plan.ctx != context()
30+
error("Trying to free $plan from an unrelated context")
31+
end
32+
2833
cufftDestroy(plan)
2934
unsafe_free!(plan.workarea, stream)
3035
end

src/pool.jl

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -351,17 +351,9 @@ Releases a buffer `buf` to the memory pool.
351351
return
352352
end
353353
@inline function _free(buf::Mem.DeviceBuffer; stream::Union{Nothing,CuStream})
354-
# NOTE: this function is often called from finalizers, from which we can't switch tasks,
355-
# so we need to take care not to call managed functions (i.e. functions that may
356-
# initialize the CUDA context) because querying the active context using
357-
# `current_context()` takes a lock
358-
359-
# verify that the caller has called `context!` already, which eagerly activates the
360-
# context (i.e. doesn't only set it in the state, but configures the CUDA APIs).
361-
handle_ref = Ref{CUcontext}()
362-
cuCtxGetCurrent(handle_ref)
363-
if buf.ctx.handle != handle_ref[]
364-
error("Trying to free $buf from a different context than the one it was allocated from ($(handle_ref[]))")
354+
# verify that the caller has switched contexts
355+
if buf.ctx != context()
356+
error("Trying to free $buf from an unrelated context")
365357
end
366358

367359
dev = current_device()

0 commit comments

Comments
 (0)