You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Serial sectorstructure and fusionblocks dominate building transformers of product sectors #596
With #580, #581 and #592, most of the time spent building the braid transformers of product sectors goes into their serial preparation. That preparation is sectorstructure, degeneracystructure and fusionblocks, and it runs before the threaded part.
Building all transformers of one CTMRG iteration with fℤ₂ × U(1) × SU(2) × U(1) (D = 7) on 8 threads takes 19.5–20.6 s. 13.5–14.9 s of that is the serial preparation.
The cost comes from storing every tree pair. That's 5.6 M pairs from 1.3 M splitting and fusion trees, over 776 spaces:
sectorstructure: about half the time hashes every pair into the Indices. The rest enumerates the trees.
fusionblocks: about 40 % sorts the groups, with tuple comparisons of product sectors. About 15 % hashes the uncoupled sectors of every pair into the Dict.
Proposal
fusiontrees(W) keeps the splitting and fusion trees of every coupled sector, not the pairs.
A pair's position follows from the trees: offset[c] + (j₂ - 1) * n₁[c] + j₁.
A small AbstractIndices type would hand out positions as tokens, so gettoken/gettokenvalue and the call sites stay unchanged.
subblockstructure(W) would become a dictionary that shares those tokens.
fusionblocks groups each side and combines the groups.
The groups are keyed by the position of their uncoupled sectors among the sectors of each space, so the sort compares integers.
Every block is filled once, at its final size.
Prototype
The prototype gives identical transformers, block order included, on all transformers of the iteration (550 for SU(2), 554 for SU(3)). The spaces, construction, indexmanipulations, braidingtensor, diagonal and doubletree tests pass.
Baseline: main + #580 + #581 + #592 (as of 832ec10, plus the unique-product shortcut it has now). Both versions also preallocate the pair vector in sectorstructure. Measured on a shared machine at load 34–50, two rounds in the same run:
1 thread
8 threads
fℤ₂ × U(1) × SU(2) × U(1), before
28.0–29.6 s
19.5–20.6 s
fℤ₂ × U(1) × SU(2) × U(1), after
18.4–19.6 s
12.5–13.8 s
fℤ₂ × U(1) × SU(3), before
9.0–12.6 s
4.2–4.3 s
fℤ₂ × U(1) × SU(3), after
7.9–8.0 s
3.3–3.4 s
The serial part (SU(2) case) goes from 13.5–14.9 s to 5.3–7.5 s:
fusionblocks: 6.6–8.0 s → 1.9–2.2 s;
sectorstructure: 4.4–5.9 s → 2.2–2.8 s;
degeneracystructure: unchanged.
Caching the trees of each side across spaces didn't pay off, so the prototype adds no new cache.
Questions
fusiontrees(W) and subblockstructure(W) would no longer return an Indices and a Dictionary. Is that acceptable, or does other code rely on those types?
The integer positions in fusionblocks depend on the order in which sectors(V) iterates, as the current sort key already does implicitly. Is that acceptable now that fusionblocks dominates?
I don't think there's an issue with changing the types, as long as they follow the same Dictionaries.jl interface nothing should really change. I think there are some internals in TensorKit that depend on the tokens being integers, but I guess that is what the prototype is already doing so that should probably be fine?
For the positions in fusionblocks, nothing really depends on that order. I think the previous order is mostly chosen such that the .data field is traversed in order (ish, because strided), but there is no real reason except for some data locality in the case of many small blocks, which we aren't really making use of. Actually, the changes in #592 already change the order within hte fusionblocks a bit, since it really is easier to just use the natural "kronecker product" order to make these computations fast.
Feel free to open a draft PR with the prototype though, I'd love to have a look
Activity
lkdvos commentedon Oct 26, 2026
I don't think there's an issue with changing the types, as long as they follow the same
Dictionaries.jlinterface nothing should really change. I think there are some internals in TensorKit that depend on the tokens being integers, but I guess that is what the prototype is already doing so that should probably be fine?For the positions in
fusionblocks, nothing really depends on that order. I think the previous order is mostly chosen such that the.datafield is traversed in order (ish, because strided), but there is no real reason except for some data locality in the case of many small blocks, which we aren't really making use of. Actually, the changes in #592 already change the order within hte fusionblocks a bit, since it really is easier to just use the natural "kronecker product" order to make these computations fast.Feel free to open a draft PR with the prototype though, I'd love to have a look