Skip to content

[WIP] Remove the compat submodule and shrink the itensors.jl shim onto the upstream API#2

Draft
mtfishman wants to merge 20 commits into
mf/itensorbase-backendfrom
mf/rm-compat
Draft

[WIP] Remove the compat submodule and shrink the itensors.jl shim onto the upstream API#2
mtfishman wants to merge 20 commits into
mf/itensorbase-backendfrom
mf/rm-compat

Conversation

@mtfishman

@mtfishman mtfishman commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

Removes the ITensorsITensorBaseCompat submodule and shrinks the remaining legacy shim onto the upstream ITensorBase / TensorAlgebra / MatrixAlgebraKit API.

The operator and named-state system, which has no upstream equivalent, becomes a TNQS-owned Ops submodule (custom gates extend Ops.op, and state is called qualified as Ops.state so it does not collide with ITensorBase.state). The remaining legacy tensor helpers move into an itensors.jl shim that this PR then trims:

  • Index and tensor ops move to the upstream versions: prime/noprime (including the whole-tensor forms), id, sim, scalartype, and the name-based index-set algebra (commoninds/uniqueinds/trycommonind/trynoncommonind). Index equality is name-based (dual-insensitive), so plain Base set-ops work directly on index collections and the local small/name set helpers and the commonind/noncommonind/similar_map wrappers are gone.
  • More index and storage helpers move to the upstream API too: index relabeling uses ITensorBase's replaceinds directly (dropping the vendored replaceind/replaceinds/swapind wrappers, with collection relabels spelled (from .=> to)...), storage access uses unnamed/Array and a datatype that delegates to TensorAlgebra.datatype (Name-based index-set algebra, whole-tensor index ops, and the id/uuid rename ITensor/ITensorBase.jl#213), and in-place scaling uses ITensorBase's rmul!. The matricize(a::ITensor) helper is dropped for the upstream matricize(a, codomain, domain), which generates the fused output names itself, so no fresh-name minting remains at the TNQS call sites. The list-contraction verb contract is renamed to contract_network, and tags are set through key => value pairs now that the comma-string settags form is gone (settags accepts any iterable of pairs).
  • Factorizations at the call sites go straight through MatrixAlgebraKit (qr_compact/svd_compact/svd_trunc/left_orth/right_orth), and the operator trace is tr(a, operator_inds(a)...). The compat factorize and eigen wrappers are removed, keeping itensor_trunc for the cutoff/maxdim to trunc translation. A call that names the new bond inlines the relabel until tag support lands in the upstream factorizations. The apply routines report their truncation error from svd_trunc's returned ϵ instead of a cancellation-prone norm subtraction.
  • Because Index equality is name-based, the contraction-sequence optimizers, the graph index-set operations, and directsum take Index objects directly, dropping the name.(...) labels and comparisons that only worked around dual-mismatched indices. directsum now aligns each tensor with unname, and gains a first test through the +/add path.
  • Legacy no-ops (disable_warn_order, denseblocks, dense) and the first-shrink shims (random_itensor, itensor, algorithm_name, dim, dag, filtered-inds) are dropped for randn, TensorAlgebra.scalar, length, conj, and inline filter at the call sites.

Depends on the ITensorBase and TensorAlgebra changes in ITensor/ITensorBase.jl#213 and ITensor/TensorAlgebra.jl#205, pinned via [sources] until those register.

TODO

  • Remove the [sources] pins once ITensorBase 0.11 and TensorAlgebra 0.17.1 register.

mtfishman and others added 11 commits July 8, 2026 20:01
Move its contents to their permanent homes: the operator and named-state system to a TNQS-owned `Ops` submodule, the remaining legacy tensor helpers to `itensors.jl`, and the index and tensor operations ITensorBase now provides (`prime`, `noprime`, `id`, `sim`, `scalartype`) to the upstream versions. Drop the legacy no-ops `disable_warn_order`, `denseblocks`, and `dense`, and name the ITensor trace `itensor_tr` so it stays distinct from `tr` on plain matrices.
randn over Index objects already covers what the legacy random_itensor wrapper did, so drop the four-line shim and call randn directly at the construction sites and in the tests. Also updates the states.md example off the removed Index tag-string constructor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
trivialrange on a named range already mints a fresh, backend-preserving range, so wrapping it back in Index(trivialrange(unnamed(...))) is redundant and collapses to trivialrange(...).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A mechanical pass replacing legacy shims with the spellings the next-gen stack already provides, shrinking the TNQS-owned shim file:

- Remove the dead `itensor` and `algorithm_name` (no callers).
- Re-export `TensorAlgebra.scalar` in place of the local `scalar`.
- Replace `dim` with `length` at the callsites.
- Replace `dag` with `conj`, which covers whole tensors, indices, and (broadcast) index collections.
- Drop the `inds(; plev, tags)` filtered wrapper for inline `filter`, taking `inds` from ITensorBase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The shim is transitional and shrinking, so the per-symbol rationale is recorded outside the source rather than carried inline. Code is unchanged, and the full test suite still passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…et-ops

The shim carried its own small-collection set operations and the commoninds/uniqueinds wrappers built on them. ITensorBase now provides these as public functions, keyed by index name internally so a graded bond still matches its dual, and NamedUnitRange equality is dual-insensitive, so Base set-ops work directly on index collections. This removes the duplicated helpers: tensor-argument callsites use ITensorBase's commoninds/uniqueinds/unioninds/hascommoninds/noncommoninds, and collection or mixed-argument callsites use Base's setdiff/intersect/union/symdiff/isdisjoint. The thin commonind/noncommonind conveniences stay, returning a single index or nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…compat helpers

Replaces the hand-rolled factorization compat layer with direct MatrixAlgebraKit-native calls. Adds operator_inds, the codomain/domain prime-level bipartition of an operator, and takes the operator trace through it with tr(a, operator_inds(a)...) rather than contracting against an identity. factorize now wraps left_orth / right_orth, which cover both the exact and truncating cases through trunc, and eigen wraps eigh_full. Drops the qr / svd / svd_trunc / itensor_tr shims and the index-bipartition helpers in favor of MatrixAlgebraKit calls and Base set functions at the callsites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removes the lenient `commonind`/`noncommonind` and the `similar_map` wrapper. Call sites now use ITensorBase's `trycommonind`/`trynoncommonind` (the single shared or unique index, or `nothing`) and the map-shaped `similar`, which takes its axes as a vector directly. The boundary-MPS link bonds carry a single `link` tag keyed by the bond index instead of the old two-tag `Link,l=...` string.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that `Index` equality is name-based, the sequence optimizers can take the `Index`es directly rather than their names. `to_eincode`, the omeinsum path, and the `optimal` dimension dict drop the `name.(...)` conversion, and a shared leg still matches across its two tensors even when stored nondual on one and dual on the other. The test compares against the `Index`es themselves.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With `Index` equality name-based, the `uniqueinds(tn, v)` graph-index difference and the loop-correction bond lookup drop their explicit `name(...)` comparisons for `Index` set-ops and equality. A shared graded link, stored nondual on one endpoint and dual on the other, still matches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`inds` already returns a fresh `Vector`, so the `collect` calls in `to_eincode`, `contraction_network`, and `uniqueinds` were redundant. Use the `inds` result directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mtfishman mtfishman changed the title [WIP] Remove the ITensorsITensorBaseCompat submodule [WIP] Remove the compat submodule and shrink the itensors.jl shim onto the upstream API Jul 9, 2026
mtfishman and others added 9 commits July 9, 2026 14:03
Factorization call sites go straight through MatrixAlgebraKit (`left_orth`/`right_orth`), keeping `itensor_trunc` for the `cutoff`/`maxdim` to `trunc` translation. Where a call named the new bond, the retag is inlined at the call site for now, until tag support lands in the MatrixAlgebraKit/ITensorBase factorizations. The compat `eigen` and the `safe_eigen` precision wrapper around it had no live callers and are deleted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nothing reads tags back (no `hastags`/`gettag` lookups anywhere), so the tag-string membership helper had no callers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`directsum` matches each tensor's axes to the target order via `findfirst(==(o), inds(t))`, since `Index` equality is name-based, dropping the `name`/`dimnames` detour. The defensive `Tuple`/`collect` wrapping is removed (`inds` returns a fresh `Vector` and the tuple splices work on any collection) and `shared` uses `setdiff`. Equivalence with the previous implementation was verified directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Covers the `+`/`add` direct-sum path (the only `directsum` caller), which had no test. Builds two states over a shared set of site indices, adds them, and checks the defining property that contracting the sum equals the sum of the contractions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`directsum` gets each tensor's axes via `unname(t, order)`, which aligns to the requested index order and unnames in one step, replacing the explicit `findfirst` permutation over `permutedims(unnamed(t), ...)`. `eltype` replaces `scalartype` for the output element type. Verified against the tensor-network addition test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…jl wrappers

Continues shrinking `src/itensors.jl` by deleting thin compat wrappers and
calling the upstream ITensorBase / TensorAlgebra functions at the call sites
instead. Index relabeling uses ITensorBase's `replaceinds` directly (in place of
the vendored `replaceind`/`replaceinds` shims, with collection relabels spelled
`(from .=> to)...`), storage access uses `unnamed`/`Array` and a `datatype` that
now delegates to `TensorAlgebra.datatype`
(ITensor/ITensorBase.jl#213), and in-place scaling goes
through ITensorBase's `rmul!` for `AbstractNamedTensor`. The list-contraction
verb `contract` is renamed to `contract_network`, and tag construction passes a
`key => value` pair now that the comma-string `settags` form is gone
(`site_tag` returns the site-type tag). `hasqns` stays for contraction-optimizer
selection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Relaxes the `AbstractDict` method to `settags(i, tags)` so it accepts any iterable
of `key => value` pairs (a `Vector` or `Tuple` of `Pair`s, not only a `Dict`). The
single-`Pair` method stays more specific, so single-tag calls are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`simple_update` and `full_update` now take the truncation error from
`svd_trunc`'s `ϵ` (the 2-norm of the discarded singular values, exposed in
ITensor/ITensorBase.jl#213) as `(ϵ / ‖M‖)^2`. This is the
same relative squared error the code reported before, but computed directly
instead of by the `1 - ‖S‖²/‖M‖²` subtraction, which lost all precision when
little was discarded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deletes the TNQS `matricize(a::ITensor)` helper and calls the new upstream
`matricize(a, codomain, domain)` from ITensorBase, which mints the fused output
names itself. `renyi_entropy` inlines the call, and the same `uniquename`
pattern in `loop_correlation` switches to the upstream form too, so no
fresh-name minting leaks into TNQS. `matricize` moves from `import` to `using`
since TNQS no longer extends it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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