Commit 1d0b9b4
committed
CUDA ext: stream/device/exception-safe cuDSS management; identity-memoized conversion
cudss_solver.jl:
- Bind every cuDSS handle to the current task's CUDA stream (new
cudssSetStream wrapper), at creation and again on every cache hit. CUDA.jl
issues buffer copies on per-task non-blocking streams, while an unbound
cuDSS handle executes on the legacy default stream, which does not
implicitly synchronize with non-blocking streams — the value-update copies
before cudssExecute and the result copy after it were ordered by timing
luck only. Solves now run correctly on explicit streams and off-root tasks.
- Cache key carries the owning device id: same-pattern solves after a
device! switch miss instead of reusing pointers that are invalid there.
- Transactional entry creation: if any create/execute stage throws, every
cuDSS object created so far is destroyed in reverse order (best-effort)
before rethrowing, so a partial entry never leaks and is never cached.
- clear_cudss_cache! synchronizes the device first, attempts every entry
even if one throws, empties the cache in finally (a failed destruction can
no longer leave half-destroyed entries to be double-destroyed later), and
rethrows the first error after the sweep.
- Deliberately NOT thread-safe and raw CUDSS_jll on purpose: concurrent
mgb_solve is not a supported use case, and the managed CUDSS.jl wrapper is
avoided by design.
conversion.jl (rewritten):
- All native_to_cuda / cuda_to_native conversions run through an identity
memo (IdDict) scoped to one top-level call: every source object converts
exactly once and the result is reused everywhere the source was shared.
An assembled MGBProblem shares one Geometry across the problem and both
AMG hierarchies, one quadrature weight vector, and every D_fine block's
data with geometry.operators — previously each reference became its own
persistent device copy (up to ~12 copies of operator data). The memo is
per call: no global state, no stale device allocations.
- The return path preserves structured types: CuArray-backed BlockDiag /
BlockColumn operators come back as their CPU block types instead of being
degraded to SparseMatrixCSC, so the Geometry inside a GPU solve's MGBSOL
supports the structured batched-GEMM fast path again.
test_cuda.jl: sharing assertions (CPU contract mirrored on device),
BlockDiag round-trip preservation, solves on a nondefault stream and in a
spawned task, and a failing solve followed by a clean one (cache flush).1 parent a7e0856 commit 1d0b9b4
3 files changed
Lines changed: 390 additions & 232 deletions
0 commit comments