Sparsifying a Tensor
This page details the algorithms used to create a tensor-of-tensors from a SparseMap and a tensor.
Things to note
We are creating an object, t of type DistArray<Tensor<Tensor<T>>> from
an object T of type DistArray<Tensor<T>>. Since the tiles are not the
same type we are going to have to copy data. At best we are going to be able to
copy full tiles of T into t at worst we are going to be copying pieces
of tiles from T into t. To my knowledge there is no way to alias the
full tiles and the copy must occur. For this reason the main kernel assumes a
SparseMap<ElementIndex, ElementIndex> instance is provided as this affords
us the most flexibility in defining tiles. Specialized kernels may be added at
a later point for other types of SparseMap instances.
Assumptions
Assume we are given a SparseMap instance, sm and a tensor T. Our
present goal is to create a tensor-of-tensors (ToT), t, out of T. The
outer rank of t is given by sm.ind_rank() and the inner rank of t is
given by sm.dep_rank().
We start by assuming sm is a SparseMap<ElementIndex, ElementIndex>
instance. Conversions exist to SparseMap<ElementIndex, ElementIndex> for all
other specializations of the SparseMap class. There are now two scenarios:
sm.dep_rank()equals the rank ofT, orsm.dep_rank()is less than the rank ofT
In the former scenario we assume that the dependent indices are valid tile
indices for T. To be more concrete, we assume that given the dependent index
{0, 1} we take this to mean that the user wants us to retrieve element
{0, 1} of T as opposed to say {1, 0}`, i.e., no offsets or
permutations are required to convert an index in the domain to an index in
T. In the second scenario we assume that by injecting one or more
independent index modes into the dependent indices we get a valid index for
T. In other words we assume that the elements of the Domain are indices of
reduced rank slices of T. Slices of the same rank as T are formed by
inserting one (or more) of the modes of the independent mode into the dependent
indices. These two scenarios are unified by realizing the first results from the
second if we have no injections. Thus as long as we code up the second scenario
in such a manner that it works with no injections we cover both scenarios.
make_tot_tile_ Algorithm
The guts of the from_sparse_tensor function are contained in
make_tot_tile_. make_tot_tile_ is more-or-less a lambda which will be
passed to TA::make_array to form the tensor-of-tensors. make_tot_tile_
works by:
Given:
the outer tile to fill,
tile,the SparseMap from independent element indices to dependent element indices,
sm,the tensor to sparsify
T, andan
std::map,ind2mode, such thatind2mode[i]is the mode ofTthat thei-th mode of the independent indices insmmaps to.
Loop over outer element indices in
tile,oeidxIf domain associated with
oedixis empty move onOtherwise:
Allocate inner tile,
bufferCreate Domain with indices of
oeidxinjected,injected_dCreate Domain with tiles of
injected_d,tdomainLoop over tiles in
tdomain,itidxGet the tile from
T,tLoop over elements in
injected_d,ieidxAdd
t[ieidx]tobuffer
Set
tile[oeidx]tobuffer
Return
tile