Skip to content

Commit

Permalink
support general backends for BlockArray (#76)
Browse files Browse the repository at this point in the history
* support general backends for BlockArray

* Don't convert in mortar

* tridiagonal

* Use getblock to support overloading for sparse

* Allow general vector blocksize backends

* template out blocksizes

* add another layer to _find_block to support fast overrides

* Allow general BlockSizes, test for constant block sizes

* Simplify show

* fix simple show

* Revert BlockArray(undef_blocks, ::Type) behaviour

* Fix docs

* more doc fixes

* another doc fix

* try removing space

* Increase coverage

* increase coverage
  • Loading branch information
dlfivefifty authored Mar 14, 2019
1 parent 8f60fd0 commit 0776c2e
Show file tree
Hide file tree
Showing 17 changed files with 221 additions and 163 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
docs/build/
docs/site/
*.jld
benchmark/*.md
benchmark/*.md
src/.DS_Store
2 changes: 1 addition & 1 deletion docs/src/man/abstractblockarrayinterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ With the methods above implemented the following are automatically provided:
* A pretty printing `show` function that uses unicode lines to split up the blocks:
```
julia> A = BlockArray(rand(4, 5), [1,3], [2,3])
2×2-blocked 4×5 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
2×2-blocked 4×5 BlockArray{Float64,2}:
0.61179 0.965631 │ 0.696476 0.392796 0.712462
--------------------┼-------------------------------
0.620099 0.364706 │ 0.0311643 0.27895 0.73477
Expand Down
43 changes: 23 additions & 20 deletions docs/src/man/blockarrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A block array can be created with initialized blocks using the `BlockArray{T}(bl
function. The block_sizes are each an `AbstractVector{Int}` which determines the size of the blocks in that dimension. We here create a `[1,2]×[3,2]` block matrix of `Float32`s:
```julia
julia> BlockArray{Float32}(undef, [1,2], [3,2])
2×2-blocked 3×5 BlockArrays.BlockArray{Float32,2,Array{Float32,2}}:
2×2-blocked 3×5 BlockArray{Float32,2}:
9.39116f-26 1.4013f-45 3.34245f-219.39064f-26 1.4013f-45
───────────────────────────────────────┼──────────────────────────
3.28434f-21 9.37645f-26 3.28436f-218.05301f-24 9.39077f-26
Expand All @@ -30,7 +30,7 @@ The `block_type` should be an array type, it could for example be `Matrix{Float6

```jldoctest
julia> BlockArray{Float32}(undef_blocks, [1,2], [3,2])
3×5 BlockArray{Float32,2,Array{Float32,2}}:
2×2-blocked 3×5 BlockArray{Float32,2}:
#undef #undef #undef │ #undef #undef
────────────────────────┼────────────────
#undef #undef #undef │ #undef #undef
Expand All @@ -42,7 +42,7 @@ specifying it as the second argument:

```jl
julia> BlockArray(undef_blocks, SparseVector{Float64, Int}, [1,2])
2-blocked 3-element BlockArrays.BlockArray{Float64,1,SparseVector{Float64,Int64}}:
2-blocked 3-element BlockArray{Float64,1,Array{SparseVector{Float64,Int64},1},BlockArrays.BlockSizes{1,Array{Int64,1}}}:
#undef
------
#undef
Expand All @@ -59,14 +59,14 @@ An alternative syntax for this is `block_array[Block(i...)] = v` or

```jldoctest block_array
julia> block_array = BlockArray{Float64}(undef_blocks, [1,2], [2,2])
3×4 BlockArray{Float64,2,Array{Float64,2}}:
2×2-blocked 3×4 BlockArray{Float64,2}:
#undef #undef │ #undef #undef
────────────────┼────────────────
#undef #undef │ #undef #undef
#undef #undef │ #undef #undef
julia> setblock!(block_array, rand(2,2), 2, 1)
3×4 BlockArray{Float64,2,Array{Float64,2}}:
2×2-blocked 3×4 BlockArray{Float64,2}:
#undef #undef │ #undef #undef
────────────────────────┼────────────────
0.590845 0.566237 │ #undef #undef
Expand All @@ -75,7 +75,7 @@ julia> setblock!(block_array, rand(2,2), 2, 1)
julia> block_array[Block(1, 1)] = [1 2];
julia> block_array
3×4 BlockArray{Float64,2,Array{Float64,2}}:
2×2-blocked 3×4 BlockArray{Float64,2}:
1.0 2.0 │ #undef #undef
────────────────────┼────────────────
0.590845 0.566237 │ #undef #undef
Expand Down Expand Up @@ -112,7 +112,7 @@ We can also view and modify views of blocks of `BlockArray` using the `view` syn
julia> A = BlockArray(ones(6), 1:3);
julia> view(A, Block(2))
2-element view(::BlockArray{Float64,1,Array{Float64,1}}, BlockSlice(Block{1,Int64}((2,)),2:3)) with eltype Float64:
2-element view(::BlockArray{Float64,1,Array{Array{Float64,1},1},BlockArrays.BlockSizes{1,Array{Int64,1}}}, BlockSlice(Block{1,Int64}((2,)),2:3)) with eltype Float64:
1.0
1.0
Expand All @@ -130,7 +130,7 @@ An array can be repacked into a `BlockArray` with `BlockArray(array, block_sizes

```jl
julia> block_array_sparse = BlockArray(sprand(4, 5, 0.7), [1,3], [2,3])
2×2-blocked 4×5 BlockArrays.BlockArray{Float64,2,SparseMatrixCSC{Float64,Int64}}:
2×2-blocked 4×5 BlockArray{Float64,2,Array{SparseMatrixCSC{Float64,Int64},2},BlockArrays.BlockSizes{2,Array{Int64,1}}}:
0.0341601 0.3741870.0118196 0.299058 0.0
----------------------------------------------------
0.0945445 0.9311150.0460428 0.0 0.0
Expand All @@ -141,16 +141,19 @@ julia> block_array_sparse = BlockArray(sprand(4, 5, 0.7), [1,3], [2,3])
To get back the underlying array use `Array`:

```jl
julia> Array(block_array_sparse))
4×5 SparseMatrixCSC{Float64,Int64} with 15 stored entries:
[1, 1] = 0.0341601
[2, 1] = 0.0945445
[3, 1] = 0.314926
[4, 1] = 0.12781
[3, 3] = 0.496169
[4, 3] = 0.732
[1, 4] = 0.299058
[4, 4] = 0.449182
[4, 5] = 0.875096
julia> Array(block_array_sparse)
4×5 SparseMatrixCSC{Float64,Int64} with 13 stored entries:
[1, 1] = 0.30006
[2, 1] = 0.451742
[3, 1] = 0.243174
[4, 1] = 0.156468
[1, 2] = 0.94057
[3, 2] = 0.544175
[4, 2] = 0.598345
[3, 3] = 0.737486
[4, 3] = 0.929512
[1, 4] = 0.539601
[3, 4] = 0.757658
[4, 4] = 0.44709
[2, 5] = 0.514679
```
12 changes: 6 additions & 6 deletions docs/src/man/pseudoblockarrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Creating a `PseudoBlockArray` works in the same way as a `BlockArray`.

```jldoctest A
julia> pseudo = PseudoBlockArray(rand(3,3), [1,2], [2,1])
3×3 PseudoBlockArray{Float64,2,Array{Float64,2}}:
2×2-blocked 3×3 PseudoBlockArray{Float64,2}:
0.590845 0.460085 │ 0.200586
────────────────────┼──────────
0.766797 0.794026 │ 0.298614
Expand All @@ -39,11 +39,11 @@ A block array can be created with uninitialized entries using the `BlockArray{T}
function. The block_sizes are each an `AbstractVector{Int}` which determines the size of the blocks in that dimension. We here create a `[1,2]×[3,2]` block matrix of `Float32`s:
```julia
julia> PseudoBlockArray{Float32}(undef, [1,2], [3,2])
2×2-blocked 3×5 BlockArrays.BlockArray{Float32,2,Array{Float32,2}}:
9.39116f-26 1.4013f-45 3.34245f-219.39064f-26 1.4013f-45
2×2-blocked 3×5 PseudoBlockArray{Float32,2}:
1.02295e-43 0.0 1.09301e-430.0 1.17709e-43
───────────────────────────────────────┼──────────────────────────
3.28434f-21 9.37645f-26 3.28436f-21 8.05301f-24 9.39077f-26
1.4013f-45 1.4013f-45 1.4013f-45 1.4013f-45 1.4013f-45
0.0 1.06499e-43 0.0 1.14906e-43 0.0
1.05097e-43 0.0 1.13505e-43 0.0 1.1911e-43
```
We can also any other user defined array type that supports `similar`.

Expand Down Expand Up @@ -83,7 +83,7 @@ We can also view and modify views of blocks of `PseudoBlockArray` using the `vie
julia> A = PseudoBlockArray(ones(6), 1:3);
julia> view(A, Block(2))
2-element view(::PseudoBlockArray{Float64,1,Array{Float64,1}}, BlockSlice(Block{1,Int64}((2,)),2:3)) with eltype Float64:
2-element view(::PseudoBlockArray{Float64,1,Array{Float64,1},BlockArrays.BlockSizes{1,Array{Int64,1}}}, BlockSlice(Block{1,Int64}((2,)),2:3)) with eltype Float64:
1.0
1.0
Expand Down
18 changes: 12 additions & 6 deletions src/abstractblockarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ const AbstractBlockVecOrMat{T} = Union{AbstractBlockMatrix{T}, AbstractBlockVect

block2string(b, s) = string(join(map(string,b), '×'), "-blocked ", Base.dims2string(s))
Base.summary(a::AbstractBlockArray) = string(block2string(nblocks(a), size(a)), " ", typeof(a))
_show_typeof(io, a) = show(io, typeof(a))
function Base.summary(io::IO, a::AbstractBlockArray)
print(io, block2string(nblocks(a), size(a)))
print(io, ' ')
_show_typeof(io, a)
end
Base.similar(block_array::AbstractBlockArray{T}) where {T} = similar(block_array, T)
Base.IndexStyle(::Type{<:AbstractBlockArray}) = IndexCartesian()

Expand Down Expand Up @@ -61,7 +67,7 @@ a single element.
```jldoctest; setup = quote using BlockArrays end
julia> A = BlockArray(ones(2,3), [1, 1], [2, 1])
2×3 BlockArray{Float64,2,Array{Float64,2}}:
2-blocked 2×3 BlockArray{Float64,2}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
Expand Down Expand Up @@ -134,7 +140,7 @@ julia> v = Array(reshape(1:6, (2, 3)))
2 4 6
julia> A = BlockArray(v, [1,1], [2,1])
2×3 BlockArray{Int64,2,Array{Int64,2}}:
2-blocked 2×3 BlockArray{Int64,2}:
1 3 │ 5
──────┼───
2 4 │ 6
Expand Down Expand Up @@ -162,7 +168,7 @@ attempted assigned block is out of bounds.
```jldoctest; setup = quote using BlockArrays end
julia> A = PseudoBlockArray(ones(2, 3), [1, 1], [2, 1])
2×3 PseudoBlockArray{Float64,2,Array{Float64,2}}:
2-blocked 2×3 PseudoBlockArray{Float64,2}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
Expand Down Expand Up @@ -196,7 +202,7 @@ julia> setblock!(A, [1 2], 1, 1);
julia> A[Block(2, 1)] = [3 4];
julia> A
2×3 PseudoBlockArray{Float64,2,Array{Float64,2}}:
2-blocked 2×3 PseudoBlockArray{Float64,2}:
1.0 2.0 │ 0.0
──────────┼─────
3.0 4.0 │ 0.0
Expand Down Expand Up @@ -246,7 +252,7 @@ specialize this method if they need to provide custom block bounds checking beha
julia> A = BlockArray(rand(2,3), [1,1], [2,1]);
julia> blockcheckbounds(A, 3, 2)
ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockArray{Float64,2,Array{Float64,2}} at block index [3,2]
ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockArray{Float64,2,Array{Array{Float64,2},2},BlockArrays.BlockSizes{2,Array{Int64,1}}} at block index [3,2]
[...]
```
"""
Expand Down Expand Up @@ -279,7 +285,7 @@ Returns the array stored in `A` as a `Array`.
```jldoctest; setup = quote using BlockArrays end
julia> A = BlockArray(ones(2,3), [1,1], [2,1])
2×3 BlockArray{Float64,2,Array{Float64,2}}:
2-blocked 2×3 BlockArray{Float64,2}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
Expand Down
Loading

0 comments on commit 0776c2e

Please sign in to comment.