Repository navigation
Conversation
For sectors with a simple unit, a superset of the coupled sectors suffices, as the fusion tree iterators yield nothing for the others: the unit if one side is empty, and otherwise the fusion product of the shorter side only, instead of the intersection of the fusion products of both sides. The trees and their order are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Instead of constructing a block for every combination of codomain and domain sectors, `fusionblocks` groups the cached `fusiontrees(W)` by their uncoupled sectors, in the same order as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| return fblocks | ||
| # in the order of `sectors(domain(W))` (outer) and `sectors(codomain(W))` (inner), each of | ||
| # which runs fastest over its first space | ||
| position(V) = Dict{I, Int}(s => i for (i, s) in enumerate(sectors(V))) |
There was a problem hiding this comment.
Do we need to map every sector to an Int, or can we get away with just calling < on the sectors themselves since they should appear in the same order, thereby avoiding having to allocate the Dicts here?
There was a problem hiding this comment.
We could do this, but I checked and the isless approach is actually slower (almost a factor of 2) for the product sectors I was testing with, since that callsfindindex for each factor at every comparison. So I would be inclined to keep the Dict positions since they're faster.
Also note I fixed an issue with the sorting below, where previously the Dict lookups were run at every comparison, whereas now we run the lookup on each block once and then sort on the obtained results.
There was a problem hiding this comment.
let me investigate if we can actually speed up the comparisons a bit, I think there are quite a few fast paths that might be able to get this closer together. It's also just about this looking a bit "ugly" or complicated, if we could just use comparison it's a bit easier to read
There was a problem hiding this comment.
Is this specifically for the SU(3) case by the way? I would guess the findindex on the other factors is cheap (unless we are missing some fast definitions here)
There was a problem hiding this comment.
QuantumKitHub/TensorKitSectors.jl#115
Mind giving it a go with that included?
There was a problem hiding this comment.
With QuantumKitHub/TensorKitSectors.jl#115, findindex for SU(3) goes from about 10 to 7 ns. For all spaces of one CTMRG iteration, the version with plain isless (keys computed once) takes 0.57–0.62 s instead of 0.64–0.65 s for fℤ₂ × U(1) × SU(3), and 6.3–6.9 s either way for fℤ₂ × U(1) × SU(2) × U(1); the Dict version takes 0.37–0.41 / 4.6–4.8 s with or without #115. So the remaining gap is the O(n log n) comparisons of sector tuples rather than findindex. Most of fusionblocks is grouping the trees anyway (0.27–0.33 / 3.3–3.4 s), so I'm fine with switching to the comparison version if you prefer how it reads.
There was a problem hiding this comment.
I think I'd say to avoid the optimization with the integers, also because it has some implicit dependence on the spaces iterating sectors in the correct order, so if this turns out to not be dominant we should probably not. Additionally it might be worth it to check with different sector types, where it might hurt performance
There was a problem hiding this comment.
Switched to plain comparisons. Timings of fusionblocks over all spaces (same blocks and order in all cases):
- SU(2), A₄, Ising, Fibonacci, SU(2) ⊠ SU(2), ℤ₂ ⊠ SU(2): about the same as with the
Dicts. - SU(3) and fℤ₂ × U(1) × SU(3): about 1.8× slower (0.46 → 0.84 s for the latter, one CTMRG iteration).
- fℤ₂ × U(1) × SU(2) × U(1): also about 1.8× slower (5.6 → 10.4 s, one CTMRG iteration).
So it only shows for larger product sectors, where comparing the sector tuples is the cost. Caching the blocks (#587) recovers part of that.
There was a problem hiding this comment.
Small follow-up: the key of each block is now computed once (sortperm) rather than at every comparison, which takes the two product cases above from 0.84 to 0.69 s and from 10.4 to 8.1 s.
`sort!(...; by = rank)` evaluated `rank`, and with it the `Dict` lookups of (product) sectors, at every comparison. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… only the longer side for trees Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…no legs on one side Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For several units, a coupled sector of a block must be compatible with the units at both ends of either side; otherwise the fusion tree iterator throws instead of being empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 14 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This is a draft illustrating some potential performance improvements; the actual implementations are
very much up for discussion.
Same blocks, same order, less work:
FusionTreeBlock{I}(uncoupled, isdual): forSimpleUnitsectors, the coupled sectors come fromthe fusion product of the shorter side only, instead of intersecting the products of both sides.
fusionblocks(W): groups the cachedfusiontrees(W)by uncoupled sectors, instead of constructinga (mostly empty) block for every combination of sectors.
New test: the blocks of a
HomSpacehold exactly its trees, in order.Cold construction of the recoupling data for one permutation of a tensor from a PEPS CTMRG step
(scripts below), main → this PR:
SU(2) gains little from threads:
FsymbolforSU2Irrepgoes through WignerSymbols, which takesa lock on every call. Removing that lock (caching the F-symbols in TensorKitSectors) is scheduled
as a follow-up.
TensorKit main (ae8abfc), SUNRepresentations c02a3f3, TensorKitSectors v0.3.10, Julia 1.12.5; shared 80-core
machine, two interleaved rounds agree within 15 %.
fℤ₂ × U(1) × SU(2) × U(1) reproducer (
julia -t8)fℤ₂ × U(1) × SU(3) reproducer (
julia -t8)🤖 Generated with Claude Code