Skip to content

Commit 93469a9

Browse files
authored
Fast copyto! for banded blocks (#73)
* Fast copyto! for banded blocks * Fix bounds check * update project * Update Project.toml * Update .travis.yml
1 parent f4412db commit 93469a9

File tree

10 files changed

+86
-68
lines changed

10 files changed

+86
-68
lines changed

.editorconfig

Lines changed: 0 additions & 7 deletions
This file was deleted.

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ matrix:
1313
notifications:
1414
email: false
1515
after_success:
16-
- julia -e 'Pkg.add("Documenter")'
17-
- julia -e 'cd(Pkg.dir("BlockBandedMatrices")); include(joinpath("docs", "make.jl"))'
18-
- julia -e 'cd(Pkg.dir("BlockBandedMatrices")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
16+
- julia -e 'using Pkg; Pkg.add("Documenter")'
17+
- julia -e 'using Pkg; cd(Pkg.dir("BlockBandedMatrices")); include(joinpath("docs", "make.jl"))'
18+
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
1919

2020
# uncomment the following lines to override the default test script
2121
#script:

Project.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockBandedMatrices"
22
uuid = "ffab5731-97b5-5995-9138-79e8c1846df0"
3-
version = "0.8.4"
3+
version = "0.8.5"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -18,9 +18,9 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1818
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1919

2020
[compat]
21-
ArrayLayouts = "0.2.6, 0.3"
22-
BandedMatrices = "0.15.6"
23-
BlockArrays = "0.12.4"
24-
FillArrays = "0.8.8"
25-
MatrixFactorizations = "0.4"
21+
ArrayLayouts = "0.3.3"
22+
BandedMatrices = "0.15.10"
23+
BlockArrays = "0.12.7"
24+
FillArrays = "0.8.10"
25+
MatrixFactorizations = "0.4.1"
2626
julia = "1.2"

src/AbstractBlockBandedMatrix.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ end
128128
# RaggedMatrix interface
129129
######################################
130130

131-
@inline function colstart(A::AbstractBlockBandedMatrix, i::Integer)
131+
@inline function blockbanded_colstart(A, i::Integer)
132132
bs = blockcolstart(A,findblock(axes(A,2),i))
133133
if isempty(axes(A,1))
134134
1
@@ -139,26 +139,26 @@ end
139139
end
140140
end
141141

142-
@inline function colstop(A::AbstractBlockBandedMatrix, i::Integer)
142+
@inline function blockbanded_colstop(A, i::Integer)
143143
CS = blockcolstop(A,findblock(axes(A,2),i))
144144
CS == Block(0) && return 0
145145
last(axes(A,1)[CS])
146146
end
147147

148-
@inline rowstart(A::AbstractBlockBandedMatrix, i::Integer) =
148+
@inline blockbanded_rowstart(A, i::Integer) =
149149
first(axes(A,2)[blockrowstart(A,findblock(axes(A,1),i))])
150150

151-
@inline function rowstop(A::AbstractBlockBandedMatrix, i::Integer)
151+
@inline function blockbanded_rowstop(A, i::Integer)
152152
CS = blockrowstop(A,findblock(axes(A,1),i))
153153
CS == Block(0) && return 0
154154
last(axes(A,2)[CS])
155155
end
156156

157-
@inline blockbanded_colsupport(A, j::Integer) = colrange(A, j)
158-
@inline blockbanded_rowsupport(A, j::Integer) = rowrange(A, j)
157+
@inline blockbanded_colsupport(A, j::Integer) = blockbanded_colstart(A, j):blockbanded_colstop(A, j)
158+
@inline blockbanded_rowsupport(A, j::Integer) = blockbanded_rowstart(A, j):blockbanded_rowstop(A, j)
159159

160-
@inline blockbanded_rowsupport(A, j) = isempty(j) ? (1:0) : rowstart(A,minimum(j)):rowstop(A,maximum(j))
161-
@inline blockbanded_colsupport(A, j) = isempty(j) ? (1:0) : colstart(A,minimum(j)):colstop(A,maximum(j))
160+
@inline blockbanded_rowsupport(A, j) = isempty(j) ? (1:0) : blockbanded_rowstart(A,minimum(j)):blockbanded_rowstop(A,maximum(j))
161+
@inline blockbanded_colsupport(A, j) = isempty(j) ? (1:0) : blockbanded_colstart(A,minimum(j)):blockbanded_colstop(A,maximum(j))
162162

163163
@inline colsupport(::AbstractBlockBandedLayout, A, j) = blockbanded_colsupport(A, j)
164164
@inline rowsupport(::AbstractBlockBandedLayout, A, j) = blockbanded_rowsupport(A, j)

src/BandedBlockBandedMatrix.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ end
318318
end
319319

320320
## structured matrix methods ##
321-
function _bandedblockbanded_replace_in_print_matrix(A, i, j, s)
321+
function layout_replace_in_print_matrix(::AbstractBandedBlockBandedLayout, A, i, j, s)
322322
bi = findblockindex.(axes(A), (i,j))
323323
I,J = block.(bi)
324324
i,j = blockindex.(bi)
@@ -327,9 +327,6 @@ function _bandedblockbanded_replace_in_print_matrix(A, i, j, s)
327327
-l Int(J-I)  u && -λ j-i μ ? s : Base.replace_with_centered_mark(s)
328328
end
329329

330-
Base.replace_in_print_matrix(A::BandedBlockBandedMatrix, i::Integer, j::Integer, s::AbstractString) =
331-
_bandedblockbanded_replace_in_print_matrix(A, i, j, s)
332-
333330

334331
############
335332
# Indexing #

src/BlockBandedMatrices.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Base: getindex, setindex!, checkbounds, @propagate_inbounds, convert,
77
unsafe_convert, fill!, length, first, last,
88
eltype, getindex, to_indices, to_index,
99
reindex, _maybetail, tail, @_propagate_inbounds_meta,
10-
==, axes, copyto!, similar, OneTo, replace_in_print_matrix
10+
==, axes, copyto!, similar, OneTo
1111

1212
import Base.Broadcast: BroadcastStyle, AbstractArrayStyle, DefaultArrayStyle, Broadcasted, broadcasted,
1313
materialize, materialize!
@@ -26,19 +26,19 @@ import ArrayLayouts: BlasMatLmulVec,
2626
triangulardata, sublayout, sub_materialize,
2727
AbstractColumnMajor, DenseColumnMajor, ColumnMajor,
2828
DiagonalLayout, MulAdd, mul, colsupport, rowsupport,
29-
_qr, _factorize, _copyto!, zero!
29+
_qr, _factorize, _copyto!, zero!, layout_replace_in_print_matrix
3030

3131
import BlockArrays: blocksize, blockcheckbounds, BlockedUnitRange, blockisequal, DefaultBlockAxis,
3232
Block, BlockSlice, getblock, unblock, setblock!, block, blockindex,
3333
_blocklengths2blocklasts, BlockIndexRange, sizes_from_blocks, BlockSlice1,
3434
blockcolsupport, blockrowsupport, blockcolstart, blockcolstop, blockrowstart, blockrowstop,
35-
AbstractBlockLayout
35+
AbstractBlockLayout, BlockLayout, blocks
3636

3737
import BandedMatrices: isbanded, bandwidths, bandwidth, banded_getindex, colrange,
3838
inbands_setindex!, inbands_getindex, banded_setindex!,
3939
banded_generic_axpy!,
4040
BlasFloat, banded_dense_axpy!, MemoryLayout,
41-
BandedLayout, BandedColumnMajor,
41+
BandedLayout, BandedColumnMajor, BandedColumns,
4242
BandedSubBandedMatrix, bandeddata, tribandeddata,
4343
_BandedMatrix, colstart, colstop, rowstart, rowstop,
4444
BandedStyle, _fill_lmul!, bandshift,

src/BlockSkylineMatrix.jl

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ function bb_blockstarts(axes, l::AbstractVector{Int}, u::AbstractVector{Int})
2626
b_start
2727
end
2828

29-
bb_blockstarts(b_size, l::Integer, u::Integer) = bb_blockstarts(b_size, Fill(l, nblocks(b_size,2)), Fill(u, nblocks(b_size,2)))
30-
3129
function bb_blockstrides(b_axes, l::AbstractVector{Int}, u::AbstractVector{Int})
3230
N, M = blocksize.(b_axes,1)
3331
L,U = maximum(l), maximum(u)
@@ -233,18 +231,12 @@ BlockBandedMatrix(A::Union{AbstractMatrix,UniformScaling},
233231
BlockBandedMatrix(A::AbstractMatrix, lu::NTuple{2,Int}) = BlockBandedMatrix(A, BlockBandedSizes(axes(A), lu...))
234232

235233
function convert(::Type{BlockSkylineMatrix}, A::AbstractMatrix)
236-
@assert isblockbanded(A)
237234
block_sizes = BlockSkylineSizes(axes(A), colblockbandwidths(A)...)
238235

239-
ret = BlockSkylineMatrix{eltype(A)}(undef, block_sizes)
240-
for J = blockaxes(ret,2), K = blockcolsupport(ret, J)
241-
view(ret, K, J) .= view(A, K, J)
242-
end
243-
ret
236+
copyto!(BlockSkylineMatrix{eltype(A)}(undef, block_sizes), A)
244237
end
245238

246239
function convert(::Type{BlockBandedMatrix}, A::AbstractMatrix)
247-
@assert isblockbanded(A)
248240
convert(BlockSkylineMatrix, A)
249241
end
250242

@@ -320,13 +312,6 @@ end
320312
return v
321313
end
322314

323-
## structured matrix methods ##
324-
function Base.replace_in_print_matrix(A::BlockSkylineMatrix, i::Integer, j::Integer, s::AbstractString)
325-
bi = findblockindex.(axes(A), (i,j))
326-
I,J = Int.(block.(bi))
327-
-A.block_sizes.l[J] J-I A.block_sizes.u[J] ? s : Base.replace_with_centered_mark(s)
328-
end
329-
330315
############
331316
# Indexing #
332317
############
@@ -405,8 +390,8 @@ const BlockBandedBlock{T} = SubArray{T,2,<:BlockSkylineMatrix,<:Tuple{<:BlockSli
405390

406391

407392
# gives the columns of parent(V).data that encode the block
408-
blocks(V::BlockBandedBlock)::Tuple{Int,Int} = first(first(parentindices(V)).block.n),
409-
first(last(parentindices(V)).block.n)
393+
_parent_blocks(V::BlockBandedBlock)::Tuple{Int,Int} =
394+
first(first(parentindices(V)).block.n),first(last(parentindices(V)).block.n)
410395

411396
######################################
412397
# Matrix interface for Blocks #
@@ -417,16 +402,16 @@ MemoryLayout(::Type{<:BlockBandedBlock}) = ColumnMajor()
417402

418403
function Base.unsafe_convert(::Type{Ptr{T}}, V::BlockBandedBlock{T}) where T
419404
A = parent(V)
420-
K,J = blocks(V)
405+
K,J = _parent_blocks(V)
421406
Base.unsafe_convert(Ptr{T}, A.data) + sizeof(T)*(blockstart(A,K,J)-1)
422407
end
423408

424-
strides(V::BlockBandedBlock) = (1,parent(V).block_sizes.block_strides[blocks(V)[2]])
409+
strides(V::BlockBandedBlock) = (1,parent(V).block_sizes.block_strides[_parent_blocks(V)[2]])
425410

426411
@propagate_inbounds function getindex(V::BlockBandedBlock, k::Int, j::Int)
427412
@boundscheck checkbounds(V, k, j)
428413
A = parent(V)
429-
K,J = blocks(V)
414+
K,J = _parent_blocks(V)
430415
if -A.block_sizes.l[J]  J-K  A.block_sizes.u[J]
431416
b_start = blockstart(A,K,J)
432417
b_start == 0 && return zero(eltype(V))
@@ -440,7 +425,7 @@ end
440425
@propagate_inbounds function setindex!(V::BlockBandedBlock, v, k::Int, j::Int)
441426
@boundscheck checkbounds(V, k, j)
442427
A = parent(V)
443-
K,J = blocks(V)
428+
K,J = _parent_blocks(V)
444429
if -A.block_sizes.l[J]  J-K  A.block_sizes.u[J]
445430
b_start = blockstart(A,K,J)
446431
# TODO: What to do if b_start == 0 ?

src/broadcast.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,62 @@ end
8080

8181

8282
_copyto!(_, ::AbstractBlockBandedLayout, dest::AbstractMatrix, src::AbstractMatrix) = blockbanded_copyto!(dest, src)
83+
function _copyto!(_, ::BlockLayout{<:BandedColumns}, dest::AbstractMatrix, src::AbstractMatrix)
84+
if !blockisequal(axes(dest), axes(src))
85+
copyto!(PseudoBlockArray(dest, axes(src)), src)
86+
return dest
87+
end
88+
89+
srcB = blocks(src)
90+
srcD = bandeddata(srcB)
91+
92+
dl, du = colblockbandwidths(dest)
93+
sl, su = bandwidths(srcB)
94+
M,N = size(srcB)
95+
# Source matrix must fit within bands of destination matrix
96+
all(dl .≥ min(sl,M-1)) && all(du .≥ min(su,N-1)) || throw(BandError(dest))
97+
98+
for J = 1:N
99+
for K = max(1,J-du[J]):min(J-su-1,M)
100+
zero!(view(dest,Block(K),Block(J)))
101+
end
102+
for K = max(1,J-su):min(J+sl,M)
103+
copyto!(view(dest,Block(K),Block(J)), srcD[K-J+su+1,J])
104+
end
105+
for K = max(1,J+sl+1):min(J+dl[J],M)
106+
zero!(view(dest,Block(K),Block(J)))
107+
end
108+
end
109+
dest
110+
end
111+
112+
function _copyto!(_, ::BlockLayout{<:AbstractBandedLayout}, dest::AbstractMatrix, src::AbstractMatrix)
113+
if !blockisequal(axes(dest), axes(src))
114+
copyto!(PseudoBlockArray(dest, axes(src)), src)
115+
return dest
116+
end
117+
118+
srcB = blocks(src)
119+
120+
dl, du = colblockbandwidths(dest)
121+
sl, su = bandwidths(srcB)
122+
M,N = size(srcB)
123+
# Source matrix must fit within bands of destination matrix
124+
all(dl .≥ min(sl,M-1)) && all(du .≥ min(su,N-1)) || throw(BandError(dest))
125+
126+
for J = 1:N
127+
for K = max(1,J-du[J]):min(J-su-1,M)
128+
zero!(view(dest,Block(K),Block(J)))
129+
end
130+
for K = max(1,J-su):min(J+sl,M)
131+
copyto!(view(dest,Block(K),Block(J)), inbands_getindex(srcB, K, J))
132+
end
133+
for K = max(1,J+sl+1):min(J+dl[J],M)
134+
zero!(view(dest,Block(K),Block(J)))
135+
end
136+
end
137+
dest
138+
end
83139

84140

85141
function copyto!(dest::AbstractArray, bc::Broadcasted{<:AbstractBlockBandedStyle, <:Any, typeof(identity)})

src/interfaceimpl.jl

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,4 @@ for op in (:-, :+)
7373
mortar(Tridiagonal(A.blocks.dl, broadcast($op, Ref(λ), A.blocks.d), A.blocks.du))
7474
end
7575
end
76-
end
77-
78-
function replace_in_print_matrix(A::BlockDiagonal, i::Integer, j::Integer, s::AbstractString)
79-
bi = findblockindex.(axes(A), (i,j))
80-
I,J = block.(bi)
81-
i,j = blockindex.(bi)
82-
Int(J-I) == 0 ? s : Base.replace_with_centered_mark(s)
83-
end
84-
85-
function replace_in_print_matrix(A::BlockTridiagonal, i::Integer, j::Integer, s::AbstractString)
86-
bi = findblockindex.(axes(A), (i,j))
87-
I,J = block.(bi)
88-
i,j = blockindex.(bi)
89-
-1 Int(J-I)  1 ? s : Base.replace_with_centered_mark(s)
9076
end

src/linalg.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ isblockbanded(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{BlockRange1}, <:Blo
9797
isblockbanded(parent(V))
9898

9999
sub_materialize(::AbstractBlockBandedLayout, V, _) = BlockBandedMatrix(V)
100+
sub_materialize(::BlockLayout{<:AbstractBandedLayout}, V, _) = BlockBandedMatrix(V)
100101

101102
strides(V::SubBlockSkylineMatrix{<:Any,LL,UU,<:Union{BlockRange1,Block1},Block1}) where {LL,UU} =
102103
(1,parent(V).block_sizes.block_strides[Int(parentindices(V)[2].block)])

0 commit comments

Comments
 (0)