-
Notifications
You must be signed in to change notification settings - Fork 29
CXX Interface
MArray is a convenient interface for accessing and manipulating tensors in C++. It is distributed as a part of TBLIS, and is included tblis
namespace as well as the original MArray
namespace. MArray provides several categories of tensor utilities:
- Container and view classes (both fixed and variable dimension).
- Multi-dimensional iteration helpers.
- Simple tensor algorithms (such as rotation).
- Expression templates for vectorized element-wise operations on tensors.
T
is the type of individual tensor elements. Allocator
is optional and defaults to std::allocator<T>
.
-
Constructors
-
varray()
Create a 0-dimensional tensor. While a zero-dimensional tensor should technically be a scalar (1 element), this instance has no accessible elements. -
varray(lengths)
Create a tensor with the given lengths (the number of elements along each direction). The number of dimensions is automatically determined. The data is zero-initialized.lengths
is a braced init list or container (vector, array, etc.) of integral types. -
varray(lengths, val)
Like above but initialize elements to valueval
-
varray(lengths, uninitialized)
Like above but do not initialize elements.uninitialized
is a global variable in theMArray
namespace. -
varray(lengths, layout)
Create a zero-initialized tensor with the specified data layout, eitherROW_MAJOR
orCOLUMN_MAJOR
. -
varray(lengths, val, layout)
Create a tensor with the specified data layout and elements initialized toval
. -
varray(lengths, uninitialized, layout)
Create an uninitialized tensor with the specified data layout. -
varray(other)
Create a copy of the tensorother
, which can be either a container or a view. -
varray(other, layout)
Create a copy of the tensorother
, with the copied data in the specified layout.
-
-
Reinitialization
-
reset(...)
Takes the same arguments as the constructor. All current data is lost.
-
-
Resizing
-
resize(lengths)
Resize the current tensor and retain any current data. The number of lengths must match the current dimension. Any new elements not corresponding to current data are zero-initialized. -
resize(lengths, val)
Like above but initialize any new elements toval
.
-
-
Push/Pop/Front/Back
-
push_back(val)
(1-dimensional tensors only) Appendval
to the end of the tensor (vector), increasing the length by 1. -
push_back(dim, other)
Increase the length along dimensiondim
by 1. The new elements are given by the elements of tensorother
.other
must have one fewer dimension that the current tensor and the lengths ofother
must match the current lengths, skipping dimensiondim
. -
pop_back()
(1-dimensional tensors only) Remove the last element of the tensor, decreasing the length by 1. -
pop_back(dim)
Decrease the length along dimensiondim
by 1. -
cfront()
(1-dimensional tensors only) Return a const-qualified reference to the first element. -
front()
(1-dimensional tensors only) Return a reference to the first element. -
cback()
(1-dimensional tensors only) Return a const-qualified reference to the last element. -
back()
(1-dimensional tensors only) Return a reference to the last element. -
cfront(dim)
Return a read-only view of the first sub-tensor along dimensiondim
. -
front(dim)
Return a view of the first sub-tensor along dimensiondim
. -
cback(dim)
Return a read-only view of the last sub-tensor along dimensiondim
. -
back(dim)
Return a view of the last sub-tensor along dimensiondim
.
-
-
Swap
-
swap(other)
Swap the dimension, lengths, and contents of this tensor with tensorother
, which must be precisely the same type.
-
-
Assignment
-
operator=(other)
Copy the elements of tensorother
into this tensor. The dimension and lengths ofother
must match the current tensor. -
operator=(val)
Set each element of this tensor toval
.
-
-
Views
-
cview()
Return a read-only view of this tensor. -
view()
Return a view of this tensor. The view will be read-only ifthis
is const-qualified. -
cview(other)
Free function that is equivalent toother.cview()
. -
view(other)
Free function that is equivalent toother.view()
. -
fix<N>()
Return a fixed-dimension view. The current dimension must equalN
. -
fix<N>(other)
Free function equivalent toother.fix<N>()
. -
shifted(shifts)
Return a view where the starting element in each dimension is given byshifts
, which can be a braced init list or contained of integral types. Note that shifted views may reference non-existent elements; it is the user's responsibility to ensure that views are well-defined. -
shifted(dim, shift)
Return a view that is shifted only along dimensiondim
. -
shifted_down(dim)
Equivalent tox.shifted(dim, x.length(dim))
. -
shifted_up(dim)
Equivalent tox.shifted(dim, -x.length(dim))
. -
permuted(perm)
Return a permuted view. For example:auto B = A.permuted({2,0,1})
impliesB(z,x,y) == A(x,y,z)
. -
lowered(split)
Return a view with possibly lower dimensionality. Thei
th dimension of the view is the aggregate of dimensionssplit[i],...,split[i+1]-1
. Thus the number of dimensions in the new view is the number of splits minus one.split
must be in ascending order. -
reversed()
Return a view where the order of elements along each dimension is reversed. -
reversed(dim)
Return a view where the order of elements along dimensiondim
is reversed.
-
-
Element Access
-
operator()(idx0, idx1, ...)
Return a reference to the element with the specified indices. All parameters must be integral types. -
operator()(idx_or_slice0, idx_or_slice1, ...)
Return a view of the specified sub-tensor. Eachidx_or_sliceN
may be either an integral type specifying that a dimension is to be fixed, arange
object giving a range of elements to include along a dimension, orslice::all
which specifies that all elements are to be included along a dimension. At least one parameter must not be an integral type, and the number of dimensions in the resulting view is given by the number of non-integral (range
orall
) parameters.
-
-
Iteration
-
for_each_element(func)
Callfunc
for each element in the tensor.func
must be callable as eitherfunc(val&)
orfunc(val&, idx)
whereval&
is a reference to an element of the tensor andidx
is astd::vector<len_type>
of indices. -
for_each_element<N>(func)
Callfunc
for each element in the tensor.func
must be callable as eitherfunc(val&)
orfunc(val&, idx0, ..., idxN-1)
whereval&
is a reference to an element of the tensor andidxN
is the index along the Nth dimension.N
must equal the number of dimensions.
-
-
Structure and Data
-
cdata()
Return a const-qualified pointer to the element at index(0,...,0)
. -
data()
Return a pointer to the element at index(0,...,0)
. -
length(dim)
Return the length of dimensiondim
. -
lengths()
Return the lengths of all dimensions (as a read-only container). -
stride(dim)
Return the stride of dimensiondim
. -
strides()
Return the strides of all dimensions (as a read-only container). -
dimension()
Return the number of dimensions.
-
-
Printing
- Tensors can be printed in a hierarchical C array-like format using
operator<<
.
- Tensors can be printed in a hierarchical C array-like format using
-
Static Helper Functions
-
strides(lengths)
Return the strides for a tensor with the given lengths and the default layout. -
strides(lengths, layout)
Return the strides for a tensor with the given lengths and the given layout. -
size(lengths)
Return the number of elements in a tensor with the given lengths. -
is_contiguous(lengths, strides)
Returns astd::pair<bool,stride_type>
. The first member is true if the tensor specified by the given lengths and strides is contiguous, i.e. elements are arranged consecutively in memory. The second member gives the total number of elements if the tensor is contiguous.
-
T
is the type of individual tensor elements, if it is const-qualified then the view is read-only.
-
Constructors
-
varray_view()
Create a 0-dimensional view. While a zero-dimensional tensor should technically be a scalar (1 element), this instance has no accessible elements. -
varray_view(lengths, ptr)
Create a view with the given lengths and the given base pointer (pointer to the element with all zero indices). The number of dimensions is automatically determined. -
varray_view(lengths, ptr, layout)
Create a view with the specified data layout, eitherROW_MAJOR
orCOLUMN_MAJOR
. -
varray_view(lengths, ptr, strides)
Create a view with the specified data structure given bylengths
andstrides
.strides[i]
is the distance in memory between elements along dimensioni
. -
varray_view(other)
Create a view of the tensorother
, which can be either a container or another view.
-
-
Reinitialization
-
reset(...)
Takes the same arguments as the constructor.
-
-
Front/Back
-
Assignment
-
Views
-
Element Access
-
Iteration
-
Structure and Data
-
Printing
-
Static Helper Functions
- All functions in these categories are the same as for
varray<T>
. (Note that the Push/Pop functions are not included).
- All functions in these categories are the same as for
-
Mutation
-
shift(shifts)
Shift the current view in-place, as inshifted(shifts)
. -
shift(dim, shift)
Shift the current view in-place, as inshifted(dim, shift)
. -
shift_down(dim)
Shift the current view in-place, as inshifted_down(dim)
. -
shift_up(dim)
Shift the current view in-place, as inshift_up(dim)
. -
permute(perm)
Permute the current view in-place, as inpermuted(perm)
. -
lower(splits)
Replace the current view with a lower-dimensional view, as inlowered(splits)
. -
reverse()
Reverse each dimension of the view, as inreversed()
. -
reverse(dim)
Reverse dimensiondim
of the view, as inreversed(dim)
. -
data(ptr)
Change the base pointer. The old pointer is returned. -
length(dim, len)
Change the length for dimensiondim
. The old length is returned. -
stride(dim, str)
Change the stride for dimensiondim
. The old stride is returned.
-
-
Swap
-
swap(other)
Swap the dimension, lengths, and pointer of this view withother
, which must be precisely the same type.
-
T
is the type of individual tensor elements. N
is the number of dimensions (> 0). Allocator
is optional and defaults to std::allocator<T>
.
matrix<T,Allocator>
is a synonym for marray<T,2,Allocator>
and row<T,Allocator>
is a synonym for marray<T,1,Allocator>
.
-
Constructors
-
marray()
Create a tensor with all lengths equal to zero; it has no accessible elements. -
marray(lengths)
Create a tensor with the given lengths (the number of elements along each direction). The number of lengths must equalN
. The data is zero-initialized.lengths
is a braced init list or container (vector, array, etc.) of integral types. -
marray(lengths, val)
Like above but initialize elements to valueval
-
marray(lengths, uninitialized)
Like above but do not initialize elements.uninitialized
is a global variable in theMArray
namespace. -
marray(lengths, layout)
Create a zero-initialized tensor with the specified data layout, eitherROW_MAJOR
orCOLUMN_MAJOR
. -
marray(lengths, val, layout)
Create a tensor with the specified data layout and elements initialized toval
. -
marray(lengths, uninitialized, layout)
Create an uninitialized tensor with the specified data layout. -
marray(other)
Create a copy of the tensorother
, which can be either a container or a view. -
marray(other, layout)
Create a copy of the tensorother
, with the copied data in the specified layout. -
marray(nested-init-list)
Create a tensor with elements and lengths given bynested-init-list
, which must be a nested braced init list withN
levels. This constructor can also be invoked by using assignment initialization, e.g.marray<int,2> M = {{0, 1}, {2, 3}}
. Note that for 1-dimensional tensors this constructor is ambiguous withmarray(lengths)
. -
marray(nested-init-list, layout)
Same as above but use the specified layout.
-
-
Reinitialization
-
reset(...)
Takes the same arguments as the constructor. All current data is lost.
-
-
Resizing
-
resize(lengths)
Resize the current tensor and retain any current data. The number of lengths must match the current dimension. Any new elements not corresponding to current data are zero-initialized. -
resize(lengths, val)
Like above but initialize any new elements toval
.
-
-
Push/Pop/Front/Back
-
push_back(val)
(1-dimensional tensors only) Appendval
to the end of the tensor (vector), increasing the length by 1. -
push_back(dim, other)
Increase the length along dimensiondim
by 1. The new elements are given by the elements of tensorother
.other
must have one fewer dimension that the current tensor and the lengths ofother
must match the current lengths, skipping dimensiondim
. -
push_back<dim>(other)
Same as above. -
pop_back()
(1-dimensional tensors only) Remove the last element of the tensor, decreasing the length by 1. -
pop_back(dim)
Decrease the length along dimensiondim
by 1. -
pop_back<dim>()
Same as above. -
cfront()
(1-dimensional tensors only) Return a const-qualified reference to the first element. -
front()
(1-dimensional tensors only) Return a reference to the first element. -
cback()
(1-dimensional tensors only) Return a const-qualified reference to the last element. -
back()
(1-dimensional tensors only) Return a reference to the last element. -
cfront(dim)
Return a read-only view of the first sub-tensor along dimensiondim
. -
front(dim)
Return a view of the first sub-tensor along dimensiondim
. -
cback(dim)
Return a read-only view of the last sub-tensor along dimensiondim
. -
back(dim)
Return a view of the last sub-tensor along dimensiondim
. -
cfront<dim>()
Return a read-only view of the first sub-tensor along dimensiondim
. -
front<dim>()
Return a view of the first sub-tensor along dimensiondim
. -
cback<dim>()
Return a read-only view of the last sub-tensor along dimensiondim
. -
back<dim>()
Return a view of the last sub-tensor along dimensiondim
.
-
-
Swap
-
swap(other)
Swap the dimension, lengths, and contents of this tensor with tensorother
, which must be precisely the same type.
-
-
Assignment
-
operator=(other)
Copy the elements of tensorother
into this tensor. The dimension and lengths ofother
must match the current tensor. -
operator=(val)
Set each element of this tensor toval
. -
operator=(nested-init-list)
Assign the elements of this tensor as in the constructor version. The lengths of the braced init lists must match the current lengths. -
operator=(expression)
Assign the elements of this tensor from the given element-wise tensor expression. See Expression Templates. -
operator+=(expression)
Modify the elements of this tensor from the given element-wise tensor expression. See Expression Templates. -
operator-=(expression)
Modify the elements of this tensor from the given element-wise tensor expression. See Expression Templates. -
operator*=(expression)
Modify the elements of this tensor from the given element-wise tensor expression. See Expression Templates. -
operator/=(expression)
Modify the elements of this tensor from the given element-wise tensor expression. See Expression Templates.
-
-
Comparison
-
operator==(other)
Return true if this tensor andother
are the same size and shape and have the same elements. -
operator!=(other)
Return!(*this == other)
.
-
-
Views
-
cview()
Return a read-only view of this tensor. -
view()
Return a view of this tensor. The view will be read-only ifthis
is const-qualified. -
cview(other)
Free function that is equivalent toother.cview()
. -
view(other)
Free function that is equivalent toother.view()
. -
vary(other)
Free function that returns a variable-dimension view ofother
. -
shifted(shifts)
Return a view where the starting element in each dimension is given byshifts
, which can be a braced init list or contained of integral types. Note that shifted views may reference non-existent elements; it is the user's responsibility to ensure that views are well-defined. -
shifted(dim, shift)
Return a view that is shifted only along dimensiondim
. -
shifted_down(dim)
Equivalent tox.shifted(dim, x.length(dim))
. -
shifted_up(dim)
Equivalent tox.shifted(dim, -x.length(dim))
. -
shifted<dim>(shift)
Return a view that is shifted only along dimensiondim
. -
shifted_down<dim>()
Equivalent tox.shifted(dim, x.length(dim))
. -
shifted_up<dim>()
Equivalent tox.shifted(dim, -x.length(dim))
. -
permuted(perm)
Return a permuted view. For example:auto B = A.permuted({2,0,1})
impliesB(z,x,y) == A(x,y,z)
. -
transposed()
(2-dimensional tensors only) Equivalent topermuted({1,0})
. -
T()
(2-dimensional tensors only) Equivalent topermuted({1,0})
. -
lowered<ndim>(split)
Return a view with possibly lower dimensionality. Thei
th dimension of the view is the aggregate of dimensionssplit[i],...,split[i+1]-1
. Thus the number of dimensions in the new view is the number of splits minus one and must be equal tondim
.split
must be in ascending order. -
reversed()
Return a view where the order of elements along each dimension is reversed. -
reversed(dim)
Return a view where the order of elements along dimensiondim
is reversed. -
reversed<dim>()
Return a view where the order of elements along dimensiondim
is reversed.
-
-
Iterators
-
cbegin()
Return an iterator of the first dimension. This iterator has its own[cr]begin()
and[cr]end()
functions to access iterators over successive dimensions. Iterators over the final dimension can be dereferenced to yield references to elements, while intermediate iterators can be dereferenced to yield sliced views(). This version returns an iterator that yields const-qualified references or views. -
begin()
Same as above, but const-ness is determined by the object. -
crbegin()
Same ascbegin()
but start at the last element and work backwards. -
rbegin()
Same asbegin()
but start at the last element and work backwards. -
cend()
Return an end iterator for the first dimension. -
end()
Return an end iterator for the first dimension. -
crend()
Return an end iterator for the first dimension. -
rend()
Return an end iterator for the first dimension.
-
-
Element Access
-
operator[](idx)
Return a temporary object representing a slice along the first dimension at positionidx
. This object can be further indexed withoperator[]
or you can call theview()
function on it to get a view. Ifoperator[]
is usedN
times, then the result is equivalent to usingoperator()
with all arguments of theoperator[]
invocations, in the same order. E.g. formarray<double,3> A(...)
,A[x][y][z]
is the same asA(x,y,z)
. -
operator[](range)
Return a temporary object representing a slice along the first dimension, where elements in the givenrange
object are retained. -
operator[](slice::all)
Return a temporary object representing a slice along the first dimension, where all elements are retained. Useful when a slice along a later dimension is needed. Obtaining a view from a temporary object returned from anyoperator[]
chain (with less thanN
calls) is equivalent to callingoperator[](slice::all)
on it to a total ofN
calls. -
operator()(idx0, idx1, ...)
Return a reference to the element with the specified indices. All parameters must be integral types. -
operator()(idx_or_slice0, idx_or_slice1, ...)
Return a view of the specified sub-tensor. Eachidx_or_sliceN
may be either an integral type specifying that a dimension is to be fixed, arange
object giving a range of elements to include along a dimension, orslice::all
which specifies that all elements are to be included along a dimension. At least one parameter must not be an integral type, and the number of dimension in the resulting view is given by the number of non-integral (range
orall
) parameters.
-
-
Iteration
-
for_each_element(func)
Callfunc
for each element in the tensor.func
must be callable as eitherfunc(val&)
orfunc(val&, idx0, ..., idxN-1)
whereval&
is a reference to an element of the tensor andidxN
is the index along the Nth dimension.N
must equal the number of dimensions.
-
-
Structure and Data
-
cdata()
Return a const-qualified pointer to the element at index(0,...,0)
. -
data()
Return a pointer to the element at index(0,...,0)
. -
length(dim)
Return the length of dimensiondim
. -
length<dim>()
Return the length of dimensiondim
. -
lengths()
Return the lengths of all dimensions (as a read-only container). -
stride(dim)
Return the stride of dimensiondim
. -
stride<dim>()
Return the stride of dimensiondim
. -
strides()
Return the strides of all dimensions (as a read-only container). -
dimension()
Return the number of dimensions.
-
-
Printing
- Tensors can be printed in a hierarchical C array-like format using
operator<<
.
- Tensors can be printed in a hierarchical C array-like format using
-
Static Helper Functions
-
strides(lengths)
Return the strides for a tensor with the given lengths and the default layout. -
strides(lengths, layout)
Return the strides for a tensor with the given lengths and the given layout. -
size(lengths)
Return the number of elements in a tensor with the given lengths. -
is_contiguous(lengths, strides)
Returns astd::pair<bool,stride_type>
. The first member is true if the tensor specified by the given lengths and strides is contiguous, i.e. elements are arranged consecutively in memory. The second member gives the total number of elements if the tensor is contiguous.
-
T
is the type of individual tensor elements, if it is const-qualified then the view is read-only. N
is the number of dimensions.
-
Constructors
-
marray_view()
Create a view with all zero lengths, it has no accessible elements. -
marray_view(lengths, ptr)
Create a view with the given lengths and the given base pointer (pointer to the element with all zero indices). -
marray_view(lengths, ptr, layout)
Create a view with the specified data layout, eitherROW_MAJOR
orCOLUMN_MAJOR
. -
marray_view(lengths, ptr, strides)
Create a view with the specified data structure given bylengths
andstrides
.strides[i]
is the distance in memory between elements along dimensioni
. -
marray_view(other)
Create a view of the tensorother
, which can be either a container or another view.
-
-
Reinitialization
-
reset(...)
Takes the same arguments as the constructor.
-
-
Front/Back
-
Assignment
-
Views
-
Element Access
-
Iteration
-
Structure and Data
-
Printing
-
Static Helper Functions
- All functions in these categories are the same as for
varray<T>
. (Note that the Push/Pop functions are not included).
- All functions in these categories are the same as for
-
Mutation
-
shift(shifts)
Shift the current view in-place, as inshifted(shifts)
. -
shift(dim, shift)
Shift the current view in-place, as inshifted(dim, shift)
. -
shift_down(dim)
Shift the current view in-place, as inshifted_down(dim)
. -
shift_up(dim)
Shift the current view in-place, as inshift_up(dim)
. -
shift<dim>(shift)
Shift the current view in-place, as inshifted<dim>(shift)
. -
shift_down<dim>()
Shift the current view in-place, as inshifted_down<dim>()
. -
shift_up<dim>()
Shift the current view in-place, as inshift_up<dim>()
. -
permute(perm)
Permute the current view in-place, as inpermuted(perm)
. -
transpose()
(2-dimensional views only) Transpose the view in-place, as intransposed()
. -
reverse()
Reverse each dimension of the view, as inreversed()
. -
reverse(dim)
Reverse dimensiondim
of the view, as inreversed(dim)
. -
reverse<dim>()
Reverse dimensiondim
of the view, as inreversed<dim>()
. -
data(ptr)
Change the base pointer. The old pointer is returned. -
length(dim, len)
Change the length for dimensiondim
. The old length is returned. -
stride(dim, str)
Change the stride for dimensiondim
. The old stride is returned. -
length<dim>(len)
Change the length for dimensiondim
. The old length is returned. -
stride<dim>(str)
Change the stride for dimensiondim
. The old stride is returned.
-
-
Swap
-
swap(other)
Swap the dimension, lengths, and pointer of this view withother
, which must be precisely the same type.
-
-
rotate(tensor, shifts)
This is a free function that rotates the data of the given tensor along each dimension. For example, ifshifts[2] == 3
, then the element at position(...,i_2,...)
is moved to position(...,i_2+3,...)
. In this version, the shift is applied along all dimensions simulateneously. A shift of 0 indicates no rotation. Elements which would be rotated off the ends of the dimension ranges are wrapped around. The operation is performed in-place, and the execution time is linear in the number of elements and the number of rotated dimensions. -
rotate(tensor, dim, shift)
Same as above, but rotate data only along dimensiondim
.
The seven basic tensor operations (and their matrix and vector counterparts) are accessible via a convenient API:
- In each function, the scalars
alpha
andbeta
are of typeT
, which must also be the element type (with possible const-qualification) of the tensor objects. - Tensors
A
,B
, andC
may be any tensor type. - While the
T
template parameter can be deduced in some cases, it is often necessary to specify it explicitly. -
idx_A
,idx_B
, andidx_C
are index strings (const index_type*
) that specify the details of the operation. Ifindex_type
ischar
(the default), then these may be string literals). - The
comm
parameter may be with atblis::communicator
to use for parallelization ortblis::single
to specify single-threaded operation. If nocomm
parameter is given, threading is automatic. - In reduction operations,
op
specifies the type of reduction (one ofREDUCE_SUM
,REDUCE_SUM_ABS == REDUCE_NORM_1
,REDUCE_MAX
,REDUCE_MAX_ABS == REDUCE_NORM_INF
,REDUCE_MIN
,REDUCE_MIN_ABS
, orREDUCE_NORM_2
).
The functions are:
add<T>(alpha, A, idx_A, beta, B, idx_B)
add<T>(comm, alpha, A, idx_A, beta, B, idx_B)
-
dot<T>(A, idx_A, B, idx_B)
The dot product is returned from the function. -
dot<T>(A, idx_A, B, idx_B, result&)
The dot product is returned in the referenceresult&
. dot<T>(comm, A, idx_A, B, idx_B)
dot<T>(comm, A, idx_A, B, idx_B, result&)
-
reduce<T>(op, A, idx_A)
The result is returned as astd::pair<T,stride_type>
where the first member is the result of the reduction and the second member is the offset of the maximal/minimal value (relative to the base pointer; when defined). -
reduce<T>(op, A, idx_A, result&, idx&)
The result is returned as above, but in theresult&
andidx&
references, respectively. reduce<T>(comm, op, A, idx_A)
reduce<T>(comm, op, A, idx_A, result&, idx&)
scale<T>(alpha, A, idx_A)
scale<T>(comm, alpha, A, idx_A)
set<T>(alpha, A, idx_A)
set<T>(comm, alpha, A, idx_A)
shift<T>(alpha, beta, A, idx_A)
shift<T>(comm, alpha, beta, A, idx_A)
mult<T>(alpha, A, idx_A, B, idx_B, beta, C, idx_C)
mult<T>(comm, alpha, A, idx_A, B, idx_B, beta, C, idx_C)
TODO