# ArrayLayouts.jl

Documentation for ArrayLayouts.jl

`ArrayLayouts.AbstractStridedLayout`

— Type`AbstractStridedLayout`

is an abstract type whose subtypes are returned by `MemoryLayout(A)`

if an array `A`

has storage laid out at regular offsets in memory, and which can therefore be passed to external C and Fortran functions expecting this memory layout.

Julia's internal linear algebra machinery will automatically (and invisibly) dispatch to BLAS and LAPACK routines if the memory layout is BLAS compatible and the element type is a `Float32`

, `Float64`

, `ComplexF32`

, or `ComplexF64`

. In this case, one must implement the strided array interface, which requires overrides of `strides(A::MyMatrix)`

and `unknown_convert(::Type{Ptr{T}}, A::MyMatrix)`

.

The complete list of more specialised types is as follows:

```
julia> using ArrayLayouts, AbstractTrees
julia> AbstractTrees.children(x::Type) = subtypes(x)
julia> print_tree(AbstractStridedLayout)
AbstractStridedLayout
├─ AbstractDecreasingStrides
│ └─ AbstractRowMajor
│ ├─ DenseRowMajor
│ └─ RowMajor
├─ AbstractIncreasingStrides
│ ├─ AbstractColumnMajor
│ │ ├─ ColumnMajor
│ │ └─ DenseColumnMajor
│ ├─ DecreasingStrides
│ └─ IncreasingStrides
├─ StridedLayout
└─ UnitStride
julia> Base.show_supertypes(AbstractStridedLayout)
AbstractStridedLayout <: MemoryLayout <: Any
```

`ArrayLayouts.ColumnMajor`

— Type`ColumnMajor()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory as a column major array, so that `stride(A,1) == 1`

and `stride(A,i) ≥ size(A,i-1) * stride(A,i-1)`

for `2 ≤ i ≤ ndims(A)`

.

Arrays with `ColumnMajor`

memory layout must conform to the `DenseArray`

interface.

`ArrayLayouts.ConjPtr`

— Type`ConjPtr{T}`

A memory address referring to complex conjugated data of type T. However, there is no guarantee that the memory is actually valid, or that it actually represents the complex conjugate of data of the specified type.

`ArrayLayouts.DecreasingStrides`

— Type`DecreasingStrides()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory as a strided array with decreasing strides, so that `stride(A,ndims(A)) ≥ 1`

and stride(A,i) ≥ size(A,i+1) * stride(A,i+1)`for`

1 ≤ i ≤ ndims(A)-1`.

`ArrayLayouts.DenseColumnMajor`

— Type`DenseColumnMajor()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory equivalent to an `Array`

, so that `stride(A,1) == 1`

and `stride(A,i) ≡ size(A,i-1) * stride(A,i-1)`

for `2 ≤ i ≤ ndims(A)`

. In particular, if `A`

is a matrix then `strides(A) ==`

(1, size(A,1))`.

Arrays with `DenseColumnMajor`

memory layout must conform to the `DenseArray`

interface.

`ArrayLayouts.DenseRowMajor`

— Type`DenseRowMajor()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory as a row major array with dense entries, so that `stride(A,ndims(A)) == 1`

and `stride(A,i) ≡ size(A,i+1) * stride(A,i+1)`

for `1 ≤ i ≤ ndims(A)-1`

. In particular, if `A`

is a matrix then `strides(A) ==`

(size(A,2), 1)`.

`ArrayLayouts.Dot`

— Type`Dot(A, B)`

is a lazy version of `dot(A, B)`

, designed to support materializing based on `MemoryLayout`

.

`ArrayLayouts.Dotu`

— Type`Dotu(A, B)`

is a lazy version of `BLAS.dotu(A, B)`

, designed to support materializing based on `MemoryLayout`

.

`ArrayLayouts.DualLayout`

— TypeDualLayout{ML<:MemoryLayout}()

represents a row-vector that should behave like a dual-vector, that is multiplication times a column-vector returns a scalar.

`ArrayLayouts.HermitianLayout`

— Type`HermitianLayout(layout, uplo)`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory as a hermitianized version of `layout`

, where the entries used are dictated by the `uplo`

, which can be `'U'`

or `L'`

.

A matrix that has memory layout `HermitianLayout(layout, uplo)`

must overrided `hermitiandata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] == B[k,j]`

for `j ≥ k`

if `uplo == 'U'`

(`j ≤ k`

if `uplo == 'L'`

) and `A[k,j] == conj(B[j,k])`

for `j < k`

if `uplo == 'U'`

(`j > k`

if `uplo == 'L'`

).

`ArrayLayouts.IncreasingStrides`

— Type`IncreasingStrides()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory as a strided array with increasing strides, so that `stride(A,1) ≥ 1`

and `stride(A,i) ≥ size(A,i-1) * stride(A,i-1)`

for `2 ≤ i ≤ ndims(A)`

.

`ArrayLayouts.LULayout`

— Type`LULayout{SLAY}()`

represents a Packed QR factorization whose factors are stored with layout SLAY and τ stored with layout TLAY

`ArrayLayouts.LowerTriangularLayout`

— Type`LowerTriangularLayout(layout)`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory equivalent to a `LowerTriangular(B)`

where `B`

satisfies `MemoryLayout(B) == layout`

.

A matrix that has memory layout `LowerTriangularLayout(layout)`

must overrided `triangulardata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] ≡ zero(eltype(A))`

for `j > k`

and `A[k,j] ≡ B[k,j]`

for `j ≤ k`

.

Moreover, `transpose(A)`

and `adjoint(A)`

must return a matrix that has memory layout `UpperTriangularLayout`

.

`ArrayLayouts.MemoryLayout`

— Method`MemoryLayout(A)`

specifies the layout in memory for an array `A`

. When you define a new `AbstractArray`

type, you can choose to override `MemoryLayout`

to indicate how an array is stored in memory. For example, if your matrix is column major with `stride(A,2) == size(A,1)`

, then override as follows:

`MemoryLayout(::MyMatrix) = DenseColumnMajor()`

The default is `UnknownLayout()`

to indicate that the layout in memory is unknown.

Julia's internal linear algebra machinery will automatically (and invisibly) dispatch to BLAS and LAPACK routines if the memory layout is compatible.

`ArrayLayouts.QRCompactWYLayout`

— TypeQRCompactWYLayout{SLAY,TLAY}()

represents a Compact-WY QR factorization whose factors are stored with layout SLAY and τ stored with layout TLAY

`ArrayLayouts.QRPackedLayout`

— Type`QRPackedLayout{SLAY,TLAY}()`

represents a Packed QR factorization whose factors are stored with layout SLAY and τ stored with layout TLAY

`ArrayLayouts.RangeCumsum`

— Type`RangeCumsum(range)`

represents the cumsum of a `AbstractRange`

.

`ArrayLayouts.RowMajor`

— Type`RowMajor()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage in memory as a row major array, so that `stride(A,ndims(A)) == 1`

and stride(A,i) ≥ size(A,i+1) * stride(A,i+1)`for`

1 ≤ i ≤ ndims(A)-1`.

If `A`

is a matrix with `RowMajor`

memory layout, then `transpose(A)`

should return a matrix whose layout is `ColumnMajor`

.

`ArrayLayouts.ScalarLayout`

— Type`ScalarLayout()`

is returned by `MemoryLayout(A)`

if A is a scalar, which does not live in memory

`ArrayLayouts.StridedLayout`

— Type`StridedLayout()`

is returned by `MemoryLayout(A)`

if an array `A`

has storage laid out at regular offsets in memory. `Array`

s with `StridedLayout`

must conform to the `DenseArray`

interface.

`ArrayLayouts.SymmetricLayout`

— Type`SymmetricLayout{layout}()`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory as a symmetrized version of `layout`

, where the entries used are dictated by the `uplo`

, which can be `'U'`

or `L'`

.

A matrix that has memory layout `SymmetricLayout(layout, uplo)`

must overrided `symmetricdata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] == B[k,j]`

for `j ≥ k`

if `uplo == 'U'`

(`j ≤ k`

if `uplo == 'L'`

) and `A[k,j] == B[j,k]`

for `j < k`

if `uplo == 'U'`

(`j > k`

if `uplo == 'L'`

).

`ArrayLayouts.UnitLowerTriangularLayout`

— Type`UnitLowerTriangularLayout(ML::MemoryLayout)`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory equivalent to a `UnitLowerTriangular(B)`

where `B`

satisfies `MemoryLayout(B) == layout`

.

A matrix that has memory layout `UnitLowerTriangularLayout(layout)`

must overrided `triangulardata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] ≡ zero(eltype(A))`

for `j > k`

, `A[k,j] ≡ one(eltype(A))`

for `j == k`

, `A[k,j] ≡ B[k,j]`

for `j < k`

.

Moreover, `transpose(A)`

and `adjoint(A)`

must return a matrix that has memory layout `UnitUpperTriangularLayout`

.

`ArrayLayouts.UnitStride`

— Type`UnitStride{D}()`

is returned by `MemoryLayout(A)`

for arrays of `ndims(A) >= 3`

which have `stride(A,D) == 1`

.

`UnitStride{1}`

is weaker than `ColumnMajor`

in that it does not demand that the other strides are increasing, hence it is not a subtype of `AbstractIncreasingStrides`

. To ensure that `stride(A,1) == 1`

, you may dispatch on `Union{UnitStride{1}, AbstractColumnMajor}`

to allow for both options. (With complex numbers, you may also need their `ConjLayout`

versions.)

Likewise, both `UnitStride{ndims(A)}`

and `AbstractRowMajor`

have `stride(A, ndims(A)) == 1`

.

`ArrayLayouts.UnitUpperTriangularLayout`

— Type`UnitUpperTriangularLayout(ML::MemoryLayout)`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory equivalent to a `UpperTriangularLayout(B)`

where `B`

satisfies `MemoryLayout(B) == ML`

.

A matrix that has memory layout `UnitUpperTriangularLayout(layout)`

must overrided `triangulardata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] ≡ B[k,j]`

for `j > k`

, `A[k,j] ≡ one(eltype(A))`

for `j == k`

, `A[k,j] ≡ zero(eltype(A))`

for `j < k`

.

Moreover, `transpose(A)`

and `adjoint(A)`

must return a matrix that has memory layout `UnitLowerTriangularLayout`

.

`ArrayLayouts.UnknownLayout`

— Type`UnknownLayout()`

is returned by `MemoryLayout(A)`

if it is unknown how the entries of an array `A`

are stored in memory.

`ArrayLayouts.UpperTriangularLayout`

— Type`UpperTriangularLayout(ML::MemoryLayout)`

is returned by `MemoryLayout(A)`

if a matrix `A`

has storage in memory equivalent to a `UpperTriangularLayout(B)`

where `B`

satisfies `MemoryLayout(B) == ML`

.

A matrix that has memory layout `UpperTriangularLayout(layout)`

must overrided `triangulardata(A)`

to return a matrix `B`

such that `MemoryLayout(B) == layout`

and `A[k,j] ≡ B[k,j]`

for `j ≥ k`

and `A[k,j] ≡ zero(eltype(A))`

for `j < k`

.

Moreover, `transpose(A)`

and `adjoint(A)`

must return a matrix that has memory layout `LowerTriangularLayout`

.

`ArrayLayouts.colsupport`

— Method`colsupport(A, j)`

Return an iterator containing the row indices of the possible non-zero entries in the `j`

-th column of `A`

.

`ArrayLayouts.colsupport`

— Method`colsupport(A)`

Return an iterator containing the row indices of the possible non-zero entries in `A`

.

`ArrayLayouts.indextype`

— Methodindextype(A)

gives the expected index type for an array, or array-like object. For example, if it is vector-like it will return `Tuple{Int}`

, or if it is matrix-like it will return `Tuple{Int,Int}`

. Other types may have non-integer based indexing.

`ArrayLayouts.mulreduce`

— Methodmulreduce(M::Mul)

returns a lower level lazy multiplication object such as `MulAdd`

, `Lmul`

or `Rmul`

. The Default is `MulAdd`

. Note that the lowered type must overload `copyto!`

and `copy`

.

`ArrayLayouts.rowsupport`

— Method`rowsupport(A, k)`

Return an iterator containing the column indices of the possible non-zero entries in the `k`

-th row of `A`

.

`ArrayLayouts.rowsupport`

— Method`rowsupport(A)`

Return an iterator containing the column indices of the possible non-zero entries in `A`

.