Skip to content

fix: return input channel directly when rechunk size matches#28

Merged
zsoerenm merged 1 commit into
mainfrom
ss/rechunk-passthrough-same-size
Feb 17, 2026
Merged

fix: return input channel directly when rechunk size matches#28
zsoerenm merged 1 commit into
mainfrom
ss/rechunk-passthrough-same-size

Conversation

@zsoerenm

Copy link
Copy Markdown
Member

Summary

  • When rechunk(channel, chunk_size) is called with a chunk_size that already matches the input channel's chunk size, return the input channel directly instead of creating an intermediate channel and task
  • Fixes a race condition where zero-copy passthrough causes buffer aliasing: the same buffer references flow through both the input and intermediate output channels, extending the pipeline depth beyond the upstream producer's buffer pool size. Under slow-consumer conditions (e.g. JIT compilation on first run), the producer wraps around and overwrites buffers still queued downstream, causing data corruption

🤖 Generated with Claude Code

When the input channel's chunk size already matches the requested output
chunk size, return the input channel directly instead of creating an
intermediate channel and spawning a rechunk task.

This fixes a race condition in pipelines where the upstream producer uses
a fixed-size buffer pool: with zero-copy passthrough, the same buffer
references flow through both the input and intermediate output channels,
extending the pipeline depth beyond the producer's pool size. Under
slow-consumer conditions (e.g. JIT compilation on first run), the
producer wraps around and overwrites buffers still queued downstream,
causing data corruption.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zsoerenm
zsoerenm enabled auto-merge (rebase) February 17, 2026 08:51
@zsoerenm
zsoerenm merged commit 89f2ba6 into main Feb 17, 2026
5 checks passed
@zsoerenm
zsoerenm deleted the ss/rechunk-passthrough-same-size branch February 17, 2026 08:54
@codecov

codecov Bot commented Feb 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.31%. Comparing base (b75e69f) to head (2db7d1c).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #28      +/-   ##
==========================================
+ Coverage   74.21%   74.31%   +0.09%     
==========================================
  Files           8        8              
  Lines         543      545       +2     
==========================================
+ Hits          403      405       +2     
  Misses        140      140              

☔ View full report in Codecov by Sentry.
📢 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

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
main 2db7d1c... main / 2db7d1c...
channel/buffer=1 3.83 ± 0.06 ms 3.88 ± 0.037 ms 0.987 ± 0.018
channel/buffer=1024 0.209 ± 0.01 ms 0.214 ± 0.023 ms 0.975 ± 0.11
channel/buffer=16 0.439 ± 0.012 ms 0.444 ± 0.013 ms 0.989 ± 0.039
channel/buffer=256 0.224 ± 0.0099 ms 0.223 ± 0.01 ms 1 ± 0.064
channel/buffer=4 1.1 ± 0.013 ms 1.11 ± 0.015 ms 0.991 ± 0.018
channel/buffer=64 0.271 ± 0.0094 ms 0.272 ± 0.01 ms 0.995 ± 0.051
rechunk/10000_to_2048/buffer=1 8.66 ± 0.19 ms 8.63 ± 0.21 ms 1 ± 0.033
rechunk/10000_to_2048/buffer=16 4.32 ± 0.12 ms 4.29 ± 0.21 ms 1.01 ± 0.057
rechunk/10000_to_2048/buffer=4 5.15 ± 0.25 ms 5.14 ± 0.18 ms 1 ± 0.06
rechunk/10000_to_2048/buffer=64 4.03 ± 0.13 ms 4.06 ± 0.15 ms 0.991 ± 0.048
rechunk/2048_to_10000/buffer=1 1.17 ± 0.16 ms 1.18 ± 0.034 ms 0.985 ± 0.13
rechunk/2048_to_10000/buffer=16 1.21 ± 0.12 ms 1.22 ± 0.14 ms 0.993 ± 0.15
rechunk/2048_to_10000/buffer=4 1.17 ± 0.11 ms 1.18 ± 0.075 ms 0.991 ± 0.12
rechunk/2048_to_10000/buffer=64 1.36 ± 0.34 ms 1.58 ± 2.6 ms 0.861 ± 1.4
rechunk_state/batch/batch_2048_to_512_1ch 1.62 ± 0.16 ms 2.1 ± 0.42 ms 0.77 ± 0.17
rechunk_state/batch/batch_2048_to_512_4ch 6.28 ± 0.3 ms 7.72 ± 1.7 ms 0.813 ± 0.18
rechunk_state/batch/batch_512_to_2048_1ch 0.244 ± 0.032 ms 0.393 ± 0.082 ms 0.622 ± 0.15
rechunk_state/batch/batch_passthrough_2048_1ch 4.66 ± 0.4 μs 5.04 ± 0.46 μs 0.924 ± 0.12
rechunk_state/batch/iterative_2048_to_512_1ch 1.6 ± 0.17 ms 1.93 ± 0.33 ms 0.828 ± 0.17
rechunk_state/batch/iterative_2048_to_512_4ch 6.18 ± 0.23 ms 6.55 ± 1.3 ms 0.943 ± 0.2
rechunk_state/batch/iterative_512_to_2048_1ch 0.245 ± 0.031 ms 0.386 ± 0.082 ms 0.634 ± 0.16
rechunk_state/batch/iterative_passthrough_2048_1ch 4.5 ± 0.38 μs 5.16 ± 0.45 μs 0.873 ± 0.11
rechunk_state/channels/2048_to_1024_1ch 1.43 ± 0.086 ms 1.43 ± 0.092 ms 0.998 ± 0.087
rechunk_state/channels/2048_to_1024_2ch 2.83 ± 0.22 ms 2.79 ± 0.24 ms 1.01 ± 0.12
rechunk_state/channels/2048_to_1024_4ch 6.13 ± 0.37 ms 5.8 ± 0.3 ms 1.06 ± 0.083
rechunk_state/channels/2048_to_1024_8ch 11.3 ± 0.37 ms 11.6 ± 0.52 ms 0.977 ± 0.054
rechunk_state/downsample/10000_to_1024_1ch 5.34 ± 0.24 ms 6.35 ± 0.41 ms 0.84 ± 0.066
rechunk_state/downsample/2048_to_512_1ch 1.38 ± 0.14 ms 1.73 ± 0.19 ms 0.796 ± 0.12
rechunk_state/downsample/2048_to_512_4ch 5.16 ± 0.11 ms 7.74 ± 1.1 ms 0.666 ± 0.092
rechunk_state/passthrough/2048_to_2048_1ch 4.55 ± 0.58 μs 4.65 ± 0.59 μs 0.978 ± 0.18
rechunk_state/passthrough/2048_to_2048_4ch 5.18 ± 0.53 μs 4.84 ± 0.33 μs 1.07 ± 0.13
rechunk_state/types/ComplexF64_2048_to_1024 2.61 ± 0.14 ms 2.51 ± 0.34 ms 1.04 ± 0.15
rechunk_state/types/Float32_2048_to_1024 0.718 ± 0.064 ms 0.907 ± 0.18 ms 0.792 ± 0.17
rechunk_state/types/Float64_2048_to_1024 1.5 ± 0.13 ms 1.43 ± 0.064 ms 1.06 ± 0.1
rechunk_state/types/Int16_2048_to_1024 0.4 ± 0.046 ms 0.445 ± 0.12 ms 0.897 ± 0.26
rechunk_state/upsample/1024_to_10000_1ch 0.546 ± 0.056 ms 0.606 ± 0.076 ms 0.901 ± 0.15
rechunk_state/upsample/512_to_2048_1ch 0.25 ± 0.035 ms 0.282 ± 0.036 ms 0.886 ± 0.17
rechunk_state/upsample/512_to_2048_4ch 1.76 ± 0.079 ms 1.69 ± 0.093 ms 1.04 ± 0.074
rechunk_state/zero_copy/near_passthrough_2048_1ch 1.2 ± 0.078 ms 1.6 ± 0.15 ms 0.751 ± 0.086
rechunk_state/zero_copy/near_passthrough_2048_4ch 5.34 ± 0.28 ms 8.12 ± 0.44 ms 0.658 ± 0.05
rechunk_state/zero_copy/near_passthrough_8192_4ch 0.0569 ± 0.1 s 0.0423 ± 0.094 s 1.35 ± 3.8
rechunk_state/zero_copy/passthrough_2048_1ch 4.53 ± 0.41 μs 5.02 ± 0.49 μs 0.902 ± 0.12
rechunk_state/zero_copy/passthrough_2048_4ch 5.23 ± 0.36 μs 5.55 ± 0.45 μs 0.943 ± 0.1
rechunk_state/zero_copy/passthrough_8192_4ch 5.75 ± 0.43 μs 5.99 ± 1.3 μs 0.96 ± 0.22
tee/buffer=1 0.611 ± 0.016 ms 0.615 ± 0.013 ms 0.993 ± 0.034
tee/buffer=16 0.102 ± 0.015 ms 0.102 ± 0.0051 ms 1.01 ± 0.16
tee/buffer=4 0.213 ± 0.016 ms 0.202 ± 0.0086 ms 1.06 ± 0.091
tee/buffer=64 0.0754 ± 0.0019 ms 0.0753 ± 0.0022 ms 1 ± 0.039
time_to_load 1.56 ± 0.0091 s 1.56 ± 0.01 s 1 ± 0.0088
Memory benchmarks
main 2db7d1c... main / 2db7d1c...
channel/buffer=1 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
channel/buffer=1024 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
channel/buffer=16 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
channel/buffer=256 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
channel/buffer=4 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
channel/buffer=64 16 allocs: 1.09 kB 16 allocs: 1.09 kB 1
rechunk/10000_to_2048/buffer=1 12 allocs: 0.75 kB 12 allocs: 0.75 kB 1
rechunk/10000_to_2048/buffer=16 12 allocs: 0.75 kB 12 allocs: 0.75 kB 1
rechunk/10000_to_2048/buffer=4 12 allocs: 0.75 kB 12 allocs: 0.75 kB 1
rechunk/10000_to_2048/buffer=64 12 allocs: 0.75 kB 12 allocs: 0.75 kB 1
rechunk/2048_to_10000/buffer=1 13 allocs: 0.781 kB 13 allocs: 0.781 kB 1
rechunk/2048_to_10000/buffer=16 13 allocs: 0.781 kB 13 allocs: 0.781 kB 1
rechunk/2048_to_10000/buffer=4 13 allocs: 0.781 kB 13 allocs: 0.781 kB 1
rechunk/2048_to_10000/buffer=64 13 allocs: 0.781 kB 13 allocs: 0.781 kB 1
rechunk_state/batch/batch_2048_to_512_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/batch_2048_to_512_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/batch_512_to_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/batch_passthrough_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/iterative_2048_to_512_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/iterative_2048_to_512_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/iterative_512_to_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/batch/iterative_passthrough_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/channels/2048_to_1024_1ch 1 allocs: 16 B 1 allocs: 16 B 1
rechunk_state/channels/2048_to_1024_2ch 1 allocs: 16 B 1 allocs: 16 B 1
rechunk_state/channels/2048_to_1024_4ch 1 allocs: 16 B 1 allocs: 16 B 1
rechunk_state/channels/2048_to_1024_8ch 1 allocs: 16 B 1 allocs: 16 B 1
rechunk_state/downsample/10000_to_1024_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/downsample/2048_to_512_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/downsample/2048_to_512_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/passthrough/2048_to_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/passthrough/2048_to_2048_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/types/ComplexF64_2048_to_1024 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/types/Float32_2048_to_1024 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/types/Float64_2048_to_1024 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/types/Int16_2048_to_1024 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/upsample/1024_to_10000_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/upsample/512_to_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/upsample/512_to_2048_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/near_passthrough_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/near_passthrough_2048_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/near_passthrough_8192_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/passthrough_2048_1ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/passthrough_2048_4ch 0 allocs: 0 B 0 allocs: 0 B
rechunk_state/zero_copy/passthrough_8192_4ch 0 allocs: 0 B 0 allocs: 0 B
tee/buffer=1 26 allocs: 1.48 kB 26 allocs: 1.48 kB 1
tee/buffer=16 26 allocs: 1.48 kB 26 allocs: 1.48 kB 1
tee/buffer=4 26 allocs: 1.48 kB 26 allocs: 1.48 kB 1
tee/buffer=64 26 allocs: 1.48 kB 26 allocs: 1.48 kB 1
time_to_load 0.145 k allocs: 11 kB 0.145 k allocs: 11 kB 1

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