From af349a2b1afd3a6c92fd6f258eb9f99c8358ac6c Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 16 Mar 2026 15:34:40 +0100 Subject: [PATCH 01/12] methods to avoid `view` --- src/sector.jl | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/sector.jl b/src/sector.jl index 19d584d..b1fec6e 100644 --- a/src/sector.jl +++ b/src/sector.jl @@ -134,13 +134,14 @@ TensorKitSectors.fusionscalartype(::Type{<:SUNIrrep}) = Float64 TensorKitSectors.Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I) where {I <: SUNIrrep} = SUN_Fsymbol(a, b, c, d, e, f) @cached function SUN_Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I)::Array{Float64, 4} where {I <: SUNIrrep} - N1 = Nsymbol(a, b, e) - N2 = Nsymbol(e, c, d) - N3 = Nsymbol(b, c, f) - N4 = Nsymbol(a, f, d) - - (N1 == 0 || N2 == 0 || N3 == 0 || N4 == 0) && - return fill(zero(fusionscalartype(I)), N1, N2, N3, N4) + return TensorKitSectors.Fsymbol_from_fusiontensor(a, b, c, d, e, f) +end +MemoizationKit.default_cache_settings(::typeof(SUN_Fsymbol)) = (; maxsize = 10^5) +function TensorKitSectors.Fsymbol_from_fusiontensor( + a::I, b::I, c::I, d::I, e::I, f::I + ) where {I <: SUNIrrep} + Nabe, Necd, Nbcd, Nafd = Nsymbol(a, b, e), Nsymbol(e, c, d), Nsymbol(b, c, f), Nsymbol(a, f, d) + iszero(Nabe * Necd * Nbcd * Nafd) && return zeros(fusionscalartype(I), Nabe, Necd, Nbcd, Nafd) # computing first diagonal element A = fusiontensor(a, b, e) @@ -152,15 +153,38 @@ TensorKitSectors.Fsymbol(a::I, b::I, c::I, d::I, e::I, f::I) where {I <: SUNIrre A[1, 2, 3, -1] * B[3, 4, -2] return Array(F) end -MemoizationKit.default_cache_settings(::typeof(SUN_Fsymbol)) = (; maxsize = 10^5) + +# remove the view calls +function TensorKitSectors.Asymbol_from_fusiontensor(a::I, b::I, c::I) where {I <: SUNIrrep} + Nabc = Nsymbol(a, b, c) + iszero(Nabc) && return zeros(fusionscalartype(typeof(a)), Nabc, Nabc) + + C1 = fusiontensor(a, b, c)[:, 1, :, :] + C2 = fusiontensor(dual(a), c, b)[:, :, 1, :] + Za = sqrtdim(a) * fusiontensor(a, dual(a), leftunit(a))[:, :, 1, 1] + @tensor A[-1, -2] := sqrtdim(b) / sqrtdim(c) * conj(Za[1, 2]) * C1[1, 3, -1] * C2[2, 3, -2] + return Array(A) +end +function TensorKitSectors.Bsymbol_from_fusiontensor(a::I, b::I, c::I) where {I <: SUNIrrep} + Nabc = Nsymbol(a, b, c) + iszero(Nabc) && return zeros(fusionscalartype(typeof(a)), Nabc, Nabc) + + C1 = fusiontensor(a, b, c)[1, :, :, :] + C2 = fusiontensor(c, dual(b), a)[:, :, 1, :] + Zb = sqrtdim(b) * fusiontensor(b, dual(b), leftunit(b))[:, :, 1, 1] + @tensor B[-1, -2] := sqrtdim(a) / sqrtdim(c) * conj(Zb[1, 2]) * C1[1, 3, -1] * C2[3, 2, -2] + return Array(B) +end TensorKitSectors.braidingscalartype(::Type{<:SUNIrrep}) = Float64 TensorKitSectors.Rsymbol(a::I, b::I, c::I) where {I <: SUNIrrep} = SUN_Rsymbol(a, b, c) @cached function SUN_Rsymbol(a::I, b::I, c::I)::Array{Float64, 2} where {I <: SUNIrrep} - N1 = Nsymbol(a, b, c) - N2 = Nsymbol(b, a, c) - - (N1 == 0 || N2 == 0) && return fill(zero(braidingscalartype(I)), N1, N2) + return TensorKitSectors.Rsymbol_from_fusiontensor(a, b, c) +end +MemoizationKit.default_cache_settings(::typeof(SUN_Rsymbol)) = (; maxsize = 10^5) +function TensorKitSectors.Rsymbol_from_fusiontensor(a::I, b::I, c::I) where {I <: SUNIrrep} + Nabc = Nsymbol(a, b, c) + iszero(Nabc) && return fill(zero(braidingscalartype(I)), Nabc, Nabc) A = fusiontensor(a, b, c)[:, :, 1, :] B = fusiontensor(b, a, c)[:, :, 1, :] @@ -168,4 +192,3 @@ TensorKitSectors.Rsymbol(a::I, b::I, c::I) where {I <: SUNIrrep} = SUN_Rsymbol(a @tensor R[-1; -2] := conj(B[1, 2, -2]) * A[2, 1, -1] return Array(R) end -MemoizationKit.default_cache_settings(::typeof(SUN_Rsymbol)) = (; maxsize = 10^5) From d75bb1fda5ce6e4ac29b66d31bc00fd04ba4ce30 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 16 Mar 2026 15:35:00 +0100 Subject: [PATCH 02/12] minor --- src/clebschgordan.jl | 4 ++-- test/generic.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clebschgordan.jl b/src/clebschgordan.jl index d873107..fa66272 100644 --- a/src/clebschgordan.jl +++ b/src/clebschgordan.jl @@ -20,10 +20,10 @@ CGC(s1::I, s2::I, s3::I) where {I <: SUNIrrep} = CGC(sectorscalartype(I), s1, s2 CGC(::Type{T}, s1::I, s2::I, s3::I) where {T, I <: SUNIrrep} = SUN_CGC(T, s1, s2, s3) @cached function SUN_CGC(::Type{T}, s1::I, s2::I, s3::I)::SparseArray{T, 4} where {T <: Real, I <: SUNIrrep} - if isone(s1) + if isunit(s1) @assert s2 == s3 CGC = trivial_CGC(T, s2, true) - elseif isone(s2) + elseif isunit(s2) @assert s1 == s3 CGC = trivial_CGC(T, s1, false) else diff --git a/test/generic.jl b/test/generic.jl index 1cede2b..e3a4dd2 100644 --- a/test/generic.jl +++ b/test/generic.jl @@ -36,7 +36,7 @@ using SUNRepresentations.TensorKitSectors: ⊗, Nsymbol, dual @test I1.I == @constinferred weight(I1) @test inv(cartanmatrix(I1)) ≈ inverse_cartanmatrix(I1) - @test SUNIrrep{N}("1") === one(SUNIrrep{N}) + @test SUNIrrep{N}("1") === unit(SUNIrrep{N}) end @timedtestset "Direct product of SUNIrrep{$N}:" for N in 2:6 From 46112ce07c5b585e957e2a4e3391ab12aa61c0f5 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 16 Mar 2026 15:35:36 +0100 Subject: [PATCH 03/12] add sector testsuite --- test/runtests.jl | 55 +++++++++++++++++----------- test/sectors.jl | 95 +----------------------------------------------- 2 files changed, 36 insertions(+), 114 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 3d069f9..0ed31b7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,7 @@ using Test using TestExtras -using Aqua using Random +using TensorKitSectors using TensorKit using SUNRepresentations using Combinatorics @@ -9,7 +9,7 @@ using TensorKit using TensorKit: ProductSector, fusiontensor, pentagon_equation, hexagon_equation, FusionTreeBlock using TensorOperations -using Base.Iterators: take, product +using Base.Iterators: take using SparseArrayKit: SparseArray using LinearAlgebra: LinearAlgebra @@ -18,45 +18,58 @@ const TK = TensorKit _isone(x; kwargs...) = isapprox(x, one(x); kwargs...) Random.seed!(1234) +Ti = time() + +# sector tests +testsuite_path = joinpath( + dirname(dirname(pathof(TensorKitSectors))), # TensorKitSectors root + "test", "testsuite.jl" +) +include(testsuite_path) +using .SectorTestSuite: randsector, smallset -smallset(::Type{I}) where {I <: Sector} = take(values(I), 5) -function smallset(::Type{ProductSector{Tuple{I1, I2}}}) where {I1, I2} - iter = product(smallset(I1), smallset(I2)) - s = collect(i ⊠ j for (i, j) in iter if dim(i) * dim(j) <= 6) - return length(s) > 6 ? rand(s, 6) : s +function SectorTestSuite.smallset(::Type{I}) where {I <: SUNIrrep} + N = SUNRepresentations.rank(I) + size = N > 4 ? 4 : 5 + dim_limit = N > 4 ? 5 * N : 10 * N + return smallset(I, size, dim_limit) end -function smallset(::Type{ProductSector{Tuple{I1, I2, I3}}}) where {I1, I2, I3} - iter = product(smallset(I1), smallset(I2), smallset(I3)) - s = collect(i ⊠ j ⊠ k for (i, j, k) in iter if dim(i) * dim(j) * dim(k) <= 6) - return length(s) > 6 ? rand(s, 6) : s +function SectorTestSuite.smallset(::Type{ProductSector{Tuple{I1, I2}}}) where {I1 <: SUNIrrep, I2 <: SUNIrrep} + s1 = smallset(I1) + s2 = smallset(I2) + N = max(SUNRepresentations.rank(I1), SUNRepresentations.rank(I2)) + size = N > 4 ? 4 : 5 + dim_limit = N > 4 ? 25 * N : 50 * N + return resize!(shuffle!([a ⊠ b for a in s1 for b in s2 if dim(a) * dim(b) <= dim_limit]), size) end -function randsector(::Type{I}) where {I <: Sector} - s = collect(smallset(I)) - a = rand(s) - while a == one(a) # don't use trivial label - a = rand(s) + +sectorlist = (SU3Irrep, SU4Irrep, SU5Irrep, SU3Irrep ⊠ SU3Irrep) +@testset "Sector tests" begin + for sector in sectorlist + SectorTestSuite.test_sector(sector) end - return a + include("sectors.jl") end -Ti = time() module GenericTests using Test using TestExtras using Random using SUNRepresentations + using TensorKitSectors include("generic.jl") end -include("caching.jl") +@testset "Caching tests" begin + include("caching.jl") +end include("casimir.jl") include("clebschgordan.jl") -sectorlist = (SU3Irrep, SU4Irrep, SU5Irrep, SU3Irrep ⊠ SU3Irrep) -include("sectors.jl") sectorlist = (SU3Irrep, SU4Irrep, SU5Irrep) include("fusiontrees.jl") @testset "Aqua" verbose = true begin + using Aqua # RationalRoots has ambiguities with Base/Core, so only test SUNRepresentations ambiguities # Intentional piracy of Rep[SU{N}] etc Aqua.test_all(SUNRepresentations; ambiguities = false, piracies = (; treat_as_own = [SU])) diff --git a/test/sectors.jl b/test/sectors.jl index dc934e3..44429c0 100644 --- a/test/sectors.jl +++ b/test/sectors.jl @@ -2,110 +2,19 @@ for I in sectorlist println("------------------------------------") println("Sector $I") println("------------------------------------") - ti = time() - @testset "Sector $I: Basic properties" begin + @testset "Sector $I: Additional basic properties" begin s = (randsector(I), randsector(I), randsector(I)) mode_old = SUNRepresentations.display_mode("dimension") for mode in ["dimension", "dynkin", "weight"] SUNRepresentations.display_mode(mode) - @test eval(Meta.parse(sprint(show, s[1]))) == s[1] end SUNRepresentations.display_mode(mode_old) - - @test @constinferred(hash(s[1])) == hash(deepcopy(s[1])) - @test @constinferred(one(s[1])) == @constinferred(one(I)) - @constinferred dual(s[1]) - @constinferred dim(s[1]) - @constinferred frobenius_schur_phase(s[1]) - @constinferred frobenius_schur_indicator(s[1]) - @constinferred Nsymbol(s...) - @constinferred Rsymbol(s...) - @constinferred Bsymbol(s...) - @constinferred Fsymbol(s..., s...) - it = @constinferred s[1] ⊗ s[2] - @constinferred ⊗(s..., s...) for i in 1:3 - @test 1 == @constinferred Nsymbol(s[i], conj(s[i]), one(s[i])) - end - end - @timedtestset "Sector $I: Value iterator" begin - @test eltype(values(I)) == I - sprev = one(I) - for (i, s) in enumerate(values(I)) - @test !isless(s, sprev) # confirm compatibility with sort order - @test s == @constinferred (values(I)[i]) - @test TensorKit.findindex(values(I), s) == i - sprev = s - i >= 10 && break - end - @test one(I) == first(values(I)) - @test (@constinferred TensorKit.findindex(values(I), one(I))) == 1 - for s in smallset(I) - @test (@constinferred values(I)[TensorKit.findindex(values(I), s)]) == s + @test 1 == @constinferred Nsymbol(s[i], dual(s[i]), unit(s[i])) end @test all(i -> TensorKit.findindex(values(I), values(I)[i]) == i, 1:1000) end - @timedtestset "Sector $I: fusion tensor and F-move and R-move" begin - for a in smallset(I), b in smallset(I) - for c in ⊗(a, b) - X1 = permutedims(fusiontensor(a, b, c), (2, 1, 3, 4)) - X2 = fusiontensor(b, a, c) - l = dim(a) * dim(b) * dim(c) - R = LinearAlgebra.transpose(Rsymbol(a, b, c)) - sz = (l, convert(Int, Nsymbol(a, b, c))) - @test reshape(X1, sz) ≈ reshape(X2, sz) * R - end - end - for a in smallset(I), b in smallset(I), c in smallset(I) - for e in ⊗(a, b), f in ⊗(b, c) - for d in intersect(⊗(e, c), ⊗(a, f)) - X1 = fusiontensor(a, b, e) - X2 = fusiontensor(e, c, d) - Y1 = fusiontensor(b, c, f) - Y2 = fusiontensor(a, f, d) - @tensor f1[-1, -2, -3, -4] := conj(Y2[a, f, d, -4]) * - conj(Y1[b, c, f, -3]) * - X1[a, b, e, -1] * X2[e, c, d, -2] - f2 = Fsymbol(a, b, c, d, e, f) * dim(d) - @test isapprox(f1, f2; atol = 1000 * eps(), rtol = 1000 * eps()) - end - end - end - end - @timedtestset "Sector $I: Unitarity of F-move" begin - for a in smallset(I), b in smallset(I), c in smallset(I), d in ⊗(a, b, c) - es = collect(intersect(⊗(a, b), map(dual, ⊗(c, dual(d))))) - fs = collect(intersect(⊗(b, c), map(dual, ⊗(dual(d), a)))) - Fblocks = Vector{Any}() - for e in es, f in fs - Fs = Fsymbol(a, b, c, d, e, f) - push!( - Fblocks, - reshape(Fs, (size(Fs, 1) * size(Fs, 2), size(Fs, 3) * size(Fs, 4))) - ) - end - F = hvcat(length(fs), Fblocks...) - @test F' * F ≈ one(F) - end - end - @testset "Sector $I: Pentagon equation" begin - for a in smallset(I), b in smallset(I), c in smallset(I), d in smallset(I) - @test pentagon_equation(a, b, c, d; atol = 1.0e-12, rtol = 1.0e-12) - end - end - @testset "Sector $I: Hexagon equation" begin - for a in smallset(I), b in smallset(I), c in smallset(I) - @test hexagon_equation(a, b, c; atol = 1.0e-12, rtol = 1.0e-12) - end - end - tf = time() - printstyled( - "Finished sector $I tests in ", - string(round(tf - ti; sigdigits = 3)), - " seconds."; bold = true, color = Base.info_color() - ) - println() try s = sprint(SUNRepresentations.cache_info) From 941af23212861b22bed9728cd862bc5cf2008206 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 16 Mar 2026 15:38:30 +0100 Subject: [PATCH 04/12] test with necessary TKS branch already --- Project.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Project.toml b/Project.toml index 572801e..64b27f6 100644 --- a/Project.toml +++ b/Project.toml @@ -54,3 +54,6 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" [targets] test = ["Test", "Random", "Combinatorics", "TestExtras", "TensorKit", "TupleTools", "Latexify", "Aqua"] + +[sources] +TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "bd/morefallbacks"} \ No newline at end of file From 43057b6df45a29bcda697da24858e1fe67c49b3f Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Thu, 28 May 2026 19:02:58 +0200 Subject: [PATCH 05/12] trying out artin braid fix --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 64b27f6..e38b708 100644 --- a/Project.toml +++ b/Project.toml @@ -56,4 +56,4 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" test = ["Test", "Random", "Combinatorics", "TestExtras", "TensorKit", "TupleTools", "Latexify", "Aqua"] [sources] -TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "bd/morefallbacks"} \ No newline at end of file +TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "bd/artin"} \ No newline at end of file From 0733ee434ec561e454eee7b43a1ae6f86aa0adaa Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 1 Jun 2026 16:29:55 +0200 Subject: [PATCH 06/12] don't strain CI too much --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e38b708..6b3927d 100644 --- a/Project.toml +++ b/Project.toml @@ -56,4 +56,4 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" test = ["Test", "Random", "Combinatorics", "TestExtras", "TensorKit", "TupleTools", "Latexify", "Aqua"] [sources] -TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "bd/artin"} \ No newline at end of file +TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "main"} \ No newline at end of file From f56364a4da75c2b8f86e4c262aaab1d6d0932fa4 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 3 Jun 2026 09:24:08 +0200 Subject: [PATCH 07/12] use new TKS version + bump --- Project.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Project.toml b/Project.toml index 6b3927d..572801e 100644 --- a/Project.toml +++ b/Project.toml @@ -54,6 +54,3 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" [targets] test = ["Test", "Random", "Combinatorics", "TestExtras", "TensorKit", "TupleTools", "Latexify", "Aqua"] - -[sources] -TensorKitSectors = {url = "https://github.com/QuantumKitHub/TensorKitSectors.jl", rev = "main"} \ No newline at end of file From 6fe8296c17c537991b0513674759187adef59e67 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 28 Oct 2026 18:45:14 -0400 Subject: [PATCH 08/12] Bound the RAM caches in bytes for the sector tests Co-Authored-By: Claude Opus 5.5 --- test/runtests.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 0ed31b7..686365c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,7 @@ using Test using TestExtras using Random using TensorKitSectors +using MemoizationKit: MemoizationKit, set_cache_size! using TensorKit using SUNRepresentations using Combinatorics @@ -44,6 +45,10 @@ function SectorTestSuite.smallset(::Type{ProductSector{Tuple{I1, I2}}}) where {I end sectorlist = (SU3Irrep, SU4Irrep, SU5Irrep, SU3Irrep ⊠ SU3Irrep) +# the sector tests visit many intermediate irreps, so keep the RAM caches small (in bytes) +set_cache_size!(SUNRepresentations.SUN_CGC, 2^30; by = MemoizationKit.cachesize) +set_cache_size!(SUNRepresentations.SUN_Fsymbol, 2^28; by = MemoizationKit.cachesize) +set_cache_size!(SUNRepresentations.SUN_Rsymbol, 2^26; by = MemoizationKit.cachesize) @testset "Sector tests" begin for sector in sectorlist SectorTestSuite.test_sector(sector) From ffa1fffe19a539845039111c9921905b104749dd Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 29 Oct 2026 09:54:50 -0400 Subject: [PATCH 09/12] Shrink the sector testsuite sets to fit CI Co-Authored-By: Claude Opus 5.5 --- test/runtests.jl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 686365c..dfaff0b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,19 +29,16 @@ testsuite_path = joinpath( include(testsuite_path) using .SectorTestSuite: randsector, smallset +# the pentagon test scales steeply with the dimensions, so keep these small enough for CI function SectorTestSuite.smallset(::Type{I}) where {I <: SUNIrrep} N = SUNRepresentations.rank(I) - size = N > 4 ? 4 : 5 - dim_limit = N > 4 ? 5 * N : 10 * N + size = N == 3 ? 5 : N == 4 ? 4 : 3 + dim_limit = N == 3 ? 11 : 16 return smallset(I, size, dim_limit) end function SectorTestSuite.smallset(::Type{ProductSector{Tuple{I1, I2}}}) where {I1 <: SUNIrrep, I2 <: SUNIrrep} - s1 = smallset(I1) - s2 = smallset(I2) - N = max(SUNRepresentations.rank(I1), SUNRepresentations.rank(I2)) - size = N > 4 ? 4 : 5 - dim_limit = N > 4 ? 25 * N : 50 * N - return resize!(shuffle!([a ⊠ b for a in s1 for b in s2 if dim(a) * dim(b) <= dim_limit]), size) + products = [a ⊠ b for a in smallset(I1) for b in smallset(I2) if dim(a) * dim(b) <= 30] + return first(shuffle!(products), 5) end sectorlist = (SU3Irrep, SU4Irrep, SU5Irrep, SU3Irrep ⊠ SU3Irrep) From 6de301018e216b7e8c28fa8a515eb0e38e00217e Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 29 Oct 2026 10:10:17 -0400 Subject: [PATCH 10/12] Require TensorKitSectors v0.3.12 for the hexagon fix Co-Authored-By: Claude Opus 5.5 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 572801e..791ef3c 100644 --- a/Project.toml +++ b/Project.toml @@ -35,7 +35,7 @@ Serialization = "1" SparseArrayKit = "0.4" SparseArrays = "1" TensorKit = "0.16.4, 0.17" -TensorKitSectors = "0.3.11" +TensorKitSectors = "0.3.12" TensorOperations = "5" Test = "1" TestExtras = "0.3" From 6ce1ee74a3dbaca0177f23ae0817c9971dd62374 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 29 Oct 2026 10:32:04 -0400 Subject: [PATCH 11/12] Empty the CGC RAM cache before testing the disk cache The sector tests no longer empty the RAM caches, so the CGCs computed there would not be written to the emptied disk cache. Co-Authored-By: Claude Opus 5.5 --- test/caching.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/caching.jl b/test/caching.jl index 50dd01a..194bbb9 100644 --- a/test/caching.jl +++ b/test/caching.jl @@ -12,6 +12,8 @@ disk_hits() = only(p.second.hits for p in MemoizationKit.disk_cache_stats() if p @testset "CGC disk cache" begin # only remove cache if running on CI get(ENV, "CI", "false") == "true" && empty_disk_caches!(SUN_CGC) + # CGCs still in RAM from earlier tests would not be written to disk + empty_caches!(SUN_CGC) precompute_disk_cache(3, 1) @test only(disk_cache_info(SUN_CGC)).second.entries > 0 From 5e4a531bb1e4e7a94587031721da9e10a3486d85 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 29 Oct 2026 13:29:57 -0400 Subject: [PATCH 12/12] Draw the fusion tree sectors from the smallest irreps The testsuite's `randsector` draws from the larger `smallset` of the sector tests, which made the fusion tree tests exceed the CI time limit. Co-Authored-By: Claude Opus 5.5 --- test/fusiontrees.jl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/fusiontrees.jl b/test/fusiontrees.jl index 06aa822..29bb200 100644 --- a/test/fusiontrees.jl +++ b/test/fusiontrees.jl @@ -1,15 +1,19 @@ +# the trees grow quickly with the dimensions, so use the smallest nontrivial irreps instead of +# `randsector`, which draws from the larger `smallset` of the sector tests +fusiontree_sector(::Type{I}) where {I <: SUNIrrep} = rand(filter(!isunit, collect(take(values(I), 5)))) + for I in sectorlist println("------------------------------------") println("Fusion Trees $I") println("------------------------------------") ti = time() N = 5 - out = ntuple(n -> randsector(I), N) + out = ntuple(n -> fusiontree_sector(I), N) isdual = ntuple(n -> rand(Bool), N) in = rand(collect(⊗(out...))) numtrees = count(n -> true, fusiontrees(out, in, isdual)) while !(0 < numtrees < 30) - out = ntuple(n -> randsector(I), N) + out = ntuple(n -> fusiontree_sector(I), N) in = rand(collect(⊗(out...))) numtrees = count(n -> true, fusiontrees(out, in, isdual)) end @@ -33,12 +37,12 @@ for I in sectorlist @timedtestset "Fusion tree $I: insertat" begin N = 3 - out2 = ntuple(n -> randsector(I), N) + out2 = ntuple(n -> fusiontree_sector(I), N) in2 = rand(collect(⊗(out2...))) isdual2 = ntuple(n -> rand(Bool), N) f2 = rand(collect(fusiontrees(out2, in2, isdual2))) for i in 1:N - out1 = ntuple(n -> randsector(I), N) + out1 = ntuple(n -> fusiontree_sector(I), N) out1 = Base.setindex(out1, in2, i) in1 = rand(collect(⊗(out1...))) isdual1 = ntuple(n -> rand(Bool), N) @@ -69,10 +73,10 @@ for I in sectorlist @timedtestset "Fusion tree $I: merging" begin N = 3 - out1 = ntuple(n -> randsector(I), N) + out1 = ntuple(n -> fusiontree_sector(I), N) in1 = rand(collect(⊗(out1...))) f1 = rand(collect(fusiontrees(out1, in1))) - out2 = ntuple(n -> randsector(I), N) + out2 = ntuple(n -> fusiontree_sector(I), N) in2 = rand(collect(⊗(out2...))) f2 = rand(collect(fusiontrees(out2, in2))) @@ -109,10 +113,10 @@ for I in sectorlist end N = 3 - out = ntuple(n -> randsector(I), N) + out = ntuple(n -> fusiontree_sector(I), N) numtrees = count(n -> true, fusiontrees((out..., map(dual, out)...))) while !(0 < numtrees < 100) - out = ntuple(n -> randsector(I), N) + out = ntuple(n -> fusiontree_sector(I), N) numtrees = count(n -> true, fusiontrees((out..., map(dual, out)...))) end incoming = rand(collect(⊗(out...)))