A Julia package for describing array layouts and more general fast linear algebra
This package implements a trait-based framework for describing array layouts such as column
major, row major, etc. that can be dispatched 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:
julia> using ArrayLayouts, LinearAlgebra
julia> A = randn(10_000,10_000); x = randn(10_000); y = similar(x);
julia> V = view(Symmetric(A),:,:)';
julia> @time mul!(y, A, x); # Julia does not recognize that V is symmetric
0.040255 seconds (4 allocations: 160 bytes)
julia> @time muladd!(1.0, V, x, 0.0, y); # ArrayLayouts does and is 3x faster as it calls BLAS
0.017677 seconds (4 allocations: 160 bytes)
The package is based on assigning a MemoryLayout
to every array, which is used for
dispatch. For example,
julia> MemoryLayout(A) # Each column of A is column major, and columns stored in order
DenseColumnMajor()
julia> MemoryLayout(view(A, 1:3,:)) # Each column of A is column major
ColumnMajor()
julia> MemoryLayout(V) # A symmetric version, whose storage is DenseColumnMajor
SymmetricLayout{DenseColumnMajor}()
This is then used by muladd!(α, A, B, β, C)
, ArrayLayouts.lmul!(A, B)
, and
ArrayLayouts.rmul!(A, B)
to lower to the correct BLAS calls via lazy objects
MulAdd(α, A, B, β, C)
, Lmul(A, B)
, Rmul(A, B)
which are materialized, in analogy to
Base.Broadcasted
.
Note there is also a higher level function mul(A, B)
that materializes via Mul(A, B)
,
which uses the layout of A
and B
to further reduce to either MulAdd
, Lmul
, and
Rmul
.