Skip to content

Reuse TT numeric reductions in temporal row queries - #279

Open
Victsm wants to merge 3 commits into
mainfrom
codex/shared-numeric-aggregation-20261110
Open

Victsm wants to merge 3 commits into
mainfrom
codex/shared-numeric-aggregation-20261110

Conversation

@Victsm

@Victsm Victsm commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

PQL and temporal row queries currently repeat numeric traversal/reduction logic. Reuse resolved TT inputs and numeric accumulation for eligible temporal aggregates, preserving each frontend’s row order, empty/NULL behavior and conservative fallbacks.

Stack slice 1/5. Targets main; subsequent slices add common IR, prepared execution, native batch consumption and the public materializer.

Change map

#279 (comment)

Testing

Release native build; 44 focused compiler/numeric tests passed at this checkpoint.

Dependency order: #279 → #280 → #281 → #282 → #283.

@Victsm

Victsm commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator Author

Change map

User-requested aggregation consolidation, slice 1/5.

Observed requirement and smallest sufficient change: PQL and temporal row queries currently repeat numeric traversal/reduction logic. Reuse resolved TT inputs and numeric accumulation for eligible temporal aggregates, preserving each frontend’s row order, empty/NULL behavior and conservative fallbacks.

Focused verification / stopping condition: Release native build; 44 focused compiler/numeric tests passed at this checkpoint. Stop at this slice’s verified behavior; fitting redesign, new temporal/LP capabilities and live sweeps are separate.

File Function / scope What changed Why
packages/diskgraph/diskgraph-pybind/README.md API and workflow documentation Describe supported routes, preparation boundaries and explicit limitations Keep usage and performance claims aligned with the implementation
packages/diskgraph/diskgraph-pybind/python/tests/test_shared_numeric_aggregates.py Focused regression coverage Verify numerical, clock, identity, lifecycle or route behavior of this slice Catch wrong answers and unintended fallback/reconstruction, not merely successful calls
packages/diskgraph/diskgraph-pybind/python/tests/test_temporal_sequence_limit.py Focused regression coverage Verify numerical, clock, identity, lifecycle or route behavior of this slice Catch wrong answers and unintended fallback/reconstruction, not merely successful calls
packages/diskgraph/diskgraph-pybind/src/temporal_query.rs Temporal query evaluation / Python conversion Reuse native execution and retain thin Python conversion/merge glue Share row/reduction work without making TT depend on PyO3
packages/diskgraph/diskgraph-train-table/src/ttgen_accumulator.rs Numeric batch accumulation / value hashing Share accumulation and typed grouping hash policy Retain full equality checks and frontend reduction behavior
packages/diskgraph/diskgraph-train-table/src/ttgen_executor.rs execute_numeric_group / execute_aggregate / stages Share numeric batch evaluation and ordered accumulation Keep precision, empty/NULL and fallback policies explicit
packages/diskgraph/diskgraph-train-table/src/ttgen_resolve.rs resolve_op / resolve_scalar_aggregate / paths and filters Resolve both frontend operations through shared handles and filter metadata Preserve PQL semantics and reuse traversal rather than reinterpret query policy
packages/diskgraph/diskgraph-train-table/tests/ttgen_integration.rs Native node projection Exercise 600 real node reads across the 512-row decoder boundary Cover the PQL Nodes route independently of projected temporal batches

Verified repair — 2026-11-11

Head: e891b9e9e9fc3e359acc8cd64bc9d212fa26ab5e. Declined numeric groups now fall back once per operation; independent signed-zero/nonfinite checks and a 600-node native decode regression.

Validation: repaired combined stack passed 146 Rust TT integration tests and 579 Python native/conformance tests with a freshly rebuilt extension. Public Python suite: 1,951 passed; optional-native import checks: two modules skipped as expected without DiskGraph. Generated artifact manifest and 403-component notice checks passed. No live sweeps or merges.

@copy-pr-bot

copy-pr-bot Bot commented Nov 10, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Explain Change →

Walkthrough

The change adds grouped numeric execution for compatible PQL aggregates and eligible aggregate-only temporal queries. It shares aggregate input resolution and accumulator behavior across execution paths. Temporal queries use the grouped path for supported one-hop, second-based numeric operations and retain the existing evaluator when eligibility checks fail or grouped execution returns no result. New tests compare results across numeric edge cases and verify temporal window behavior.

Sequence Diagram(s)

sequenceDiagram
  participant TemporalQuery
  participant resolve_named_path
  participant execute_numeric_group
  participant accumulate_numeric_batch
  TemporalQuery->>resolve_named_path: Resolve frame relation path
  resolve_named_path-->>TemporalQuery: Return resolved edges
  TemporalQuery->>execute_numeric_group: Submit eligible operations and projected rows
  execute_numeric_group->>accumulate_numeric_batch: Accumulate selected numeric columns
  accumulate_numeric_batch-->>execute_numeric_group: Return accumulator status
  execute_numeric_group-->>TemporalQuery: Return aggregate results or no grouped result
Loading
Merge Risk: Low · up to e891b

The numeric results have no established production defect, but the signed-zero test could miss a regression in the shared path. Add a route assertion for confidence; the remaining risk is bounded.

Security architecture risk: Low · up to e891b

The shared execution path retains conservative eligibility checks and isolates incomplete results before falling back. No introduced security vulnerability was established, but incomplete coverage of downstream consumers and authorization prevents a minimal-risk assessment.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The confirmed propagation surface is query execution in the bindings and train-table library. Caller-supplied temporal plans reach the shared reducer through the existing API; tenant, service, or environment-wide collateral exposure cannot be established from the supplied deployment and authorization context.

Trust Boundaries and Controls

  • observed — The optimized temporal path still uses frame materialization that checks decoded timestamps against exact bounds and preserves established ordering. Shared execution eligibility does not replace these row-selection controls.

Resilience and Maintainability Implications

  • inferred — Accumulator and result ownership is local to each execution, containing partial failures without cross-call numeric state. The 512-row decode batches do not bound total selected-row memory, but the existing traversal already materialized an edge vector; the evidence does not establish a newly introduced unbounded-memory security condition.
Pre-merge checks: Passed 2 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Change Map Design Review Inconclusive The full marked change-map comment and its linked problem are unavailable. The supplied summary cannot establish whether the same comment explains the observed failure or release requirement, necessit… Provide the full comment starting with <!-- kumo-pr-change-map --> and the linked problem context. Review the design against both and the repository code.
Passed Passed checks: 2 passed

Check name Status Explanation
Pr Size Passed The PR changes 8 files. The limit is 40 files.
Public Resource Access Passed The changed lines add no external resource references. The added file paths are local test fixtures.
Full details: Change Map Design Review

Explanation

The full marked change-map comment and its linked problem are unavailable. The supplied summary cannot establish whether the same comment explains the observed failure or release requirement, necessity, and stopping condition. The diff has 1,036 additions and deletions, so file-level scope descriptions are permitted. The code shows shared numeric execution and fallback paths, but that does not establish the proposed design’s necessity.

Resolution

Provide the full comment starting with &lt;!-- kumo-pr-change-map --&gt; and the linked problem context. Review the design against both and the repository code.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

Other comments: 1

packages/diskgraph/diskgraph-train-table/src/ttgen_executor.rs: 1

2744-2770: Minor · Performance & Scalability · Quick win

Run the whole group per operation when the grouped attempt declines.

execute_numeric_group can return None after a full traversal and decode. This happens when accumulate_numeric_batch finds a non-finite value. The loop then handles only stage.ops[position] with the per-operation path and advances position by one. On the next iteration, map_while builds the group again from the remaining suffix. If that suffix has more than one operation, the grouped path traverses and decodes the same rows again, and it fails the same way.

Example: a stage has k compatible Sum operations and the entity has one inf value. That entity and timestamp then costs k−1 failed grouped traversals plus k per-operation traversals. The cost is quadratic in the group size, on every row that has a non-finite value.

The loop also allocates a group Vec for every Aggregate operation on every row, including single-operation groups.

When the grouped attempt declines, evaluate all members of group with execute_aggregate and then skip past the group.

♻️ Proposed fix

-                if group.len() > 1 {
+                if group.len() > 1 {
                     let cutoff = observation_ts.unwrap_or(Abs::from_raw(0));
                     if let Ok(Some(values)) = execute_numeric_group(&group, &[entity_node], &[cutoff],
                         ...
                         }) {
                         for (aggregate, mut column) in group.iter().zip(values) {
                             aliases[aggregate.alias_idx] = column.pop().unwrap();
                         }
-                        position += group.len();
-                        continue;
+                    } else {
+                        for aggregate in &group {
+                            aliases[aggregate.alias_idx] = execute_aggregate(
+                                plan, entity_node, aggregate, entity_cols, observation_ts,
+                                link_frequencies, link_split_values,
+                            );
+                        }
                     }
+                    position += group.len();
+                    continue;
                 }
Nitpick comments: 2

packages/diskgraph/diskgraph-pybind/python/tests/test_shared_numeric_aggregates.py: 1

86-93: Trivial · Functional Correctness · Quick win

The signed-zero check never reaches the shared path.

The test queries roots [3, 4] in one batch. accumulate_numeric_batch returns false when it finds the inf value of user 3. execute_numeric_group then returns None for the whole batch. The general evaluator therefore computes both the actual and reference results.

As a result, the shared reducers never see the -0.0/0.0 rows of user 4. A signed-zero regression in observe_numeric_row with keep_first_equal would pass this test. Query user 4 by itself so that the shared path runs for it.

💚 Proposed fix

 def test_nonfinite_and_signed_zero_keep_general_numeric_policy(numeric_graph):
-    actual = query(numeric_graph, [3, 4], operations=("sum", "mean", "min", "max"))
-    reference = query(numeric_graph, [3, 4], general=True, operations=("sum", "mean", "min", "max"))
-    for name in actual:
-        for left, right in zip(actual[name].to_pylist(), reference[name].to_pylist()):
-            assert left == right or math.isnan(left) and math.isnan(right), name
-            if left == 0.0:
-                assert math.copysign(1, left) == math.copysign(1, right), name
+    operations = ("sum", "mean", "min", "max")
+    # Separate batches: a nonfinite anchor makes the whole batch fall back.
+    for keys in ([3], [4]):
+        actual = query(numeric_graph, keys, operations=operations)
+        reference = query(numeric_graph, keys, general=True, operations=operations)
+        for name in actual:
+            for left, right in zip(actual[name].to_pylist(), reference[name].to_pylist()):
+                assert left == right or math.isnan(left) and math.isnan(right), name
+                if left == 0.0:
+                    assert math.copysign(1, left) == math.copysign(1, right), name
packages/diskgraph/diskgraph-train-table/src/ttgen_executor.rs: 1

3036-3170: Trivial · Maintainability & Code Quality · Quick win

Add PQL tests for numeric node chunking.

The existing grouped PQL tests use a small fixture. The 600-row Python test uses NumericRows::Projected, so it does not test the 512-row NumericRows::Nodes chunks.

Add Rust tests that compare grouped and per-operation PQL results for more than 512 rows, nulls, non-finite fallback, and window bounds. Check that the grouped path runs rather than silently falling back.

Source: Coding guidelines

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 5889014 and 09ffe30.

Files selected for processing: 7

  • packages/diskgraph/diskgraph-pybind/README.md
  • packages/diskgraph/diskgraph-pybind/python/tests/test_shared_numeric_aggregates.py
  • packages/diskgraph/diskgraph-pybind/python/tests/test_temporal_sequence_limit.py
  • packages/diskgraph/diskgraph-pybind/src/temporal_query.rs
  • packages/diskgraph/diskgraph-train-table/src/ttgen_accumulator.rs
  • packages/diskgraph/diskgraph-train-table/src/ttgen_executor.rs
  • packages/diskgraph/diskgraph-train-table/src/ttgen_resolve.rs

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@Victsm
Victsm deployed to gha-kumo-workflow-tests November 11, 2026 03:47 — with GitHub Actions Active

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nitpick comments: 1

packages/diskgraph/diskgraph-pybind/python/tests/test_shared_numeric_aggregates.py: 1

86-89: Trivial · Maintainability & Code Quality · Quick win

Assert that the finite case uses the shared path.

Key 3 tests the non-finite fallback. Key 4 already provides finite signed zeros, but the test can pass if shared execution declines and both queries use the general evaluator. Add a route assertion for key 4.

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 09ffe30 and e891b9e.

Files selected for processing: 3

  • packages/diskgraph/diskgraph-pybind/python/tests/test_shared_numeric_aggregates.py
  • packages/diskgraph/diskgraph-train-table/src/ttgen_executor.rs
  • packages/diskgraph/diskgraph-train-table/tests/ttgen_integration.rs

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

This branch was successfully deployed

1 active deployment
gha-kumo-workflow-tests — e891b9e9 Deployed Nov 11, 2026 by Victsm via import #2042
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