26 namespace MultiDimensional {
34 value =
static_cast<IndexType>(value | (value >> 1));
35 value =
static_cast<IndexType>(value | (value >> 2));
36 value =
static_cast<IndexType>(value | (value >> 4));
37 value =
static_cast<IndexType>(value | (value >> 8));
42 AlignedIndexing::AlignedIndexing()
43 : _dimensions{}, _alignPads{}, _alignMasks{}, _maxIndex{0}, _maxAlignedIndex{0}, _unalignedEntries{} {
59 to_string(
_dimensions.size()) +
": all your base are belong to us.");
71 bool valid = (indices.size() ==
_dimensions.size());
74 valid = inner_product(indices.begin(), indices.end(),
_dimensions.begin(), valid, logical_and<bool>(),
80 bool valid = (distance(first,last) ==
static_cast<ptrdiff_t
>(
_dimensions.size()));
83 valid = inner_product(first, last,
_dimensions.begin(), valid, logical_and<bool>(),
93 IndexList::const_iterator last)
const {
101 index = inner_product(first, last,
_alignPads.begin(), index, plus<PositionType>(), opCombine);
110 for (; itp !=
_alignPads.end(); ++itp, ++itm) {
111 result.push_back(static_cast<IndexType>((alignedPosition >> (*itp)) & (*itm)));
121 const IndexList& outerShiftsInnerPositions,
122 const vector<bool>& isOuter,
123 IndexList& innerList, vector<bool>& innerAdded,
bool shouldCompare)
const {
124 fill(innerAdded.begin(), innerAdded.end(),
false);
129 newPos +=
static_cast<PositionType>(idx << outerShiftsInnerPositions[i]);
131 ASSERT(outerShiftsInnerPositions[i] < innerList.size());
132 if (!shouldCompare) {
133 size_t innerPos = outerShiftsInnerPositions[i];
134 if (innerAdded[innerPos] && innerList[innerPos] != idx) {
135 return numeric_limits<size_t>::max();
137 innerAdded[innerPos] =
true;
138 innerList[innerPos] = idx;
139 }
else if (innerList[outerShiftsInnerPositions[i]] != idx) {
140 return numeric_limits<size_t>::max();
149 map<IndexType, IndexType> inners;
150 for (
IndexType i = 0; i < pairs.size(); ++i) {
153 inners.insert(make_pair(pairs[i].first, i));
156 inners.insert(make_pair(pairs[i].second, i));
159 inners.insert(make_pair(pairs[i].first, i));
160 inners.insert(make_pair(pairs[i].second, i));
167 newDims.push_back((inners.find(i) != inners.end()) ?
'\0' :
_dimensions[i]);
172 for (
auto elem : inners) {
173 retIndices[elem.first] = elem.second;
174 retBools[elem.first] =
false;
176 return make_tuple(retIndices, retBools, maxIdx+1);
185 tmpPads.reserve(dimensions.size());
186 transform(dimensions.rbegin(), dimensions.rend(), back_inserter(tmpPads),
190 partial_sum(tmpPads.begin(), tmpPads.end(), back_inserter(pads));
191 PositionType maxAlignedIndex = (1ul << pads.back()) - 1ul;
193 reverse(pads.begin(), pads.end());
194 return maxAlignedIndex;
199 transform(dimensions.rbegin(), dimensions.rend(), back_inserter(masks),
201 reverse(masks.begin(), masks.end());
222 auto itd = dimensions.rbegin();
223 auto itp = pads.rbegin();
226 for(; itp != pads.rend(); ++itd, ++itp) {
227 currentStride *= *itd;
229 unaligned.push_back(make_pair(currentStride, *itp));
232 reverse(unaligned.begin(), unaligned.end());
240 reminder -= (tmp << elem.second);
241 result += tmp * elem.first - (tmp << elem.second);
251 reminder -= (tmp * elem.first);
252 result += (tmp << elem.second) - (tmp * elem.first);
259 if(indexPosition == 0) {
263 PositionType tmp2 = alignedPosition - (tmp1 << _alignPads[indexPosition]);
264 return (tmp1 << _alignPads[indexPosition - 1]) +
265 static_cast<PositionType>(indexValue << _alignPads[indexPosition]) + tmp2;
270 auto res = div(static_cast<long>(position), static_cast<long>(stride));
271 return posToAlignedPos((static_cast<PositionType>(res.quot *
_dimensions[indexPosition]) + indexValue) * stride + static_cast<PositionType>(res.rem));
275 if (
rank() != indices.size())
void calcMasks(const IndexList &dimensions, IndexList &masks) const
std::vector< PosIndexPair > PosIndexPairList
std::vector< IndexPair > IndexPairList
void calcUnaligned(const IndexList &dimensions, const IndexList &pads, PosIndexPairList &unaligned) const
PosIndexPairList _unalignedEntries
PositionType extendPosition(PositionType position, PositionType stride, IndexType indexPosition, IndexType indexValue) const
extends an unaligned absolute position from a rank N-1 tensor to the corresponding aligned position f...
IndexList _alignPads
the strides for each tensor index (necessary to convert coordinates to position in _data) ...
IndexType ithIndexInPos(PositionType alignedPosition, IndexType indexPosition) const
extract the value of the i-th index from an absolute aligned position
static IndexType nextPowerOf2(IndexType value)
PositionType numValues() const
the number of elements (product of all the dimensions)
const IndexList & dims() const
get the dimensions of all the indices at once
size_t rank() const
rank of the tensor
Hammer exception definitions.
PositionType alignedPosToPos(PositionType alignedPosition) const
convert the absolute aligned position to the absolute unaligned position that can be used with a Sequ...
std::vector< IndexType > IndexList
PositionType calcPadding(const IndexList &dimensions, IndexList &pads) const
PositionType _maxAlignedIndex
PositionType posToAlignedPos(PositionType position) const
convert the absolute unaligned position (e.g.
IndexType dim(IndexType index) const
dimension of a specific component
PositionType maxIndex(bool aligned=true) const
get the maximum allowed value for the absolute position
bool checkValidIndices(const IndexList &indices) const
check that the indices are within range for each component
void posToIndices(PositionType alignedPosition, IndexList &result) const
convert the absolute aligned position (in row-major convention) into the list of indices ...
IndexList _dimensions
the dimensions of each tensor index
std::enable_if< std::is_unsigned< T >::value &&std::is_integral< T >::value, T >::type minPadding(T value)
PositionType splitPosition(PositionType alignedPosition, const IndexList &outerShiftsInnerPositions, const std::vector< bool > &isOuter, IndexList &innerList, std::vector< bool > &innerAdded, bool shouldCompare=false) const
split an absolute aligned position by separating contracted and uncontracted indices and returning th...
PositionType indicesToPos(const IndexList &indices) const
convert the indices into the (aligned) position indicizing a sparse tensor container organized as row...
PositionType extendAlignedPosition(PositionType alignedPosition, IndexType indexPosition, IndexType indexValue) const
extends an aligned absolute position from a rank N-1 tensor to the corresponding aligned position for...
IndexList _alignMasks
the strides for each tensor index (necessary to convert coordinates to position in _data) ...
bool isSameShape(const BasicIndexing &other) const
Out-of-range error class.
std::tuple< IndexList, std::vector< bool >, PositionType > processShifts(const IndexPairList &pairs, IndexPairMember which) const
build the input lists necessary for calling splitPosition based on which indices are being contracted...