@@ -93,23 +93,22 @@ function _create_descriptor(sz::NTuple{N,Int}, T::Type, complex::Bool) where {N}
9393 prec = T<: Float64 || T<: ComplexF64 ? ONEMKL_DFT_PRECISION_DOUBLE : ONEMKL_DFT_PRECISION_SINGLE
9494 dom = complex ? ONEMKL_DFT_DOMAIN_COMPLEX : ONEMKL_DFT_DOMAIN_REAL
9595 desc_ref = Ref {onemklDftDescriptor_t} ()
96- # Create descriptor for the full array dimensions. `lengths` must stay rooted
97- # across the ccall: oneMKL copies the dimensions out of `pointer(lengths)`, and
98- # without GC.@preserve the array can be collected first, leaving the descriptor
99- # with garbage dimensions (commit then fails with FFT_INVALID_DESCRIPTOR).
96+ # Create descriptor for the full array dimensions
10097 lengths = collect (Int64, sz)
101- st = GC. @preserve lengths (length (lengths) == 1 ?
102- onemklDftCreate1D (desc_ref, prec, dom, lengths[1 ]) :
103- onemklDftCreateND (desc_ref, prec, dom, length (lengths), pointer (lengths)))
98+ # NB: pass the arrays themselves to the ccall wrappers (NOT `pointer(...)`) so they
99+ # are rooted for the duration of the call; passing a raw Ptr lets the GC collect the
100+ # vector mid-call, which made MKL read garbage lengths/strides and fail `commit` with
101+ # invalid_descriptor_exception or a SIGFPE, depending on heap reuse.
102+ st = length (lengths) == 1 ? onemklDftCreate1D (desc_ref, prec, dom, lengths[1 ]) : onemklDftCreateND (desc_ref, prec, dom, length (lengths), lengths)
104103 st == 0 || error (" onemkl DFT create failed (status $st )" )
105104 desc = desc_ref[]
106105 # Do not program descriptor scaling; we'll perform inverse normalization manually.
107106 # Set placement explicitly based on plan type later
108- # Use the task-local cached SYCL queue wrapping the global Level Zero queue, like the
109- # other oneMKL wrappers do. Creating fresh syclContext/syclQueue objects per plan is
110- # unsound: once they become garbage their finalizers (syclQueueDestroy etc.) tear down
111- # SYCL runtime state for the still-in-use underlying queue, corrupting later DFT
112- # commits and crashing at process exit.
107+ # Use the task-local cached SYCL queue wrapping the global Level Zero queue, like
108+ # the other oneMKL wrappers do. Creating fresh syclContext/syclQueue objects per
109+ # plan is unsound: once they become garbage their finalizers (syclQueueDestroy etc.)
110+ # tear down SYCL runtime state for the still-in-use underlying queue, corrupting
111+ # later DFT commits (SIGFPE) and crashing at process exit.
113112 ze_ctx = oneAPI. context (); ze_dev = oneAPI. device ()
114113 q = oneAPI. sycl_queue (oneAPI. global_queue (ze_ctx, ze_dev))
115114 return desc, q
@@ -132,10 +131,8 @@ function plan_fft(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,Co
132131 strides[i+ 1 ] = prod
133132 prod *= size (X,i)
134133 end
135- GC. @preserve strides begin
136- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer (strides), length (strides))
137- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer (strides), length (strides))
138- end
134+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, strides, length (strides))
135+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, strides, length (strides))
139136 end
140137 stc = onemklDftCommit (desc, q); stc == 0 || error (" commit failed ($stc )" )
141138 return cMKLFFTPlan {T,MKLFFT_FORWARD,false,N,R,Nothing} (desc,q,size (X),size (X),false ,reg,nothing ,nothing )
@@ -153,10 +150,8 @@ function plan_bfft(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,C
153150 @inbounds for i in 1 : N
154151 strides[i+ 1 ]= prod; prod*= size (X,i)
155152 end
156- GC. @preserve strides begin
157- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer (strides), length (strides))
158- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer (strides), length (strides))
159- end
153+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, strides, length (strides))
154+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, strides, length (strides))
160155 end
161156 stc = onemklDftCommit (desc, q); stc == 0 || error (" commit failed ($stc )" )
162157 return cMKLFFTPlan {T,MKLFFT_INVERSE,false,N,R,Nothing} (desc,q,size (X),size (X),false ,reg,nothing ,nothing )
@@ -176,10 +171,8 @@ function plan_fft!(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,C
176171 @inbounds for i in 1 : N
177172 strides[i+ 1 ]= prod; prod*= size (X,i)
178173 end
179- GC. @preserve strides begin
180- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer (strides), length (strides))
181- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer (strides), length (strides))
182- end
174+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, strides, length (strides))
175+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, strides, length (strides))
183176 end
184177 stc = onemklDftCommit (desc, q); stc == 0 || error (" commit failed ($stc )" )
185178 cMKLFFTPlan {T,MKLFFT_FORWARD,true,N,R,Nothing} (desc,q,size (X),size (X),false ,reg,nothing ,nothing )
@@ -197,10 +190,8 @@ function plan_bfft!(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,
197190 @inbounds for i in 1 : N
198191 strides[i+ 1 ]= prod; prod*= size (X,i)
199192 end
200- GC. @preserve strides begin
201- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer (strides), length (strides))
202- onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer (strides), length (strides))
203- end
193+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_FWD_STRIDES, strides, length (strides))
194+ onemklDftSetValueInt64Array (desc, ONEMKL_DFT_PARAM_BWD_STRIDES, strides, length (strides))
204195 end
205196 stc = onemklDftCommit (desc, q); stc == 0 || error (" commit failed ($stc )" )
206197 cMKLFFTPlan {T,MKLFFT_INVERSE,true,N,R,Nothing} (desc,q,size (X),size (X),false ,reg,nothing ,nothing )
0 commit comments