Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BlockSparseArrays] Fix initializing blocks using broadcasting #1506

Merged
merged 7 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Manifest.toml
.benchmarkci
*.o
*.swp
*.swo
*.cov
benchmark/mult
benchmark/*.json
Expand Down
2 changes: 1 addition & 1 deletion NDTensors/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "NDTensors"
uuid = "23ae76d9-e61a-49c4-8f12-3f1a16adf9cf"
authors = ["Matthew Fishman <[email protected]>"]
version = "0.3.33"
version = "0.3.34"

[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,22 @@ function Base.setindex!(a::BlockSparseArrayLike{<:Any,1}, value, I::Block{1})
return a
end

function Base.fill!(a::AbstractBlockSparseArray, value)
if iszero(value)
# This drops all of the blocks.
sparse_zero!(blocks(a))
return a
end
blocksparse_fill!(a, value)
return a
end

function Base.fill!(a::BlockSparseArrayLike, value)
# TODO: Even if `iszero(value)`, this doesn't drop
# blocks from `a`, and additionally allocates
# new blocks filled with zeros, unlike
# `fill!(a::AbstractBlockSparseArray, value)`.
# Consider changing that behavior when possible.
blocksparse_fill!(a, value)
return a
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ function blocksparse_setindex!(
end

function blocksparse_fill!(a::AbstractArray, value)
if iszero(value)
# This drops all of the blocks.
sparse_zero!(blocks(a))
return a
end
for b in BlockRange(a)
# We can't use:
# ```julia
Expand Down Expand Up @@ -284,12 +279,14 @@ function Base.getindex(a::SparseSubArrayBlocks{<:Any,N}, I::CartesianIndex{N}) w
return a[Tuple(I)...]
end
function Base.setindex!(a::SparseSubArrayBlocks{<:Any,N}, value, I::Vararg{Int,N}) where {N}
parent_blocks = view(blocks(parent(a.array)), axes(a)...)
parent_blocks = @view blocks(parent(a.array))[blockrange(a)...]
# TODO: The following line is required to instantiate
# uninstantiated blocks, maybe use `@view!` instead,
# or some other code pattern.
parent_blocks[I...] = parent_blocks[I...]
return parent_blocks[I...][blockindices(parent(a.array), Block(I), a.array.indices)...] =
# TODO: Define this using `blockrange(a::AbstractArray, indices::Tuple{Vararg{AbstractUnitRange}})`.
block = Block(ntuple(i -> blockrange(a)[i][I[i]], ndims(a)))
return parent_blocks[I...][blockindices(parent(a.array), block, a.array.indices)...] =
value
end
function Base.isassigned(a::SparseSubArrayBlocks{<:Any,N}, I::Vararg{Int,N}) where {N}
Expand Down
147 changes: 0 additions & 147 deletions NDTensors/src/lib/BlockSparseArrays/test/backup/runtests.jl

This file was deleted.

78 changes: 65 additions & 13 deletions NDTensors/src/lib/BlockSparseArrays/test/test_basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using BlockArrays:
blocksize,
blocksizes,
mortar
using Compat: @compat
using LinearAlgebra: mul!
using NDTensors.BlockSparseArrays:
@view!, BlockSparseArray, block_nstored, block_reshape, view!
Expand All @@ -23,22 +24,21 @@ include("TestBlockSparseArraysUtils.jl")
@testset "BlockSparseArrays (eltype=$elt)" for elt in
(Float32, Float64, ComplexF32, ComplexF64)
@testset "Broken" begin
a = BlockSparseArray{elt}([2, 3], [3, 4])
@test_broken a[Block(1, 2)] .= 1

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
@test b isa SubArray{<:Any,<:Any,<:BlockSparseArray}
@test_broken b[2:4, 2:4]

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @views a[[Block(2), Block(1)], [Block(2), Block(1)]][Block(1, 1)]
@test_broken b isa SubArray{<:Any,<:Any,<:BlockSparseArray}

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @views a[Block(1, 1)][1:2, 1:1]
@test b isa SubArray{<:Any,<:Any,<:BlockSparseArray}
for i in parentindices(b)
@test_broken i isa BlockSlice{<:BlockIndexRange{1}}
end

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
@test_broken b[Block(1, 1)] = randn(3, 3)
end
@testset "Basics" begin
a = BlockSparseArray{elt}([2, 3], [2, 3])
Expand Down Expand Up @@ -82,6 +82,26 @@ include("TestBlockSparseArraysUtils.jl")
@test block_nstored(a) == 2
@test nstored(a) == 2 * 4 + 3 * 3

a = BlockSparseArray{elt}([2, 3], [3, 4])
a[Block(1, 2)] .= 2
@test eltype(a) == elt
@test all(==(2), a[Block(1, 2)])
@test iszero(a[Block(1, 1)])
@test iszero(a[Block(2, 1)])
@test iszero(a[Block(2, 2)])
@test block_nstored(a) == 1
@test nstored(a) == 2 * 4

a = BlockSparseArray{elt}([2, 3], [3, 4])
a[Block(1, 2)] .= 0
@test eltype(a) == elt
@test iszero(a[Block(1, 1)])
@test iszero(a[Block(2, 1)])
@test iszero(a[Block(1, 2)])
@test iszero(a[Block(2, 2)])
@test block_nstored(a) == 1
@test nstored(a) == 2 * 4

a = BlockSparseArray{elt}(undef, ([2, 3], [3, 4]))
@views for b in [Block(1, 2), Block(2, 1)]
a[b] = randn(elt, size(a[b]))
Expand Down Expand Up @@ -490,13 +510,45 @@ include("TestBlockSparseArraysUtils.jl")
@test b[Block(2, 2)] == x
end

function f1()
a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
x = randn(elt, 3, 4)
b[Block(1, 1)] .= x
return (; a, b, x)
end
function f2()
a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
x = randn(elt, 3, 4)
b[Block(1, 1)] = x
return (; a, b, x)
end
for abx in (f1(), f2())
@compat (; a, b, x) = abx
@test b isa SubArray{<:Any,<:Any,<:BlockSparseArray}
@test block_nstored(b) == 1
@test b[Block(1, 1)] == x
for blck in [Block(2, 1), Block(1, 2), Block(2, 2)]
@test iszero(b[blck])
end
@test block_nstored(a) == 1
@test a[Block(2, 2)] == x
for blck in [Block(1, 1), Block(2, 1), Block(1, 2)]
@test iszero(a[blck])
end
@test_throws DimensionMismatch b[Block(1, 1)] .= randn(2, 3)
end

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
x = randn(elt, 3, 4)
b[Block(1, 1)] .= x
@test b[Block(1, 1)] == x
@test a[Block(2, 2)] == x
@test_throws DimensionMismatch b[Block(1, 1)] .= randn(2, 3)
b = @views a[[Block(2), Block(1)], [Block(2), Block(1)]][Block(2, 1)]
@test iszero(b)
@test size(b) == (2, 4)
x = randn(elt, 2, 4)
b .= x
@test b == x
@test a[Block(1, 2)] == x
@test block_nstored(a) == 1

a = BlockSparseArray{elt}([2, 3], [3, 4])
b = @view a[[Block(2), Block(1)], [Block(2), Block(1)]]
Expand Down
Loading