From 94dc3e52dc07d7a7f456ab2ebae16697aee4395e Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Tue, 30 Jun 2026 14:54:05 -0400 Subject: [PATCH 1/3] Support TensorAlgebra 0.14 graded contraction and add! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes graded contraction and `add!` under TensorAlgebra 0.14's `StridedView`-based permute path (https://github.com/ITensor/TensorAlgebra.jl/pull/194). `unmatricize(::SectorFusion, ::FusedGradedMatrix, …)` now returns a graded rank-0 array for the scalar case, matching the graded result it returns at every other rank, so the permute-add back into the destination dispatches to the graded `bipermutedimsopadd!` overload rather than the generic strided one. It also defines `StridedViews.StridedView(::AbelianSectorArray)` as a view of its data block, so adding an `AbelianSectorArray` into a plain dense array works. --- Project.toml | 14 ++++++++++++-- src/fusion.jl | 6 ++++-- src/tensoralgebra.jl | 7 +++++++ test/Project.toml | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index 61bbe912..4dc9f741 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GradedArrays" uuid = "bc96ca6e-b7c8-4bb6-888e-c93f838762c2" -version = "0.13.1" +version = "0.13.2" authors = ["ITensor developers and contributors"] [workspace] @@ -18,12 +18,21 @@ MatrixAlgebraKit = "6c742aac-3347-4629-af66-fc926824e5e4" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SparseArraysBase = "0d5efcca-f356-4864-8770-e1ed8d78f208" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a" TensorKitSectors = "13a9c161-d5da-41f0-bcbd-e1a08ae0647f" [weakdeps] SUNRepresentations = "1a50b95c-7aac-476d-a9ce-2bfc675fc617" +[sources.SparseArraysBase] +rev = "mf/tensoralgebra-0.14" +url = "https://github.com/ITensor/SparseArraysBase.jl" + +[sources.TensorAlgebra] +rev = "mf/inline-strided-permute" +url = "https://github.com/ITensor/TensorAlgebra.jl" + [extensions] GradedArraysSUNRepresentationsExt = "SUNRepresentations" @@ -40,6 +49,7 @@ Random = "1.10" SUNRepresentations = "0.3, 0.4" SparseArraysBase = "0.10" SplitApplyCombine = "1.2.3" -TensorAlgebra = "0.12.4, 0.13" +StridedViews = "0.5" +TensorAlgebra = "0.14" TensorKitSectors = "0.3" julia = "1.10" diff --git a/src/fusion.jl b/src/fusion.jl index 2c85f7c1..05bfb800 100644 --- a/src/fusion.jl +++ b/src/fusion.jl @@ -159,8 +159,10 @@ function TensorAlgebra.unmatricize( if isempty(codomain_axes) && isempty(domain_axes) # Scalar (rank-0) result: only the trivial-sector block contributes, and # `cod ∩ dom = {trivial}` for a fused scalar means `m.blocks` is at most - # one 1×1 entry. Return a 0-D `Array` matching the eltype. - a = fill(zero(eltype(m))) + # one 1×1 entry. Return a graded rank-0 array, like the result at every other + # rank, so the permute-add back into the destination dispatches to the graded + # `bipermutedimsopadd!` overload rather than the generic strided path. + a = zero!(similar(m, ())) triv = trivial(sectortype(m)) haskey(m.blocks, triv) && (a[] = m.blocks[triv][1, 1]) return a diff --git a/src/tensoralgebra.jl b/src/tensoralgebra.jl index 5b285fce..460c2f6d 100644 --- a/src/tensoralgebra.jl +++ b/src/tensoralgebra.jl @@ -1,4 +1,5 @@ using SplitApplyCombine: groupcount +using StridedViews: StridedViews function tensor_product(r1, r2, r3, rs...) return tensor_product(tensor_product(r1, r2), r3, rs...) @@ -173,6 +174,12 @@ function TensorAlgebra.bipermutedimsopadd!( return y end +# An abelian sector array's dense form is its data block (each abelian sector is +# one-dimensional, so the structural sector-delta factor is an identity selection). +# Wrapping it as a `StridedView` of its data lets it flow through the generic strided +# permute-add path when the other operand is a plain dense array. +StridedViews.StridedView(a::AbelianSectorArray) = StridedViews.StridedView(data(a)) + function TensorAlgebra.bipermutedimsopadd!( y::AbstractGradedArray{<:Any, <:Any, N}, op, x::AbstractGradedArray{<:Any, <:Any, N}, perm_codomain, perm_domain, diff --git a/test/Project.toml b/test/Project.toml index 098074f2..7b0f8e09 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -32,7 +32,7 @@ SUNRepresentations = "0.3, 0.4" SafeTestsets = "0.1" SparseArraysBase = "0.10" Suppressor = "0.2.8" -TensorAlgebra = "0.12.4, 0.13" +TensorAlgebra = "0.14" TensorKitSectors = "0.3" Test = "1.10" TestExtras = "0.3.1" From c4a1a73e771eac57fcf645ad936190b0b116ffaf Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Tue, 30 Jun 2026 15:49:20 -0400 Subject: [PATCH 2/3] Update the rank-0 unmatricize test for the graded result The rank-0 `unmatricize` test still expected a plain `Array{Float64, 0}`. Assert an `AbelianGradedArray` instead, matching the graded rank-0 result that `unmatricize` now returns. --- test/test_tensoralgebra.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_tensoralgebra.jl b/test/test_tensoralgebra.jl index f36cf18b..84f7de3a 100644 --- a/test/test_tensoralgebra.jl +++ b/test/test_tensoralgebra.jl @@ -338,7 +338,7 @@ end @test isdual(col) # A rank-0 graded array matricizes to a 1×1 trivial-sector `FusedGradedMatrix`, - # and unmatricizing back recovers the scalar. + # and unmatricizing back recovers the scalar as a rank-0 graded array. a = AbelianGradedArray{Float64, U1, 0, Array{Float64, 0}}(undef, ()) a[] = 4.0 m = matricize(GradedArrays.SectorFusion(), a, Val(0)) @@ -347,7 +347,7 @@ end @test data(m[Block(1, 1)]) == fill(4.0, 1, 1) back = unmatricize(GradedArrays.SectorFusion(), m, (), ()) - @test back isa Array{Float64, 0} + @test back isa AbelianGradedArray{Float64, <:Any, 0} @test back[] == 4.0 end From 4e4c1cbcdc932aea639e42281bf33979790ec69f Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Tue, 30 Jun 2026 23:21:01 -0400 Subject: [PATCH 3/3] Drop the source pins now that the upstreams are registered TensorAlgebra 0.14 and SparseArraysBase 0.10.4 are registered, so the `[compat]` bounds resolve against the releases and the branch pins are no longer needed. --- Project.toml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Project.toml b/Project.toml index 4dc9f741..aea029e6 100644 --- a/Project.toml +++ b/Project.toml @@ -25,14 +25,6 @@ TensorKitSectors = "13a9c161-d5da-41f0-bcbd-e1a08ae0647f" [weakdeps] SUNRepresentations = "1a50b95c-7aac-476d-a9ce-2bfc675fc617" -[sources.SparseArraysBase] -rev = "mf/tensoralgebra-0.14" -url = "https://github.com/ITensor/SparseArraysBase.jl" - -[sources.TensorAlgebra] -rev = "mf/inline-strided-permute" -url = "https://github.com/ITensor/TensorAlgebra.jl" - [extensions] GradedArraysSUNRepresentationsExt = "SUNRepresentations"