Layout
Index
MoYe.GenColMajor
MoYe.GenRowMajor
MoYe.Layout
Base.cat
Base.coalesce
Base.getindex
Base.size
MoYe.blocked_product
MoYe.complement
MoYe.composition
MoYe.cosize
MoYe.depth
MoYe.flatten
MoYe.left_inverse
MoYe.logical_divide
MoYe.logical_product
MoYe.make_layout
MoYe.make_layout
MoYe.raked_product
MoYe.rank
MoYe.right_inverse
MoYe.tiled_divide
MoYe.zipped_divide
MoYe.@Layout
Constructors
MoYe.Layout
— TypeLayout{N, Shape, Stride}
A Layout
is a pair of Shape
and Stride
tuples. The Shape
tuple contains the number of elements in each dimension, and the Stride
tuple contains the number of elements to skip to get to the next element in each dimension.
Fields
shape
.stride
.
Indexing
A Layout
can be indexed with three types of indices:
Int
: a linear index in a column-major order.IntTuple
: a hierarchical index. It has the exact hierarchical structure as defined by theShape
.IntTuple
: a congruent index. A tuple ofN
mixes hierarchical and linear indices along each dimension.
Examples
julia> layout = Layout((4, (2, 2)), (2, (1, 8)));
julia> print_layout(ans)
(4, (2, 2)):(2, (1, 8))
1 2 3 4
+----+----+----+----+
1 | 1 | 2 | 9 | 10 |
+----+----+----+----+
2 | 3 | 4 | 11 | 12 |
+----+----+----+----+
3 | 5 | 6 | 13 | 14 |
+----+----+----+----+
4 | 7 | 8 | 15 | 16 |
+----+----+----+----+
julia> layout(6) # linear index
4
julia> layout((2,2)) # hierarchical index
4
julia> layout((2,(2,1))) # congruent index
4
MoYe.@Layout
— Macro@Layout(shape, stride=nothing)
Construct a static layout with the given shape and stride.
Arguments
shape
: a tuple of integers or a single integerstride
: a tuple of integers, a single integer,GenColMajor
orGenRowMajor
MoYe.make_layout
— Functionmake_layout(shape::IntTuple, stride::IntTuple)
make_layout(shape::IntTuple, major=GenColMajor)
Construct a layout with the given shape and stride. If the stride is not given, it is set to col-major compact stride. See alse GenColMajor
and GenRowMajor
.
make_layout(::Layouts...)
Concatenate layouts into a single layout.
Fundamentals
Base.size
— Methodsize(::Layout)
size(::Layout, i::Union{Int, StaticInt})
Get the cardinality of the domain of the layout. See also cosize
.
MoYe.rank
— Methodrank(::Layout)
rank(::Layout, i::Union{Int, StaticInt})
Get the rank, i.e., the dimensionality, of the layout.
MoYe.depth
— Methoddepth(::Layout)
depth(::Layout, i::Union{Int, StaticInt})
Get the depth of the hierarchy of the layout. For example, the depth of (1,2)
is 1, and the depth of ((1,2),3)
is 2.
MoYe.cosize
— Methodcosize(::Layout)
cosize(::Layout, i::Union{Int, StaticInt})
Get the cardinality of the codomain of the layout. See also size
.
Base.getindex
— Methodgetindex(layout::Layout, Is...)
Get the sub-layout of layout
with the given indices.
Compact Layout
MoYe.GenColMajor
— TypeGenColMajor
make_layout
uses this to create a col-major compact layout.
julia> make_layout(((1, (2, 4)), 1), MoYe.GenColMajor)
((1, (2, 4)), 1):((_1, (1, 2)), 8)
MoYe.GenRowMajor
— TypeGenRowMajo
make_layout
uses this to create a row-major compact layout.
julia> make_layout(((1, (2, 4)), 1), MoYe.GenRowMajor)
((1, (2, 4)), 1):((8, (4, 1)), _1)
Algebra
Concatenation
Base.cat
— Methodcat(::Layouts...)
Concatenate layouts into a single layout.
MoYe.make_layout
— Methodmake_layout(::Layouts...)
Concatenate layouts into a single layout.
Composition
MoYe.composition
— Functioncomposition(l1::Layout, l2::Layout)
Compose two layouts as composing two functions. You can use ∘
operator as well.
Examples
julia> make_layout(20, 2) ∘ make_layout((4, 5), (1, 4))
(4, 5):(2, 8)
julia> make_layout(20, 2) ∘ make_layout((4, 5), (5, 1))
(4, 5):(10, 2)
Complement
MoYe.complement
— Functioncomplement(l::Layout, cosize::IntType)
A complement layout of A
is a layout B
such that (A, B)
is a compact layout of size cosize
.
Inverse
MoYe.left_inverse
— Functionleft_inverse(layout::Layout)
Return the left inverse of layout
, i.e. a layout layout′
such that (layout′ ∘ layout)(i) == (i)
. The domain of layout′
is chosen to be the maximum continues squence of the domain of layout
.
MoYe.right_inverse
— Functionright_inverse(layout::Layout)
Return the right inverse of layout
, i.e. a layout layout′
such that (layout ∘ layout′)(i) == (i)
. The domain of layout′
is chosen to be the maximum continues squence of the codomain of layout
.
Product
MoYe.logical_product
— Functionlogical_product(A::Layout, B::Layout)
Compute the logical product of two layouts. Indexing through the first mode of the resulting layout corresponds to indexing through A
and indexing through the second mode corresponds to indexing through B
.
julia> tile = @Layout((2, 2), (1, 2));
julia> print_layout(tile)
(_2, _2):(_1, _2)
1 2
+---+---+
1 | 1 | 3 |
+---+---+
2 | 2 | 4 |
+---+---+
julia> matrix_of_tiles = @Layout((3, 4), (4, 1));
julia> print_layout(matrix_of_tiles)
(_3, _4):(_4, _1)
1 2 3 4
+----+----+----+----+
1 | 1 | 2 | 3 | 4 |
+----+----+----+----+
2 | 5 | 6 | 7 | 8 |
+----+----+----+----+
3 | 9 | 10 | 11 | 12 |
+----+----+----+----+
julia> print_layout(logical_product(tile, matrix_of_tiles))
((_2, _2), (_3, _4)):((_1, _2), (_16, _4))
1 2 3 4 5 6 7 8 9 10 11 12
+----+----+----+----+----+----+----+----+----+----+----+----+
1 | 1 | 17 | 33 | 5 | 21 | 37 | 9 | 25 | 41 | 13 | 29 | 45 |
+----+----+----+----+----+----+----+----+----+----+----+----+
2 | 2 | 18 | 34 | 6 | 22 | 38 | 10 | 26 | 42 | 14 | 30 | 46 |
+----+----+----+----+----+----+----+----+----+----+----+----+
3 | 3 | 19 | 35 | 7 | 23 | 39 | 11 | 27 | 43 | 15 | 31 | 47 |
+----+----+----+----+----+----+----+----+----+----+----+----+
4 | 4 | 20 | 36 | 8 | 24 | 40 | 12 | 28 | 44 | 16 | 32 | 48 |
+----+----+----+----+----+----+----+----+----+----+----+----+
MoYe.blocked_product
— Functionblocked_product(tile::Layout, matrix_of_tiles::Layout, coalesce_result::Bool=false)
Compute the blocked product of two layouts. Indexing through the first mode of the resulting layout corresponds to indexing through the cartesian product of the first mode of tile
and the first mode of matrix_of_tiles
. Indexing through the second mode is similar. If coalesce_result
is true, then the result is coalesced.
julia> tile = @Layout (2, 2);
julia> matrix_of_tiles = @Layout (3, 4) (4, 1);
julia> print_layout(blocked_product(tile, matrix_of_tiles))
((_2, _3), (_2, _4)):((_1, _16), (_2, _4))
1 2 3 4 5 6 7 8
+----+----+----+----+----+----+----+----+
1 | 1 | 3 | 5 | 7 | 9 | 11 | 13 | 15 |
+----+----+----+----+----+----+----+----+
2 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 |
+----+----+----+----+----+----+----+----+
3 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 |
+----+----+----+----+----+----+----+----+
4 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 |
+----+----+----+----+----+----+----+----+
5 | 33 | 35 | 37 | 39 | 41 | 43 | 45 | 47 |
+----+----+----+----+----+----+----+----+
6 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 |
+----+----+----+----+----+----+----+----+
MoYe.raked_product
— Functionraked_product(tile::Layout, matrix_of_tiles::Layout, coalesce_result::Bool=false)
The tile is shattered or interleaved with the matrix of tiles.
julia> tile = @Layout (2, 2) (1, 2);
julia> matrix_of_tiles = @Layout (3, 4) (4, 1);
julia> print_layout(raked_product(tile, matrix_of_tiles))
((_3, _2), (_4, _2)):((_16, _1), (_4, _2))
1 2 3 4 5 6 7 8
+----+----+----+----+----+----+----+----+
1 | 1 | 5 | 9 | 13 | 3 | 7 | 11 | 15 |
+----+----+----+----+----+----+----+----+
2 | 17 | 21 | 25 | 29 | 19 | 23 | 27 | 31 |
+----+----+----+----+----+----+----+----+
3 | 33 | 37 | 41 | 45 | 35 | 39 | 43 | 47 |
+----+----+----+----+----+----+----+----+
4 | 2 | 6 | 10 | 14 | 4 | 8 | 12 | 16 |
+----+----+----+----+----+----+----+----+
5 | 18 | 22 | 26 | 30 | 20 | 24 | 28 | 32 |
+----+----+----+----+----+----+----+----+
6 | 34 | 38 | 42 | 46 | 36 | 40 | 44 | 48 |
+----+----+----+----+----+----+----+----+
Division
MoYe.logical_divide
— Functionlogical_divide(layout::Layout, tile::Tile)
Gather the elements of layout
along all modes into blocks according to tile
.
julia> raked_prod = @Layout ((3, 2), (4, 2)) ((16, 1), (4, 2));
julia> print_layout(raked_prod)
((_3, _2), (_4, _2)):((_16, _1), (_4, _2))
1 2 3 4 5 6 7 8
+----+----+----+----+----+----+----+----+
1 | 1 | 5 | 9 | 13 | 3 | 7 | 11 | 15 |
+----+----+----+----+----+----+----+----+
2 | 17 | 21 | 25 | 29 | 19 | 23 | 27 | 31 |
+----+----+----+----+----+----+----+----+
3 | 33 | 37 | 41 | 45 | 35 | 39 | 43 | 47 |
+----+----+----+----+----+----+----+----+
4 | 2 | 6 | 10 | 14 | 4 | 8 | 12 | 16 |
+----+----+----+----+----+----+----+----+
5 | 18 | 22 | 26 | 30 | 20 | 24 | 28 | 32 |
+----+----+----+----+----+----+----+----+
6 | 34 | 38 | 42 | 46 | 36 | 40 | 44 | 48 |
+----+----+----+----+----+----+----+----+
julia> subtile = (Layout(2, 3), Layout(2, 4)); # gather 2 elements with stride 3 along the first mode
# and 2 elements with stride 4 along the second mode
julia> print_layout(logical_divide(raked_prod, subtile))
(((1, 2), ((3, 1), (1, 1))), ((1, 2), ((4, 1), (1, 1)))):(((48, 1), ((_16, _1), (48, 2))), ((16, 2), ((_4, _2), (16, 4))))
1 2 3 4 5 6 7 8
+----+----+----+----+----+----+----+----+
1 | 1 | 3 | 5 | 7 | 9 | 11 | 13 | 15 |
+----+----+----+----+----+----+----+----+
2 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 |
+----+----+----+----+----+----+----+----+
3 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 |
+----+----+----+----+----+----+----+----+
4 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 |
+----+----+----+----+----+----+----+----+
5 | 33 | 35 | 37 | 39 | 41 | 43 | 45 | 47 |
+----+----+----+----+----+----+----+----+
6 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 |
+----+----+----+----+----+----+----+----+
MoYe.zipped_divide
— Functionzipped_divide(layout::Layout, tile)
Compute the logical division of layout
by tile
, then group the resulting subtiles into the first mode and the rest into the second mode.
julia> raked_prod = @Layout ((3, 2), (4, 2)) ((16, 1), (4, 2));
julia> print_layout(raked_prod)
((_3, _2), (_4, _2)):((_16, _1), (_4, _2))
1 2 3 4 5 6 7 8
+----+----+----+----+----+----+----+----+
1 | 1 | 5 | 9 | 13 | 3 | 7 | 11 | 15 |
+----+----+----+----+----+----+----+----+
2 | 17 | 21 | 25 | 29 | 19 | 23 | 27 | 31 |
+----+----+----+----+----+----+----+----+
3 | 33 | 37 | 41 | 45 | 35 | 39 | 43 | 47 |
+----+----+----+----+----+----+----+----+
4 | 2 | 6 | 10 | 14 | 4 | 8 | 12 | 16 |
+----+----+----+----+----+----+----+----+
5 | 18 | 22 | 26 | 30 | 20 | 24 | 28 | 32 |
+----+----+----+----+----+----+----+----+
6 | 34 | 38 | 42 | 46 | 36 | 40 | 44 | 48 |
+----+----+----+----+----+----+----+----+
julia> subtile = (@Layout(2, 3), @Layout(2, 4)); # gather 2 elements with stride 3 along the first mode and 2 elements with stride 4 along the second mode
julia> print_layout(zipped_divide(raked_prod, subtile))
((_2, _2), (_3, _4)):((_1, _2), (_16, _4))
1 2 3 4 5 6 7 8 9 10 11 12
+----+----+----+----+----+----+----+----+----+----+----+----+
1 | 1 | 17 | 33 | 5 | 21 | 37 | 9 | 25 | 41 | 13 | 29 | 45 |
+----+----+----+----+----+----+----+----+----+----+----+----+
2 | 2 | 18 | 34 | 6 | 22 | 38 | 10 | 26 | 42 | 14 | 30 | 46 |
+----+----+----+----+----+----+----+----+----+----+----+----+
3 | 3 | 19 | 35 | 7 | 23 | 39 | 11 | 27 | 43 | 15 | 31 | 47 |
+----+----+----+----+----+----+----+----+----+----+----+----+
4 | 4 | 20 | 36 | 8 | 24 | 40 | 12 | 28 | 44 | 16 | 32 | 48 |
+----+----+----+----+----+----+----+----+----+----+----+----+
MoYe.tiled_divide
— Functiontiled_divide(layout::Layout, tile)
Similar to zipped_divide
, but upack the second mode into multiple modes.
Miscellaneous
Base.coalesce
— Functioncoalesce(layout::Layout)
Coalesce the layout by merging adjacent dimensions with stride 1.
Examples
julia> layout = @Layout (2, (1, 6)) (1, (6, 2))
(_2, (_1, _6)):(_1, (_6, _2))
julia> print(coalesce(layout))
_12:_1
MoYe.flatten
— Methodflatten(layout::Layout)
Remove the hierarchy of the layout and make it a flat layout.
Examples
julia> layout = make_layout(((4, 3), 1), ((3, 1), 0))
((4, 3), 1):((3, 1), 0)
julia> print(flatten(layout))
(4, 3, 1):(3, 1, 0)