43 #ifndef DOMI_MDARRAYVIEW_HPP
44 #define DOMI_MDARRAYVIEW_HPP
50 #include "Teuchos_Array.hpp"
51 #include "Teuchos_ArrayView.hpp"
52 #include "Teuchos_ConstTypeTraits.hpp"
53 #include "Teuchos_RCPNode.hpp"
56 #include "Domi_ConfigDefs.hpp"
57 #include "Domi_Exceptions.hpp"
58 #include "Domi_Utils.hpp"
60 #include "Domi_MDIterator.hpp"
61 #include "Domi_MDRevIterator.hpp"
69 template<
typename T >
class MDArray;
77 template<
typename T >
85 template<
typename T >
93 template<
typename T >
113 template<
typename T >
149 MDArrayView(Teuchos::ENull null_arg = Teuchos::null);
165 const Teuchos::ArrayView< dim_type > & dims,
166 const Layout
layout = DEFAULT_ORDER);
189 const Teuchos::Array< dim_type > & dims,
190 const Teuchos::Array< size_type > &
strides,
191 const Layout
layout = DEFAULT_ORDER);
246 inline const Teuchos::Array< dim_type > &
dimensions()
const;
253 inline dim_type
dimension(
int axis)
const;
257 inline size_type
size()
const;
261 inline const Teuchos::Array< size_type > &
strides()
const;
265 inline const Teuchos::ArrayView< T > &
arrayView()
const;
270 inline const Teuchos::ArrayView< const T > &
arrayViewConst()
const;
274 inline Layout
layout()
const;
418 inline T &
operator()(dim_type i, dim_type j);
432 inline T &
operator()(dim_type i, dim_type j, dim_type k);
448 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m);
466 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m,
490 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m,
491 dim_type n, dim_type p, ...);
501 inline const T &
operator()(dim_type i)
const;
513 inline const T &
operator()(dim_type i, dim_type j)
const;
527 inline const T &
operator()(dim_type i, dim_type j, dim_type k)
const;
543 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
562 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
563 dim_type m, dim_type n)
const;
586 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
587 dim_type m, dim_type n, dim_type p, ...)
const;
600 void assign(
const T & value);
611 T &
at(dim_type i, ...);
621 const T &
at(dim_type i, ...)
const;
651 template<
typename T2 >
656 template<
typename T2 >
661 template<
typename T2 >
668 template<
typename T2 >
669 friend std::ostream &
operator<<(std::ostream & os,
676 Teuchos::Array< dim_type > _dimensions;
677 Teuchos::Array< size_type > _strides;
678 Teuchos::ArrayView< T > _array;
686 void assertAxis(
int axis)
const;
691 void assertIndex(dim_type i,
int axis)
const;
697 std::string
toString(
int indent)
const;
705 template<
typename T >
708 _dimensions(Teuchos::tuple< dim_type >(0)),
709 _strides(Teuchos::tuple< size_type >(1)),
711 _layout(DEFAULT_ORDER),
719 template<
typename T >
721 const Teuchos::ArrayView< dim_type > & dims,
722 const Layout layout) :
724 _strides(computeStrides< size_type, dim_type >(dims, layout)),
727 _ptr(_array.getRawPtr()),
730 TEUCHOS_TEST_FOR_EXCEPTION(array.size() < computeSize(dims),
732 "Teuchos::ArrayView size too small for "
738 template<
typename T >
740 const Teuchos::Array< dim_type > & dims,
741 const Teuchos::Array< size_type > & strides,
742 const Layout layout) :
747 _ptr(_array.getRawPtr()),
750 const size_type required = computeSize<
const size_type,
751 const dim_type >(dims(),strides());
752 TEUCHOS_TEST_FOR_EXCEPTION(
753 array.size() < required,
755 "Teuchos::ArrayView size too small for "
756 "dimensions and strides");
761 template<
typename T >
763 _dimensions(array._dimensions),
764 _strides(array._strides),
765 _array(array._array),
766 _layout(array._layout),
767 _ptr(_array.getRawPtr()),
774 template<
typename T >
781 _layout(parent._layout),
786 parent.assertAxis(axis);
787 parent.assertIndex(index, axis);
789 size_type offset = index * parent._strides[axis];
791 size_type n = parent._dimensions.size();
795 _dimensions.push_back(1);
796 _strides.push_back(1);
800 for (
int myAxis = 0; myAxis < n; myAxis++)
803 _dimensions.push_back(parent._dimensions[myAxis]);
804 _strides.push_back(parent._strides[myAxis]);
808 _array = parent._array.view(offset,
809 computeSize(_dimensions(),
811 _ptr = _array.getRawPtr();
816 template<
typename T >
817 MDArrayView< T >::MDArrayView(
const MDArrayView< T > & parent,
820 _dimensions(parent._dimensions),
821 _strides(parent._strides),
823 _layout(parent._layout),
828 parent.assertAxis(axis);
830 Slice bounds = slice.bounds(_dimensions[axis]);
832 size_type offset = bounds.start() * _strides[axis];
834 _dimensions[axis] = (bounds.stop() - bounds.start()) / bounds.step();
836 _strides[axis] *= bounds.step();
838 _array = parent._array.view(offset,
839 computeSize(_dimensions(),
841 _ptr = _array.getRawPtr();
846 template<
typename T >
850 _dimensions = array._dimensions;
851 _strides = array._strides;
852 _array = array._array;
853 _layout = array._layout;
855 _next_axis = array._next_axis;
861 template<
typename T >
868 template<
typename T >
872 return _dimensions.
size();
877 template<
typename T >
878 const Teuchos::Array< dim_type > &
886 template<
typename T >
890 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
893 return _dimensions[axis];
898 template<
typename T >
902 return computeSize(_dimensions(), _strides());
907 template<
typename T >
908 const Teuchos::Array< size_type > &
916 template<
typename T >
917 const Teuchos::ArrayView< T > &
925 template<
typename T >
926 const Teuchos::ArrayView< const T > &
929 return Teuchos::av_const_cast< const T >(_array);
934 template<
typename T >
943 template<
typename T >
949 Teuchos::Array< size_type > contig_strides =
950 computeStrides< size_type, dim_type >(_dimensions, _layout);
953 return (contig_strides == _strides);
958 template<
typename T >
967 template<
typename T >
977 template<
typename T >
986 template<
typename T >
996 template<
typename T >
1005 template<
typename T >
1015 template<
typename T >
1024 template<
typename T >
1034 template<
typename T >
1043 template<
typename T >
1053 template<
typename T >
1065 template<
typename T >
1072 if (_next_axis < result.
numDims())
1073 result._next_axis = _next_axis;
1080 template<
typename T >
1087 if (_next_axis < result.
numDims())
1088 result._next_axis = _next_axis;
1095 template<
typename T >
1102 result._next_axis = _next_axis + 1;
1103 if (result._next_axis >= _dimensions.size())
1104 result._next_axis = 0;
1111 template<
typename T >
1118 result._next_axis = _next_axis + 1;
1119 if (result._next_axis >= _dimensions.size())
1120 result._next_axis = 0;
1127 template<
typename T >
1131 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1132 TEUCHOS_TEST_FOR_EXCEPTION(
1134 "Attempt to access " << _dimensions.size() <<
"D array with 1 index"
1138 return _ptr[i * _strides[0]];
1143 template<
typename T >
1148 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1149 TEUCHOS_TEST_FOR_EXCEPTION(
1151 "Attempt to access " << _dimensions.size() <<
"D array with 2 indexes"
1156 return _ptr[i * _strides[0] + j * _strides[1]];
1161 template<
typename T >
1167 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1168 TEUCHOS_TEST_FOR_EXCEPTION(
1170 "Attempt to access " << _dimensions.size() <<
"D array with 3 indexes"
1176 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1181 template<
typename T >
1188 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1189 TEUCHOS_TEST_FOR_EXCEPTION(
1191 "Attempt to access " << _dimensions.size() <<
"D array with 4 indexes"
1198 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1204 template<
typename T >
1212 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1213 TEUCHOS_TEST_FOR_EXCEPTION(
1215 "Attempt to access " << _dimensions.size() <<
"D array with 5 indexes"
1223 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1224 m * _strides[3] + n * _strides[4]];
1229 template<
typename T >
1239 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1240 TEUCHOS_TEST_FOR_EXCEPTION(
1242 "Attempt to access " << _dimensions.size() <<
"D array with too many indexes"
1252 size_type offset = i * _strides[0] + j * _strides[1] + k * _strides[2] +
1253 m * _strides[3] + n * _strides[4] + p * _strides[5];
1254 va_start(indexes, p);
1255 for (
int axis = 6; axis < _dimensions.size(); axis++)
1257 dim_type q = va_arg(indexes, dim_type);
1258 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1259 assertIndex(q, axis);
1261 offset += q * _strides[axis];
1264 return _ptr[offset];
1269 template<
typename T >
1273 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1274 TEUCHOS_TEST_FOR_EXCEPTION(
1276 "Attempt to access " << _dimensions.size() <<
"D array with 1 index"
1280 return _ptr[i * _strides[0]];
1285 template<
typename T >
1290 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1291 TEUCHOS_TEST_FOR_EXCEPTION(
1293 "Attempt to access " << _dimensions.size() <<
"D array with 2 indexes"
1298 return _ptr[i * _strides[0] + j * _strides[1]];
1303 template<
typename T >
1309 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1310 TEUCHOS_TEST_FOR_EXCEPTION(
1312 "Attempt to access " << _dimensions.size() <<
"D array with 3 indexes"
1318 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1323 template<
typename T >
1330 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1331 TEUCHOS_TEST_FOR_EXCEPTION(
1333 "Attempt to access " << _dimensions.size() <<
"D array with 4 indexes"
1340 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1346 template<
typename T >
1354 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1355 TEUCHOS_TEST_FOR_EXCEPTION(
1357 "Attempt to access " << _dimensions.size() <<
"D array with 5 indexes"
1365 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1366 m * _strides[3] + n * _strides[4]];
1371 template<
typename T >
1381 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1382 TEUCHOS_TEST_FOR_EXCEPTION(
1384 "Attempt to access " << _dimensions.size() <<
"D array with too many indexes"
1394 size_type offset = i * _strides[0] + j * _strides[1] + k * _strides[2] +
1395 m * _strides[3] + n * _strides[4] + p * _strides[5];
1396 va_start(indexes, p);
1397 for (
int axis = 6; axis < _dimensions.size(); axis++)
1399 dim_type q = va_arg(indexes, dim_type);
1400 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1401 assertIndex(q, axis);
1403 offset += q * _strides[axis];
1406 return _ptr[offset];
1411 template<
typename T >
1415 for (
iterator it = begin(); it != end(); ++it)
1421 template<
typename T >
1427 size_type offset = i * _strides[0];
1428 va_start(indexes, i);
1429 for (
int axis = 1; axis < _dimensions.size(); axis++)
1431 dim_type j = va_arg(indexes, dim_type);
1432 assertIndex(j, axis);
1433 offset += j * _strides[axis];
1436 return _array[offset];
1441 template<
typename T >
1447 size_type offset = i * _strides[0];
1448 va_start(indexes, i);
1449 for (
int axis = 1; axis < _dimensions.size(); axis++)
1451 dim_type j = va_arg(indexes, dim_type);
1452 assertIndex(j, axis);
1453 offset += j * _strides[axis];
1456 return _array[offset];
1461 template<
typename T >
1465 #ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1474 template<
typename T >
1485 template<
typename T >
1489 std::stringstream ss;
1491 for (size_type i = 0; i < _dimensions[0]; i++)
1495 ss << operator()(i);
1497 ss << operator[](i).toString(indent+1);
1499 if (i < _dimensions[0]-1)
1508 ss << std::endl <<
" ";
1509 for (
int ii = 0; ii < indent; ii++) ss <<
" ";
1519 template<
typename T >
1528 template<
typename T >
1537 template<
typename T >
1540 if (a1._dimensions != a2._dimensions)
return false;
1541 if (a1._layout != a2._layout )
return false;
1544 for ( ; it1 != a1.
end() && it2 != a2.
end(); ++it1, ++it2)
1546 if (*it1 != *it2)
return false;
1553 template<
typename T >
1556 return not (a1 == a2);
1561 template<
typename T >
1569 template<
typename T >
1580 template<
typename T >
1582 MDArrayView< T >::assertAxis(
int axis)
const
1584 TEUCHOS_TEST_FOR_EXCEPTION(
1585 !(0 <= axis && axis < _dimensions.size()),
1587 "MDArrayView<T>::assertAxis(axis=" << axis <<
"): out of "
1588 <<
"range axis in [0, " << _dimensions.size() <<
")"
1592 template<
typename T >
1594 MDArrayView< T >::assertIndex(dim_type i,
int axis)
const
1596 TEUCHOS_TEST_FOR_EXCEPTION(
1597 !(0 <= i && i < _dimensions[axis]), RangeError,
1598 "MDArrayView<T>::assertIndex(i=" << i <<
",axis=" << axis <<
"): out of "
1599 <<
"range i in [0, " << _dimensions[axis] <<
")"
1605 #endif // DOMI_MDARRAYVIEW_HPP