Skip to content

einsum: delegate nesting-preserving products to the expression layer; drop per-tile reference kernels#566

Merged
evaleev merged 3 commits into
evaleev/feature/general-product-exprfrom
evaleev/feature/einsum-expr-nesting-preserving
Jun 12, 2026
Merged

einsum: delegate nesting-preserving products to the expression layer; drop per-tile reference kernels#566
evaleev merged 3 commits into
evaleev/feature/general-product-exprfrom
evaleev/feature/einsum-expr-nesting-preserving

Conversation

@evaleev

@evaleev evaleev commented Jun 12, 2026

Copy link
Copy Markdown
Member

Stacked on #562 (evaleev/feature/general-product-expr). Narrows einsum so that, by default, only type-mutating products (the ToT·ToT→T denest reduction) remain its own; every nesting-preserving product now flows through the general-product expression engine.

Commits

1. einsum: delegate nesting-preserving products to the expression layer

  • Fused broadcast C(h,e) = A(h) · B(h,e) (one operand entirely fused, no contraction): drops the replicate_array() expand-then-Hadamard and delegates directly. The engine evaluates it natively once the fully-fused operand leads — its folded left tile is rank-0, restored by a synthetic unit left-external mode. ContEngine::synthetic_unit_left_external() now fires for a rank-0 left operand (broadcast), not only a rank-0 result (no-external). einsum orders the fully-fused operand first and applies any inner result permutation afterward.
  • No-external C(h;…) = A(h,i;…) · B(h,i;…) (fused + contracted, no free index): now defaults to the expression layer (the existing no-external synthetic-unit mode). The legacy local kernel is retained only behind einsum_legacy_subworld() as the cross-check oracle, mirroring the generalized-subworld path.
  • Tests: dense fused broadcast (both operand orders); ToT no-external with inner Hadamard and inner contraction.

2. tests: guard assign_subblock REQUIRE_THROW on TA_ASSERT_POLICY

  • That throw is enforced by a TA_ASSERT, so it only happens under TA_ASSERT_THROW. Under the Release default (TA_ASSERT_IGNORE) the assert is a no-op and the REQUIRE_THROW failed; guard it to only expect the throw when assertions actually throw.

3. tests: remove the per-tile general-product reference kernels

  • contraction_helpers.h (kernels::{s_t_t,t_s_t,t_t_t,t_tot_tot,tot_t_tot,tot_tot_tot}_contract_) and its dedicated tests were scaffolding used only to develop/cross-check einsum; the expression-layer engine supersedes them and no production code references them. Removes the header, the generated test files, their CMake entries, the stale einsum.cpp include, and the generate_answers.ipynb generator.

Validation

einsum (einsum_manual, einsum_tot, einsum_tot_t, einsum_tiledarray, einsum_eigen) + general_product_suite — 102 cases green post-nuke.

evaleev added 2 commits June 12, 2026 16:51
Two general-product shapes that einsum handled with bespoke machinery are
nesting-preserving (the result keeps the operand nesting), so the general-
product expression engine can own them; only the type-mutating ToT*ToT->T
denest reduction remains einsum's by default.

* Fused broadcast C(h,e) = A(h) * B(h,e) (one operand entirely fused, no
  contraction): replaces the replicate_array() expand-then-Hadamard with a
  direct delegation. The engine evaluates it natively once the fully-fused
  operand leads -- its folded left tile is rank-0, restored by a synthetic
  unit left-external mode. ContEngine::synthetic_unit_left_external() now
  fires for a rank-0 LEFT operand (broadcast), not only a rank-0 RESULT
  (no-external). einsum orders the fully-fused operand first and applies any
  inner result permutation afterward.

* No-external products C(h;..) = A(h,i;..) * B(h,i;..) (fused + contracted,
  no free index) now default to the expression layer (the existing
  no-external synthetic-unit mode). The legacy local kernel is retained only
  behind einsum_legacy_subworld() as the cross-check oracle, mirroring the
  generalized-subworld path.

Tests: dense fused broadcast (both operand orders), ToT no-external with
inner Hadamard and inner contraction.
The "overriding trange of result block is not allowed" check is enforced by a
TA_ASSERT, so it only throws when TA_ASSERT_POLICY == TA_ASSERT_THROW. Under
the Release default (TA_ASSERT_IGNORE) the assert is a no-op, so
BOOST_REQUIRE_THROW failed with "Exception expected but not raised". Only
expect the throw when assertions actually throw.

Copilot AI 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.

Pull request overview

This PR narrows einsum() so that nesting-preserving products (including fused broadcast and “no-external” fused+contracted reductions) are evaluated by the expression-layer general-product engine by default, and removes the legacy per-tile reference kernels/tests that were previously used as a development oracle.

Changes:

  • Route fused-broadcast and no-external (nesting-preserving) products through the expression engine (with operand ordering + canonical-eval + final permutation where needed).
  • Extend ContEngine’s synthetic-unit handling to cover rank-0 left operand folds (broadcast) in addition to rank-0 result folds (no-external).
  • Remove contraction_helpers.h and its associated generated tests/scaffolding (plus related build/test wiring).

Reviewed changes

Copilot reviewed 11 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/t_s_t_contract_.cpp Removed generated tests for legacy per-tile contraction helper kernels.
tests/s_t_t_contract_.cpp Removed generated tests for legacy per-tile contraction helper kernels.
tests/general_product.cpp Added coverage for dense fused-broadcast and ToT no-external cases; removed debug try/catch noise.
tests/expressions_impl.h Guarded a throw-expectation that only applies when TA_ASSERT is configured to throw.
tests/einsum.cpp Dropped now-removed legacy header include; formatting-only adjustments in touched hunks.
tests/contraction_helpers.cpp Removed tests for legacy helper utilities tied to the deleted header.
tests/CMakeLists.txt Removed deleted legacy test sources from the test build.
src/TiledArray/expressions/contraction_helpers.h Removed legacy helper header and its old einsum implementation.
src/TiledArray/expressions/cont_engine.h General-product engine: synthetic-unit mode now also supports rank-0 left operand folds (broadcast).
src/TiledArray/einsum/tiledarray.h einsum() delegates fused-broadcast + no-external nesting-preserving products to the expression layer (with canonicalization and post-permute).
src/CMakeLists.txt Removed deleted header from the installed/source header list.
bin/generate_answers.ipynb Removed obsolete generator notebook for the deleted reference-kernel tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

contraction_helpers.h (kernels::{s_t_t,t_s_t,t_t_t,t_tot_tot,tot_t_tot,
tot_tot_tot}_contract_) and its dedicated tests were scaffolding used only to
develop and cross-check einsum; the expression-layer general-product engine
has superseded them and no production code references them. Remove the header,
the generated test files, their CMake entries, the stale einsum.cpp include,
and the generate_answers.ipynb generator.
@evaleev evaleev force-pushed the evaleev/feature/einsum-expr-nesting-preserving branch from fc52bff to 5e8d5b4 Compare June 12, 2026 23:08
@evaleev evaleev merged commit 10c18da into evaleev/feature/general-product-expr Jun 12, 2026
9 checks passed
@evaleev evaleev deleted the evaleev/feature/einsum-expr-nesting-preserving branch June 12, 2026 23:53
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.

2 participants