Layout
Index
MoYe.GenColMajorMoYe.GenRowMajorMoYe.LayoutBase.catBase.coalesceBase.getindexBase.sizeMoYe.blocked_productMoYe.complementMoYe.compositionMoYe.cosizeMoYe.depthMoYe.flattenMoYe.left_inverseMoYe.logical_divideMoYe.logical_productMoYe.make_layoutMoYe.make_layoutMoYe.raked_productMoYe.rankMoYe.right_inverseMoYe.tiled_divideMoYe.zipped_divideMoYe.@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 ofNmixes 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
4MoYe.@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,GenColMajororGenRowMajor
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 — TypeGenColMajormake_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 — TypeGenRowMajomake_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:_1MoYe.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)