From 6083ca55eeeafe57fa3a1f0c2b2b7abf2266e798 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 7 Feb 2025 15:13:02 -0500 Subject: [PATCH 1/8] More compact show for block sparse arrays --- Project.toml | 2 +- src/BlockSparseArrays.jl | 2 +- .../abstractblocksparsearray.jl | 46 +++++++++++++++++++ src/blocksparsearray/blocksparsearray.jl | 35 ++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 50581f2b..49376e68 100644 --- a/Project.toml +++ b/Project.toml @@ -47,7 +47,7 @@ SparseArraysBase = "0.2.10" SplitApplyCombine = "1.2.3" TensorAlgebra = "0.1.0" Test = "1.10" -TypeParameterAccessors = "0.2.0" +TypeParameterAccessors = "0.3.0" julia = "1.10" [extras] diff --git a/src/BlockSparseArrays.jl b/src/BlockSparseArrays.jl index 276b1f78..d58a9b75 100644 --- a/src/BlockSparseArrays.jl +++ b/src/BlockSparseArrays.jl @@ -25,9 +25,9 @@ include("blocksparsearrayinterface/cat.jl") # functions defined for any abstractblocksparsearray include("abstractblocksparsearray/abstractblocksparsearray.jl") -include("abstractblocksparsearray/wrappedabstractblocksparsearray.jl") include("abstractblocksparsearray/abstractblocksparsematrix.jl") include("abstractblocksparsearray/abstractblocksparsevector.jl") +include("abstractblocksparsearray/wrappedabstractblocksparsearray.jl") include("abstractblocksparsearray/views.jl") include("abstractblocksparsearray/arraylayouts.jl") include("abstractblocksparsearray/sparsearrayinterface.jl") diff --git a/src/abstractblocksparsearray/abstractblocksparsearray.jl b/src/abstractblocksparsearray/abstractblocksparsearray.jl index b03d262e..b08bb8e6 100644 --- a/src/abstractblocksparsearray/abstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/abstractblocksparsearray.jl @@ -77,3 +77,49 @@ function Base.setindex!( blocks(a)[Int.(I)...] = value return a end + +using TypeParameterAccessors: unspecify_type_parameters +function show_typeof_blocksparse(io::IO, a::AbstractBlockSparseArray) + Base.show(io, unspecify_type_parameters(typeof(a))) + print(io, '{') + show(io, eltype(a)) + print(io, ", ") + show(io, ndims(a)) + print(io, ", ") + show(io, blocktype(a)) + print(io, ", …") + print(io, '}') + return nothing +end + +# Copied from `BlockArrays.jl`. +block2string(b, s) = string(join(map(string,b), '×'), "-blocked ", Base.dims2string(s)) + +function summary_blocksparse(io::IO, a::AbstractArray) + print(io, block2string(blocksize(a), size(a))) + print(io, ' ') + show_typeof_blocksparse(io, a) + return nothing +end + +function Base.summary(io::IO, a::AbstractBlockSparseArray) + summary_blocksparse(io, a) + return nothing +end + +function Base.showarg(io::IO, a::AbstractBlockSparseArray, toplevel::Bool) + if toplevel + show_typeof_blocksparse(io, a) + else + print(io, "::") + show_typeof_blocksparse(io, a) + end + return nothing +end + +# TypeParameterAccessors.jl interface +using TypeParameterAccessors: TypeParameterAccessors, Position, set_type_parameters +TypeParameterAccessors.position(::Type{BlockSparseArray}, eltype) = Position(1) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ndims) = Position(2) +TypeParameterAccessors.position(::Type{BlockSparseArray}, blocktype) = Position(3) +TypeParameterAccessors.position(::Type{BlockSparseArray}, blockstype) = Position(4) diff --git a/src/blocksparsearray/blocksparsearray.jl b/src/blocksparsearray/blocksparsearray.jl index 1a0117ad..3e70aaa7 100644 --- a/src/blocksparsearray/blocksparsearray.jl +++ b/src/blocksparsearray/blocksparsearray.jl @@ -199,3 +199,38 @@ blockstype(arraytype::Type{<:BlockSparseArray}) = SparseArrayDOK{AbstractArray} ## # TODO: Preserve GPU data! ## return BlockSparseArray{elt}(undef, axes) ## end + +# TypeParameterAccessors.jl interface +using TypeParameterAccessors: TypeParameterAccessors, Position, set_type_parameters +TypeParameterAccessors.position(::Type{BlockSparseArray}, eltype) = Position(1) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ndims) = Position(2) +TypeParameterAccessors.position(::Type{BlockSparseArray}, blocktype) = Position(3) +TypeParameterAccessors.position(::Type{BlockSparseArray}, blockstype) = Position(4) + +# TODO: Make this generic to `AbstractBlockSparseVector` using +# TypeParameterAccessors.jl, for example using: +# `set_ndims(unspecify_type_parameters(typeof(a)), 1)`. +function show_typeof_blocksparse(io::IO, a::BlockSparseVector) + print(io, "BlockSparseVector") + print(io, '{') + show(io, eltype(a)) + print(io, ", ") + show(io, blocktype(a)) + print(io, ", …") + print(io, '}') + return nothing +end + +# TODO: Make this generic to `AbstractBlockSparseMatrix` using +# TypeParameterAccessors.jl, for example using: +# `set_ndims(unspecify_type_parameters(typeof(a)), 2)`. +function show_typeof_blocksparse(io::IO, a::BlockSparseMatrix) + print(io, "BlockSparseMatrix") + print(io, '{') + show(io, eltype(a)) + print(io, ", ") + show(io, blocktype(a)) + print(io, ", …") + print(io, '}') + return nothing +end From 5ac38ae359419cd27fdbd87237199fad151917f5 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Feb 2025 08:34:27 -0500 Subject: [PATCH 2/8] Revert to TypeParameterAccessors v0.2 --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 2fb40f8b..ef55821e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "BlockSparseArrays" uuid = "2c9a651f-6452-4ace-a6ac-809f4280fbb4" authors = ["ITensor developers and contributors"] -version = "0.2.14" +version = "0.2.15" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -47,7 +47,7 @@ SparseArraysBase = "0.2.10" SplitApplyCombine = "1.2.3" TensorAlgebra = "0.1.0" Test = "1.10" -TypeParameterAccessors = "0.3.0" +TypeParameterAccessors = "0.2.0" julia = "1.10" [extras] From 95f47ceddfc4af57d02a1bb475cca738ff0b5c24 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Feb 2025 08:37:08 -0500 Subject: [PATCH 3/8] Delete repeated definitions --- src/abstractblocksparsearray/abstractblocksparsearray.jl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/abstractblocksparsearray/abstractblocksparsearray.jl b/src/abstractblocksparsearray/abstractblocksparsearray.jl index b08bb8e6..351712f7 100644 --- a/src/abstractblocksparsearray/abstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/abstractblocksparsearray.jl @@ -116,10 +116,3 @@ function Base.showarg(io::IO, a::AbstractBlockSparseArray, toplevel::Bool) end return nothing end - -# TypeParameterAccessors.jl interface -using TypeParameterAccessors: TypeParameterAccessors, Position, set_type_parameters -TypeParameterAccessors.position(::Type{BlockSparseArray}, eltype) = Position(1) -TypeParameterAccessors.position(::Type{BlockSparseArray}, ndims) = Position(2) -TypeParameterAccessors.position(::Type{BlockSparseArray}, blocktype) = Position(3) -TypeParameterAccessors.position(::Type{BlockSparseArray}, blockstype) = Position(4) From 688295a802f3ef5da9ee7c886b2a3557646f0c77 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Feb 2025 08:42:32 -0500 Subject: [PATCH 4/8] Fix position definitions --- src/blocksparsearray/blocksparsearray.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/blocksparsearray/blocksparsearray.jl b/src/blocksparsearray/blocksparsearray.jl index 3e70aaa7..91f2e45f 100644 --- a/src/blocksparsearray/blocksparsearray.jl +++ b/src/blocksparsearray/blocksparsearray.jl @@ -202,10 +202,10 @@ blockstype(arraytype::Type{<:BlockSparseArray}) = SparseArrayDOK{AbstractArray} # TypeParameterAccessors.jl interface using TypeParameterAccessors: TypeParameterAccessors, Position, set_type_parameters -TypeParameterAccessors.position(::Type{BlockSparseArray}, eltype) = Position(1) -TypeParameterAccessors.position(::Type{BlockSparseArray}, ndims) = Position(2) -TypeParameterAccessors.position(::Type{BlockSparseArray}, blocktype) = Position(3) -TypeParameterAccessors.position(::Type{BlockSparseArray}, blockstype) = Position(4) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(eltype)) = Position(1) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(ndims)) = Position(2) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(blocktype)) = Position(3) +TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(blockstype)) = Position(4) # TODO: Make this generic to `AbstractBlockSparseVector` using # TypeParameterAccessors.jl, for example using: From dcc02b20bc0102f70f734632ee722e9cf7854f39 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Feb 2025 08:43:23 -0500 Subject: [PATCH 5/8] Format --- src/abstractblocksparsearray/abstractblocksparsearray.jl | 2 +- src/blocksparsearray/blocksparsearray.jl | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/abstractblocksparsearray/abstractblocksparsearray.jl b/src/abstractblocksparsearray/abstractblocksparsearray.jl index 351712f7..cb4bcb4b 100644 --- a/src/abstractblocksparsearray/abstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/abstractblocksparsearray.jl @@ -93,7 +93,7 @@ function show_typeof_blocksparse(io::IO, a::AbstractBlockSparseArray) end # Copied from `BlockArrays.jl`. -block2string(b, s) = string(join(map(string,b), '×'), "-blocked ", Base.dims2string(s)) +block2string(b, s) = string(join(map(string, b), '×'), "-blocked ", Base.dims2string(s)) function summary_blocksparse(io::IO, a::AbstractArray) print(io, block2string(blocksize(a), size(a))) diff --git a/src/blocksparsearray/blocksparsearray.jl b/src/blocksparsearray/blocksparsearray.jl index 91f2e45f..bae90bda 100644 --- a/src/blocksparsearray/blocksparsearray.jl +++ b/src/blocksparsearray/blocksparsearray.jl @@ -205,7 +205,9 @@ using TypeParameterAccessors: TypeParameterAccessors, Position, set_type_paramet TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(eltype)) = Position(1) TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(ndims)) = Position(2) TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(blocktype)) = Position(3) -TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(blockstype)) = Position(4) +function TypeParameterAccessors.position(::Type{BlockSparseArray}, ::typeof(blockstype)) + return Position(4) +end # TODO: Make this generic to `AbstractBlockSparseVector` using # TypeParameterAccessors.jl, for example using: From 4b31589cc99f2b3ffb43431fd2fd8abe5db856af Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 10 Feb 2025 16:55:03 -0500 Subject: [PATCH 6/8] Add tests --- test/Project.toml | 1 + test/test_basics.jl | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index e5418bd8..a2173d86 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -19,3 +19,4 @@ SymmetrySectors = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TestExtras = "5ed8adda-3752-4e41-b88a-e8b09835ee3a" +TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" diff --git a/test/test_basics.jl b/test/test_basics.jl index 6120bb95..fb125874 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -38,6 +38,7 @@ using SparseArraysBase: SparseArrayDOK, SparseMatrixDOK, SparseVectorDOK, stored using TensorAlgebra: contract using Test: @test, @test_broken, @test_throws, @testset, @inferred using TestExtras: @constinferred +using TypeParameterAccessors: TypeParameterAccessors, Position include("TestBlockSparseArraysUtils.jl") arrayts = (Array, JLArray) @@ -1084,13 +1085,35 @@ arrayts = (Array, JLArray) @test storedlength(b) == 17 end @testset "show" begin + vectort_elt = arrayt{elt,1} + matrixt_elt = arrayt{elt,2} + arrayt_elt = arrayt{elt,3} + + a = BlockSparseVector{elt,arrayt{elt,1}}([2, 2]) + @test sprint(summary, a) == + "2-blocked 4-element BlockSparseVector{$(elt), $(vectort_elt), …}" + + a = BlockSparseMatrix{elt,arrayt{elt,2}}([2, 2], [2, 2]) + @test sprint(summary, a) == + "2×2-blocked 4×4 BlockSparseMatrix{$(elt), $(matrixt_elt), …}" + + a = BlockSparseArray{elt,3,arrayt{elt,3}}([2, 2], [2, 2], [2, 2]) + @test sprint(summary, a) == + "2×2×2-blocked 4×4×4 BlockSparseArray{$(elt), 3, $(arrayt_elt), …}" + if elt === Float64 # Not testing other element types since they change the # spacing so it isn't easy to make the test general. - a = BlockSparseArray{elt}([2, 2], [2, 2]) + a = BlockSparseMatrix{elt,arrayt{elt,2}}([2, 2], [2, 2]) a[1, 2] = 12 @test sprint(show, "text/plain", a) == "$(summary(a)):\n $(zero(eltype(a))) $(eltype(a)(12)) │ . .\n $(zero(eltype(a))) $(zero(eltype(a))) │ . .\n ───────────┼──────\n . . │ . .\n . . │ . ." end end + @testset "TypeParameterAccessors.position" begin + @test TypeParameterAccessors.position(BlockSparseArray, eltype) == Position(1) + @test TypeParameterAccessors.position(BlockSparseArray, ndims) == Position(2) + @test TypeParameterAccessors.position(BlockSparseArray, blocktype) == Position(3) + @test TypeParameterAccessors.position(BlockSparseArray, blockstype) == Position(4) + end end From cdf4ae12cc793c9a1e1b01042a8b3f3a536a10a8 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 10 Feb 2025 17:10:32 -0500 Subject: [PATCH 7/8] Fix tests --- .../wrappedabstractblocksparsearray.jl | 3 +- test/test_basics.jl | 28 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl b/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl index bc8c14b9..9ce0bd2a 100644 --- a/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl @@ -10,6 +10,7 @@ using BlockArrays: mortar, unblock using DerivableInterfaces: DerivableInterfaces, @interface +using GPUArraysCore: @allowscalar using SplitApplyCombine: groupcount using TypeParameterAccessors: similartype @@ -390,6 +391,6 @@ function Base.show(io::IO, mime::MIME"text/plain", a::AnyAbstractBlockSparseArra print(io, ":") println(io) a′ = ReplacedUnstoredBlockSparseArray(a, GetUnstoredBlockShow(axes(a))) - Base.print_array(io, a′) + @allowscalar Base.print_array(io, a′) return nothing end diff --git a/test/test_basics.jl b/test/test_basics.jl index fb125874..de982d6b 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -1090,22 +1090,40 @@ arrayts = (Array, JLArray) arrayt_elt = arrayt{elt,3} a = BlockSparseVector{elt,arrayt{elt,1}}([2, 2]) - @test sprint(summary, a) == + # Either option is possible depending on namespacing. + @test ( + sprint(summary, a) == "2-blocked 4-element BlockSparseVector{$(elt), $(vectort_elt), …}" + ) || ( + sprint(summary, a) == + "2-blocked 4-element BlockSparseArrays.BlockSparseVector{$(elt), $(vectort_elt), …}" + ) a = BlockSparseMatrix{elt,arrayt{elt,2}}([2, 2], [2, 2]) - @test sprint(summary, a) == - "2×2-blocked 4×4 BlockSparseMatrix{$(elt), $(matrixt_elt), …}" + # Either option is possible depending on namespacing. + @test ( + sprint(summary, a) == "2×2-blocked 4×4 BlockSparseMatrix{$(elt), $(matrixt_elt), …}" + ) || ( + sprint(summary, a) == + "2×2-blocked 4×4 BlockSparseArrays.BlockSparseMatrix{$(elt), $(matrixt_elt), …}" + ) a = BlockSparseArray{elt,3,arrayt{elt,3}}([2, 2], [2, 2], [2, 2]) - @test sprint(summary, a) == + + # Either option is possible depending on namespacing. + @test ( + sprint(summary, a) == "2×2×2-blocked 4×4×4 BlockSparseArray{$(elt), 3, $(arrayt_elt), …}" + ) || ( + sprint(summary, a) == + "2×2×2-blocked 4×4×4 BlockSparseArrays.BlockSparseArray{$(elt), 3, $(arrayt_elt), …}" + ) if elt === Float64 # Not testing other element types since they change the # spacing so it isn't easy to make the test general. a = BlockSparseMatrix{elt,arrayt{elt,2}}([2, 2], [2, 2]) - a[1, 2] = 12 + @allowscalar a[1, 2] = 12 @test sprint(show, "text/plain", a) == "$(summary(a)):\n $(zero(eltype(a))) $(eltype(a)(12)) │ . .\n $(zero(eltype(a))) $(zero(eltype(a))) │ . .\n ───────────┼──────\n . . │ . .\n . . │ . ." end From 75342a2b62670a530617da1ef0f3218e878e1e42 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Mon, 10 Feb 2025 17:58:26 -0500 Subject: [PATCH 8/8] Bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 71890edd..e88d2265 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "BlockSparseArrays" uuid = "2c9a651f-6452-4ace-a6ac-809f4280fbb4" authors = ["ITensor developers and contributors"] -version = "0.2.15" +version = "0.2.16" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"