Skip to content

Fix rocFFT error with multiple tasks#935

Merged
luraess merged 4 commits into
mainfrom
lr/rocfft
Jul 3, 2026
Merged

Fix rocFFT error with multiple tasks#935
luraess merged 4 commits into
mainfrom
lr/rocfft

Conversation

@luraess

@luraess luraess commented Jun 19, 2026

Copy link
Copy Markdown
Member

Problem

Running FFT operations on a Threads.@spawn-ed task (or any task other than the one that created the plan) would intermittently produce rocfft_status_failure. This was observed in CI when running tests in parallel on MI300.

The root cause is a constraint in the rocFFT API: rocfft_execution_info_set_stream must be called on the same OS thread as the subsequent rocfft_execute. Julia tasks can migrate between OS threads at yield points, so storing a single rocfft_execution_info per plan and updating its stream before execution is not sufficient — the task may land on a different OS thread between the stream update and the actual execute call. rocFFT's OS-thread constraint applies to the entire create → set_stream → execute sequence.

Fix

rocfft_execution_info is now created fresh per execution inside each unsafe_execute! call, rather than being stored in the plan struct. The stream and work buffer are set immediately before rocfft_execute, with no yield points between setup and execution. The execution_info is destroyed after each call.

This matches the intended C++ usage pattern: rocfft_plan is the expensive, reusable, thread-safe object; rocfft_execution_info is a lightweight per-call envelope carrying runtime context (stream, work buffer). The plan.stream and plan.execution_info fields are removed from both plan structs accordingly.

@luraess luraess changed the title Set stream before every execution Fix roFFT error with multiple tasks Jun 19, 2026
@luraess luraess changed the title Fix roFFT error with multiple tasks Fix rocFFT error with multiple tasks Jun 19, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AMDGPU.jl Benchmarks

Details
Benchmark suite Current: 959beea Previous: 122a77d Ratio
amdgpu/synchronization/context/device 600 ns 610 ns 0.98
amdgpu/synchronization/stream/blocking 240 ns 250 ns 0.96
amdgpu/synchronization/stream/nonblocking 330 ns 350 ns 0.94
array/accumulate/Float32/1d 86201 ns 87801 ns 0.98
array/accumulate/Float32/dims=1 401046 ns 337664 ns 1.19
array/accumulate/Float32/dims=1L 136262 ns 136022 ns 1.00
array/accumulate/Float32/dims=2 129491 ns 138791 ns 0.93
array/accumulate/Float32/dims=2L 2808079 ns 2812325 ns 1.00
array/accumulate/Int64/1d 97231 ns 96001 ns 1.01
array/accumulate/Int64/dims=1 283804 ns 325024 ns 0.87
array/accumulate/Int64/dims=1L 167763 ns 167872 ns 1.00
array/accumulate/Int64/dims=2 126642 ns 128101 ns 0.99
array/accumulate/Int64/dims=2L 2985942 ns 2978066 ns 1.00
array/broadcast 118422 ns 139582 ns 0.85
array/construct 1650 ns 1680 ns 0.98
array/copy 39840 ns 36000 ns 1.11
array/copyto!/cpu_to_gpu 114431 ns 98171 ns 1.17
array/copyto!/gpu_to_cpu 184013 ns 182952 ns 1.01
array/copyto!/gpu_to_gpu 66831 ns 130452 ns 0.51
array/iteration/findall/bool 180112 ns 181773 ns 0.99
array/iteration/findall/int 189393 ns 201313 ns 0.94
array/iteration/findfirst/bool 117711 ns 121972 ns 0.97
array/iteration/findfirst/int 115002 ns 116632 ns 0.99
array/iteration/findmin/1d 169213 ns 171813 ns 0.98
array/iteration/findmin/2d 155022 ns 155922 ns 0.99
array/iteration/logical 355715 ns 354734 ns 1.00
array/iteration/scalar 288554 ns 289223 ns 1.00
array/permutedims/2d 75141 ns 74161 ns 1.01
array/permutedims/3d 74591 ns 75121 ns 0.99
array/permutedims/4d 76421 ns 76851 ns 0.99
array/random/rand/Float32 51081 ns 52441 ns 0.97
array/random/rand/Int64 57730 ns 57411 ns 1.01
array/random/rand!/Float32 129092 ns 146302 ns 0.88
array/random/rand!/Int64 107592 ns 146922 ns 0.73
array/random/randn/Float32 101801 ns 89532 ns 1.14
array/random/randn!/Float32 115762 ns 160592 ns 0.72
array/reductions/mapreduce/Float32/1d 132742 ns 133381 ns 1.00
array/reductions/mapreduce/Float32/dims=1 94791 ns 95152 ns 1.00
array/reductions/mapreduce/Float32/dims=1L 775101 ns 776099 ns 1.00
array/reductions/mapreduce/Float32/dims=2 96821 ns 97391 ns 0.99
array/reductions/mapreduce/Float32/dims=2L 297964 ns 299993 ns 0.99
array/reductions/mapreduce/Int64/1d 133041 ns 135062 ns 0.99
array/reductions/mapreduce/Int64/dims=1 95102 ns 95441 ns 1.00
array/reductions/mapreduce/Int64/dims=1L 780611 ns 784259 ns 1.00
array/reductions/mapreduce/Int64/dims=2 96181 ns 97071 ns 0.99
array/reductions/mapreduce/Int64/dims=2L 296445 ns 301494 ns 0.98
array/reductions/reduce/Float32/1d 132782 ns 133202 ns 1.00
array/reductions/reduce/Float32/dims=1 94611 ns 96031 ns 0.99
array/reductions/reduce/Float32/dims=1L 774341 ns 775290 ns 1.00
array/reductions/reduce/Float32/dims=2 97251 ns 97391 ns 1.00
array/reductions/reduce/Float32/dims=2L 294274 ns 298723 ns 0.99
array/reductions/reduce/Int64/1d 132702 ns 133912 ns 0.99
array/reductions/reduce/Int64/dims=1 94921 ns 95231 ns 1.00
array/reductions/reduce/Int64/dims=1L 779441 ns 782440 ns 1.00
array/reductions/reduce/Int64/dims=2 95951 ns 96852 ns 0.99
array/reductions/reduce/Int64/dims=2L 298234 ns 298143 ns 1.00
array/reverse/1d 44210 ns 43171 ns 1.02
array/reverse/1dL 75241 ns 75361 ns 1.00
array/reverse/1dL_inplace 99501 ns 166932 ns 0.60
array/reverse/1d_inplace 75621 ns 140412 ns 0.54
array/reverse/2d 51390 ns 50811 ns 1.01
array/reverse/2dL 101191 ns 101331 ns 1.00
array/reverse/2dL_inplace 123482 ns 178202 ns 0.69
array/reverse/2d_inplace 68571 ns 61290 ns 1.12
array/sorting/1d 381835 ns 343314 ns 1.11
integration/byval/reference 39150 ns 39221 ns 1.00
integration/byval/slices=1 40461 ns 40110 ns 1.01
integration/byval/slices=2 160393 ns 137081 ns 1.17
integration/byval/slices=3 239514 ns 247933 ns 0.97
integration/volumerhs 5031862 ns 5039162 ns 1.00
kernel/indexing 118662 ns 101861 ns 1.16
kernel/indexing_checked 87422 ns 63861 ns 1.37
kernel/launch 1290 ns 1390 ns 0.93
kernel/rand 108201 ns 195682 ns 0.55
latency/import 1502528312 ns 1593049884 ns 0.94
latency/precompile 11784100596 ns 36362655526 ns 0.32
latency/ttfp 10974586647 ns 2158618452 ns 5.08

This comment was automatically generated by workflow using github-action-benchmark.

@luraess

luraess commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

cscs-ci run

@luraess luraess marked this pull request as ready for review June 30, 2026 05:54
@luraess luraess marked this pull request as draft June 30, 2026 14:09
@luraess luraess marked this pull request as ready for review July 1, 2026 07:29
@luraess

luraess commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

cscs-ci run

@luraess

luraess commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

EDIT: Improved

  • per-execution rocfft_execution_info lifetime with try/finally
  • pointer buffers allocated before the thread-sensitive execution-info setup
  • async FFT regression test repeated with an explicit yield() inside the spawned task

@luraess luraess merged commit 790ffef into main Jul 3, 2026
5 checks passed
@luraess luraess deleted the lr/rocfft branch July 3, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant