Implement Cypher 25 allReduce predicate function and dynamic early path pruning#60
Implement Cypher 25 allReduce predicate function and dynamic early path pruning#60maxdemarzi wants to merge 4 commits into
Conversation
…th pruning - Add syntax support for 'allReduce(acc = init, x IN list | reduction, predicate)' in lexer and parser. - Implement typechecking for allReduce in checker.rs, validating list source, boolean predicate return types, and local variable scoping. - Add runtime evaluation of AllReduce expressions in engine.rs. - Integrate stepwise path pruning inside adjacency-driven repeat traversals, pruning branches early when the predicate returns false. - Allow querying global constraints (outer-bound variables) inside the allReduce predicate. - Add comprehensive integration tests in tests/all_reduce_test.rs. - Fix allocator subtraction overflow issues in tests/bench_test.rs.
Walkthrough -
|
… add deep repetition tests
Walkthrough - Variable-Length Repeating Pattern Optimization &
|
| Scenario / Case | Optimization Strategy | Execution Time (ms) | Rows Produced | Description / Notes |
|---|---|---|---|---|
| Case 1: Unused Variable | Unrolled Union | 285.57 ms | 6,080 | Variable e is unused and stripped. Pattern unrolls to flat union of joins. |
| Case 2: Used Variable | Adjacency Fallback | 8.55 ms | 6,080 | Variable e is returned, preventing unrolling. Uses new level-by-level traversal. |
| Case 3: Simulated Legacy | Global Path Enumeration | 2604.69 ms | 1,430,812 | Old behavior where the repeating pattern evaluates globally before filtering. |
Insights
- Adjacency Fallback (Case 2): Starts directly from the filtered set of
n1nodes (nodes wherescore > 9950) and expands paths locally step-by-step. This drops execution time to 8.55 ms (a 300x speedup compared to legacy global enumeration). - Legacy Behavior (Case 3): In the original engine, because the pattern could not be unrolled (since variables were named or filters couldn't push past the repetition boundary), the engine evaluated
-[e]-{1,2}globally first. On a 10K-node graph, this enumerated 1,430,812 paths of length 1 and 2 globally before any filtering, taking over 2.6 seconds. On a larger 57MB graph database, this would cause the OOM crash.
Verification Plan
Automated Tests
- Added comprehensive integration tests in
tests/all_reduce_test.rsvalidating:- Pure expression evaluation of
allReduce(passing/failing cases). - Early path pruning correctness under different constraint thresholds (
dist < 6anddist < 8). - Dynamic pruning of deep repetitions (e.g.,
{1,8}which exceeds unrolling bounds) to verify early branch pruning at scale. - Evaluation of global constraints inside
allReducepredicates, allowing the path search to query outer/query-scoped nodes or parameters (resolving User Review Comment 2). - Enforcing that any repetition variable referenced inside
allReduceis preserved (not stripped or unrolled by the compiler optimization passes), forcing level-by-level fallback traversal where dynamic path pruning runs (resolving User Review Comment 1). - Typechecker validation rules (checking list source types and boolean predicate return types).
- Pure expression evaluation of
- All tests (including
all_reduce_test.rs, memory allocation benchmarks, and the fullfrogqltest suite) compile and pass successfully.
Repository Contribution
The changes have been staged, committed, and submitted as a pull request to the upstream repository:
- Pull Request: #60
- Branch:
maxdemarzi:feat/all-reduce-pruning
Walkthrough - Variable-Length Repeating Pattern Optimization &
|
| Scenario / Case | Optimization Strategy | Execution Time (ms) | Rows Produced | Description / Notes |
|---|---|---|---|---|
| Case 1: Unused Variable | Unrolled Union | 285.57 ms | 6,080 | Variable e is unused and stripped. Pattern unrolls to flat union of joins. |
| Case 2: Used Variable | Adjacency Fallback | 8.55 ms | 6,080 | Variable e is returned, preventing unrolling. Uses new level-by-level traversal. |
| Case 3: Simulated Legacy | Global Path Enumeration | 2604.69 ms | 1,430,812 | Old behavior where the repeating pattern evaluates globally before filtering. |
Insights
- Adjacency Fallback (Case 2): Starts directly from the filtered set of
n1nodes (nodes wherescore > 9950) and expands paths locally step-by-step. This drops execution time to 8.55 ms (a 300x speedup compared to legacy global enumeration). - Legacy Behavior (Case 3): In the original engine, because the pattern could not be unrolled (since variables were named or filters couldn't push past the repetition boundary), the engine evaluated
-[e]-{1,2}globally first. On a 10K-node graph, this enumerated 1,430,812 paths of length 1 and 2 globally before any filtering, taking over 2.6 seconds. On a larger 57MB graph database, this would cause the OOM crash.
Verification Plan
Automated Tests
- Added comprehensive integration tests in
tests/all_reduce_test.rsvalidating:- Pure expression evaluation of
allReduce(passing/failing cases). - Early path pruning correctness under different constraint thresholds (
dist < 6anddist < 8). - Dynamic pruning of deep repetitions (e.g.,
{1,8}which exceeds unrolling bounds) to verify early branch pruning at scale. - Evaluation of global constraints inside
allReducepredicates, allowing the path search to query outer/query-scoped nodes or parameters (resolving User Review Comment 2). - Enforcing that any repetition variable referenced inside
allReduceis preserved (not stripped or unrolled by the compiler optimization passes), forcing level-by-level fallback traversal where dynamic path pruning runs (resolving User Review Comment 1). - Typechecker validation rules (checking list source types and boolean predicate return types).
- Pure expression evaluation of
- Added integration tests in
tests/shortest_bfs_test.rs(differential_edge_variables) validating that edge variables inANY SHORTESTandALL SHORTESTpatterns are correctly bound to lists of traversed edges for both directed and undirected graphs, including self-matches and coincident endpoints. - All tests (including
all_reduce_test.rs,shortest_bfs_test.rs, memory allocation benchmarks, and the fullfrogqltest suite) compile and pass successfully.
Repository Contribution
The changes have been staged, committed, and submitted as a pull request to the upstream repository:
- Pull Request: #60
- Branch:
maxdemarzi:feat/all-reduce-pruning
Add support for the Cypher 25
allReduce()predicate function and dynamic path pruning during variable-length repeating pattern matching.Key Changes
allReduce(acc = init, x IN list | reduction, predicate)insidelexer.rsandgrammar.rs.checker.rsto verify source list types, predicate boolean return types, and local variable scopes.engine.rs'srun_expr.try_concat_with_edge_repetition. EvaluateallReducestep-by-step at each level of the traversal and prune invalid branches early.allReduce(e.g., comparing against starting node attributes).tests/all_reduce_test.rs.tests/bench_test.rs.