Skip to content

add unified contraction algebra interface with tropical and bf16 applications - #125

Open
DeanTMaxim wants to merge 16 commits into
tensorcircuit:masterfrom
DeanTMaxim:feat/contraction-algebra-tropical
Open

add unified contraction algebra interface with tropical and bf16 applications#125
DeanTMaxim wants to merge 16 commits into
tensorcircuit:masterfrom
DeanTMaxim:feat/contraction-algebra-tropical

Conversation

@DeanTMaxim

@DeanTMaxim DeanTMaxim commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

A generic, in-source ContractionAlgebra interface: run a tensor-network contraction over an arbitrary algebra (kernels + a boundary representation) via tc.set_contractor(algebra=...), routed by cons._algebraic_base_contraction. Two reference applications in applications/:

  • tropical (max-plus) — ground-state energy, configuration recovery, degeneracy counting (arXiv:2008.06888)
  • complex<bfloat16> pair-algebra — complex multiply as 4 real bf16 matmuls

Standard contractions are unchanged.

Motivation

tc-ng contractions normally run over the standard complex semiring. Some workloads need a different algebra — tropical (max-plus) for spin-glass ground states, or a low-precision storage (bf16 pair) for memory. Rather than special-case each in the contraction internals, this PR adds one generic entry point. The key choice is where a non-standard representation plugs in: the _algebraic_base_contraction boundary is the single place raw tensors are materialized outside the kernels, so a representation can transform storage once (leaves in, final out) without touching tn.Node or the topology. That keeps a non-standard axis (e.g. the bf16 pair axis) off tn.Node, which assumes axis==edge — avoiding that conflict by construction.

Design

Two ABCs in tensorcircuit/contraction_algebra/base.py: ContractionAlgebra (tensordot/einsum kernels + optional hooks) carries a Representation (boundary encode/decode codec), bundled so a kernel can't be mis-paired with a codec. _algebraic_base_contraction runs encode→kernels→decode at the topology boundary (after _extract_topology, before tn.Node); three small in-source guards in cons.py route non-standard algebras and skip preprocessing. Counting's degeneracy rides an aux side-channel (degeneracy()).

Breaking changes

None for upstream master — master has no contraction_algebra module; the diff is additive except ~11 internal lines in cons.py. Activate an algebra with tc.set_contractor(algebra=...), or the tropical() / counting_tropical() / bcomplex32() context managers.

Testing

~65 tests: standard==native keystone; tropical energy / counting (scalar + non-scalar) / tracking vs brute force; bf16 4M kernel units + end-to-end vs complex64 + an axis==edge wall canary. Author-run gates green (black, mypy --strict, pylint 10.00/10 on the new modules).

Notes for review

  • bf16 is numpy-correctness only this PR; GPU (jax/torch/cupy) bf16 kernels + benchmark are a follow-up (the codec is already backend-agnostic). numpy einsum rejects bf16, so _pair_einsum upcasts bf16→float32 per call (structure/quantization unchanged).
  • ml_dtypes is currently undeclared (lazily imported by the bf16 path; not in pyproject.toml) — maintainer decision whether to add it (e.g. an optional extra).

Out of scope (follow-up PRs)

GPU bf16 kernel + benchmark (L3); set_dtype("bcomplex32") pipeline (L4); non-scalar tracking recover_configuration (orthogonal, separately gated).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a generic contraction_algebra monkey-patch interface to TensorCircuit-NG, enabling custom contraction primitives such as max-plus (tropical) algebra, counting, and configuration recovery. It includes reference implementations, examples, and comprehensive test suites. The review feedback suggests improving code conciseness by using np.prod instead of explicit loops, utilizing be.abs() for clearer floating-point comparisons, refactoring redundant logic in the tropical context manager, and adopting a more robust declarative approach for test path configuration in conftest.py.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread applications/tropical_algebra.py Outdated
Comment thread applications/tropical_algebra.py Outdated
Comment thread applications/tropical_algebra.py Outdated
Comment thread applications/tropical_algebra.py Outdated
Comment thread applications/tropical_algebra.py Outdated
Comment thread conftest.py Outdated
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch 2 times, most recently from fad6f8d to 2f7ecac Compare July 16, 2026 19:53

@refraction-ray refraction-ray left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am just quickly going through and raise some more evident catches, the most important on is on the interface deisgn, you need to consider the node patch case together to design the interface in one run, instead of further changing the interface later

Comment thread examples/tropical_ising.py Outdated
Comment thread applications/tropical_algebra.py
Comment thread tests/_tropical_test_utils.py Outdated
Comment thread CHANGELOG.md Outdated
Comment thread pyproject.toml Outdated
Comment thread examples/tropical_ising.py Outdated
Comment thread tensorcircuit/contraction_algebra.py
Comment thread tensorcircuit/contraction_algebra/injection.py Outdated
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from 2f7ecac to afde184 Compare July 17, 2026 15:09
@DeanTMaxim DeanTMaxim changed the title add contraction algebra interface + tropical reference application add unified contraction algebra interface with tropical and bf16 applications Jul 17, 2026
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch 5 times, most recently from 7bcb112 to 03a192f Compare July 18, 2026 04:17
…ications

ContractionAlgebra + Representation ABCs (boundary encode/decode) activated
via set_contractor(algebra=...); routed in-source by cons._algebraic_base_contraction
(no monkey-patch). Two reference applications in applications/: tropical (max-plus
ground-state energy, configuration recovery, degeneracy counting; arXiv:2008.06888)
and complex<bfloat16> pair-algebra (4M real bf16 matmul; boundary encode/decode
keeps the pair axis off tn.Node, dodging the axis==edge wall).
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from 03a192f to 539ff5d Compare July 18, 2026 07:35
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from 9968429 to a1f8c1b Compare July 18, 2026 12:42
Comment thread applications/bcomplex32_algebra.py Outdated
Comment thread tensorcircuit/contraction_algebra/base.py Outdated
Comment thread tensorcircuit/contraction_algebra/__init__.py Outdated
Comment thread tensorcircuit/cons.py Outdated
Comment thread tensorcircuit/cons.py Outdated
Comment thread applications/tropical_algebra.py
Comment thread tensorcircuit/cons.py Outdated
Comment thread tensorcircuit/cons.py Outdated
Comment thread applications/tropical_algebra.py
Comment thread applications/bcomplex32_algebra.py Outdated
Comment thread applications/tropical_algebra.py
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from 7612492 to 5de41f8 Compare July 18, 2026 15:47
Comment thread requirements/requirements-dev.txt Outdated
- Replace prefer_einsum: bool on ContractionAlgebra ABC with get_contractor_kwargs()
  method (default {}), keeping the ABC clean of cotengra-specific flags
- ComplexPairAlgebra overrides to return {'prefer_einsum': True}
- cons.py unpacks via **alg.get_contractor_kwargs()
- De-hardcode float32/complex64 in _pair_to_complex to use cons.rdtypestr/dtypestr
- Remove personal pythonpath config from pyproject.toml and example docstring
- Add unit test for get_contractor_kwargs default behavior
- Tighten test_tropical_public_api_surface to direct import assertions
- Merge base.py into contraction_algebra.py (122 lines total → single module)
- Remove subpackage directory (__init__.py + base.py → contraction_algebra.py)
- Fix deep imports in cons.py and test_contraction_algebra.py
- Tighten GHZ-8 test tolerance (5e-2 → 1.5e-2)
- Replace fake_node string with real tn.Node in merge_single_gates test
- Fix 'Opt-in' comment → 'ALGEBRAIC EXECUTION PATH'
- Document thread-safety limitation of _aux_outputs_store
- Explain be/kbe naming and einsum diagonal safety
- Inline _expand_to_layout_pair (single call-site)
- Fix CHANGELOG: set_contractor → set_contraction_algebra
- Revert unrelated black version pin in requirements-dev.txt
- Add _stash_aux_outputs({}) to legacy contraction path
…ebra

- _contraction_algebra defaults to None; _standard singleton for fallback
- _ns_alg check uses is not None (not isinstance)
- _algebraic_base_contraction uses alg or _standard
- Zero overhead for default users: legacy path runs with no diff
- Cleaner branch, better backward compat and reviewer friendliness
@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
tensorcircuit/cons.py 91.02% 7 Missing ⚠️
Files with missing lines Coverage Δ
tensorcircuit/contraction_algebra.py 100.00% <100.00%> (ø)
tensorcircuit/cons.py 81.66% <91.02%> (+2.76%) ⬆️

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread docs/2026-07-19-contractor-kwargs.md Outdated
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch 2 times, most recently from 269c756 to 0184776 Compare July 19, 2026 16:38
DeanTMaxim added a commit to DeanTMaxim/tensorcircuit-ng that referenced this pull request Jul 20, 2026
@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from a64526f to 915cc76 Compare July 20, 2026 11:37
Comment thread tensorcircuit/cons.py
from .backends import get_backend
from .simplify import _multi_remove
from .contraction_algebra import (
ContractionAlgebra as _ContractionAlgebra,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why as, and there is also lower case _contraction_algebra variable in this file, dangerously similar and confusing

Comment thread tensorcircuit/cons.py
return _contraction_algebra


def set_contraction_algebra(alg: Optional[_ContractionAlgebra]) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no support for default arg, say set_contraction_algebra() with no arg should recover the default behavior

Comment thread tensorcircuit/cons.py
"""Decode the contraction output under a non-standard algebra.

``rep.decode`` is responsible for stashing any aux internally."""
if not ns:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no need for ns, if not ns, in the parent function there should be no call on _decode

Comment thread tensorcircuit/cons.py
if alg is not None:
rep = alg.representation
else:
rep = IdentityRepresentation() # no-op; _decode skips it when ns=False

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

better no need to set?

Comment thread tensorcircuit/cons.py
size_dict,
algorithm,
alg is not None,
algebra=alg,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

merge the two variable? as algebra=None means ns=False

Comment thread tensorcircuit/cons.py
ctg=ctg,
)

final = _decode(alg is not None, rep, backend, final, output_set)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if outside the _decode call

Comment thread tensorcircuit/cons.py

To change the contraction algebra, use ``cons.set_contraction_algebra(alg)``
separately (the algebra is orthogonal to the contractor configuration). The
``tropical()`` / ``bcomplex32()`` / ``counting_tropical()`` context managers

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no, dont define these sub context managers, just use something like set_contraction_algebra(TropicalAlgebra)

return tensor, {}


class ContractionAlgebra(ABC):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is there elegant way to merge Representation class and Algebra class?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is it okay just define encode and decode in Algebra class?

return be.einsum(eq, *operands)


class PairTensor:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why bother the class, just bare tuple suffices?



@contextlib.contextmanager
def bcomplex32() -> Iterator[None]:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

delete this

@DeanTMaxim
DeanTMaxim force-pushed the feat/contraction-algebra-tropical branch from 915cc76 to bc7671c Compare July 20, 2026 12:36
@sonarqubecloud

Copy link
Copy Markdown


# --- Task 12: end-to-end through real tc.Circuit + wall-avoidance canary ---

import tensorcircuit as tc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

middle import is not allowed

# --- Task 12: end-to-end through real tc.Circuit + wall-avoidance canary ---

import tensorcircuit as tc
from applications.bcomplex32_algebra import bcomplex32

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how can you import something from application instead of tensoricrcuit.application?

from applications.bcomplex32_algebra import bcomplex32


def test_bf16_end_to_end_matches_complex64():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

set jax, tf and numpy backend with fixtures?

c.cnot(i, i + 1)
st = np.asarray(c.state())
assert st.shape == (16,) # ran cleanly, no axis==edge crash
import tensorcircuit.cons as cons

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no middle import, too ugly

@@ -0,0 +1,470 @@
import numpy as np
import tensorcircuit as tc
import tensorcircuit.cons as cons

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

better just use tc.cons



def test_public_api_surface():
from tensorcircuit import contraction_algebra as tca

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no middle and repeated import

def test_public_api_surface():
from tensorcircuit import contraction_algebra as tca

# After Task 14 the package exports only the 4 base names; activation lives

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

dont leave think loudly type comments

"IdentityRepresentation",
]:
assert hasattr(tca, name), name
# The old monkey-patch API names are intentionally gone:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why you test something are changed to ensure they are not existing anymore, weird...

StandardAlgebra,
Representation,
IdentityRepresentation,
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

middle import again

import numpy as np
import tensornetwork as tn
import opt_einsum
import pytest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

...

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