1+ # Deferred release queue for sparse matrix handles.
2+ # Finalizers run on the GC thread, but onemklXsparse_release_matrix_handle submits
3+ # work to the SYCL queue. Using the same queue from the GC thread and the main thread
4+ # concurrently is not safe and causes ZE_RESULT_ERROR_DEVICE_LOST / ZE_RESULT_ERROR_UNKNOWN.
5+ # Instead, finalizers push handles here and they are released on the main thread.
6+ const _deferred_sparse_handles = Vector {matrix_handle_t} ()
7+ const _deferred_sparse_handles_lock = ReentrantLock ()
8+
19function sparse_release_matrix_handle (A:: oneAbstractSparseMatrix )
210 return if A. handle != = nothing
11+ lock (_deferred_sparse_handles_lock) do
12+ push! (_deferred_sparse_handles, A. handle)
13+ end
14+ end
15+ end
16+
17+ function flush_deferred_sparse_releases ()
18+ handles = lock (_deferred_sparse_handles_lock) do
19+ if isempty (_deferred_sparse_handles)
20+ return matrix_handle_t[]
21+ end
22+ h = copy (_deferred_sparse_handles)
23+ empty! (_deferred_sparse_handles)
24+ return h
25+ end
26+ isempty (handles) && return
27+ dev = device ()
28+ ctx = context ()
29+ queue = global_queue (ctx, dev)
30+ for handle in handles
331 try
4- queue = global_queue (context (A. nzVal), device (A. nzVal))
5- handle_ptr = Ref {matrix_handle_t} (A. handle)
32+ handle_ptr = Ref {matrix_handle_t} (handle)
633 onemklXsparse_release_matrix_handle (sycl_queue (queue), handle_ptr)
7- # Only synchronize after successful release to ensure completion
8- synchronize (queue)
934 catch err
10- # Don't let finalizer errors crash the program
1135 @warn " Error releasing sparse matrix handle" exception = err
1236 end
1337 end
38+ return synchronize (queue)
1439end
1540
1641for (fname, elty, intty) in ((:onemklSsparse_set_csr_data , :Float32 , :Int32 ),
@@ -27,6 +52,7 @@ for (fname, elty, intty) in ((:onemklSsparse_set_csr_data , :Float32 , :Int3
2752 rowPtr:: oneVector{$intty} , colVal:: oneVector{$intty} ,
2853 nzVal:: oneVector{$elty} , dims:: NTuple{2, Int}
2954 )
55+ flush_deferred_sparse_releases ()
3056 handle_ptr = Ref {matrix_handle_t} ()
3157 onemklXsparse_init_matrix_handle (handle_ptr)
3258 m, n = dims
@@ -47,6 +73,7 @@ for (fname, elty, intty) in ((:onemklSsparse_set_csr_data , :Float32 , :Int3
4773 colPtr:: oneVector{$intty} , rowVal:: oneVector{$intty} ,
4874 nzVal:: oneVector{$elty} , dims:: NTuple{2, Int}
4975 )
76+ flush_deferred_sparse_releases ()
5077 queue = global_queue (context (nzVal), device (nzVal))
5178 handle_ptr = Ref {matrix_handle_t} ()
5279 onemklXsparse_init_matrix_handle (handle_ptr)
@@ -106,6 +133,7 @@ for (fname, elty, intty) in ((:onemklSsparse_set_coo_data , :Float32 , :Int3
106133 (:onemklZsparse_set_coo_data_64 , :ComplexF64 , :Int64 ))
107134 @eval begin
108135 function oneSparseMatrixCOO (A:: SparseMatrixCSC{$elty, $intty} )
136+ flush_deferred_sparse_releases ()
109137 handle_ptr = Ref {matrix_handle_t} ()
110138 onemklXsparse_init_matrix_handle (handle_ptr)
111139 m, n = size (A)
0 commit comments