Skip to content

Flush kernel output when synchronizing a stream that polling finds done - #3368

Merged
maleadt merged 2 commits into
mainfrom
tb/flush-output
Oct 8, 2026
Merged

maleadt merged 2 commits into
mainfrom
tb/flush-output

Conversation

@maleadt

@maleadt maleadt commented Oct 8, 2026

Copy link
Copy Markdown
Member

The driver only flushes the device's printf buffer when synchronizing (cu{Ctx,Stream,Event}Synchronize), launching a kernel, loading a module, etc., not when querying for completion. Since #3315, synchronize() returns without synchronizing when a query finds the stream done, so the output of short kernels only appeared after a later launch or blocking synchronization.

Synchronizing the stream after polling, as before #3315, would wait for work other tasks submitted in the meantime. Instead, this synchronizes an event that is never recorded, which flushes the buffer without waiting for anything. Each context keeps one such event; creating and destroying one on every call, as in #3363, more than tripled the cost of synchronizing an idle stream. Exception reporting already flushed this way and now shares the helper.

synchronize() on an idle stream, RTX 5080, interleaved in one process:

time
main 66 ns
#3363 (event per call) 292 ns
this PR (cached event) 159 ns

The second commit makes @grab_output synchronize the task's stream instead of the whole context, so that tests capturing kernel output go through the same synchronization as users do. A dedicated test covers the case where polling finds the stream done.

Supersedes #3363.

The driver only flushes the device's printf buffer when synchronizing,
not when querying for completion. Since #3315, synchronizing a stream that
a query finds done returns without synchronizing, so the output of short
kernels only appeared after a later kernel launch or blocking
synchronization. Synchronizing the stream anyway would wait for work
submitted since, which #3315 avoided, so instead synchronize an event that
is never recorded: that flushes the buffer without waiting for any work.
Each context keeps one such event, as creating and destroying one on every
synchronization doubled its cost. Exception reporting already flushed this
way, and now shares the helper.
Synchronizing a stream now flushes kernel output, so the test helper no
longer needs to synchronize the whole context. This also makes the tests
that capture kernel output exercise the synchronization users call.
@maleadt maleadt added bugfix regression Something that used to work, doesn't anymore. labels Oct 8, 2026
@maleadt
maleadt merged commit 0cbdfbc into main Oct 8, 2026
15 of 17 checks passed
@maleadt
maleadt deleted the tb/flush-output branch October 8, 2026 19:34
@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.23%. Comparing base (853cbdf) to head (2780c9f).
⚠️ Report is 21 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3368      +/-   ##
==========================================
- Coverage   87.40%   85.23%   -2.17%     
==========================================
  Files         195      194       -1     
  Lines       20072    19992      -80     
==========================================
- Hits        17543    17040     -503     
- Misses       2529     2952     +423     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

CUDA.jl Benchmarks

Details
Benchmark suite Current: 2780c9f Previous: 853cbdf Ratio
array/accumulate/Float32/1d 104414 ns 104545 ns 1.00
array/accumulate/Float32/dims=1 76806 ns 77216 ns 0.99
array/accumulate/Float32/dims=1L 1675140 ns 1681678 ns 1.00
array/accumulate/Float32/dims=2 147550 ns 147990 ns 1.00
array/accumulate/Float32/dims=2L 683700 ns 684823 ns 1.00
array/accumulate/Int64/1d 122420 ns 123482 ns 0.99
array/accumulate/Int64/dims=1 81088 ns 82067 ns 0.99
array/accumulate/Int64/dims=1L 1798181 ns 1804719 ns 1.00
array/accumulate/Int64/dims=2 162182 ns 163653 ns 0.99
array/accumulate/Int64/dims=2L 987247 ns 988348 ns 1.00
array/broadcast 16908 ns 16933 ns 1.00
array/broadcast launch 7542.25 ns 7531.25 ns 1.00
array/construct 896.3846153846154 ns 918.3055555555555 ns 0.98
array/copy 16829 ns 16994 ns 0.99
array/copyto!/cpu_to_gpu 207017 ns 208853 ns 0.99
array/copyto!/gpu_to_cpu 240522 ns 241692 ns 1.00
array/copyto!/gpu_to_gpu 8844 ns 8852 ns 1.00
array/iteration/findall/bool 138262 ns 137908 ns 1.00
array/iteration/findall/int 148144 ns 148516 ns 1.00
array/iteration/findfirst/bool 73705 ns 73524 ns 1.00
array/iteration/findfirst/int 75725 ns 75762 ns 1.00
array/iteration/findmin/1d 60264 ns 66141 ns 0.91
array/iteration/findmin/2d 102740 ns 103221 ns 1.00
array/iteration/logical 192288 ns 188598 ns 1.02
array/iteration/scalar 59579 ns 52780 ns 1.13
array/permutedims/2d 49185 ns 49695 ns 0.99
array/permutedims/3d 50327 ns 50504 ns 1.00
array/permutedims/4d 51485 ns 51914 ns 0.99
array/random/rand/Float32 11088 ns 11126 ns 1.00
array/random/rand/Int64 17986 ns 18386 ns 0.98
array/random/rand!/Float32 8167 ns 8346.666666666666 ns 0.98
array/random/rand!/Int64 15677 ns 16183 ns 0.97
array/random/randn/Float32 34288 ns 34716 ns 0.99
array/random/randn!/Float32 24694 ns 24925 ns 0.99
array/reductions/mapreduce/Float32/1d 31760 ns 31156 ns 1.02
array/reductions/mapreduce/Float32/dims=1 39821 ns 39658 ns 1.00
array/reductions/mapreduce/Float32/dims=1L 53283 ns 53129 ns 1.00
array/reductions/mapreduce/Float32/dims=2 58592 ns 58976 ns 0.99
array/reductions/mapreduce/Float32/dims=2L 70709 ns 71388 ns 0.99
array/reductions/mapreduce/Int64/1d 38989 ns 38448 ns 1.01
array/reductions/mapreduce/Int64/dims=1 42343 ns 42737 ns 0.99
array/reductions/mapreduce/Int64/dims=1L 88870 ns 89229 ns 1.00
array/reductions/mapreduce/Int64/dims=2 59867 ns 60306 ns 0.99
array/reductions/mapreduce/Int64/dims=2L 86369 ns 86904 ns 0.99
array/reductions/reduce/Float32/1d 31850 ns 31707 ns 1.00
array/reductions/reduce/Float32/dims=1 39437 ns 39862 ns 0.99
array/reductions/reduce/Float32/dims=1L 52606 ns 52911 ns 0.99
array/reductions/reduce/Float32/dims=2 58670 ns 58836 ns 1.00
array/reductions/reduce/Float32/dims=2L 70977 ns 71759 ns 0.99
array/reductions/reduce/Int64/1d 38667 ns 38435 ns 1.01
array/reductions/reduce/Int64/dims=1 42491 ns 42816 ns 0.99
array/reductions/reduce/Int64/dims=1L 89070 ns 89319 ns 1.00
array/reductions/reduce/Int64/dims=2 60004 ns 60402 ns 0.99
array/reductions/reduce/Int64/dims=2L 87210 ns 87189 ns 1.00
array/reverse/1d 15883 ns 16005 ns 0.99
array/reverse/1dL 69739 ns 69941 ns 1.00
array/reverse/1dL_inplace 67283 ns 67498 ns 1.00
array/reverse/1d_inplace 9040 ns 9218 ns 0.98
array/reverse/2d 20320 ns 20751 ns 0.98
array/reverse/2dL 74214 ns 74844 ns 0.99
array/reverse/2dL_inplace 67474 ns 67610 ns 1.00
array/reverse/2d_inplace 10450 ns 10714 ns 0.98
array/sorting/1d 2841387 ns 2849188 ns 1.00
array/sorting/2d 1087259 ns 1090151 ns 1.00
array/sorting/by 3393430 ns 3401762 ns 1.00
cuda/graph/capture 40386 ns 40998 ns 0.99
cuda/graph/eager 37550 ns 38515 ns 0.97
cuda/graph/launch 14231 ns 14283 ns 1.00
cuda/synchronization/context/auto 7867.666666666667 ns 7914 ns 0.99
cuda/synchronization/context/blocking 894.8636363636364 ns 861.1481481481482 ns 1.04
cuda/synchronization/context/nonblocking 7935.333333333333 ns 7894.666666666667 ns 1.01
cuda/synchronization/stream/auto 825.7692307692307 ns 340.4063926940639 ns 2.43
cuda/synchronization/stream/blocking 756.2372881355932 ns 760.6017699115044 ns 0.99
cuda/synchronization/stream/nonblocking 7744.5 ns 7937 ns 0.98
integration/byval/reference 147547 ns 147753 ns 1.00
integration/byval/slices=1 148648 ns 148908 ns 1.00
integration/byval/slices=2 290179 ns 290256 ns 1.00
integration/byval/slices=3 432082 ns 432393 ns 1.00
integration/cudadevrt 105099 ns 105057 ns 1.00
integration/volumerhs 9200309 ns 9207429 ns 1.00
kernel/indexing 11514 ns 11777 ns 0.98
kernel/indexing_checked 11891 ns 12029 ns 0.99
kernel/launch 2363.777777777778 ns 2453 ns 0.96
kernel/occupancy 877.6326530612245 ns 885.2075471698113 ns 0.99
kernel/rand 14792 ns 15123 ns 0.98
latency/import 4336855968 ns 4349657474 ns 1.00
latency/precompile 5128596926 ns 5113951581 ns 1.00
latency/ttfp 4853603558 ns 4845722062 ns 1.00

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

regression Something that used to work, doesn't anymore.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant