Add hash for FusionTreeBlock to fix cacheing behind AdjointTensorMap permutes - #518
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
| return h | ||
| end | ||
| Base.hash(b::FusionTreeBlock, h::UInt) = hash(fusiontrees(b), h) | ||
| Base.hash(b::FusionTreeBlock, h::UInt) = isempty(b) ? h : hash(b.uncoupled, hash(b.isdual, h)) |
There was a problem hiding this comment.
Is just returning h in the empty case a good idea? Or should we e.g. return the equivalent of an empty tuple, hash((), h) ?
|
Clearly, adding this hash function is a no-brainer. This is really a major oversight. One off-topic question that comes up, thinking about the |
Hashing the first tree pair still covers the block's defining data (uncoupled, isdual), but additionally disambiguates the ad-hoc single-pair blocks constructed in planar_trace, which would otherwise all collide in the fstranspose LRU cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
That's actually a very good point. I think currently we are guarding most of the code to never enter this part when there are no fusiontrees (these objects are typically generated from indexmanipulation loops, where we know everything has at least one channel, since it is from a valid tensor). This did make me check the codebase, and we do actually have one spot where this can be an issue (properly denoted hack): where we would now end up with colliding hashes because these only have a single fusiontree, so I've reworked the implementation to just hash the first fusiontree pair, which is again a hack but might be worth it to remain like that until I properly fix that "hack" of the traces. (See #522) |
Potential first step to addressing #516.
The cache underlying
permutes ofAdjointTensorMaps (GLOBAL_FSBRAID_CACHE) never gets a single hit, making it effectively useless. This cache uses keys generated from aFusionTreeBlock, butBase.hashwasn't defined for this type causing literally all keys to miss. Adding the hash improves the performance of permutingAdjointTensorMaps with non-Abelian sector types.Running the reproduction script from #516 gives:
Reproduction script
After
fℤ₂fℤ₂ ⊠ U(1)SU(2)fℤ₂ ⊠ U(1) ⊠ SU(3)Before
fℤ₂fℤ₂ ⊠ U(1)SU(2)fℤ₂ ⊠ U(1) ⊠ SU(3)