MiniTensor Version of the Day
Loading...
Searching...
No Matches
MiniTensor_TensorBase.h
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MiniTensor Package
4//
5// Copyright 2016 NTESS and the MiniTensor contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#if !defined(MiniTensor_TensorBase_h)
11#define MiniTensor_TensorBase_h
12
13#include <algorithm>
14#include <cassert>
15#include <iostream>
16#include <vector>
17
18#include "MiniTensor_Storage.h"
19#include "MiniTensor_Scalar.h"
20
21namespace minitensor {
22
25
29enum class Filler {
30 ZEROS,
31 ONES,
33 RANDOM,
36 NANS
37};
38
47
51enum class Source {
52 ARRAY
53};
54
60template<typename T, typename ST>
62{
63public:
64
68 using value_type = T;
69
73 using storage_type = ST;
74
80
86 explicit
88 TensorBase(Index const dimension, Index const order);
89
97 TensorBase(Index const dimension, Index const order, Filler const value);
98
106 TensorBase(Index const dimension, Index const order, T const & s);
107
115 // TensorBase for Kokkos Data Types (we can 't use pointers with Kokkos::View)
116 template<class ArrayT>
119 Index const dimension,
120 Index const order,
121 ArrayT & data,
122 Index index1);
123
132 template<class ArrayT>
135 Index const dimension,
136 Index const order,
137 ArrayT & data,
138 Index index1,
139 Index index2);
140
150 template<class ArrayT>
153 Index const dimension,
154 Index const order,
155 ArrayT & data,
156 Index index1,
157 Index index2,
158 Index index3);
159
170 template<class ArrayT>
173 Index const dimension,
174 Index const order,
175 ArrayT & data,
176 Index index1,
177 Index index2,
178 Index index3,
179 Index index4);
180
192 template<class ArrayT>
195 Index const dimension,
196 Index const order,
197 ArrayT & data,
198 Index index1,
199 Index index2,
200 Index index3,
201 Index index4,
202 Index index5);
203
216 template<class ArrayT>
219 Index const dimension,
220 Index const order,
221 ArrayT & data,
222 Index index1,
223 Index index2,
224 Index index3,
225 Index index4,
226 Index index5,
227 Index index6);
228
229 //TensorBase for Shards and other data Types
237 TensorBase(Index const dimension, Index const order, T const * data_ptr);
244
252
258 T const &
259 operator[](Index const i) const;
260
266 T &
268
273 Index
275
281 void
282 fill(Filler const value);
283
289 void
290 fill(T const & s);
291
297 template<class ArrayT>
299 void
301 ArrayT & data,
302 Index index1);
303
310 template<class ArrayT>
312 void
314 ArrayT & data,
315 Index index1,
316 Index index2);
317
325 template<class ArrayT>
327 void
329 ArrayT & data,
330 Index index1,
331 Index index2,
332 Index index3);
333
342 template<class ArrayT>
344 void
346 ArrayT & data,
347 Index index1,
348 Index index2,
349 Index index3,
350 Index index4);
351
361 template<class ArrayT>
363 void
365 ArrayT & data,
366 Index index1,
367 Index index2,
368 Index index3,
369 Index index4,
370 Index index5);
371
382 template<class ArrayT>
384 void
386 ArrayT & data,
387 Index index1,
388 Index index2,
389 Index index3,
390 Index index4,
391 Index index5,
392 Index index6);
393
399 void fill(T const * data_ptr);
400
401
408 void
409 fill(T const * data_ptr, ComponentOrder const component_order);
410
415 template<typename S, typename SS>
419
424 template<typename S, typename SS>
428
433 template<typename S>
436 operator*=(S const & X);
437
442 template<typename S>
445 operator/=(S const & X);
446
451 void
453
454protected:
455
460 void
461 set_number_components(Index const number_components);
462
467 Index
468 get_dimension(Index const order) const;
469
475 void
476 set_dimension(Index const dimension, Index const order);
477
481 ST
483
487 Index
489};
490
494template<typename T, typename ST>
496T
497norm_f(TensorBase<T, ST> const & X);
498
502template<typename T, typename ST>
504T
505norm_f_square(TensorBase<T, ST> const & X);
506
510template<typename R, typename S, typename T, typename SR, typename SS,
511 typename ST>
513void
514add(
515 TensorBase<R, SR> const & A,
516 TensorBase<S, SS> const & B,
517 TensorBase<T, ST> & C);
518
522template<typename R, typename S, typename T, typename SR, typename SS,
523 typename ST>
525void
527 TensorBase<R, SR> const & A,
528 TensorBase<S, SS> const & B,
529 TensorBase<T, ST> & C);
530
534template<typename T, typename ST>
536void
537minus(TensorBase<T, ST> const & A, TensorBase<T, ST> & B);
538
542template<typename T, typename ST>
544bool
545equal(TensorBase<T, ST> const & A, TensorBase<T, ST> const & B);
546
550template<typename T, typename ST>
552bool
553not_equal(TensorBase<T, ST> const & A, TensorBase<T, ST> const & B);
554
558template<typename R, typename S, typename T, typename SR, typename ST>
560void
561scale(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B);
562
566template<typename R, typename S, typename T, typename SR, typename ST>
568void
569divide(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B);
570
574template<typename R, typename S, typename T, typename SR, typename ST>
576void
577split(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B);
578
579} // namespace minitensor
580
581namespace minitensor
582{
583
584//
585// Default constructor.
586//
587template<typename T, typename ST>
590{
591 Index const
592 static_size = ST::static_size();
593
594 set_number_components(static_size);
595 fill(Filler::NANS);
596
597 return;
598}
599
600//
601// Construction that initializes to NaNs
602//
603template<typename T, typename ST>
605TensorBase<T, ST>::TensorBase(Index const dimension, Index const order)
606{
607 set_dimension(dimension, order);
608 fill(Filler::NANS);
609 return;
610}
611
612//
613// Create with specified value
614//
615template<typename T, typename ST>
618 Index const dimension,
619 Index const order,
620 Filler const value)
621{
622 set_dimension(dimension, order);
623 fill(value);
624 return;
625}
626
627//
628// Construction from a scalar
629//
630template<typename T, typename ST>
633 Index const dimension,
634 Index const order,
635 T const & s)
636{
637 set_dimension(dimension, order);
638 fill(s);
639 return;
640}
641
642//
643// Construction from array
644//Kokkos data Types:
645template<typename T, typename ST>
646template<class ArrayT>
649 Index const dimension,
650 Index const order,
651 ArrayT & data,
652 Index index1)
653{
654 set_dimension(dimension, order);
655 fill(data, index1);
656 return;
657}
658
659template<typename T, typename ST>
660template<class ArrayT>
663 Index const dimension,
664 Index const order,
665 ArrayT & data,
666 Index index1,
667 Index index2)
668{
669 set_dimension(dimension, order);
670 fill(data, index1, index2);
671 return;
672}
673
674template<typename T, typename ST>
675template<class ArrayT>
678 Index const dimension,
679 Index const order,
680 ArrayT & data,
681 Index index1,
682 Index index2,
683 Index index3)
684{
685 set_dimension(dimension, order);
686 fill(data, index1, index2, index3);
687 return;
688}
689
690template<typename T, typename ST>
691template<class ArrayT>
694 Index const dimension,
695 Index const order,
696 ArrayT & data,
697 Index index1,
698 Index index2,
699 Index index3,
700 Index index4)
701{
702 set_dimension(dimension, order);
703 fill(data, index1, index2, index3, index4);
704 return;
705}
706
707template<typename T, typename ST>
708template<class ArrayT>
711 Index const dimension,
712 Index const order,
713 ArrayT & data,
714 Index index1,
715 Index index2,
716 Index index3,
717 Index index4,
718 Index index5)
719{
720 set_dimension(dimension, order);
721 fill(data, index1, index2, index3, index4, index5);
722 return;
723}
724
725template<typename T, typename ST>
726template<class ArrayT>
729 Index const dimension,
730 Index const order,
731 ArrayT & data,
732 Index index1,
733 Index index2,
734 Index index3,
735 Index index4,
736 Index index5,
737 Index index6)
738{
739 set_dimension(dimension, order);
740 fill(data, index1, index2, index3, index4, index5, index6);
741 return;
742}
743
744template<typename T, typename ST>
747 Index const dimension,
748 Index const order,
749 T const * data_ptr)
750{
751 set_dimension(dimension, order);
752 fill(data_ptr);
753 return;
754}
755
756//
757// Copy constructor
758//
759template<typename T, typename ST>
762 dimension_(X.dimension_)
763{
764 Index const
765 number_components = X.get_number_components();
766
767 set_number_components(number_components);
768
769 for (Index i = 0; i < number_components; ++i) {
770 (*this)[i] = X[i];
771 }
772
773 return;
774}
775
776//
777// Copy assignment
778//
779template<typename T, typename ST>
783{
784 if (this == &X) return *this;
785
786 dimension_ = X.dimension_;
787
788 Index const
789 number_components = X.get_number_components();
790
791 set_number_components(number_components);
792
793 for (Index i = 0; i < number_components; ++i) {
794 (*this)[i] = X[i];
795 }
796
797 return *this;
798}
799
800//
801// Get dimension
802//
803template<typename T, typename ST>
805Index
807{
808 return dimension_;
809}
810
811//
812// Set dimension
813//
814template<typename T, typename ST>
816void
817TensorBase<T, ST>::set_dimension(Index const dimension, Index const order)
818{
819 dimension_ = dimension;
820
821 Index const
822 number_components = integer_power(dimension, order);
823
824 set_number_components(number_components);
825
826 return;
827}
828
829//
830// Linear access to components
831//
832template<typename T, typename ST>
834T const &
836{
837 return components_[i];
838}
839
840//
841// Linear access to components
842//
843template<typename T, typename ST>
845T &
847{
848 return components_[i];
849}
850
851//
852// Get total number of components
853//
854template<typename T, typename ST>
856Index
858{
859 return components_.size();
860}
861
862//
863// Allocate space for components
864//
865template<typename T, typename ST>
867void
869{
870 using S = typename Sacado::ScalarType<T>::type;
871
872 Index const
873 old_size = get_number_components();
874
875 Index const
876 new_size = number_components;
877
878 if (new_size < old_size) {
879 for (auto i = new_size; i < old_size; ++i) {
880 auto & entry = (*this)[i];
881 fill_AD<T>(entry, not_a_number<S>());
882 entry = not_a_number<T>();
883 }
884 }
885
886 components_.resize(number_components);
887
888 if (new_size > old_size) {
889 for (auto i = old_size; i < new_size; ++i) {
890 auto & entry = (*this)[i];
891 fill_AD<T>(entry, not_a_number<S>());
892 entry = not_a_number<T>();
893 }
894 }
895
896 return;
897}
898
899//
900// Fill components with value.
901//
902template<typename T, typename ST>
904void
906{
907 using S = typename Sacado::ScalarType<T>::type;
908
909 Index const
910 number_components = get_number_components();
911
912 switch (value) {
913
914 case Filler::ZEROS:
915 for (Index i = 0; i < number_components; ++i) {
916 auto & entry = (*this)[i];
917 fill_AD<T>(entry, S(0));
918 entry = S(0);
919 }
920 break;
921
922 case Filler::ONES:
923 for (Index i = 0; i < number_components; ++i) {
924 auto & entry = (*this)[i];
925 fill_AD<T>(entry, S(0));
926 entry = S(1);
927 }
928 break;
929
930 case Filler::SEQUENCE:
931 for (Index i = 0; i < number_components; ++i) {
932 auto & entry = (*this)[i];
933 fill_AD<T>(entry, S(0));
934 entry = static_cast<S>(i);
935 }
936 break;
937
938 case Filler::NANS:
939 for (Index i = 0; i < number_components; ++i) {
940 auto & entry = (*this)[i];
941 fill_AD<T>(entry, not_a_number<S>());
942 entry = not_a_number<S>();
943 }
944 break;
945
946 case Filler::RANDOM:
947 KOKKOS_IF_ON_HOST((
948 for (Index i = 0; i < number_components; ++i) {
949 auto & entry = (*this)[i];
950 fill_AD<T>(entry, S(0));
951 entry = random<S>();
952 }
953 break;
954 ))
955 KOKKOS_IF_ON_DEVICE((
956 [[fallthrough]];
957 ))
958
960 KOKKOS_IF_ON_HOST((
961 for (Index i = 0; i < number_components; ++i) {
962 auto & entry = (*this)[i];
963 fill_AD<T>(entry, S(0));
964 entry = random_uniform<S>();
965 }
966 break;
967 ))
968 KOKKOS_IF_ON_DEVICE((
969 [[fallthrough]];
970 ))
971
973 KOKKOS_IF_ON_HOST((
974 for (Index i = 0; i < number_components; ++i) {
975 auto & entry = (*this)[i];
976 fill_AD<T>(entry, S(0));
977 entry = random_normal<S>();
978 }
979 break;
980 ))
981 KOKKOS_IF_ON_DEVICE((
982 [[fallthrough]];
983 ))
984
985 default:
986 MT_ERROR_EXIT("Unknown or undefined (in execution space) specification of "
987 "value for filling components.");
988 break;
989 }
990
991 return;
992}
993
994//
995// Fill components from argument
996//
997template<typename T, typename ST>
999void
1001{
1002 using S = typename Sacado::ScalarType<T>::type;
1003
1004 Index const
1005 number_components = get_number_components();
1006
1007 for (Index i = 0; i < number_components; ++i) {
1008 auto & entry = (*this)[i];
1009 fill_AD<T>(entry, S(0));
1010 entry = s;
1011 }
1012
1013 return;
1014}
1015
1016//
1017// Fill components from array defined by pointer.
1018//
1019template<typename T, typename ST>
1020template<class ArrayT>
1022void
1024 ArrayT & data,
1025 Index index1)
1026{
1027 assert(index1 == 0);
1028
1029 Index const
1030 number_components = get_number_components();
1031
1032 Index const
1033 rank = number_components / data.extent(0);
1034
1035 switch (rank) {
1036
1037 default:
1038 MT_ERROR_EXIT("Invalid rank.");
1039 break;
1040
1041 case 1:
1042 for (Index i = 0; i < number_components; ++i) {
1043 (*this)[i] = data(i);
1044 }
1045 break;
1046 }
1047
1048 return;
1049}
1050
1051template<typename T, typename ST>
1052template<class ArrayT>
1054void
1056 ArrayT & data,
1057 Index index1,
1058 Index index2)
1059{
1060 assert(index2 == 0);
1061
1062 Index const
1063 number_components = get_number_components();
1064
1065 Index
1066 rank = 0;
1067
1068 Index
1069 sub_dimension = number_components;
1070
1071 Index const
1072 dim = data.extent(1);
1073
1074 while (sub_dimension != 1) {
1075
1076 sub_dimension /= dim;
1077 ++rank;
1078
1079 assert(sub_dimension >= 1);
1080
1081 }
1082
1083 switch (rank) {
1084
1085 default:
1086 MT_ERROR_EXIT("Invalid rank.");
1087 break;
1088
1089 case 1:
1090 for (Index j = 0; j < number_components; ++j) {
1091 (*this)[j] = data(index1, j);
1092 }
1093 break;
1094
1095 case 2:
1096 for (Index i = 0; i < dim; ++i) {
1097 for (Index j = 0; j < dim; ++j) {
1098 (*this)[dim * i + j] = data(i, j);
1099 }
1100 }
1101 break;
1102 }
1103
1104 return;
1105}
1106
1107template<typename T, typename ST>
1108template<class ArrayT>
1110void
1112 ArrayT & data,
1113 Index index1,
1114 Index index2,
1115 Index index3)
1116{
1117 assert(index3 == 0);
1118
1119 Index const
1120 number_components = get_number_components();
1121
1122 Index const
1123 dim = data.extent(2);
1124
1125 Index
1126 rank = 0;
1127
1128 Index
1129 sub_dimension = number_components;
1130
1131 while (sub_dimension != 1) {
1132
1133 sub_dimension /= dim;
1134 ++rank;
1135
1136 assert(sub_dimension >= 1);
1137
1138 }
1139
1140 switch (rank) {
1141
1142 default:
1143 MT_ERROR_EXIT("Invalid rank.");
1144 break;
1145
1146 case 1:
1147 for (Index k = 0; k < number_components; ++k) {
1148 (*this)[k] = data(index1, index2, k);
1149 }
1150 break;
1151
1152 case 2:
1153 for (Index j = 0; j < dim; ++j) {
1154 for (Index k = 0; k < dim; ++k) {
1155 (*this)[dim * j + k] = data(index1, j, k);
1156 }
1157 }
1158 break;
1159
1160 case 3:
1161 for (Index i = 0; i < dim; ++i) {
1162 for (Index j = 0; j < dim; ++j) {
1163 for (Index k = 0; k < dim; ++k) {
1164 (*this)[dim * (dim * i + j) + k] = data(i, j, k);
1165 }
1166 }
1167 }
1168 break;
1169 }
1170
1171 return;
1172}
1173
1174template<typename T, typename ST>
1175template<class ArrayT>
1177void
1179 ArrayT & data,
1180 Index index1,
1181 Index index2,
1182 Index index3,
1183 Index index4)
1184{
1185 assert(index4 == 0);
1186
1187 Index const
1188 number_components = get_number_components();
1189
1190 Index const
1191 dim = data.extent(2);
1192
1193 Index
1194 rank = 0;
1195
1196 Index
1197 sub_dimension = number_components;
1198
1199 while (sub_dimension != 1) {
1200
1201 sub_dimension /= dim;
1202 ++rank;
1203
1204 assert(sub_dimension >= 1);
1205
1206 }
1207
1208 switch (rank) {
1209
1210 default:
1211 MT_ERROR_EXIT("Invalid rank.");
1212 break;
1213
1214 case 1:
1215 for (Index l = 0; l < number_components; ++l) {
1216 (*this)[l] = data(index1, index2, index3, l);
1217 }
1218 break;
1219
1220 case 2:
1221 for (Index k = 0; k < dim; ++k) {
1222 for (Index l = 0; l < dim; ++l) {
1223 (*this)[dim * k + l] = data(index1, index2, k, l);
1224 }
1225 }
1226 break;
1227
1228 case 3:
1229 for (Index j = 0; j < dim; ++j) {
1230 for (Index k = 0; k < dim; ++k) {
1231 for (Index l = 0; l < dim; ++l) {
1232 (*this)[dim * (dim * j + k) + l] = data(index1, j, k, l);
1233 }
1234 }
1235 }
1236 break;
1237
1238 case 4:
1239 for (Index i = 0; i < dim; ++i) {
1240 for (Index j = 0; j < dim; ++j) {
1241 for (Index k = 0; k < dim; ++k) {
1242 for (Index l = 0; l < dim; ++l) {
1243 (*this)[dim * (dim * (dim * i + j) + k) + l] =
1244 data(i, j, k, l);
1245 }
1246 }
1247 }
1248 }
1249 break;
1250 }
1251
1252 return;
1253}
1254
1255template<typename T, typename ST>
1256template<class ArrayT>
1258void
1260 ArrayT & data,
1261 Index index1,
1262 Index index2,
1263 Index index3,
1264 Index index4,
1265 Index index5)
1266{
1267 assert(index5 == 0);
1268
1269 Index const
1270 number_components = get_number_components();
1271
1272 Index const
1273 dim = data.extent(2);
1274
1275 Index
1276 rank = 0;
1277
1278 Index
1279 sub_dimension = number_components;
1280
1281 while (sub_dimension != 1) {
1282
1283 sub_dimension /= dim;
1284 ++rank;
1285
1286 assert(sub_dimension >= 1);
1287
1288 }
1289
1290 switch (rank) {
1291
1292 default:
1293 MT_ERROR_EXIT("Invalid rank.");
1294 break;
1295
1296 case 1:
1297 for (Index m = 0; m < number_components; ++m) {
1298 (*this)[m] = data(index1, index2, index3, index4, m);
1299 }
1300 break;
1301
1302 case 2:
1303 for (Index l = 0; l < dim; ++l) {
1304 for (Index m = 0; m < dim; ++m) {
1305 (*this)[dim * l + m] = data(index1, index2, index3, l, m);
1306 }
1307 }
1308 break;
1309
1310 case 3:
1311 for (Index k = 0; k < dim; ++k) {
1312 for (Index l = 0; l < dim; ++l) {
1313 for (Index m = 0; m < dim; ++m) {
1314 (*this)[dim * (dim * k + l) + m] = data(index1, index2, k, l, m);
1315 }
1316 }
1317 }
1318 break;
1319
1320 case 4:
1321 for (Index j = 0; j < dim; ++j) {
1322 for (Index k = 0; k < dim; ++k) {
1323 for (Index l = 0; l < dim; ++l) {
1324 for (Index m = 0; m < dim; ++m) {
1325 (*this)[dim * (dim * (dim * j + k) + l) + m] =
1326 data(index1, j, k, l, m);
1327 }
1328 }
1329 }
1330 }
1331 break;
1332
1333 case 5:
1334 for (Index i = 0; i < dim; ++i) {
1335 for (Index j = 0; j < dim; ++j) {
1336 for (Index k = 0; k < dim; ++k) {
1337 for (Index l = 0; l < dim; ++l) {
1338 for (Index m = 0; m < dim; ++m) {
1339 (*this)[dim * (dim * (dim * (dim * i + j) + k) + l) + m] =
1340 data(i, j, k, l, m);
1341 }
1342 }
1343 }
1344 }
1345 }
1346 break;
1347 }
1348
1349 return;
1350}
1351
1352template<typename T, typename ST>
1353template<class ArrayT>
1355void
1357 ArrayT & data,
1358 Index index1,
1359 Index index2,
1360 Index index3,
1361 Index index4,
1362 Index index5,
1363 Index index6)
1364{
1365 assert(index6 == 0);
1366
1367 Index const
1368 number_components = get_number_components();
1369
1370 Index const
1371 dim = data.extent(2);
1372
1373 Index
1374 rank = 0;
1375
1376 Index
1377 sub_dimension = number_components;
1378
1379 while (sub_dimension != 1) {
1380
1381 sub_dimension /= dim;
1382 ++rank;
1383
1384 assert(sub_dimension >= 1);
1385
1386 }
1387
1388 switch (rank) {
1389
1390 default:
1391 MT_ERROR_EXIT("Invalid rank.");
1392 break;
1393
1394 case 1:
1395 for (Index n = 0; n < number_components; ++n) {
1396 (*this)[n] = data(index1, index2, index3, index4, index5, n);
1397 }
1398 break;
1399
1400 case 2:
1401 for (Index m = 0; m < dim; ++m) {
1402 for (Index n = 0; n < dim; ++n) {
1403 (*this)[dim * m + n] = data(index1, index2, index3, index4, m, n);
1404 }
1405 }
1406 break;
1407
1408 case 3:
1409 for (Index l = 0; l < dim; ++l) {
1410 for (Index m = 0; m < dim; ++m) {
1411 for (Index n = 0; n < dim; ++n) {
1412 (*this)[dim * (dim * l + m) + n] =
1413 data(index1, index2, index3, l, m, n);
1414 }
1415 }
1416 }
1417 break;
1418
1419 case 4:
1420 for (Index k = 0; k < dim; ++k) {
1421 for (Index l = 0; l < dim; ++l) {
1422 for (Index m = 0; m < dim; ++m) {
1423 for (Index n = 0; n < dim; ++n) {
1424 (*this)[dim * (dim * (dim * k + l) + m) + n] =
1425 data(index1, index2, k, l, m, n);
1426 }
1427 }
1428 }
1429 }
1430 break;
1431
1432 case 5:
1433 for (Index j = 0; j < dim; ++j) {
1434 for (Index k = 0; k < dim; ++k) {
1435 for (Index l = 0; l < dim; ++l) {
1436 for (Index m = 0; m < dim; ++m) {
1437 for (Index n = 0; n < dim; ++n) {
1438 (*this)[dim * (dim * (dim * (dim * j + k) + l) + m) + n] =
1439 data(index1, j, k, l, m, n);
1440 }
1441 }
1442 }
1443 }
1444 }
1445 break;
1446
1447 case 6:
1448 for (Index i = 0; i < dim; ++i) {
1449 for (Index j = 0; j < dim; ++j) {
1450 for (Index k = 0; k < dim; ++k) {
1451 for (Index l = 0; l < dim; ++l) {
1452 for (Index m = 0; m < dim; ++m) {
1453 for (Index n = 0; n < dim; ++n) {
1454 (*this)[dim * (dim * (dim * (dim * (dim *
1455 i + j) + k) + l) + m) + n] = data(i, j, k, l, m, n);
1456 }
1457 }
1458 }
1459 }
1460 }
1461 }
1462 break;
1463 }
1464
1465 return;
1466}
1467template<typename T, typename ST>
1469void
1470TensorBase<T, ST>::fill(T const * data_ptr)
1471{
1472 assert(data_ptr != NULL);
1473
1474 Index const
1475 number_components = get_number_components();
1476
1477 for (Index i = 0; i < number_components; ++i) {
1478 (*this)[i] = data_ptr[i];
1479 }
1480
1481 return;
1482}
1483
1484//
1485// Fill components from array defined by pointer.
1486//
1487template<typename T, typename ST>
1489void
1491 T const * data_ptr,
1492 ComponentOrder const component_order)
1493{
1494 assert(data_ptr != NULL);
1495
1497 self = (*this);
1498
1499 Index const
1500 number_components = self.get_number_components();
1501
1502 switch (number_components) {
1503
1504 default:
1505 self.fill(data_ptr);
1506 break;
1507
1508 case 9:
1509
1510 switch (component_order) {
1511
1513 self.fill(data_ptr);
1514 break;
1515
1517 // 0 1 2 3 4 5 6 7 8
1518 // XX YY ZZ XY YZ ZX YX ZY XZ
1519 // 0 4 8 1 5 6 3 7 2
1520 self[0] = data_ptr[0];
1521 self[4] = data_ptr[1];
1522 self[8] = data_ptr[2];
1523
1524 self[1] = data_ptr[3];
1525 self[5] = data_ptr[4];
1526 self[6] = data_ptr[5];
1527
1528 self[3] = data_ptr[6];
1529 self[7] = data_ptr[7];
1530 self[2] = data_ptr[8];
1531 break;
1532
1534 self[0] = data_ptr[0];
1535 self[4] = data_ptr[1];
1536 self[8] = data_ptr[2];
1537
1538 self[1] = data_ptr[3];
1539 self[5] = data_ptr[4];
1540 self[6] = data_ptr[5];
1541
1542 self[3] = data_ptr[3];
1543 self[7] = data_ptr[4];
1544 self[2] = data_ptr[5];
1545 break;
1546
1547 default:
1548 MT_ERROR_EXIT("Unknown component order.");
1549 break;
1550
1551 }
1552
1553 break;
1554 }
1555
1556 return;
1557}
1558
1559//
1560// Component increment
1561//
1562template<typename T, typename ST>
1563template<typename S, typename SS>
1567{
1568 Index const
1569 number_components = get_number_components();
1570
1571 assert(number_components == X.get_number_components());
1572
1573 for (Index i = 0; i < number_components; ++i) {
1574 (*this)[i] += X[i];
1575 }
1576
1577 return *this;
1578}
1579
1580//
1581// Component decrement
1582//
1583template<typename T, typename ST>
1584template<typename S, typename SS>
1588{
1589 Index const
1590 number_components = get_number_components();
1591
1592 assert(number_components == X.get_number_components());
1593
1594 for (Index i = 0; i < number_components; ++i) {
1595 (*this)[i] -= X[i];
1596 }
1597
1598 return *this;
1599}
1600
1601//
1602// Component scale
1603//
1604template<typename T, typename ST>
1605template<typename S>
1609{
1610 Index const
1611 number_components = get_number_components();
1612
1613 for (Index i = 0; i < number_components; ++i) {
1614 (*this)[i] *= X;
1615 }
1616 return *this;
1617}
1618
1619//
1620// Component divide
1621//
1622template<typename T, typename ST>
1623template<typename S>
1627{
1628 Index const
1629 number_components = get_number_components();
1630
1631 for (Index i = 0; i < number_components; ++i) {
1632 (*this)[i] /= X;
1633 }
1634 return *this;
1635}
1636
1637//
1638// Fill with zeros
1639//
1640template<typename T, typename ST>
1642void
1644{
1645 fill(Filler::ZEROS);
1646 return;
1647}
1648
1649//
1650// Square of Frobenius norm
1651//
1652template<typename T, typename ST>
1654T
1656{
1657 T
1658 s = 0.0;
1659
1660 for (Index i = 0; i < X.get_number_components(); ++i) {
1661 s += X[i] * X[i];
1662 }
1663
1664 return s;
1665}
1666
1667//
1668// Frobenius norm
1669//
1670template<typename T, typename ST>
1672T
1674{
1675 T const
1676 s = norm_f_square(X);
1677
1678 if (s > 0.0) return std::sqrt(s);
1679
1680 return 0.0;
1681}
1682
1683//
1684// Base addition
1685//
1686template<typename R, typename S, typename T, typename SR, typename SS,
1687 typename ST>
1689void
1691 TensorBase<R, SR> const & A,
1692 TensorBase<S, SS> const & B,
1694 )
1695{
1696 Index const
1697 number_components = A.get_number_components();
1698
1699 assert(B.get_number_components() == number_components);
1700 assert(C.get_number_components() == number_components);
1701
1702 for (Index i = 0; i < number_components; ++i) {
1703 C[i] = A[i] + B[i];
1704 }
1705
1706 return;
1707}
1708
1709//
1710// Base subtraction
1711//
1712template<typename R, typename S, typename T, typename SR, typename SS,
1713 typename ST>
1715void
1717 TensorBase<R, SR> const & A,
1718 TensorBase<S, SS> const & B,
1720{
1721 Index const
1722 number_components = A.get_number_components();
1723
1724 assert(B.get_number_components() == number_components);
1725 assert(C.get_number_components() == number_components);
1726
1727 for (Index i = 0; i < number_components; ++i) {
1728 C[i] = A[i] - B[i];
1729 }
1730
1731 return;
1732}
1733
1734//
1735// Base minus
1736//
1737template<typename T, typename ST>
1739void
1741{
1742 Index const
1743 number_components = A.get_number_components();
1744
1745 assert(B.get_number_components() == number_components);
1746
1747 for (Index i = 0; i < number_components; ++i) {
1748 B[i] = -A[i];
1749 }
1750
1751 return;
1752}
1753
1754//
1755// Base equality
1756//
1757template<typename T, typename ST>
1759bool
1761{
1762 Index const
1763 number_components = A.get_number_components();
1764
1765 assert(B.get_number_components() == number_components);
1766
1767 for (Index i = 0; i < number_components; ++i) {
1768 if (A[i] != B[i]) return false;
1769 }
1770
1771 return true;
1772}
1773
1774//
1775// Base not equality
1776//
1777template<typename T, typename ST>
1779bool
1781{
1782 return !(equal(A, B));
1783}
1784
1785//
1786// Base scaling
1787//
1788template<typename R, typename S, typename T, typename SR, typename ST>
1790void
1791scale(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
1792{
1793 Index const
1794 number_components = A.get_number_components();
1795
1796 assert(B.get_number_components() == number_components);
1797
1798 for (Index i = 0; i < number_components; ++i) {
1799 B[i] = s * A[i];
1800 }
1801
1802 return;
1803}
1804
1805//
1806// Base division
1807//
1808template<typename R, typename S, typename T, typename SR, typename ST>
1810void
1811divide(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
1812{
1813 Index const
1814 number_components = A.get_number_components();
1815
1816 assert(B.get_number_components() == number_components);
1817
1818 for (Index i = 0; i < number_components; ++i) {
1819 B[i] = A[i] / s;
1820 }
1821
1822 return;
1823}
1824
1825//
1826// Base split (scalar divided by tensor)
1827//
1828template<typename R, typename S, typename T, typename SR, typename ST>
1830void
1831split(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
1832{
1833 Index const
1834 number_components = A.get_number_components();
1835
1836 assert(B.get_number_components() == number_components);
1837
1838 for (Index i = 0; i < number_components; ++i) {
1839 B[i] = s / A[i];
1840 }
1841
1842 return;
1843}
1844
1845} // namespace minitensor
1846namespace minitensor {
1847
1848// Placeholder for now.
1849
1851} // namespace minitensor
1852
1853#endif //MiniTensor_TensorBase_h
#define KOKKOS_INLINE_FUNCTION
#define MT_ERROR_EXIT(...)
KOKKOS_INLINE_FUNCTION void clear()
KOKKOS_INLINE_FUNCTION TensorBase< T, ST > & operator*=(S const &X)
KOKKOS_INLINE_FUNCTION void minus(TensorBase< T, ST > const &A, TensorBase< T, ST > &B)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1, Index index2, Index index3, Index index4, Index index5, Index index6)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1, Index index2, Index index3, Index index4)
KOKKOS_INLINE_FUNCTION void set_number_components(Index const number_components)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1, Index index2, Index index3, Index index4, Index index5)
KOKKOS_INLINE_FUNCTION void add(TensorBase< R, SR > const &A, TensorBase< S, SS > const &B, TensorBase< T, ST > &C)
KOKKOS_INLINE_FUNCTION T const & operator[](Index const i) const
KOKKOS_INLINE_FUNCTION void fill(T const *data_ptr, ComponentOrder const component_order)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1, Index index2, Index index3, Index index4, Index index5)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1, Index index2)
KOKKOS_INLINE_FUNCTION T norm_f(TensorBase< T, ST > const &X)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1, Index index2, Index index3, Index index4)
KOKKOS_INLINE_FUNCTION bool equal(TensorBase< T, ST > const &A, TensorBase< T, ST > const &B)
KOKKOS_INLINE_FUNCTION void fill(T const &s)
KOKKOS_INLINE_FUNCTION TensorBase< T, ST > & operator-=(TensorBase< S, SS > const &X)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1, Index index2)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1, Index index2, Index index3)
KOKKOS_INLINE_FUNCTION Index get_dimension(Index const order) const
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1)
KOKKOS_INLINE_FUNCTION void fill(T const *data_ptr)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1, Index index2, Index index3)
KOKKOS_INLINE_FUNCTION void fill(Filler const value)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order)
KOKKOS_INLINE_FUNCTION T norm_f_square(TensorBase< T, ST > const &X)
KOKKOS_INLINE_FUNCTION TensorBase()
KOKKOS_INLINE_FUNCTION void scale(TensorBase< R, SR > const &A, S const &s, TensorBase< T, ST > &B)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, T const *data_ptr)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, T const &s)
KOKKOS_INLINE_FUNCTION TensorBase< T, ST > & operator/=(S const &X)
KOKKOS_INLINE_FUNCTION TensorBase< T, ST > & operator=(TensorBase< T, ST > const &X)
KOKKOS_INLINE_FUNCTION T & operator[](Index const i)
KOKKOS_INLINE_FUNCTION void split(TensorBase< R, SR > const &A, S const &s, TensorBase< T, ST > &B)
KOKKOS_INLINE_FUNCTION TensorBase(TensorBase< T, ST > const &X)
KOKKOS_INLINE_FUNCTION TensorBase< T, ST > & operator+=(TensorBase< S, SS > const &X)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, Filler const value)
KOKKOS_INLINE_FUNCTION bool not_equal(TensorBase< T, ST > const &A, TensorBase< T, ST > const &B)
KOKKOS_INLINE_FUNCTION Index get_number_components() const
KOKKOS_INLINE_FUNCTION void set_dimension(Index const dimension, Index const order)
KOKKOS_INLINE_FUNCTION TensorBase(Index const dimension, Index const order, ArrayT &data, Index index1, Index index2, Index index3, Index index4, Index index5, Index index6)
KOKKOS_INLINE_FUNCTION void divide(TensorBase< R, SR > const &A, S const &s, TensorBase< T, ST > &B)
KOKKOS_INLINE_FUNCTION void fill(ArrayT &data, Index index1)
KOKKOS_INLINE_FUNCTION void subtract(TensorBase< R, SR > const &A, TensorBase< S, SS > const &B, TensorBase< T, ST > &C)
uint32_t Index
Indexing type.
KOKKOS_INLINE_FUNCTION T integer_power(T const &X, Index const exponent)