Skip to content

feat(pyamber): route range double keys - #8258

Open
carloea2 wants to merge 1 commit into
apache:mainfrom
carloea2:fix/route-range-nan-keys
Open

carloea2 wants to merge 1 commit into
apache:mainfrom
carloea2:fix/route-range-nan-keys

Conversation

@carloea2

@carloea2 carloea2 commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Align Python range-key conversion with the JVM: NaN becomes zero and finite doubles truncate toward zero. Infinite values still route to the endpoint receivers.

This adds previously missing support, so the type remains feat. No release backport is requested.

Any related issues, documentation, discussions?

Closes #8257

The finite-key change overlaps #8256. Duplicate receiver counting remains separately covered by #8246.

How was this PR tested?

Rebased onto upstream main at 7426431337, preserving the shared indexed-shuffle partitioner. The regressions fail before the implementation change: 2 failed and 41 passed. After the change, all 43 partitioner tests pass. NaN, finite fractions and both infinities are covered.

Generate protobufs with bash bin/python-proto-gen.sh, then run from amber:

python -m pytest src/test/python/core/architecture/sendsemantics/test_partitioners.py -q --tb=line -p no:cacheprovider
python -m ruff check src/main/python src/test/python
python -m ruff format --check src/main/python src/test/python

Ruff lint and formatting pass for all 217 Python files.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Codex

@Yicong-Huang Yicong-Huang added the release/v1.2 back porting to release/v1.2 label Aug 31, 2026
@github-actions
github-actions Bot requested a review from xuang7 August 31, 2026 05:34
@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Backport auto-label report

This fix: PR was checked against each actively-supported release branch. release/* labels drive the post-merge backport, so add or remove one to change where this fix lands.

Release branch Analysis
⚠️ release/v1.3 Not labeled automatically — none of the files this PR modifies exist on this branch (amber/src/main/python/core/architecture/sendsemantics/range_based_shuffle_partitioner.py, amber/src/test/python/core/architecture/sendsemantics/test_partitioners.py). The fix may target code that isn't on this release, or the files were moved/renamed after the branch was cut. Please check and add release/v1.3 by hand if this fix should be backported here.
✅ release/v1.2 Already labeled — this fix is queued to backport here.

Auto-label run.

@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @Ma77Ball
    You can notify them by mentioning @Ma77Ball in a comment.

@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 7 worse · ⚪ 8 noise (<±5%) · 0 without baseline

Compared against main 7426431 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 376 0.229 26,244/34,971/34,971 us 🔴 -9.8% / 🔴 +126.1%
🔴 bs=100 sw=10 sl=64 777 0.474 127,365/155,030/155,030 us 🔴 +12.0% / 🔴 +48.8%
🔴 bs=1000 sw=10 sl=64 908 0.554 1,095,506/1,253,655/1,253,655 us 🔴 +6.9% / 🔴 +27.2%
Baseline details

Latest main 7426431 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 376 tuples/sec 417 tuples/sec 822.11 tuples/sec -9.8% -54.3%
bs=10 sw=10 sl=64 MB/s 0.229 MB/s 0.254 MB/s 0.502 MB/s -9.8% -54.4%
bs=10 sw=10 sl=64 p50 26,244 us 23,959 us 12,129 us +9.5% +116.4%
bs=10 sw=10 sl=64 p95 34,971 us 34,649 us 15,469 us +0.9% +126.1%
bs=10 sw=10 sl=64 p99 34,971 us 34,649 us 18,357 us +0.9% +90.5%
bs=100 sw=10 sl=64 throughput 777 tuples/sec 816 tuples/sec 1,058 tuples/sec -4.8% -26.5%
bs=100 sw=10 sl=64 MB/s 0.474 MB/s 0.498 MB/s 0.646 MB/s -4.8% -26.6%
bs=100 sw=10 sl=64 p50 127,365 us 122,571 us 97,399 us +3.9% +30.8%
bs=100 sw=10 sl=64 p95 155,030 us 138,468 us 104,184 us +12.0% +48.8%
bs=100 sw=10 sl=64 p99 155,030 us 138,468 us 117,615 us +12.0% +31.8%
bs=1000 sw=10 sl=64 throughput 908 tuples/sec 921 tuples/sec 1,099 tuples/sec -1.4% -17.4%
bs=1000 sw=10 sl=64 MB/s 0.554 MB/s 0.562 MB/s 0.671 MB/s -1.4% -17.4%
bs=1000 sw=10 sl=64 p50 1,095,506 us 1,083,209 us 946,743 us +1.1% +15.7%
bs=1000 sw=10 sl=64 p95 1,253,655 us 1,173,147 us 985,437 us +6.9% +27.2%
bs=1000 sw=10 sl=64 p99 1,253,655 us 1,173,147 us 1,012,622 us +6.9% +23.8%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,532.29,200,128000,376,0.229,26244.32,34971.40,34971.40
1,100,10,64,20,2573.75,2000,1280000,777,0.474,127364.93,155029.65,155029.65
2,1000,10,64,20,22016.70,20000,12800000,908,0.554,1095505.80,1253655.32,1253655.32

@Yicong-Huang

Copy link
Copy Markdown
Contributor

I am converting this PR to a draft: please follow our PR template and mark it ready for review.

@Yicong-Huang
Yicong-Huang marked this pull request as draft August 31, 2026 19:56
@carloea2
carloea2 marked this pull request as ready for review August 31, 2026 20:12
@carloea2

Copy link
Copy Markdown
Contributor Author

The description now follows the current template, and this is ready for review.

@carloea2 carloea2 changed the title fix(pyamber): route range NaN keys feat(pyamber): route range NaN keys Aug 31, 2026
@mengw15 mengw15 removed the release/v1.2 back porting to release/v1.2 label Aug 31, 2026
@codecov-commenter

codecov-commenter commented Aug 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.30%. Comparing base (7426431) to head (d955f14).
⚠️ Report is 45 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8258      +/-   ##
============================================
- Coverage     92.30%   92.30%   -0.01%     
  Complexity     5046     5046              
============================================
  Files          1260     1260              
  Lines         53887    53893       +6     
  Branches       6711     6714       +3     
============================================
+ Hits          49743    49746       +3     
- Misses         2486     2488       +2     
- Partials       1658     1659       +1     
Flag Coverage Δ *Carryforward flag
access-control-service 77.38% <ø> (ø) Carriedforward from 7426431
agent-service 99.16% <ø> (ø) Carriedforward from 7426431
amber 87.32% <ø> (ø) Carriedforward from 7426431
computing-unit-managing-service 60.48% <ø> (ø) Carriedforward from 7426431
config-service 87.37% <ø> (ø) Carriedforward from 7426431
file-service 82.00% <ø> (ø) Carriedforward from 7426431
frontend 96.55% <ø> (ø) Carriedforward from 7426431
notebook-migration-service 83.73% <ø> (ø) Carriedforward from 7426431
pyamber 98.47% <100.00%> (-0.07%) ⬇️
workflow-compiling-service 72.43% <ø> (ø) Carriedforward from 7426431

*This pull request uses carry forward flags. Click here to find out more.

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@xuang7 xuang7 removed the fix label Sep 1, 2026
@xuang7
xuang7 removed their request for review September 1, 2026 01:44
@carloea2

carloea2 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

/request-review @Yicong-Huang

@Yicong-Huang Yicong-Huang 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.

🔴 1 must-fix · 3 advisory · 0 polish: the NaN fix is correct and well tested, but it patches one cell of a conversion that is missing entirely.

Correctness (2)

  • range_based_shuffle_partitioner.py:55: no double to long narrowing, so fractional keys diverge from the JVM (must-fix, see inline)
  • range_based_shuffle_partitioner.py:54: bucket width divides by the raw channel list, not the de-duplicated receivers (advisory, question, see inline)

Simplifications (1)

  • test_partitioners.py:334: nothing pins the description's infinite-key claim (advisory, see inline)

Conventions (1)

  • test_partitioners.py:334: feat also takes this out of the auto-backport path (advisory, question, see inline)
Verification trace

Checked the parity claim against the JVM twin rather than reading it off. RangeBasedShufflePartitioner.scala:43 narrows the key with .toLong and then divides integers, while the Python side divides the raw float. Executing both under this PR's own test config (range -10 to 9, two receivers), key -0.5 gives index 0 here and 1 on the JVM. A 0.1-step sweep found 9 diverging keys for that config and 18 for a [-50, 49] range over five receivers, all just below a bucket boundary in a range spanning negatives. Positive fractional keys agree, which is why this survived until a NaN made it raise. The infinite-key claim in the description does hold.

@@ -51,6 +52,8 @@ def __init__(self, partitioning: RangeBasedShufflePartitioning):
)

def get_receiver_index(self, column_val) -> int:

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.

Advisory:

A question about keys_per_receiver, which is computed at :46 outside this diff, so the comment sits on the method it feeds. Python divides the range by len(partitioning.channels), the raw channel list, while the JVM divides by receivers.length after .distinct, and Python's own build_receiver_batches de-duplicates as well. The two divisors genuinely differ. I could not construct a partitioner instance holding two channels with the same to_worker_id, so I am asking rather than asserting: is that shape reachable?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I reproduced this with channels S1 to A, S2 to A, and S1 to B: two receivers, but key 9 produces index 2. #8246 covers the divisor change separately. I have not demonstrated that topology through the planner.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I traced ResourceAllocator to LinkConfig and executed a 2 by 2 range configuration (-10 to 9). It produces four channels, which OutputManager passes to the partitioner. Key 9 raises IndexError in Python; the JVM chooses bucket 1. Single-sender controls pass. Keeping the divisor fix in #8246.

@carloea2
carloea2 force-pushed the fix/route-range-nan-keys branch from 7c8830d to df2c526 Compare September 21, 2026 06:21
@github-actions github-actions Bot added the fix label Sep 21, 2026
@carloea2 carloea2 changed the title feat(pyamber): route range NaN keys feat(pyamber): route range double keys Sep 21, 2026
@carloea2

Copy link
Copy Markdown
Contributor Author

/request-review @Yicong-Huang

@Yicong-Huang Yicong-Huang 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.

🟢 3 resolved · 1 open · 0 new (0 new = 0 newly introduced · 0 late catches)

Clean round: the round-1 must-fix (JVM-style finite-double narrowing) and both round-1 advisories (Infinity test pinning, backport note) are all verified fixed in the tree. The one open thread is the keys_per_receiver divisor question, which the author answered and deferred to #8246, so it stays open.

The three verified-fixed threads have been marked resolved.

Verification trace

Confirmed the new int() narrowing matches JVM Double.toLong on the discriminating inputs (e.g. -0.5 now routes to B on both sides), infinite keys saturate to the endpoint receivers as on the JVM, and the description's backport statement matches the backport-auto-label.yml rule.

@Yicong-Huang Yicong-Huang 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.

🚫 Merge conflict with main — no review was performed on this revision.

This PR cannot merge in its current state, so its diff is not the change that would land. Please merge or rebase onto main, resolve the conflict, and re-request review.

@carloea2
carloea2 force-pushed the fix/route-range-nan-keys branch from df2c526 to d955f14 Compare October 15, 2026 06:30
@carloea2

Copy link
Copy Markdown
Contributor Author

/request-review @Yicong-Huang

Rebased onto current main and preserved the shared partitioner refactor. All 43 partitioner tests and Ruff checks pass. The receiver-divisor advisory remains separate in #8246.

@Yicong-Huang Yicong-Huang 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.

🟢 0 resolved · 1 open · 0 new (0 new = 0 newly introduced · 0 late catches)

Clean round: the rebase preserves the reviewed fix and its tests exactly. The one open thread is the keys_per_receiver divisor question, deferred to #8246.

Verification trace

Verified the rebase preserved the fix: the PR diff vs the new base holds only the narrowing and the six parametrized tests, and the shared-base add_tuple_to_batch/flush/flush_state match the old inlined bodies. Also re-checked the description's test counts at the rebased head (43 cases; 2 failed / 41 passed before the fix).

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NaN keys crash Python range shuffle

5 participants