Repository navigation
Conversation
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Must-use annotations Cargo.toml, crates/einfold-datafusion/src/fold_node.rs, crates/einfold-datafusion/src/ein_fold_exec.rs, crates/einfold-ir/src/fold.rs, crates/einfold-kernels/src/relation.rs |
The workspace enables the Clippy must_use_candidate warning. Public methods and constructors gain #[must_use] annotations. Fold::dimension documentation states that an out-of-range ID causes a panic. |
DataFusion fold planning
| Layer / File(s) | Summary |
|---|---|
Detection and planner organization crates/einfold-datafusion/src/detect_folds.rs, crates/einfold-datafusion/src/planner.rs, crates/einfold-datafusion/src/lib.rs |
Fold detection now represents fallback choice with Fallback. EinFoldPlanner and EinFoldQueryPlanner are implemented in planner.rs, and the crate exports them from that module. |
Execution and joined-back references crates/einfold-datafusion/src/ein_fold_exec.rs, crates/einfold-datafusion/src/join_back.rs, crates/einfold-datafusion/src/fold_node.rs |
Planner definitions are removed from ein_fold_exec.rs; the operator remains there. Joined-back logic and execution references use the reorganized detection and fold-node modules. |
DataFusion call sites and checks crates/einfold-datafusion/examples/matmul_gradient.rs, crates/einfold-datafusion/tests/operator.rs, crates/einfold-datafusion/tests/detect_vs_host.rs |
Expression constructors use the logical_expr module. The detection sweep returns named counts and checks joined-back dense and host-plan cases. |
Kernel key handling
| Layer / File(s) | Summary |
|---|---|
Dense and host-key implementation crates/einfold-kernels/src/dense.rs, crates/einfold-kernels/src/hash.rs, crates/einfold-kernels/src/keys.rs |
Dense domain metadata is consolidated into CellKey values consumed by locate. Host-key construction uses a generic helper with float-width-specific negative-zero predicates. |
Kernel validation and imports crates/einfold-kernels/tests/kernels_vs_sql.rs |
The tests use a module-level HashSet import and local fmt::Write imports. Set and formatting behavior is unchanged. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Refactor
Possibly related PRs
- xqlsystems/einfold#48: Introduced fold detection and planner types that this change reorganizes into dedicated modules.
- xqlsystems/einfold#46: Introduced fold nodes, execution, and planners that this change separates and updates.
- xqlsystems/einfold#44: Introduced kernel hash and key code directly refactored in this change.
Merge Risk: 
Minimal · up to a8ad3
-
No actionable merge-blocking issue was identified.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Description check
-
Explanation
The description gives a detailed rationale and summary of the mechanical style changes. It does not include the template headings, a completed "Closes #" entry, or testing details, but it remains substantially complete and relevant.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 75.76% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 33 functions across 15 files. (1 skipped: 1 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
6953a34 to
5800535
Compare
4aa4942 to
6f035be
Compare
3b2c923 to
f49c9a4
Compare
cf6c883 to
91e91d6
Compare
🪭 Claude (einfold) Stacked on #53. The maintainer asked that einfold's Rust follow [Google's Rust style guide](https://google.github.io/styleguide/rustguide.html). This is the first of two pull requests doing that. It holds the changes to the published crates' APIs; #55 has the mechanical rest. - **Named fields over tuples.** `Operand::keys` held `(DimensionId, ColumnIndex)` pairs, and `Output::domain_key` a `(ColumnIndex, KeyEquality)` pair, read as `.0` and `.1`. The hash kernel's `key(i).0 .0` showed why the guide prefers names. They are now `Key { dimension, column }` and `DomainKey { column, equality }`, with `new` constructors. - **No API in non-leaf modules.** `einfold-kernels`' root defined its whole API next to its submodules. The root now only declares modules and re-exports. The API moves to leaf modules: `options.rs`, `relation.rs`, `schema.rs` and `algorithm.rs`. - **Options.** `Options`, a bag of options with public fields, implements `Default`, so callers can write `..Options::default()`. Its `unique_domain: bool` is the enum `DomainRows { Any, UniqueKeys }`. `fold` returns a `Folded { algorithm, batches }` rather than a pair. - **`#[non_exhaustive]`** on `FloatKeys` and `Algorithm`, which will grow (block-sparse and fused algorithms, other hosts' rules). `KeyEquality` stays exhaustive: SQL has exactly two equalities. Left as they are, on purpose: - The IR's structs (`Dimension`, `Operand`, `Output`, `Domain`) stay exhaustive for now. They describe the fold's vocabulary, which the guide exempts, and einfold's other crates build them with literals. Worth revisiting before `einfold-ir` is published. - `Arc` stays where Arrow's and DataFusion's APIs require it. No behavior changes: the same property tests pass, unchanged except for the new names. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **New Features** * Fold operations can now use either dense or hash-based processing, with automatic fallback when dense processing is unsuitable. * Folding supports an option to require unique domain keys, and reports when that requirement cannot be met. * **Improvements** * Fold result schemas now validate operand and domain compatibility, including required columns and data types. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
fold_node.rs holds FoldNode, detect_folds.rs DetectFolds, and ein_fold_exec.rs EinFoldExec, as Google's Rust style guide asks. The two planners, which aren't the operator, move to planner.rs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS
- Call functions through their modules (compute::cast, future::try_join_all, detect_folds::resolve), and use types unqualified (Ordering, Any, HashSet, ScalarValue). - Import a trait inside the function that uses it, where only one does. - Mark functions whose result a caller must use #[must_use], with the must_use_candidate lint on for the workspace. - The rule's fallback is the Fallback enum rather than a bool. - Say when Fold::dimension panics, and take &DFSchema rather than &DFSchemaRef where a function only reads it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS
… tuples - The dense kernel's a_matrix, b_matrix, a_factors and b_factors, and positions a_x to b_y, rather than am, bm, av, bv and ax to by. - A domain's keys are CellKeys, each with its column, extent and stride, rather than three slices zipped together. - Combinator chains move out of for-loop headers. - keys.rs's zero_signs is a generic function rather than a macro. - The detection test's sweep returns a Ran with named counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS
…mns (#56) 🪭 Claude (einfold) Stacked on #55. The last of the speedups that bring M1's gate past 4× (#49, ddx's `matmul` gradient program at n = 50,000, end to end; ddx is an XQL Systems project for automatic differentiation of SQL queries). - **Positions are computed by column, in parallel.** Each batch's key columns are read, and its rows' positions computed, a column at a time in 32 bits. The compiler vectorizes that, and batches run in parallel. A sequential pass then places the rows. Placing `a`'s 800,000 rows took about 5 ms on one thread. - **Blocks of columns too.** The output was split into blocks of 256 rows. ddx's Ā step has an output of 16 rows and 50,000 columns, so it ran on one thread. Blocks now split columns as well. Each cell's terms are still added in `z` order, so the bits are what they were. - **A parallel uniqueness check.** A domain's batches are checked in parallel, with an atomic mark per cell: of two rows that reach one cell, whichever marks it second sees the mark. **M1's gate (#49) is passed: 4.0–4.1× over five runs** (369 ms with einfold off, 90 ms on), with the same gradients. More than half of what remains is ddx's own work outside the folds: its key check (32 ms) and an elementwise step (17 ms). The three folds take 37 ms between them. About 130 non-test lines. **Invariants tested.** `kernels_vs_sql.rs` gains a shape of 3 rows by 5,000 columns, so that column blocks run; its invariants are unchanged: - the same rows as DataFusion's SQL, within float summation's bound; - exactly SQL's NULLs, NaNs, infinities and signed zeros; - the same bits across arrival orders, batchings and thread counts. <!-- - [x] 400 default cases; a 3,000-case sweep from seed 7700000 (dense path in 541; unique-domain check accepted 119 of 345) - [x] mutation: reading b's row from column 0 rather than the block's first column, caught by the new shape (seed 141) - [x] detect_vs_host.rs: 300 + 300 default cases - [x] fmt, clippy -D warnings, doc -D warnings, reuse lint --> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Performance** * Dense-fold processing is more efficient for batched workloads and outputs with many columns. * Duplicate-key checks for domain data now run in parallel. * **Reliability** * Processing preserves deterministic accumulation order for large outputs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
🪭 Claude (einfold)
Stacked on #54. The second of two pull requests that bring einfold's Rust in line with Google's Rust style guide, as the maintainer asked. Everything here is mechanical, with no change in behavior.
einfold-datafusion:fold_node.rsholdsFoldNode,detect_folds.rsholdsDetectFolds, andein_fold_exec.rsholdsEinFoldExec;planner.rs.compute::cast,future::try_join_all,detect_folds::resolve,logical_expr::col.Ordering,Any,HashSet,ScalarValue.#[must_use]on every function whose result a caller must use, with clippy'smust_use_candidateon for the workspace so new ones get it too.bool. The rule's private fallback flag is the enumFallback { HostPlan, Hash }.Fold::dimensiondocuments when it panics.&DFSchema, not&DFSchemaRef.EinFoldExecreads its inputs by pattern rather than withunwrap.am,bm,av,bvandax…byare spelled out.CellKeys with named fields, rather than three zipped slices.forheaders.sweepreturns aRanwith named counts.keys.rs'szero_signs!is a generic function.Three of the rustfmt options the guide recommends (
imports_granularity = "Module",hex_literal_case = "Lower",format_macro_matchers) exist only on nightly rustfmt. The code follows them by hand, and they aren't configured.🤖 Generated with Claude Code
https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS
Summary by CodeRabbit