Repository navigation
Conversation
`_instantiate_operators` ran all of the work of the `MPOHamiltonian` constructors inside `map(collect(local_operators)) do term ... end`. Below that `map` call, type inference applies its recursion limit to every nested `map` over a vector whose element type is not concrete, such as `map(dual, S.spaces)` in `dual(::SumSpace)`. The limited results are not cached, so each function between the two `map` calls is inferred again at every call site (JuliaLang/julia#64862). A comprehension gives the same result without a `map` frame at the root. First call of `InfiniteMPOHamiltonian([P, P], (1, 2) => h, (2, 3) => h)` from that issue: | Julia | before | after | |---------------|------------------|------------------| | 1.10.13 | 10.7 s, 4.5 GiB | 9.4 s, 3.5 GiB | | 1.13.3 | 36.0 s, 16.7 GiB | 16.8 s, 7.6 GiB | | 1.14.0-alpha2 | 29.5 s, 16.4 GiB | 14.7 s, 7.9 GiB | Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Put inference barriers around the calls in `_instantiate_operators` that receive the untyped representatives, and reorder the inverse `swap!` contraction so that `τ'` is not the first `@plansor` tensor. That ordering threw `UndefVarError: τ` (QuantumKitHub/TensorKit.jl#622), and since it was an undefined global it also made the whole method infer abstractly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Same measurement on Julia 1.10 and 1.11: the first call that builds the SU(2) Heisenberg
The first The abstract inference costs time even on 1.10, where limited inference results are still cached. On newer versions it costs more. With this PR, the three versions end up within a few seconds of each other. |
# Conflicts: # src/operators/mpohamiltonian.jl
|
Looking at this from a far, so have not checked in detail, but I have a vague feeling like it might (or should?) be possible to actually make things run on concrete types instead. At the end of the day, we do actually know what the type will be, it has to be the unique space type shared by all inputs, and the promoted scalar type. Computing these beforehand, we might just be able to make the Note though that I absolutely have not tried this out, so this might not be possible at all, and the compiler might still give up, it's just that it would feel to me like a slightly more "elegant" approach to the problem at hand. |
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
I somehow tried it in #557, but this introduces some behaviour change ( possible bond dimension growth) |
Follow-up to #554.
When a Hamiltonian is constructed after #554 and QuantumKitHub/BlockTensorKit.jl#90, about 30k inference frames still run on abstract signatures. They come from two places:
_instantiate_operators: the representatives are stored asTuple{Any, Any, Any}, soinstantiate_operator,_proportionalityand the rescaling of the last tensor are all inferred with abstract argument types. This PR puts these calls behindBase.inferencebarrier, and moves the rescaling into a small function_rescale_last.swap!withinv = true:@plansormishandles a leadingτ'(@plansorthrowsUndefVarError: τwhenτ'is the first input tensor TensorKit.jl#622). It ends up referring to an undefined globalτ, soswap(mpo, i; inv = true)throws anUndefVarError, and the whole method is inferred abstractly. Movingτ'to the end of the contraction avoids the bug. This PR also adds a test thatswapfollowed by its inverse returns the original operator, for ℂ², FermionParity and Fibonacci anyons. The test compares dense operators, becauseisapproxon MPOs is flaky at its default tolerance (isapprox(::MPO, ::MPO)is flaky at the default tolerance #555).Measurements are from a single A/B run with Julia 1.13.3, on top of #554 and BlockTensorKit#90, building an SU(2) Heisenberg
InfiniteMPOHamiltonianin a fresh process:FiniteMPOHamiltonianwith an unsorted term (swap!)Warm runtime does not change. Across three alternating rounds of four constructions (2-site infinite, unsorted term, 40-site chain, all-to-all on 12 sites), the minimum times were equal or slightly lower after the change. Locally, the
mpo,hamiltonianandoperatorstest files pass.I have not measured other Julia versions, or this change without #554 underneath.
🤖 Generated with Claude Code