@@ -15,7 +15,6 @@ function AMDGPU.unsafe_free!(plan::ROCFFTPlan)
1515 unsafe_free! (plan. buffer)
1616 end
1717 unsafe_free! (plan. workarea)
18- rocfft_execution_info_destroy (plan. execution_info)
1918end
2019
2120const ROCFFT_FORWARD = true
@@ -27,9 +26,7 @@ const ROCFFT_INVERSE = false
2726# K is flag for forward/inverse
2827mutable struct cROCFFTPlan{T,K,inplace,N,R,B} <: ROCFFTPlan{T, K, inplace}
2928 handle:: rocfft_plan
30- stream:: HIPStream
3129 workarea:: ROCVector{Int8}
32- execution_info:: rocfft_execution_info
3330 sz:: NTuple{N, Int} # Julia size of input array
3431 osz:: NTuple{N, Int} # Julia size of output array
3532 xtype:: rocfft_transform_type
@@ -47,26 +44,14 @@ mutable struct cROCFFTPlan{T,K,inplace,N,R,B} <: ROCFFTPlan{T, K, inplace}
4744 xtype:: rocfft_transform_type , region:: NTuple{R,Int} ,
4845 buffer:: B , input_sz_as_key:: Bool , key_T:: Type ,
4946 ) where {T,K,inplace,N,R,B}
50- info_ref = Ref {rocfft_execution_info} ()
51- rocfft_execution_info_create (info_ref)
52- info = info_ref[]
53-
54- # assign to the current stream
55- stream = AMDGPU. stream ()
56- rocfft_execution_info_set_stream (info, stream)
57- if length (workarea) > 0
58- rocfft_execution_info_set_work_buffer (info, workarea, length (workarea))
59- end
60- p = new (handle, stream, workarea, info, size (X), sizey, xtype, region, buffer, input_sz_as_key, key_T)
47+ p = new (handle, workarea, size (X), sizey, xtype, region, buffer, input_sz_as_key, key_T)
6148 return finalizer (AMDGPU. unsafe_free!, p)
6249 end
6350end
6451
6552mutable struct rROCFFTPlan{T,K,inplace,N,R,B} <: ROCFFTPlan{T,K,inplace}
6653 handle:: rocfft_plan
67- stream:: HIPStream
6854 workarea:: ROCVector{Int8}
69- execution_info:: rocfft_execution_info
7055 sz:: NTuple{N,Int} # Julia size of input array
7156 osz:: NTuple{N,Int} # Julia size of output array
7257 xtype:: rocfft_transform_type
@@ -83,28 +68,27 @@ mutable struct rROCFFTPlan{T,K,inplace,N,R,B} <: ROCFFTPlan{T,K,inplace}
8368 sizey:: Tuple , xtype:: rocfft_transform_type , region:: NTuple{R,Int} ,
8469 buffer:: B , input_sz_as_key:: Bool , key_T:: Type ,
8570 ) where {T,inplace,N,K,R,B}
86- info_ref = Ref {rocfft_execution_info} ()
87- rocfft_execution_info_create (info_ref)
88- info = info_ref[]
89-
90- stream = AMDGPU. stream ()
91- rocfft_execution_info_set_stream (info, stream)
92- if length (workarea) > 0
93- rocfft_execution_info_set_work_buffer (info, workarea, length (workarea))
94- end
95- p = new (handle, stream, workarea, info, size (X), sizey, xtype, region, buffer, input_sz_as_key, key_T)
71+ p = new (handle, workarea, size (X), sizey, xtype, region, buffer, input_sz_as_key, key_T)
9672 return finalizer (unsafe_free!, p)
9773 end
9874end
9975
100- function update_stream! (plan:: ROCFFTPlan )
101- new_stream = AMDGPU. stream ()
102- if plan. stream != new_stream
103- plan. stream = new_stream
104- info = plan. execution_info
105- rocfft_execution_info_set_stream (info, new_stream)
76+ # Create a per-call execution_info with the current task's stream and workbuffer.
77+ # rocfft_execution_info_set_stream must be called on the same OS thread as rocfft_execute;
78+ # creating it fresh per-call avoids any OS-thread binding issues from task migration.
79+ function with_execution_info (f:: F , plan:: ROCFFTPlan ) where {F}
80+ info_ref = Ref {rocfft_execution_info} ()
81+ rocfft_execution_info_create (info_ref)
82+ info = info_ref[]
83+ try
84+ rocfft_execution_info_set_stream (info, AMDGPU. stream ())
85+ if length (plan. workarea) > 0
86+ rocfft_execution_info_set_work_buffer (info, plan. workarea, length (plan. workarea))
87+ end
88+ return f (info)
89+ finally
90+ rocfft_execution_info_destroy (info)
10691 end
107- return
10892end
10993
11094const xtypenames = (" complex forward" , " complex inverse" , " real forward" , " real inverse" )
@@ -258,33 +242,44 @@ function assert_applicable(p::ROCFFTPlan{T,K}, X::ROCArray{T}, Y::ROCArray{Ty})
258242end
259243
260244function unsafe_execute! (plan:: cROCFFTPlan{T,K,true,N} , X:: ROCArray{T,N} ) where {T,K,N}
261- update_stream! (plan)
262- rocfft_execute (plan, [pointer (X),], C_NULL , plan. execution_info)
245+ in_buffer = [pointer (X)]
246+ with_execution_info (plan) do info
247+ rocfft_execute (plan, in_buffer, C_NULL , info)
248+ end
263249end
264250
265251function unsafe_execute! (
266252 plan:: cROCFFTPlan{T,K,false,N} , X:: ROCArray{T,N} , Y:: ROCArray{T} ,
267253) where {T,N,K}
268- update_stream! (plan)
269- rocfft_execute (plan, [pointer (X),], [pointer (Y),], plan. execution_info)
254+ in_buffer = [pointer (X)]
255+ out_buffer = [pointer (Y)]
256+ with_execution_info (plan) do info
257+ rocfft_execute (plan, in_buffer, out_buffer, info)
258+ end
270259end
271260
272261function unsafe_execute! (
273262 plan:: rROCFFTPlan{T,ROCFFT_FORWARD,false,N} ,
274263 X:: ROCArray{T,N} , Y:: ROCArray{<:rocfftComplexes,N} ,
275264) where {T<: rocfftReals ,N}
276265 @assert plan. xtype == rocfft_transform_type_real_forward
277- update_stream! (plan)
278- rocfft_execute (plan, [pointer (X),], [pointer (Y),], plan. execution_info)
266+ in_buffer = [pointer (X)]
267+ out_buffer = [pointer (Y)]
268+ with_execution_info (plan) do info
269+ rocfft_execute (plan, in_buffer, out_buffer, info)
270+ end
279271end
280272
281273function unsafe_execute! (
282274 plan:: rROCFFTPlan{T,ROCFFT_INVERSE,false,N} ,
283275 X:: ROCArray{T,N} , Y:: ROCArray{<:rocfftReals,N} ,
284276) where {T<: rocfftComplexes ,N}
285277 @assert plan. xtype == rocfft_transform_type_real_inverse
286- update_stream! (plan)
287- rocfft_execute (plan, [pointer (X),], [pointer (Y),], plan. execution_info)
278+ in_buffer = [pointer (X)]
279+ out_buffer = [pointer (Y)]
280+ with_execution_info (plan) do info
281+ rocfft_execute (plan, in_buffer, out_buffer, info)
282+ end
288283end
289284
290285function LinearAlgebra. mul! (y:: ROCArray{Ty} , p:: ROCFFTPlan{T,K,false} , x:: ROCArray{T} ) where {T,Ty,K}
0 commit comments