Skip to content

Commit 4f17d53

Browse files
authored
Fixes for fast triangle recurrences (#49)
* Fix ambiguity in LayoutVector'*LayoutMatrix * Update Project.toml * FillLayout copyto! * Add RangeCumsum(?) * FillArrays 0.11 * Update ArrayLayouts.jl * v 0.5 * increase codecov
1 parent 9fbed3a commit 4f17d53

File tree

8 files changed

+74
-10
lines changed

8 files changed

+74
-10
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ArrayLayouts"
22
uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.4.12"
4+
version = "0.5.0"
55

66
[deps]
77
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
@@ -11,7 +11,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1111

1212
[compat]
1313
Compat = "3.16"
14-
FillArrays = "0.10.1"
14+
FillArrays = "0.11"
1515
julia = "1"
1616

1717
[extras]

src/ArrayLayouts.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import Base: AbstractArray, AbstractMatrix, AbstractVector,
2727
similar, @_gc_preserve_end, @_gc_preserve_begin,
2828
@nexprs, @ncall, @ntuple, tuple_type_tail,
2929
all, any, isbitsunion, issubset, replace_in_print_matrix, replace_with_centered_mark,
30-
strides, unsafe_convert, first_index, unalias
30+
strides, unsafe_convert, first_index, unalias, union
3131

3232
import Base.Broadcast: BroadcastStyle, AbstractArrayStyle, Broadcasted, broadcasted,
3333
combine_eltypes, DefaultArrayStyle, instantiate, materialize,
@@ -54,7 +54,8 @@ export materialize, materialize!, MulAdd, muladd!, Ldiv, Rdiv, Lmul, Rmul, Dot,
5454
DiagonalLayout, ScalarLayout, SymTridiagonalLayout, TridiagonalLayout, BidiagonalLayout,
5555
HermitianLayout, SymmetricLayout, TriangularLayout,
5656
UnknownLayout, AbstractBandedLayout, ApplyBroadcastStyle, ConjLayout, AbstractFillLayout, DualLayout,
57-
colsupport, rowsupport, layout_getindex, QLayout, LayoutArray, LayoutMatrix, LayoutVector
57+
colsupport, rowsupport, layout_getindex, QLayout, LayoutArray, LayoutMatrix, LayoutVector,
58+
RangeCumsum
5859

5960
struct ApplyBroadcastStyle <: BroadcastStyle end
6061
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{ApplyBroadcastStyle})
@@ -104,6 +105,7 @@ include("factorizations.jl")
104105
@inline sub_materialize(_, V, _) = Array(V)
105106
@inline sub_materialize(L, V) = sub_materialize(L, V, axes(V))
106107
@inline sub_materialize(V::SubArray) = sub_materialize(MemoryLayout(V), V)
108+
@inline sub_materialize(V::AbstractArray) = V # Anything not a SubArray is already materialized
107109

108110
@inline layout_getindex(A, I...) = sub_materialize(view(A, I...))
109111

@@ -178,6 +180,7 @@ copyto!(dest::AbstractArray{<:Any,N}, src::SubArray{<:Any,N,<:LayoutArray}) wher
178180
copyto!(dest::LayoutMatrix, src::AdjOrTrans{<:Any,<:LayoutArray}) = _copyto!(dest, src)
179181
copyto!(dest::LayoutMatrix, src::SubArray{<:Any,2,<:AdjOrTrans{<:Any,<:LayoutArray}}) = _copyto!(dest, src)
180182
copyto!(dest::AbstractMatrix, src::AdjOrTrans{<:Any,<:LayoutArray}) = _copyto!(dest, src)
183+
copyto!(dest::SubArray{<:Any,2,<:LayoutArray}, src::AdjOrTrans{<:Any,<:LayoutArray}) = _copyto!(dest, src)
181184
copyto!(dest::SubArray{<:Any,2,<:LayoutMatrix}, src::SubArray{<:Any,2,<:AdjOrTrans{<:Any,<:LayoutArray}}) = _copyto!(dest, src)
182185
copyto!(dest::AbstractMatrix, src::SubArray{<:Any,2,<:AdjOrTrans{<:Any,<:LayoutArray}}) = _copyto!(dest, src)
183186
# ambiguity from sparsematrix.jl
@@ -281,6 +284,6 @@ Base.print_matrix_row(io::IO,
281284
axes_print_matrix_row(axes(X), io, X, A, i, cols, sep)
282285

283286

284-
287+
include("cumsum.jl")
285288

286289
end

src/cumsum.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
RangeCumsum(range)
3+
4+
represents the cumsum of a `AbstractRange`.
5+
"""
6+
struct RangeCumsum{T, RR<:AbstractRange{T}} <: LayoutVector{T}
7+
range::RR
8+
end
9+
10+
size(c::RangeCumsum) = size(c.range)
11+
12+
==(a::RangeCumsum, b::RangeCumsum) = a.range == b.range
13+
BroadcastStyle(::Type{<:RangeCumsum{<:Any,RR}}) where RR = BroadcastStyle(RR)
14+
15+
16+
Base.@propagate_inbounds function getindex(c::RangeCumsum{<:Any,<:AbstractRange}, k::Integer)
17+
@boundscheck checkbounds(c, k)
18+
r = c.range
19+
k * (first(r) + r[k]) ÷ 2
20+
end
21+
Base.@propagate_inbounds function getindex(c::RangeCumsum{<:Any,<:AbstractUnitRange}, k::Integer)
22+
@boundscheck checkbounds(c, k)
23+
r = c.range
24+
k * (2first(r) + k - 1) ÷ 2
25+
end
26+
27+
Base.@propagate_inbounds getindex(c::RangeCumsum, kr::OneTo) = RangeCumsum(c.range[kr])
28+
29+
last(r::RangeCumsum) = sum(r.range)
30+
diff(r::RangeCumsum) = r.range[2:end]
31+
32+
union(a::RangeCumsum{<:Any,<:Base.OneTo}, b::RangeCumsum{<:Any,<:Base.OneTo}) =
33+
RangeCumsum(Base.OneTo(max(last(a.range),last(b.range))))
34+
35+
sort!(a::RangeCumsum{<:Any,<:AbstractUnitRange}) = a

src/memorylayout.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,11 @@ sublayout(L::AbstractFillLayout, inds::Type) = L
530530
reshapedlayout(L::AbstractFillLayout, _) = L
531531
adjointlayout(::Type, L::AbstractFillLayout) = L
532532
transposelayout(L::AbstractFillLayout) = L
533-
# TODO: Move to FillArrays.jl
534-
_getindex_value(V::SubArray) = getindex_value(parent(V))
535533

536-
sub_materialize(::AbstractFillLayout, V, ax) = Fill(_getindex_value(V), ax)
534+
_copyto!(_, ::AbstractFillLayout, dest::AbstractArray{<:Any,N}, src::AbstractArray{<:Any,N}) where N =
535+
fill!(dest, getindex_value(src))
536+
537+
sub_materialize(::AbstractFillLayout, V, ax) = Fill(getindex_value(V), ax)
537538
sub_materialize(::ZerosLayout, V, ax) = Zeros{eltype(V)}(ax)
538539
sub_materialize(::OnesLayout, V, ax) = Ones{eltype(V)}(ax)
539540

src/mul.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ macro veclayoutmul(Typ)
142142
LinearAlgebra.mul!(dest::AbstractVector, A::$Mod{<:Any,<:$Typ}, b::AbstractVector) =
143143
ArrayLayouts.mul!(dest,A,b)
144144

145+
Base.:*(A::$Mod{<:Any,<:$Typ}, B::ArrayLayouts.LayoutMatrix) = ArrayLayouts.mul(A,B)
145146
Base.:*(A::$Mod{<:Any,<:$Typ}, B::AbstractMatrix) = ArrayLayouts.mul(A,B)
146147
Base.:*(A::$Mod{<:Any,<:$Typ}, B::AbstractVector) = ArrayLayouts.mul(A,B)
147148
Base.:*(A::$Mod{<:Number,<:$Typ}, B::AbstractVector{<:Number}) = ArrayLayouts.mul(A,B)

test/runtests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor()
7979
@test copyto!(MyMatrix(Array{Float64}(undef,5,5)), view(A',:,:)) == A'
8080
@test copyto!(Array{Float64}(undef,5,5), A') == A'
8181
@test copyto!(Array{Float64}(undef,5,5), view(A',:,:)) == A'
82+
@test copyto!(view(MyMatrix(Array{Float64}(undef,5,5)),:,:), A') == A'
8283

8384
@test copyto!(view(MyMatrix(Array{Float64}(undef,5,5)),:,:), view(A',:,:)) == A'
8485

@@ -219,3 +220,4 @@ triangulardata(A::MyUpperTriangular) = triangulardata(A.A)
219220
@test_skip lmul!(U,view(copy(B),collect(1:5),1:5)) U * B
220221
end
221222

223+
include("test_cumsum.jl")

test/test_cumsum.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using ArrayLayouts, Test
2+
3+
@testset "RangeCumsum" begin
4+
for r in (RangeCumsum(Base.OneTo(5)), RangeCumsum(2:5), RangeCumsum(2:2:6), RangeCumsum(6:-2:1))
5+
@test r == cumsum(r.range)
6+
@test r == r
7+
@test r .+ 1 == cumsum(r.range) .+ 1
8+
@test r[Base.OneTo(3)] == r[1:3]
9+
@test last(r) == r[end]
10+
@test diff(r) == diff(Vector(r))
11+
end
12+
13+
a,b = RangeCumsum(Base.OneTo(5)), RangeCumsum(Base.OneTo(6))
14+
@test union(a,b) union(b,a) b
15+
@test sort!(a) a
16+
end

test/test_layouts.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ struct FooNumber <: Number end
287287
@test MemoryLayout(Fill(1,10)) == FillLayout()
288288
@test MemoryLayout(Ones(10)) == OnesLayout()
289289
@test MemoryLayout(Zeros(10)) == ZerosLayout()
290-
@test MemoryLayout(view(Fill(1,10),1:3)) == FillLayout()
290+
@test MemoryLayout(SubArray(Fill(1,10),(1:3,))) == FillLayout()
291291
@test MemoryLayout(view(Fill(1,10),1:3,1)) == FillLayout()
292-
@test MemoryLayout(view(Fill(1,10),[1,3,2])) == FillLayout()
292+
@test MemoryLayout(SubArray(Fill(1,10),([1,3,2],))) == FillLayout()
293293
@test MemoryLayout(reshape(Fill(1,10),2,5)) == FillLayout()
294294
@test MemoryLayout(Fill(1+0im,10)') == DualLayout{FillLayout}()
295295
@test MemoryLayout(Adjoint(Fill(1+0im,10,2))) == FillLayout()
@@ -298,6 +298,12 @@ struct FooNumber <: Number end
298298
@test layout_getindex(Fill(1,10), 1:3) Fill(1,3)
299299
@test layout_getindex(Ones{Int}(1,10), 1, 1:3) Ones{Int}(3)
300300
@test layout_getindex(Zeros{Int}(5,10,12), 1, 1:3,4:6) Zeros{Int}(3,3)
301+
302+
# views of Fill no longer create Sub Arrays, but are supported
303+
# as there was no strong need to delete their support
304+
v = SubArray(Fill(1,10),(1:3,))
305+
@test ArrayLayouts.sub_materialize(v) Fill(1,3)
306+
@test ArrayLayouts._copyto!(Vector{Float64}(undef,3), v) == ones(3)
301307
end
302308

303309
@testset "Triangular col/rowsupport" begin

0 commit comments

Comments
 (0)