docs: fix distributed-op docstrings and the ReduceOp type-stub - #2218
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughDocumentation-only updates clarify distributed execution patterns, host-versus-InCore API constraints, collective signal shapes, SPMD forms, reduction support, remote-operation examples, and benchmark accessors. Runtime logic, public signatures, enum values, and serialization behavior remain unchanged. ChangesDistributed Documentation
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@python/pypto/ir/distributed_compiled_program.py`:
- Around line 95-106: Update the “Persistent dispatch” example to use the
documented prepare-and-run API: prepare the compiled program before creating the
runtime, then invoke rt.run(compiled, ...) inside the loop instead of calling
the runtime directly. Keep the one-shot dispatch example unchanged.
In `@python/pypto/language/distributed/op/system_ops.py`:
- Around line 143-150: Update the documentation note around the notify signature
to say that only the first operand, the signal/target DistributedTensor, must be
passed positionally; keep the example’s peer= keyword usage and avoid implying
that all arguments must be positional.
In `@python/pypto/language/distributed/op/tile_ops.py`:
- Around line 146-150: Update the documentation example around
pld.tile.remote_store so its destination uses a data-window name rather than
signal, and do not imply that remote_store provides synchronization; if
presenting a signal handoff, show the required notify/wait protocol separately.
In `@python/pypto/runtime/bench.py`:
- Line 327: Update the documentation for stats.all_zero_device to state that it
is true only when samples exist and every device_wall_us sample is zero;
explicitly describe the empty-sample case as false.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ddc042b3-0ae1-49f3-b3a1-eabebbef430d
📒 Files selected for processing (7)
python/pypto/ir/distributed_compiled_program.pypython/pypto/language/distributed/op/system_ops.pypython/pypto/language/distributed/op/tensor_ops.pypython/pypto/language/distributed/op/tile_ops.pypython/pypto/language/dsl_api.pypython/pypto/pypto_core/ir.pyipython/pypto/runtime/bench.py
- distributed_compiled_program.py: persistent-dispatch example used DistributedWorker(compiled) directly; DistributedWorker's own docstring says to obtain it via compiled.prepare(). Fixed the example to match the documented entry point. - system_ops.py: notify()'s docstring said "always use positional args" then showed peer= as a keyword in the same sentence. Reworded to describe what's actually true — the first operand must be positional, the rest are positional-or-keyword. - tile_ops.py: remote_store()'s example wrote into a variable named "signal", implying the call itself synchronizes. remote_store is a raw write with no notify/wait semantics; renamed the variable and added a note that synchronization needs a separate notify/wait. - bench.py: all_zero_device returns False (not True) when device_wall_us is empty, per its own property docstring and implementation (`bool(self.device_wall_us) and ...`). Fixed the quick-reference table entry to match.
|
Reviewed the whole diff against the implementation. The core corrections check out — Three newly introduced statements are not backed by the code, though. Must fix1. 2. 3. Signal-reuse blocker points at the wrong tracker. The added paragraph attributes the missing self-resetting variant to "PTOAS issue #797". The constraint is tracked in this repo by #2156 ("Make composite collective barrier signals reusable"), which explicitly lists "any corresponding DSL/API documentation that describes signal lifetime or reuse" as in scope. A cross-repo issue number is also opaque to pypto readers. Worth noting: #2156's Affected areas lists allgather / reduce_scatter / all_to_all / all_to_all_v but not allreduce (which uses Question4. The removed mesh partial-valid / symbolic-extent paragraph. That is the largest deletion in the diff, and the behaviour it documented is still live ( Worth doing while you're in these docstrings5. The two RST simple tables do not render. The docs site is mkdocs + mkdocstrings with <p>.. rubric:: Quick-reference</p>
<p>============================== =========================================================
Accessor Description
============================== ====================...
<code>stats.device_us_median</code> Median device wall (µs).
...</p>The whole table collapses into a single paragraph and the column structure is lost (browsers then collapse the newlines into spaces). Same for the 6. 7. Separate change, not this PR8. Minor
|
- distributed_compiled_program.py: persistent-dispatch example used DistributedWorker(compiled) directly; DistributedWorker's own docstring says to obtain it via compiled.prepare(). Fixed the example to match the documented entry point. - system_ops.py: notify()'s docstring said "always use positional args" then showed peer= as a keyword in the same sentence. Reworded to describe what's actually true — the first operand must be positional, the rest are positional-or-keyword. - tile_ops.py: remote_store()'s example wrote into a variable named "signal", implying the call itself synchronizes. remote_store is a raw write with no notify/wait semantics; renamed the variable and added a note that synchronization needs a separate notify/wait. - bench.py: all_zero_device returns False (not True) when device_wall_us is empty, per its own property docstring and implementation (`bool(self.device_wall_us) and ...`). Fixed the quick-reference table entry to match.
Fixes three inaccurate docstring claims (alloc_window_buffer host-only enforcement, num_sub_workers=0 semantics, signal-reuse issue reference), adds a pointer for the removed mesh partial-valid paragraph, converts two non-rendering RST tables to Markdown (extending the BenchmarkStats one to cover the new per-dispatch API), fixes DistributedConfig's docstring section header and stale allgather prose, narrows the notify/wait signal parameter type to DistributedTensor, and drops an unverifiable history note.
28a3a2a to
0df025b
Compare
|
Thanks for the thorough review — addressed all of these (commits Must fix
Question Worth doing Item 8 (notify/wait typing) — tried, reverted Minor
Full |
|
Re-checked the fix round — all points land, and thanks for chasing the One thing to fix in the new parser check: raise ParserSyntaxError(
"pld.system.alloc_window_buffer() can only be called in HOST orchestration "
...
For what it's worth, I also scanned the enforcement for fallout: 138 |
Corrects several stale/incorrect docstrings and one shipped type stub found while writing the distributed programming and benchmarking user-manual chapters (split out of PR hw-native-sys#2162): - ir.pyi: ReduceOp's docstring claimed only Sum is operational and the others "raise a C++ deducer error if passed to any collective." That's wrong — allreduce accepts all four; only reduce_scatter is actually Sum-only. Restated per-operation. - tensor_ops.py: per-operation signal-shape docstrings (allreduce accepts rank-1 or rank-2 on the HOST builtin path; barrier/ broadcast/reduce_scatter are rank-1-only; allgather/all_to_all accept both) — previously uniform and wrong for several ops. - system_ops.py, tile_ops.py, dsl_api.py, bench.py, distributed_compiled_program.py: docstring completeness fixes (missing benchmark() keyword params, DistributedConfig field docs, dispatch examples, spmd form table, code examples).
- distributed_compiled_program.py: persistent-dispatch example used DistributedWorker(compiled) directly; DistributedWorker's own docstring says to obtain it via compiled.prepare(). Fixed the example to match the documented entry point. - system_ops.py: notify()'s docstring said "always use positional args" then showed peer= as a keyword in the same sentence. Reworded to describe what's actually true — the first operand must be positional, the rest are positional-or-keyword. - tile_ops.py: remote_store()'s example wrote into a variable named "signal", implying the call itself synchronizes. remote_store is a raw write with no notify/wait semantics; renamed the variable and added a note that synchronization needs a separate notify/wait. - bench.py: all_zero_device returns False (not True) when device_wall_us is empty, per its own property docstring and implementation (`bool(self.device_wall_us) and ...`). Fixed the quick-reference table entry to match.
Fixes three inaccurate docstring claims (alloc_window_buffer host-only enforcement, num_sub_workers=0 semantics, signal-reuse issue reference), adds a pointer for the removed mesh partial-valid paragraph, converts two non-rendering RST tables to Markdown (extending the BenchmarkStats one to cover the new per-dispatch API), fixes DistributedConfig's docstring section header and stale allgather prose, narrows the notify/wait signal parameter type to DistributedTensor, and drops an unverifiable history note.
Narrowing to DistributedTensor broke pyright on two legitimate call sites where a loop-carried DistributedTensor value loses its static type through pl.range/pl.while_. Tracked separately in hw-native-sys#2234 along with the loop-carry typing gap it exposed.
… message The error message said "pld.system.alloc_window_buffer()" but the op lives in the tensor namespace (pld.tensor.alloc_window_buffer, short form pld.alloc_window_buffer). Copy-paste from the world_size check where pld.system.world_size() is correct.
7a7019a to
825d209
Compare
|
Fixed. Exactly right — that was a copy-paste leftover from the Also rebased onto current main (672871b) — no conflicts, all pre-commit checks pass (ruff, pyright, headers, etc.). Ready for another look. |
Summary
Split out of #2162 (which is being broken into smaller PRs — see that
PR's description). This piece is fully independent of the rest: pure
Python docstring / type-stub corrections found while writing the
distributed-programming and benchmarking user-manual chapters.
ir.pyi:ReduceOp's docstring claimed onlySumis operationaland that
Max/Min/Prod"raise a C++ deducer error if passed toany collective." That's wrong —
allreduceaccepts all four (bothInCore and HOST paths); only
reduce_scatteris actuallySum-only.Restated per-operation.
tensor_ops.py: per-operation signal-shape docstrings. Previouslyuniform ("rank-1 or rank-2" for every collective) — actually only
allreduce/allgather/all_to_allaccept both ranks on the HOSTbuiltin path;
barrier/broadcast/reduce_scatterare rank-1-only.system_ops.py,tile_ops.py,dsl_api.py,bench.py,distributed_compiled_program.py: docstring completeness fixes —DistributedConfigfield documentation, dispatch examples, thespmdthree-form table, and a couple of missing code examples.Addressed review feedback (see PR discussion) in a follow-up commit:
alloc_window_buffer(previously only claimed by the docstring), with tests.
num_sub_workers=0docstring to match actual runtimesemantics (
max(num_sub_workers, len(sub_worker_fns))).constraints are documented (unchanged, just relocated out of this
docstring).
renders docstrings as Markdown, not RST), extending the
BenchmarkStatsone to cover the per-dispatch API added by Add per-dispatch benchmark timing and resolve callable names #2223.DistributedConfig's docstring section header(
Fields:→Attributes:) and staleallgatherprose referring toa since-renamed parameter.
notify'sdocstring note.
notify/wait's signal parameter type (Tensorvs.DistributedTensor)was intentionally not narrowed here: doing so broke
pyrighton twolegitimate call sites where a loop-carried
DistributedTensorvalueloses its static type through
pl.range/pl.while_. That's trackedseparately in #2234, along with the type-narrowing itself.
No behavior changes beyond the
alloc_window_bufferscope check(makes parse-time behavior match what was already enforced at runtime).
Verification
python -c "import ast; ast.parse(...)"on every changed filepre-commit run --files <changed files>(ruff check/format, pyright,headers) — all pass
pytest tests/utsuite (8433 passed, 13 skipped, 0 failed) runvia the
pypto3-hw-native-sys:simDocker imagemarkdown.markdown(..., extensions=["tables"])to confirm they nowproduce real
<table>elements (previously collapsed to oneparagraph under RST simple-table syntax)