Skip to content

Commit a959bed

Browse files
committed
Add README
1 parent fbd58ff commit a959bed

File tree

4 files changed

+90
-67
lines changed

4 files changed

+90
-67
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
11
# ArrayLayouts.jl
22
A Julia package for describing array layouts and more general fast linear algebra
3+
4+
[![Travis](https://travis-ci.org/JuliaMatrices/ArrayLayouts.jl.svg?branch=master)](https://travis-ci.org/JuliaMatrices/ArrayLayouts.jl)
5+
[![codecov](https://codecov.io/gh/JuliaMatrices/ArrayLayouts.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMatrices/ArrayLayouts.jl)
6+
7+
This package implements a trait-based framework for describing array layouts such as column major, row major, etc. that can be dispatched
8+
to appropriate BLAS or optimised Julia linear algebra routines. This supports a much wider class of matrix types than Julia's in-built `StridedArray`. Here is an example:
9+
```julia
10+
julia> using ArrayLayouts
11+
12+
julia> A = randn(10_000,10_000); x = randn(10_000); y = similar(x);
13+
14+
julia> V = view(Symmetric(A),:,:)';
15+
16+
julia> @time mul!(y, A, x); # Julia does not recognize that V is symmetric
17+
0.040255 seconds (4 allocations: 160 bytes)
18+
19+
julia> @time muladd!(1.0, V, x, 0.0, y); # ArrayLayouts does and is 3x faster as it calls BLAS
20+
0.017677 seconds (4 allocations: 160 bytes)
21+
```

src/ArrayLayouts.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ else
4646
import Base: require_one_based_indexing
4747
end
4848

49-
export materialize, materialize!, MulAdd, muladd!, Ldiv, Lmul, Rmul, MemoryLayout
49+
export materialize, materialize!, MulAdd, muladd!, Ldiv, Lmul, Rmul, MemoryLayout, AbstractStridedLayout,
50+
DenseColumnMajor, ColumnMajor, ZerosLayout, FillLayout, AbstractColumnMajor, RowMajor, AbstractRowMajor,
51+
DiagonalLayout, ScalarLayout, SymTridiagonalLayout, SymmetricLayout,
52+
ApplyBroadcastStyle, colsupport, rowsupport
5053

5154
struct ApplyBroadcastStyle <: BroadcastStyle end
5255
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{ApplyBroadcastStyle})

src/memorylayout.jl

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -156,81 +156,81 @@ MemoryLayout(::Type{<:ReshapedArray{T,N,A,DIMS}}) where {T,N,A,DIMS} = reshapedl
156156

157157

158158
@inline MemoryLayout(A::Type{<:SubArray{T,N,P,I}}) where {T,N,P,I} =
159-
subarraylayout(MemoryLayout(P), I)
160-
subarraylayout(_1, _2) = UnknownLayout()
161-
subarraylayout(_1, _2, _3)= UnknownLayout()
162-
subarraylayout(::DenseColumnMajor, ::Type{<:Tuple{<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex}}}) =
159+
sublayout(MemoryLayout(P), I)
160+
sublayout(_1, _2) = UnknownLayout()
161+
sublayout(_1, _2, _3)= UnknownLayout()
162+
sublayout(::DenseColumnMajor, ::Type{<:Tuple{<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex}}}) =
163163
DenseColumnMajor() # A[:] is DenseColumnMajor if A is DenseColumnMajor
164-
subarraylayout(ml::AbstractColumnMajor, inds) = _column_subarraylayout1(ml, inds)
165-
subarraylayout(::AbstractRowMajor, ::Type{<:Tuple{<:Any}}) =
164+
sublayout(ml::AbstractColumnMajor, inds) = _column_sublayout1(ml, inds)
165+
sublayout(::AbstractRowMajor, ::Type{<:Tuple{<:Any}}) =
166166
UnknownLayout() # A[:] does not have any structure if A is AbstractRowMajor
167-
subarraylayout(ml::AbstractRowMajor, inds) = _row_subarraylayout1(ml, tuple_type_reverse(inds))
168-
subarraylayout(ml::AbstractStridedLayout, inds) = _strided_subarraylayout(ml, inds)
167+
sublayout(ml::AbstractRowMajor, inds) = _row_sublayout1(ml, tuple_type_reverse(inds))
168+
sublayout(ml::AbstractStridedLayout, inds) = _strided_sublayout(ml, inds)
169169

170-
_column_subarraylayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
170+
_column_sublayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
171171
DenseColumnMajor() # view(A,1,1,2) is a scalar, which we include in DenseColumnMajor
172-
_column_subarraylayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Slice =
172+
_column_sublayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Slice =
173173
DenseColumnMajor() # view(A,:,1,2) is a DenseColumnMajor vector
174-
_column_subarraylayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
174+
_column_sublayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
175175
DenseColumnMajor() # view(A,1:3,1,2) is a DenseColumnMajor vector
176-
_column_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
176+
_column_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
177177
DenseColumnMajor() # view(A,1,1,2) is a scalar, which we include in DenseColumnMajor
178-
_column_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
178+
_column_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
179179
DenseColumnMajor() # view(A,1:3,1,2) is a DenseColumnMajor vector
180-
_column_subarraylayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Slice =
181-
_column_subarraylayout(DenseColumnMajor(), DenseColumnMajor(), tuple_type_tail(inds))
182-
_column_subarraylayout1(par::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
183-
_column_subarraylayout(par, ColumnMajor(), tuple_type_tail(inds))
184-
_column_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
185-
_column_subarraylayout(par, ColumnMajor(), tuple_type_tail(inds))
186-
_column_subarraylayout1(par::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
187-
_column_subarraylayout(par, StridedLayout(), tuple_type_tail(inds))
188-
_column_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
189-
_column_subarraylayout(par, StridedLayout(), tuple_type_tail(inds))
190-
_column_subarraylayout1(par, inds) = UnknownLayout()
191-
_column_subarraylayout(par, ret, ::Type{<:Tuple{}}) = ret
192-
_column_subarraylayout(par, ret, ::Type{<:Tuple{I}}) where I = UnknownLayout()
193-
_column_subarraylayout(::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
180+
_column_sublayout1(::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Slice =
181+
_column_sublayout(DenseColumnMajor(), DenseColumnMajor(), tuple_type_tail(inds))
182+
_column_sublayout1(par::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
183+
_column_sublayout(par, ColumnMajor(), tuple_type_tail(inds))
184+
_column_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
185+
_column_sublayout(par, ColumnMajor(), tuple_type_tail(inds))
186+
_column_sublayout1(par::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
187+
_column_sublayout(par, StridedLayout(), tuple_type_tail(inds))
188+
_column_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
189+
_column_sublayout(par, StridedLayout(), tuple_type_tail(inds))
190+
_column_sublayout1(par, inds) = UnknownLayout()
191+
_column_sublayout(par, ret, ::Type{<:Tuple{}}) = ret
192+
_column_sublayout(par, ret, ::Type{<:Tuple{I}}) where I = UnknownLayout()
193+
_column_sublayout(::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
194194
DenseColumnMajor() # A[:,1:3,1,2] is DenseColumnMajor if A is DenseColumnMajor
195-
_column_subarraylayout(par::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I, Vararg{Int}}}) where I<:Slice =
195+
_column_sublayout(par::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I, Vararg{Int}}}) where I<:Slice =
196196
DenseColumnMajor()
197-
_column_subarraylayout(par::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Slice =
198-
_column_subarraylayout(par, DenseColumnMajor(), tuple_type_tail(inds))
199-
_column_subarraylayout(par, ::AbstractColumnMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
200-
_column_subarraylayout(par, ColumnMajor(), tuple_type_tail(inds))
201-
_column_subarraylayout(par, ::AbstractStridedLayout, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
202-
_column_subarraylayout(par, StridedLayout(), tuple_type_tail(inds))
203-
204-
_row_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
197+
_column_sublayout(par::DenseColumnMajor, ::DenseColumnMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Slice =
198+
_column_sublayout(par, DenseColumnMajor(), tuple_type_tail(inds))
199+
_column_sublayout(par, ::AbstractColumnMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
200+
_column_sublayout(par, ColumnMajor(), tuple_type_tail(inds))
201+
_column_sublayout(par, ::AbstractStridedLayout, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
202+
_column_sublayout(par, StridedLayout(), tuple_type_tail(inds))
203+
204+
_row_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{Int,AbstractCartesianIndex} =
205205
DenseColumnMajor() # view(A,1,1,2) is a scalar, which we include in DenseColumnMajor
206-
_row_subarraylayout1(::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Slice =
206+
_row_sublayout1(::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Slice =
207207
DenseColumnMajor() # view(A,1,2,:) is a DenseColumnMajor vector
208-
_row_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
208+
_row_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:AbstractUnitRange{Int} =
209209
DenseColumnMajor() # view(A,1,2,1:3) is a DenseColumnMajor vector
210-
_row_subarraylayout1(::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Slice =
211-
_row_subarraylayout(DenseRowMajor(), DenseRowMajor(), tuple_type_tail(inds))
212-
_row_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
213-
_row_subarraylayout(par, RowMajor(), tuple_type_tail(inds))
214-
_row_subarraylayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
215-
_row_subarraylayout(par, StridedLayout(), tuple_type_tail(inds))
216-
_row_subarraylayout1(par, inds) = UnknownLayout()
217-
_row_subarraylayout(par, ret, ::Type{<:Tuple{}}) = ret
218-
_row_subarraylayout(par, ret, ::Type{<:Tuple{I}}) where I = UnknownLayout()
219-
_row_subarraylayout(::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
210+
_row_sublayout1(::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Slice =
211+
_row_sublayout(DenseRowMajor(), DenseRowMajor(), tuple_type_tail(inds))
212+
_row_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:AbstractUnitRange{Int} =
213+
_row_sublayout(par, RowMajor(), tuple_type_tail(inds))
214+
_row_sublayout1(par, inds::Type{<:Tuple{I,Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
215+
_row_sublayout(par, StridedLayout(), tuple_type_tail(inds))
216+
_row_sublayout1(par, inds) = UnknownLayout()
217+
_row_sublayout(par, ret, ::Type{<:Tuple{}}) = ret
218+
_row_sublayout(par, ret, ::Type{<:Tuple{I}}) where I = UnknownLayout()
219+
_row_sublayout(::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I,Vararg{Int}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
220220
DenseRowMajor() # A[1,2,1:3,:] is DenseRowMajor if A is DenseRowMajor
221-
_row_subarraylayout(par::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I, Vararg{Int}}}) where I<:Slice =
221+
_row_sublayout(par::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I, Vararg{Int}}}) where I<:Slice =
222222
DenseRowMajor()
223-
_row_subarraylayout(par::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Slice =
224-
_row_subarraylayout(par, DenseRowMajor(), tuple_type_tail(inds))
225-
_row_subarraylayout(par::AbstractRowMajor, ::AbstractRowMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
226-
_row_subarraylayout(par, RowMajor(), tuple_type_tail(inds))
227-
_row_subarraylayout(par::AbstractRowMajor, ::AbstractStridedLayout, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
228-
_row_subarraylayout(par, StridedLayout(), tuple_type_tail(inds))
229-
230-
_strided_subarraylayout(par, inds) = UnknownLayout()
231-
_strided_subarraylayout(par, ::Type{<:Tuple{}}) = StridedLayout()
232-
_strided_subarraylayout(par, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
233-
_strided_subarraylayout(par, tuple_type_tail(inds))
223+
_row_sublayout(par::DenseRowMajor, ::DenseRowMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Slice =
224+
_row_sublayout(par, DenseRowMajor(), tuple_type_tail(inds))
225+
_row_sublayout(par::AbstractRowMajor, ::AbstractRowMajor, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{AbstractUnitRange{Int},Int,AbstractCartesianIndex} =
226+
_row_sublayout(par, RowMajor(), tuple_type_tail(inds))
227+
_row_sublayout(par::AbstractRowMajor, ::AbstractStridedLayout, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
228+
_row_sublayout(par, StridedLayout(), tuple_type_tail(inds))
229+
230+
_strided_sublayout(par, inds) = UnknownLayout()
231+
_strided_sublayout(par, ::Type{<:Tuple{}}) = StridedLayout()
232+
_strided_sublayout(par, inds::Type{<:Tuple{I, Vararg{Any}}}) where I<:Union{RangeIndex,AbstractCartesianIndex} =
233+
_strided_sublayout(par, tuple_type_tail(inds))
234234

235235
# MemoryLayout of transposed and adjoint matrices
236236
struct ConjLayout{ML<:MemoryLayout} <: MemoryLayout end
@@ -241,7 +241,7 @@ conjlayout(::Type{<:Complex}, ::ML) where ML<:AbstractStridedLayout = ConjLayout
241241
conjlayout(::Type{<:Real}, M::MemoryLayout) = M
242242

243243

244-
subarraylayout(::ConjLayout{ML}, t::Type{<:Tuple}) where ML = ConjLayout{typeof(subarraylayout(ML(), t))}()
244+
sublayout(::ConjLayout{ML}, t::Type{<:Tuple}) where ML = ConjLayout{typeof(sublayout(ML(), t))}()
245245

246246
MemoryLayout(::Type{Transpose{T,P}}) where {T,P} = transposelayout(MemoryLayout(P))
247247
MemoryLayout(::Type{Adjoint{T,P}}) where {T,P} = adjointlayout(T, MemoryLayout(P))
@@ -299,8 +299,8 @@ symmetriclayout(::ML) where ML<:AbstractRowMajor = SymmetricLayout{ML}()
299299
transposelayout(S::SymmetricLayout) = S
300300
adjointlayout(::Type{T}, S::SymmetricLayout) where T<:Real = S
301301
adjointlayout(::Type{T}, S::HermitianLayout) where T = S
302-
subarraylayout(S::SymmetricLayout, ::Type{<:Tuple{<:Slice,<:Slice}}) = S
303-
subarraylayout(S::HermitianLayout, ::Type{<:Tuple{<:Slice,<:Slice}}) = S
302+
sublayout(S::SymmetricLayout, ::Type{<:Tuple{<:Slice,<:Slice}}) = S
303+
sublayout(S::HermitianLayout, ::Type{<:Tuple{<:Slice,<:Slice}}) = S
304304

305305
symmetricdata(A::Symmetric) = A.data
306306
symmetricdata(A::Hermitian{<:Real}) = A.data
@@ -314,6 +314,8 @@ hermitiandata(V::Transpose{<:Real}) = hermitiandata(parent(V))
314314

315315
symmetricuplo(A::Symmetric) = A.uplo
316316
symmetricuplo(A::Hermitian) = A.uplo
317+
symmetricuplo(A::Adjoint) = symmetricuplo(parent(A))
318+
symmetricuplo(A::Transpose) = A.uplo
317319
symmetricuplo(A::SubArray{<:Any, 2, <:Any, <:Tuple{<:Slice,<:Slice}}) = symmetricuplo(parent(A))
318320

319321
# MemoryLayout of triangular matrices
@@ -395,7 +397,7 @@ triangularlayout(_, ::MemoryLayout) = UnknownLayout()
395397
triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AbstractColumnMajor} = Tri{ML}()
396398
triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AbstractRowMajor} = Tri{ML}()
397399
triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:ConjLayout{<:AbstractRowMajor}} = Tri{ML}()
398-
subarraylayout(layout::TriangularLayout, ::Type{<:Tuple{<:Union{Slice,Base.OneTo},<:Union{Slice,Base.OneTo}}}) = layout
400+
sublayout(layout::TriangularLayout, ::Type{<:Tuple{<:Union{Slice,Base.OneTo},<:Union{Slice,Base.OneTo}}}) = layout
399401
conjlayout(::Type{<:Complex}, ::TriangularLayout{UPLO,UNIT,ML}) where {UPLO,UNIT,ML} =
400402
TriangularLayout{UPLO,UNIT,ConjLayout{ML}}()
401403

@@ -445,7 +447,7 @@ MemoryLayout(::Type{<:AbstractFill}) = FillLayout()
445447
MemoryLayout(::Type{<:Zeros}) = ZerosLayout()
446448
diagonallayout(::ML) where ML<:AbstractFillLayout = DiagonalLayout{ML}()
447449
# all sub arrays are same
448-
subarraylayout(L::AbstractFillLayout, inds::Type) = L
450+
sublayout(L::AbstractFillLayout, inds::Type) = L
449451
reshapedlayout(L::AbstractFillLayout, _) = L
450452
adjointlayout(::Type, L::AbstractFillLayout) = L
451453
transposelayout(L::AbstractFillLayout) = L

src/muladd.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ const BlasMatMulMatAdd{StyleA,StyleB,StyleC,T<:BlasFloat} = MulAdd{StyleA,StyleB
7171
const BlasVecMulMatAdd{StyleA,StyleB,StyleC,T<:BlasFloat} = MulAdd{StyleA,StyleB,StyleC,T,<:AbstractVector{T},<:AbstractMatrix{T},<:AbstractMatrix{T}}
7272

7373
muladd!(α, A, B, β, C) = materialize!(MulAdd(α, A, B, β, C))
74-
muladd(α, A, B, β, C) = materialize(MulAdd(α, A, B, β, C))
7574
materialize(M::MulAdd) = copy(instantiate(M))
7675
copy(M::MulAdd) = copyto!(similar(M), M)
7776

0 commit comments

Comments
 (0)