Skip to content

core/tensor_network: braket-symmetric tensor shade invariant under bra↔ket exchange#542

Open
evaleev wants to merge 4 commits into
masterfrom
evaleev/feature/braket-symm-halftensor-canon
Open

core/tensor_network: braket-symmetric tensor shade invariant under bra↔ket exchange#542
evaleev wants to merge 4 commits into
masterfrom
evaleev/feature/braket-symm-halftensor-canon

Conversation

@evaleev
Copy link
Copy Markdown
Member

@evaleev evaleev commented Jun 6, 2026

Summary

VertexPainterImpl::to_hash_value() computes a tensor's shade — the color that salts every one of its slot/index vertices in the canonicalization graph — from a hash that included bra_rank and ket_rank in fixed order, with no regard for braket_symmetry().

For a braket-symmetric tensor, bra↔ket exchange is a symmetry, so a half-tensor X{a;;x} (bra-orbital) and its swapped form X{;a;x} (ket-orbital) should canonicalize identically. They didn't: the ordered (bra_rank, ket_rank) gave them different shades → different canonical graphs → different canonical hashes. TNV3 already colors bra/ket slot and bundle vertices symmetrically for such tensors (is_braket_symm); the core-vertex shade was the last ordered-by-bra/ket asymmetry.

Change

  • vertex_painter.cpp: when braket_symmetry == Symm, hash the two ranks as an unordered pair (sort them) so the shade is bra↔ket-invariant.
  • Regression test (test_canonicalize.cpp): a braket-symmetric half-tensor's bra-orbital and ket-orbital forms now share a canonical hash; the non-symmetric forms stay distinct.

Impact

No effect on tensors with equal bra/ket ranks or non-symmetric braket (the common cases) — the existing canonicalization snapshots are unchanged (full unit suite passes, no rebaselines).

Scope note

This makes the canonicalizer recognize braket-symmetric half-tensors as equivalent. It is a prerequisite for, but does not by itself deliver, auto-folding of such half-tensors in the eval/export path (e.g. noncovariant-THC export), which additionally requires routing regular (non-ToT) eval leaves through tensor-network canonicalization — a separate, broader follow-up.

…under bra<->ket

VertexPainterImpl::to_hash_value() seeds a tensor's "shade" (the color salting
all of its slot/index vertices in the canonicalization graph) from a hash that
included bra_rank and ket_rank in fixed order. For a braket-symmetric tensor,
bra<->ket exchange is a symmetry, so a half-tensor X{a;;x} and its swapped form
X{;a;x} got different shades — hence different canonical graphs/hashes — even
though they are equivalent. TNV3 already colors bra/ket slot and bundle vertices
symmetrically for such tensors; this was the last ordered-by-bra/ket asymmetry.

Hash the two ranks as an unordered pair when braket_symmetry == Symm, so the
shade is bra<->ket invariant. No effect on tensors with equal bra/ket ranks or
non-symmetric braket (the common cases), so the canonicalization snapshots are
unchanged; adds a regression test for half-tensor folding.
Comment thread tests/unit/test_canonicalize.cpp Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 makes tensor-network canonicalization bra↔ket-invariant for braket-symmetric tensors by ensuring the vertex painter’s per-tensor “shade” hash no longer depends on an ordered (bra_rank, ket_rank) pair. This aligns the core-vertex coloring with existing TNV3 symmetric coloring behavior so swapped half-tensor forms canonicalize identically when they should.

Changes:

  • Update VertexPainterImpl::to_hash_value() to hash bra/ket ranks as an unordered pair when BraKetSymmetry::Symm.
  • Add a regression test verifying swapped half-tensor forms share a canonical hash under braket symmetry, while remaining distinct without it.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
SeQuant/core/tensor_network/vertex_painter.cpp Makes tensor “shade” hashing bra↔ket-invariant for braket-symmetric tensors by sorting ranks before hashing.
tests/unit/test_canonicalize.cpp Adds regression coverage ensuring braket-symmetric half-tensors canonicalize identically under bra↔ket exchange.

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

Comment on lines +29 to +30
if (tensor._braket_symmetry() == BraKetSymmetry::Symm && bra_rank > ket_rank)
std::swap(bra_rank, ket_rank);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Braced it to match the rest of the file (f-up commit).

evaleev added 3 commits June 6, 2026 12:51
The braket-symmetric half-tensor test only uses occupied/unoccupied indices
(i, a), so the legacy spaces + PAO setup (copied from the existing
canonicalization test) was unnecessary; make_sr_spaces suffices.
Every other if in this file uses braces; match that (Copilot review).
The global test harness (test_main) already sets the default context to
make_sr_spaces() and the cardinal tensor labels, so the test needs no custom
index-space registry or canonicalizer registration — just deserialize and
canonicalize against the default context.
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.

3 participants