Domi
Multi-dimensional, distributed data structures
Loading...
Searching...
No Matches
Domi_MDArrayView.hpp
1// @HEADER
2// ***********************************************************************
3//
4// Domi: Multi-dimensional Distributed Linear Algebra Services
5// Copyright (2014) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia
8// Corporation, the U.S. Government retains certain rights in this
9// software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact William F. Spotz (wfspotz@sandia.gov)
39//
40// ***********************************************************************
41// @HEADER
42
43#ifndef DOMI_MDARRAYVIEW_HPP
44#define DOMI_MDARRAYVIEW_HPP
45
46// Standar includes
47#include <cstdarg>
48
49// Teuchos includes
50#include "Teuchos_Array.hpp"
51#include "Teuchos_ArrayView.hpp"
52#include "Teuchos_ConstTypeTraits.hpp"
53#include "Teuchos_RCPNode.hpp"
54
55// Domi includes
56#include "Domi_ConfigDefs.hpp"
57#include "Domi_Exceptions.hpp"
58#include "Domi_Utils.hpp"
59#include "Domi_Slice.hpp"
60#include "Domi_MDIterator.hpp"
61#include "Domi_MDRevIterator.hpp"
62
63namespace Domi
64{
65
66// I put these non-member template functions here for the same reason
67// that Ross did the same thing for the Teuchos::Array class. See
68// Teuchos_Array.hpp for details.
69template< typename T > class MDArray;
70template< typename T > class MDArrayView;
71template< typename T > class MDArrayRCP;
72
77template< typename T >
79 const MDArrayView< T > & a2);
80
85template< typename T >
87 const MDArrayView< T > & a2);
88
93template< typename T >
94void swap(MDArrayView< T > & a1,
96
113template< typename T >
115{
116public:
117
120
122 typedef T value_type;
123
125 typedef T* pointer;
126
128 typedef const T* const_pointer;
129
131 typedef T& reference;
132
134 typedef const T& const_reference;
135
137
140
149 MDArrayView(Teuchos::ENull null_arg = Teuchos::null);
150
164 MDArrayView(const Teuchos::ArrayView< T > & array,
165 const Teuchos::ArrayView< dim_type > & dims,
166 const Layout layout = DEFAULT_ORDER);
167
188 MDArrayView(const Teuchos::ArrayView< T > & array,
189 const Teuchos::Array< dim_type > & dims,
190 const Teuchos::Array< size_type > & strides,
191 const Layout layout = DEFAULT_ORDER);
192
198
199 /* \brief Parent/single index sub-array view constructor
200 *
201 * \param parent [in] an MDArrayView, from which this MDArrayView
202 * will be derived
203 *
204 * \param axis [in] the axis to which this index ordinal applies
205 *
206 * \param index [in] the ordinal that defines this sub-array
207 */
209 int axis,
210 dim_type index);
211
212 /* \brief Parent/single slice sub-array view constructor
213 *
214 * \param parent [in] an MDArrayView, from which this MDArrayView
215 * will be derived
216 *
217 * \param axis [in] the axis to which this index ordinal applies
218 *
219 * \param slice [in] the slice that defines this sub-array
220 */
222 int axis,
223 Slice slice);
224
230
234
236
239
242 inline int numDims() const;
243
246 inline const Teuchos::Array< dim_type > & dimensions() const;
247
253 inline dim_type dimension(int axis) const;
254
257 inline size_type size() const;
258
261 inline const Teuchos::Array< size_type > & strides() const;
262
265 inline const Teuchos::ArrayView< T > & arrayView() const;
266
270 inline const Teuchos::ArrayView< const T > & arrayViewConst() const;
271
274 inline Layout layout() const;
275
278 inline bool contiguous() const;
279
281
284
285 friend class MDIterator< MDArrayView< T > >;
286 friend class MDIterator< MDArrayView< const T > >;
287 friend class MDRevIterator< MDArrayView< T > >;
288 friend class MDRevIterator< MDArrayView< const T > >;
289
294
298
302
306
310
314
318
322
326
330
334
336
339
346
357
367 const MDArrayView< T > operator[](dim_type i) const;
368
380
392
394
397
406 inline T & operator()(dim_type i);
407
418 inline T & operator()(dim_type i, dim_type j);
419
432 inline T & operator()(dim_type i, dim_type j, dim_type k);
433
448 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m);
449
466 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m,
467 dim_type n);
468
490 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m,
491 dim_type n, dim_type p, ...);
492
501 inline const T & operator()(dim_type i) const;
502
513 inline const T & operator()(dim_type i, dim_type j) const;
514
527 inline const T & operator()(dim_type i, dim_type j, dim_type k) const;
528
543 inline const T & operator()(dim_type i, dim_type j, dim_type k,
544 dim_type m) const;
545
562 inline const T & operator()(dim_type i, dim_type j, dim_type k,
563 dim_type m, dim_type n) const;
564
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;
588
589
591
594
600 void assign(const T & value);
601
611 T & at(dim_type i, ...);
612
621 const T & at(dim_type i, ...) const;
622
626 inline static bool hasBoundsChecking();
627
631 std::string toString() const;
632
636 inline const T * getRawPtr() const;
637
641 inline T * getRawPtr();
642
643 // These operators are declared as friends so that the compiler will
644 // do automatic type conversion.
645
648
651 template< typename T2 >
652 friend bool operator==(const MDArrayView< T2 > & a1, const MDArrayView< T2 > & a2);
653
656 template< typename T2 >
657 friend bool operator!=(const MDArrayView< T2 > & a1, const MDArrayView< T2 > & a2);
658
661 template< typename T2 >
663
668 template< typename T2 >
669 friend std::ostream & operator<<(std::ostream & os,
670 const MDArrayView< T2 > & a);
671
673
674private:
675
676 Teuchos::Array< dim_type > _dimensions;
677 Teuchos::Array< size_type > _strides;
678 Teuchos::ArrayView< T > _array;
679 Layout _layout;
680 pointer _ptr;
681 int _next_axis;
682
683 // Method provided for aiding in array bounds checking. It raises
684 // an exception when the given axis is out of range of valid
685 // dimensions.
686 void assertAxis(int axis) const;
687
688 // Method provided for aiding in array bounds checking. It raises
689 // an exception when the given index i is out of range along the
690 // given axis.
691 void assertIndex(dim_type i, int axis) const;
692
693 // Private implementation of the toString() method that includes an
694 // indent argument. The publicly available version takes no
695 // arguments and calls this one with initial indent value of zero.
696 // This method can call itself recursively.
697 std::string toString(int indent) const;
698
699}; // class MDArrayView
700
702// Implementations //
704
705template< typename T >
707MDArrayView(Teuchos::ENull null_arg) :
708 _dimensions(Teuchos::tuple< dim_type >(0)),
709 _strides(Teuchos::tuple< size_type >(1)),
710 _array(),
711 _layout(DEFAULT_ORDER),
712 _ptr(),
713 _next_axis(0)
714{
715}
716
718
719template< typename T >
720MDArrayView< T >::MDArrayView(const Teuchos::ArrayView< T > & array,
721 const Teuchos::ArrayView< dim_type > & dims,
722 const Layout layout) :
723 _dimensions(dims),
724 _strides(computeStrides< size_type, dim_type >(dims, layout)),
725 _array(array),
726 _layout(layout),
727 _ptr(_array.getRawPtr()),
728 _next_axis(0)
729{
730 TEUCHOS_TEST_FOR_EXCEPTION(array.size() < computeSize(dims),
732 "Teuchos::ArrayView size too small for "
733 "dimensions");
734}
735
737
738template< typename T >
739MDArrayView< T >::MDArrayView(const Teuchos::ArrayView< T > & array,
740 const Teuchos::Array< dim_type > & dims,
741 const Teuchos::Array< size_type > & strides,
742 const Layout layout) :
743 _dimensions(dims),
744 _strides(strides),
745 _array(array),
746 _layout(layout),
747 _ptr(_array.getRawPtr()),
748 _next_axis(0)
749{
750 const size_type required = computeSize< const size_type,
751 const dim_type >(dims(),strides());
753 array.size() < required,
755 "Teuchos::ArrayView size too small for "
756 "dimensions and strides");
757}
758
760
761template< typename T >
763 _dimensions(array._dimensions),
764 _strides(array._strides),
765 _array(array._array),
766 _layout(array._layout),
767 _ptr(_array.getRawPtr()),
768 _next_axis(0)
769{
770}
771
773
774template< typename T >
776 int axis,
777 dim_type index) :
778 _dimensions(),
779 _strides(),
780 _array(),
781 _layout(parent._layout),
782 _ptr(),
783 _next_axis(0)
784{
785 // Make sure axis and index are valid
786 parent.assertAxis(axis);
787 parent.assertIndex(index, axis);
788 // Find the offset to the new MDArrayView
789 size_type offset = index * parent._strides[axis];
790 // Compute the dimensions of the new MDArrayView
791 size_type n = parent._dimensions.size();
792 // Compute the new dimensions and strides
793 if (n == 1)
794 {
795 _dimensions.push_back(1);
796 _strides.push_back(1);
797 }
798 else
799 {
800 for (int myAxis = 0; myAxis < n; myAxis++)
801 if (myAxis != axis)
802 {
803 _dimensions.push_back(parent._dimensions[myAxis]);
804 _strides.push_back(parent._strides[myAxis]);
805 }
806 }
807 // Compute the new MDArrayView and pointer
808 _array = parent._array.view(offset,
809 computeSize(_dimensions(),
810 _strides()));
811 _ptr = _array.getRawPtr();
812}
813
815
816template< typename T >
817MDArrayView< T >::MDArrayView(const MDArrayView< T > & parent,
818 int axis,
819 Slice slice) :
820 _dimensions(parent._dimensions),
821 _strides(parent._strides),
822 _array(),
823 _layout(parent._layout),
824 _ptr(),
825 _next_axis(0)
826{
827 // Make sure axis is valid
828 parent.assertAxis(axis);
829 // Note: the Slice.bounds() method produces safe indexes
830 Slice bounds = slice.bounds(_dimensions[axis]);
831 // Find the offset to the new MDArrayView
832 size_type offset = bounds.start() * _strides[axis];
833 // Compute the dimensions of the new MDArrayView
834 _dimensions[axis] = (bounds.stop() - bounds.start()) / bounds.step();
835 // Compute the strides of the new MDArrayView
836 _strides[axis] *= bounds.step();
837 // Compute the new MDArrayView and pointer
838 _array = parent._array.view(offset,
839 computeSize(_dimensions(),
840 _strides()));
841 _ptr = _array.getRawPtr();
842}
843
845
846template< typename T >
847MDArrayView< T > &
849{
850 _dimensions = array._dimensions;
851 _strides = array._strides;
852 _array = array._array;
853 _layout = array._layout;
854 _ptr = array._ptr;
855 _next_axis = array._next_axis;
856 return *this;
857}
858
860
861template< typename T >
865
867
868template< typename T >
869int
871{
872 return _dimensions.size();
873}
874
876
877template< typename T >
878const Teuchos::Array< dim_type > &
880{
881 return _dimensions;
882}
883
885
886template< typename T >
887dim_type
889{
890#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
891 assertAxis(axis);
892#endif
893 return _dimensions[axis];
894}
895
897
898template< typename T >
899size_type
901{
902 return computeSize(_dimensions(), _strides());
903}
904
906
907template< typename T >
908const Teuchos::Array< size_type > &
910{
911 return _strides;
912}
913
915
916template< typename T >
917const Teuchos::ArrayView< T > &
919{
920 return _array;
921}
922
924
925template< typename T >
926const Teuchos::ArrayView< const T > &
928{
929 return Teuchos::av_const_cast< const T >(_array);
930}
931
933
934template< typename T >
935Layout
937{
938 return _layout;
939}
940
942
943template< typename T >
944bool
946{
947 // Temporarily compute the strides this MDArrayView would have if
948 // its memory were contiguous with no stride gaps
949 Teuchos::Array< size_type > contig_strides =
950 computeStrides< size_type, dim_type >(_dimensions, _layout);
951 // If these strides are the same as the actual strides, then the
952 // MDArrayView is contiguous
953 return (contig_strides == _strides);
954}
955
957
958template< typename T >
961{
962 return iterator(*this);
963}
964
966
967template< typename T >
970{
971 // Return the iterator corresponding to the last element
972 return iterator(*this, true);
973}
974
976
977template< typename T >
980{
981 return const_iterator(getConst());
982}
983
985
986template< typename T >
989{
990 // Return the iterator corresponding to the last element
991 return const_iterator(getConst(), true);
992}
993
995
996template< typename T >
999{
1000 return const_iterator(getConst());
1001}
1002
1004
1005template< typename T >
1008{
1009 // Return the iterator corresponding to the last element
1010 return const_iterator(getConst(), true);
1011}
1012
1014
1015template< typename T >
1018{
1019 return reverse_iterator(*this);
1020}
1021
1023
1024template< typename T >
1027{
1028 // Return the reverse_iterator corresponding to the last element
1029 return reverse_iterator(*this, true);
1030}
1031
1033
1034template< typename T >
1037{
1038 return const_reverse_iterator(*this);
1039}
1040
1042
1043template< typename T >
1046{
1047 // Return the reverse_iterator corresponding to the last element
1048 return const_reverse_iterator(*this, true);
1049}
1050
1052
1053template< typename T >
1056{
1057 return MDArrayView< const T >(_array.getConst(),
1058 _dimensions,
1059 _strides,
1060 _layout);
1061}
1062
1064
1065template< typename T >
1068{
1069 // Construct the new MDArrayView
1070 MDArrayView< T > result(*this, _next_axis, i);
1071 // Correct the next axis of the new MDArrayView
1072 if (_next_axis < result.numDims())
1073 result._next_axis = _next_axis;
1074 // Return the result
1075 return result;
1076}
1077
1079
1080template< typename T >
1081const MDArrayView< T >
1083{
1084 // Construct the new MDArrayView
1085 MDArrayView< T > result(*this, _next_axis, i);
1086 // Correct the next axis of the new MDArrayView
1087 if (_next_axis < result.numDims())
1088 result._next_axis = _next_axis;
1089 // Return the result
1090 return result;
1091}
1092
1094
1095template< typename T >
1098{
1099 // Construct the new MDArrayView
1100 MDArrayView< T > result(*this, _next_axis, s);
1101 // Correct the next axis of the new MDArrayView
1102 result._next_axis = _next_axis + 1;
1103 if (result._next_axis >= _dimensions.size())
1104 result._next_axis = 0;
1105 // Return the result
1106 return result;
1107}
1108
1110
1111template< typename T >
1112const MDArrayView< T >
1114{
1115 // Construct the new MDArrayView
1116 MDArrayView< T > result(*this, _next_axis, s);
1117 // Correct the next axis of the new MDArrayView
1118 result._next_axis = _next_axis + 1;
1119 if (result._next_axis >= _dimensions.size())
1120 result._next_axis = 0;
1121 // Return the result
1122 return result;
1123}
1124
1126
1127template< typename T >
1128T &
1130{
1131#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1133 (_dimensions.size() != 1), RangeError,
1134 "Attempt to access " << _dimensions.size() << "D array with 1 index"
1135 );
1136 assertIndex(i, 0);
1137#endif
1138 return _ptr[i * _strides[0]];
1139}
1140
1142
1143template< typename T >
1144T &
1146 dim_type j)
1147{
1148#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1150 (_dimensions.size() != 2), RangeError,
1151 "Attempt to access " << _dimensions.size() << "D array with 2 indexes"
1152 );
1153 assertIndex(i, 0);
1154 assertIndex(j, 1);
1155#endif
1156 return _ptr[i * _strides[0] + j * _strides[1]];
1157}
1158
1160
1161template< typename T >
1162T &
1164 dim_type j,
1165 dim_type k)
1166{
1167#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1169 (_dimensions.size() != 3), RangeError,
1170 "Attempt to access " << _dimensions.size() << "D array with 3 indexes"
1171 );
1172 assertIndex(i, 0);
1173 assertIndex(j, 1);
1174 assertIndex(k, 2);
1175#endif
1176 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1177}
1178
1180
1181template< typename T >
1182T &
1184 dim_type j,
1185 dim_type k,
1186 dim_type m)
1187{
1188#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1190 (_dimensions.size() != 4), RangeError,
1191 "Attempt to access " << _dimensions.size() << "D array with 4 indexes"
1192 );
1193 assertIndex(i, 0);
1194 assertIndex(j, 1);
1195 assertIndex(k, 2);
1196 assertIndex(m, 3);
1197#endif
1198 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1199 m * _strides[3]];
1200}
1201
1203
1204template< typename T >
1205T &
1207 dim_type j,
1208 dim_type k,
1209 dim_type m,
1210 dim_type n)
1211{
1212#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1214 (_dimensions.size() != 5), RangeError,
1215 "Attempt to access " << _dimensions.size() << "D array with 5 indexes"
1216 );
1217 assertIndex(i, 0);
1218 assertIndex(j, 1);
1219 assertIndex(k, 2);
1220 assertIndex(m, 3);
1221 assertIndex(n, 4);
1222#endif
1223 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1224 m * _strides[3] + n * _strides[4]];
1225}
1226
1228
1229template< typename T >
1230T &
1232 dim_type j,
1233 dim_type k,
1234 dim_type m,
1235 dim_type n,
1236 dim_type p,
1237 ...)
1238{
1239#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1241 (_dimensions.size() < 6), RangeError,
1242 "Attempt to access " << _dimensions.size() << "D array with too many indexes"
1243 );
1244 assertIndex(i, 0);
1245 assertIndex(j, 1);
1246 assertIndex(k, 2);
1247 assertIndex(m, 3);
1248 assertIndex(n, 4);
1249 assertIndex(p, 5);
1250#endif
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++)
1256 {
1257 dim_type q = va_arg(indexes, dim_type);
1258#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1259 assertIndex(q, axis);
1260#endif
1261 offset += q * _strides[axis];
1262 }
1263 va_end(indexes);
1264 return _ptr[offset];
1265}
1266
1268
1269template< typename T >
1270const T &
1272{
1273#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1275 (_dimensions.size() != 1), RangeError,
1276 "Attempt to access " << _dimensions.size() << "D array with 1 index"
1277 );
1278 assertIndex(i, 0);
1279#endif
1280 return _ptr[i * _strides[0]];
1281}
1282
1284
1285template< typename T >
1286const T &
1288 dim_type j) const
1289{
1290#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1292 (_dimensions.size() != 2), RangeError,
1293 "Attempt to access " << _dimensions.size() << "D array with 2 indexes"
1294 );
1295 assertIndex(i, 0);
1296 assertIndex(j, 1);
1297#endif
1298 return _ptr[i * _strides[0] + j * _strides[1]];
1299}
1300
1302
1303template< typename T >
1304const T &
1306 dim_type j,
1307 dim_type k) const
1308{
1309#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1311 (_dimensions.size() != 3), RangeError,
1312 "Attempt to access " << _dimensions.size() << "D array with 3 indexes"
1313 );
1314 assertIndex(i, 0);
1315 assertIndex(j, 1);
1316 assertIndex(k, 2);
1317#endif
1318 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1319}
1320
1322
1323template< typename T >
1324const T &
1326 dim_type j,
1327 dim_type k,
1328 dim_type m) const
1329{
1330#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1332 (_dimensions.size() != 4), RangeError,
1333 "Attempt to access " << _dimensions.size() << "D array with 4 indexes"
1334 );
1335 assertIndex(i, 0);
1336 assertIndex(j, 1);
1337 assertIndex(k, 2);
1338 assertIndex(m, 3);
1339#endif
1340 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1341 m * _strides[3]];
1342}
1343
1345
1346template< typename T >
1347const T &
1349 dim_type j,
1350 dim_type k,
1351 dim_type m,
1352 dim_type n) const
1353{
1354#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1356 (_dimensions.size() != 5), RangeError,
1357 "Attempt to access " << _dimensions.size() << "D array with 5 indexes"
1358 );
1359 assertIndex(i, 0);
1360 assertIndex(j, 1);
1361 assertIndex(k, 2);
1362 assertIndex(m, 3);
1363 assertIndex(n, 4);
1364#endif
1365 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1366 m * _strides[3] + n * _strides[4]];
1367}
1368
1370
1371template< typename T >
1372const T &
1374 dim_type j,
1375 dim_type k,
1376 dim_type m,
1377 dim_type n,
1378 dim_type p,
1379 ...) const
1380{
1381#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1383 (_dimensions.size() < 6), RangeError,
1384 "Attempt to access " << _dimensions.size() << "D array with too many indexes"
1385 );
1386 assertIndex(i, 0);
1387 assertIndex(j, 1);
1388 assertIndex(k, 2);
1389 assertIndex(m, 3);
1390 assertIndex(n, 4);
1391 assertIndex(p, 5);
1392#endif
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++)
1398 {
1399 dim_type q = va_arg(indexes, dim_type);
1400#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1401 assertIndex(q, axis);
1402#endif
1403 offset += q * _strides[axis];
1404 }
1405 va_end(indexes);
1406 return _ptr[offset];
1407}
1408
1410
1411template< typename T >
1412void
1414{
1415 for (iterator it = begin(); it != end(); ++it)
1416 *it = value;
1417}
1418
1420
1421template< typename T >
1422T &
1424{
1425 assertIndex(i, 0);
1427 size_type offset = i * _strides[0];
1428 va_start(indexes, i);
1429 for (int axis = 1; axis < _dimensions.size(); axis++)
1430 {
1431 dim_type j = va_arg(indexes, dim_type);
1432 assertIndex(j, axis);
1433 offset += j * _strides[axis];
1434 }
1435 va_end(indexes);
1436 return _array[offset];
1437}
1438
1440
1441template< typename T >
1442const T &
1443MDArrayView< T >::at(dim_type i, ...) const
1444{
1445 assertIndex(i, 0);
1447 size_type offset = i * _strides[0];
1448 va_start(indexes, i);
1449 for (int axis = 1; axis < _dimensions.size(); axis++)
1450 {
1451 dim_type j = va_arg(indexes, dim_type);
1452 assertIndex(j, axis);
1453 offset += j * _strides[axis];
1454 }
1455 va_end(indexes);
1456 return _array[offset];
1457}
1458
1460
1461template< typename T >
1462bool
1464{
1465#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1466 return true;
1467#else
1468 return false;
1469#endif
1470}
1471
1473
1474template< typename T >
1475std::string
1477{
1478 // Call the private version of toString() with an indentation level
1479 // of zero
1480 return toString(0);
1481}
1482
1484
1485template< typename T >
1486std::string
1488{
1489 std::stringstream ss;
1490 ss << "[";
1491 for (size_type i = 0; i < _dimensions[0]; i++)
1492 {
1493 // If 1D, output an element, else output a sub-array recursively
1494 if (numDims() == 1)
1495 ss << operator()(i);
1496 else
1497 ss << operator[](i).toString(indent+1);
1498 // If not the last item along this axis, output a comma
1499 if (i < _dimensions[0]-1)
1500 {
1501 ss << ",";
1502 // If 1D, follow the comma with a space, else a newline and
1503 // indentation spacing
1504 if (numDims() == 1)
1505 ss << " ";
1506 else
1507 {
1508 ss << std::endl << " ";
1509 for (int ii = 0; ii < indent; ii++) ss << " ";
1510 }
1511 }
1512 }
1513 ss << "]";
1514 return ss.str();
1515}
1516
1518
1519template< typename T >
1520const T *
1522{
1523 return _array.getRawPtr();
1524}
1525
1527
1528template< typename T >
1529T *
1531{
1532 return _array.getRawPtr();
1533}
1534
1536
1537template< typename T >
1538bool operator==(const MDArrayView< T > & a1, const MDArrayView< T > & a2)
1539{
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)
1545 {
1546 if (*it1 != *it2) return false;
1547 }
1548 return true;
1549}
1550
1552
1553template< typename T >
1554bool operator!=(const MDArrayView< T > & a1, const MDArrayView< T > & a2)
1555{
1556 return not (a1 == a2);
1557}
1558
1560
1561template< typename T >
1563{
1564 a1.swap(a2);
1565}
1566
1568
1569template< typename T >
1570std::ostream & operator<<(std::ostream & os, const MDArrayView< T > & a)
1571{
1572 os << a.toString();
1573 return os;
1574}
1575
1577// Private implementations //
1579
1580template< typename T >
1581void
1582MDArrayView< T >::assertAxis(int axis) const
1583{
1585 !(0 <= axis && axis < _dimensions.size()),
1586 RangeError,
1587 "MDArrayView<T>::assertAxis(axis=" << axis << "): out of "
1588 << "range axis in [0, " << _dimensions.size() << ")"
1589 );
1590}
1591
1592template< typename T >
1593void
1594MDArrayView< T >::assertIndex(dim_type i, int axis) const
1595{
1597 !(0 <= i && i < _dimensions[axis]), RangeError,
1598 "MDArrayView<T>::assertIndex(i=" << i << ",axis=" << axis << "): out of "
1599 << "range i in [0, " << _dimensions[axis] << ")"
1600 );
1601}
1602
1603} // End namespace Domi
1604
1605#endif // DOMI_MDARRAYVIEW_HPP
A Slice defines a subset of a container.
Memory-safe templated multi-dimensional array class.
Definition Domi_MDArray.hpp:287
const Teuchos::Array< T > & array() const
Return the underlying Teuchos::Array
Definition Domi_MDArray.hpp:1055
MDArrayView< T > operator[](dim_type i)
Sub-array access operator. The returned MDArrayView object will have one fewer dimensions than the ca...
Definition Domi_MDArray.hpp:1225
std::string toString() const
Convert the MDArray to a string representation.
Definition Domi_MDArray.hpp:1705
void swap(MDArray< T > &a)
Swap this MDArray with the given MDArray
Definition Domi_MDArray.hpp:1672
MDArray()
Default constructor.
Definition Domi_MDArray.hpp:915
size_type size() const
Return the total size of the MDArray
Definition Domi_MDArray.hpp:1037
MDArrayView< T > operator()()
Conversion to non-const MDArrayView
Definition Domi_MDArray.hpp:1267
int numDims() const
Return the number of dimensions.
Definition Domi_MDArray.hpp:1007
iterator end()
Return the ending iterator.
Definition Domi_MDArray.hpp:1082
iterator begin()
Return the beginning iterator.
Definition Domi_MDArray.hpp:1073
Memory-safe templated multi-dimensional array view class.
Definition Domi_MDArrayView.hpp:115
const MDArrayView< T > operator[](dim_type i) const
Sub-array const access operator. The returned MDArrayView object will have one fewer dimensions than ...
Definition Domi_MDArrayView.hpp:1082
const_reverse_iterator crend() const
Return the ending const_reverse_iterator.
Definition Domi_MDArrayView.hpp:1045
const T & operator()(dim_type i) const
Const 1D element access operator.
Definition Domi_MDArrayView.hpp:1271
const T & const_reference
Const reference type.
Definition Domi_MDArrayView.hpp:134
const T & operator()(dim_type i, dim_type j) const
Const 2D element access operator.
Definition Domi_MDArrayView.hpp:1287
size_type size() const
Return the total size of the MDArrayView
Definition Domi_MDArrayView.hpp:900
reverse_iterator rbegin()
Return the beginning reverse_iterator.
Definition Domi_MDArrayView.hpp:1017
const T * getRawPtr() const
Return a const raw pointer to the beginning of the MDArrayView or NULL if unsized.
Definition Domi_MDArrayView.hpp:1521
const_reverse_iterator crbegin() const
Return the beginning const_reverse_iterator.
Definition Domi_MDArrayView.hpp:1036
friend bool operator!=(const MDArrayView< T2 > &a1, const MDArrayView< T2 > &a2)
Inequality operator.
bool operator!=(const MDArrayView< T > &a1, const MDArrayView< T > &a2)
Inequality operator.
Definition Domi_MDArrayView.hpp:1554
const T * const_pointer
Const pointer type.
Definition Domi_MDArrayView.hpp:128
friend void swap(MDArrayView< T2 > &a1, MDArrayView< T2 > &a2)
Swap function.
MDArrayView< const T > getConst() const
Return an MDArrayView< const T > of an MDArrayView< T > object.
Definition Domi_MDArrayView.hpp:1055
const Teuchos::Array< dim_type > & dimensions() const
Return the array of dimensions.
Definition Domi_MDArrayView.hpp:879
const T & operator()(dim_type i, dim_type j, dim_type k, dim_type m, dim_type n) const
Const 5D element access operator.
Definition Domi_MDArrayView.hpp:1348
bool operator==(const MDArrayView< T > &a1, const MDArrayView< T > &a2)
Equality operator.
Definition Domi_MDArrayView.hpp:1538
static bool hasBoundsChecking()
Return true if MDArrayView has been compiled with bounds checking on.
Definition Domi_MDArrayView.hpp:1463
iterator end()
Return the ending iterator.
Definition Domi_MDArrayView.hpp:969
MDArrayView< T > operator[](dim_type i)
Sub-array access operator. The returned MDArrayView object will have one fewer dimensions than the ca...
Definition Domi_MDArrayView.hpp:1067
MDArrayView(const MDArrayView< T > &array)
Copy constructor.
Definition Domi_MDArrayView.hpp:762
T & at(dim_type i,...)
Non-const single element access method with bounds checking.
Definition Domi_MDArrayView.hpp:1423
const_iterator begin() const
Return the beginning const_iterator.
Definition Domi_MDArrayView.hpp:979
std::string toString() const
Convert the MDArrayView to a string representation.
Definition Domi_MDArrayView.hpp:1476
const_iterator end() const
Return the ending const_iterator.
Definition Domi_MDArrayView.hpp:988
T & operator()(dim_type i, dim_type j, dim_type k, dim_type m)
Non-const 4D element access operator.
Definition Domi_MDArrayView.hpp:1183
T & operator()(dim_type i, dim_type j, dim_type k, dim_type m, dim_type n)
Non-const 5D element access operator.
Definition Domi_MDArrayView.hpp:1206
const Teuchos::Array< size_type > & strides() const
Return the indexing strides.
Definition Domi_MDArrayView.hpp:909
const T & operator()(dim_type i, dim_type j, dim_type k, dim_type m) const
Const 4D element access operator.
Definition Domi_MDArrayView.hpp:1325
T & operator()(dim_type i)
Non-const 1D element access operator.
Definition Domi_MDArrayView.hpp:1129
T & reference
Reference type.
Definition Domi_MDArrayView.hpp:131
MDArrayView(Teuchos::ENull null_arg=Teuchos::null)
Default constructor.
Definition Domi_MDArrayView.hpp:707
const Teuchos::ArrayView< T > & arrayView() const
Return the underlying Teuchos::ArrayView
Definition Domi_MDArrayView.hpp:918
T & operator()(dim_type i, dim_type j, dim_type k)
Non-const 3D element access operator.
Definition Domi_MDArrayView.hpp:1163
MDArrayView< T > & operator=(const MDArrayView< T > &array)
Assignment operator.
Definition Domi_MDArrayView.hpp:848
T * pointer
Pointer type.
Definition Domi_MDArrayView.hpp:125
MDArrayView(const Teuchos::ArrayView< T > &array, const Teuchos::ArrayView< dim_type > &dims, const Layout layout=DEFAULT_ORDER)
Constructor with a source Teuchos::ArrayView, dimensions, and optional storage order.
Definition Domi_MDArrayView.hpp:720
const_iterator cend() const
Return the ending const_iterator.
Definition Domi_MDArrayView.hpp:1007
T * getRawPtr()
Return a raw pointer to the beginning of the MDArrayView or NULL if unsized.
Definition Domi_MDArrayView.hpp:1530
dim_type dimension(int axis) const
Return the dimension of the given axis.
Definition Domi_MDArrayView.hpp:888
const MDArrayView< T > operator[](Slice s) const
Sub-array const access operator. The returned MDArrayView object will have the same number of dimensi...
Definition Domi_MDArrayView.hpp:1113
friend std::ostream & operator<<(std::ostream &os, const MDArrayView< T2 > &a)
Stream output operator.
const T & operator()(dim_type i, dim_type j, dim_type k, dim_type m, dim_type n, dim_type p,...) const
Const 6D and higher element access operator.
Definition Domi_MDArrayView.hpp:1373
~MDArrayView()
Destructor.
Definition Domi_MDArrayView.hpp:862
MDArrayView< T > operator[](Slice s)
Sub-array access operator. The returned MDArrayView object will have the same number of dimensions as...
Definition Domi_MDArrayView.hpp:1097
const Teuchos::ArrayView< const T > & arrayViewConst() const
Return const version of the underlying Teuchos::ArrayView
Definition Domi_MDArrayView.hpp:927
iterator begin()
Return the beginning iterator.
Definition Domi_MDArrayView.hpp:960
Layout layout() const
Return the storage order.
Definition Domi_MDArrayView.hpp:936
T & operator()(dim_type i, dim_type j)
Non-const 2D element access operator.
Definition Domi_MDArrayView.hpp:1145
const_iterator cbegin() const
Return the beginning const_iterator.
Definition Domi_MDArrayView.hpp:998
friend bool operator==(const MDArrayView< T2 > &a1, const MDArrayView< T2 > &a2)
Equality operator.
const T & operator()(dim_type i, dim_type j, dim_type k) const
Const 3D element access operator.
Definition Domi_MDArrayView.hpp:1305
bool contiguous() const
Return whether the MDArrayView is contiguous in memory.
Definition Domi_MDArrayView.hpp:945
void assign(const T &value)
Assign a value to all elements of the MDArrayView
Definition Domi_MDArrayView.hpp:1413
reverse_iterator rend()
Return the ending reverse_iterator.
Definition Domi_MDArrayView.hpp:1026
int numDims() const
Return the number of dimensions.
Definition Domi_MDArrayView.hpp:870
T & operator()(dim_type i, dim_type j, dim_type k, dim_type m, dim_type n, dim_type p,...)
Non-const 6D and higher element access operator.
Definition Domi_MDArrayView.hpp:1231
MDArrayView(const Teuchos::ArrayView< T > &array, const Teuchos::Array< dim_type > &dims, const Teuchos::Array< size_type > &strides, const Layout layout=DEFAULT_ORDER)
Constructor with a source Teuchos::ArrayView, dimensions, strides, and optional storage order.
Definition Domi_MDArrayView.hpp:739
const T & at(dim_type i,...) const
Const single element access method with bounds checking.
Definition Domi_MDArrayView.hpp:1443
T value_type
Value type.
Definition Domi_MDArrayView.hpp:122
Iterator class suitable for multi-dimensional arrays.
Definition Domi_MDIterator.hpp:102
Reverse iterator class suitable for multi-dimensional arrays.
Definition Domi_MDRevIterator.hpp:100
Range Error exception type.
Definition Domi_Exceptions.hpp:66
A Slice contains a start, stop, and step index, describing a subset of an ordered container.
Definition Domi_Slice.hpp:138

Generated for Domi by doxygen 1.10.0