Skip to content

Commit 790ffef

Browse files
authored
Merge pull request #935
Fix rocFFT error with multiple tasks
2 parents 683eb99 + 959beea commit 790ffef

3 files changed

Lines changed: 48 additions & 48 deletions

File tree

.buildkite/pipeline.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ steps:
4343
rocmgpu: "*"
4444
if: build.message !~ /\[skip tests\]/
4545
command: "julia --project -e 'using Pkg; Pkg.update()'"
46-
timeout_in_minutes: 60
46+
timeout_in_minutes: 90
4747
env:
4848
JULIA_NUM_THREADS: 4
4949
JULIA_AMDGPU_CORE_MUST_LOAD: "1"
@@ -62,7 +62,7 @@ steps:
6262
rocmgpu: "*"
6363
if: build.message !~ /\[skip tests\]/
6464
command: "julia --project -e 'using Pkg; Pkg.update()'"
65-
timeout_in_minutes: 60
65+
timeout_in_minutes: 90
6666
env:
6767
JULIA_NUM_THREADS: 4
6868
JULIA_AMDGPU_CORE_MUST_LOAD: "1"
@@ -81,7 +81,7 @@ steps:
8181
rocmgpu: "*"
8282
if: build.message !~ /\[skip tests\]/
8383
command: "julia --project -e 'using Pkg; Pkg.update()'"
84-
timeout_in_minutes: 60
84+
timeout_in_minutes: 90
8585
env:
8686
JULIA_NUM_THREADS: 4
8787
JULIA_AMDGPU_CORE_MUST_LOAD: "1"
@@ -100,7 +100,7 @@ steps:
100100
rocmgpu: "*"
101101
if: build.message !~ /\[skip tests\]/
102102
command: "julia --project -e 'using Pkg; Pkg.update()'"
103-
timeout_in_minutes: 60
103+
timeout_in_minutes: 90
104104
soft_fail: true
105105
env:
106106
JULIA_NUM_THREADS: 4

src/fft/fft.jl

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
1918
end
2019

2120
const ROCFFT_FORWARD = true
@@ -27,9 +26,7 @@ const ROCFFT_INVERSE = false
2726
# K is flag for forward/inverse
2827
mutable 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
6350
end
6451

6552
mutable 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
9874
end
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
10892
end
10993

11094
const 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})
258242
end
259243

260244
function 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
263249
end
264250

265251
function 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
270259
end
271260

272261
function 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
279271
end
280272

281273
function 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
288283
end
289284

290285
function LinearAlgebra.mul!(y::ROCArray{Ty}, p::ROCFFTPlan{T,K,false}, x::ROCArray{T}) where {T,Ty,K}

test/hip_rocarray/fft.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,15 @@ end
357357

358358
Y = p * X
359359

360-
task = Threads.@spawn d_p * d_X # executes FFT on separate AMDGPU stream
361-
d_Y = fetch(task)
360+
for _ in 1:10
361+
task = Threads.@spawn begin # executes FFT on separate AMDGPU stream
362+
yield()
363+
d_p * d_X
364+
end
365+
d_Y = fetch(task)
362366

363-
@test isapprox(collect(d_Y), Y; rtol=MYRTOL, atol=MYATOL)
367+
@test isapprox(collect(d_Y), Y; rtol=MYRTOL, atol=MYATOL)
368+
end
364369
end
365370

366371
end # testset FFT

0 commit comments

Comments
 (0)