16#ifndef Intrepid2_Data_h
17#define Intrepid2_Data_h
23#include "Intrepid2_ScalarView.hpp"
41template<
class DataScalar,
typename DeviceType>
44 static ScalarView<DataScalar,DeviceType> zeroView()
46 static ScalarView<DataScalar,DeviceType> zeroView = ScalarView<DataScalar,DeviceType>(
"zero",1);
47 static bool havePushedFinalizeHook =
false;
48 if (!havePushedFinalizeHook)
50 Kokkos::push_finalize_hook( [=] {
51 zeroView = ScalarView<DataScalar,DeviceType>();
53 havePushedFinalizeHook =
true;
76 template<
class DataScalar,
typename DeviceType>
79 using value_type = DataScalar;
80 using execution_space =
typename DeviceType::execution_space;
82 using reference_type =
typename ScalarView<DataScalar,DeviceType>::reference_type;
83 using const_reference_type =
typename ScalarView<const DataScalar,DeviceType>::reference_type;
85 ordinal_type dataRank_;
86 Kokkos::View<DataScalar*, DeviceType> data1_;
87 Kokkos::View<DataScalar**, DeviceType> data2_;
88 Kokkos::View<DataScalar***, DeviceType> data3_;
89 Kokkos::View<DataScalar****, DeviceType> data4_;
90 Kokkos::View<DataScalar*****, DeviceType> data5_;
91 Kokkos::View<DataScalar******, DeviceType> data6_;
92 Kokkos::View<DataScalar*******, DeviceType> data7_;
93 Kokkos::Array<int,7> extents_;
94 Kokkos::Array<DataVariationType,7> variationType_;
95 Kokkos::Array<int,7> variationModulus_;
96 int blockPlusDiagonalLastNonDiagonal_ = -1;
98 bool hasNontrivialModulusUNUSED_;
99 bool underlyingMatchesLogical_;
100 Kokkos::Array<ordinal_type,7> activeDims_;
106 using return_type = const_reference_type;
108 ScalarView<DataScalar,DeviceType> zeroView_;
111 KOKKOS_INLINE_FUNCTION
114 return (lastNondiagonal + 1) * (lastNondiagonal + 1);
118 KOKKOS_INLINE_FUNCTION
121 return i * (lastNondiagonal + 1) + j;
125 KOKKOS_INLINE_FUNCTION
128 return i - (lastNondiagonal + 1) + numNondiagonalEntries;
132 KOKKOS_INLINE_FUNCTION
137 case 1:
return data1_.extent_int(dim);
138 case 2:
return data2_.extent_int(dim);
139 case 3:
return data3_.extent_int(dim);
140 case 4:
return data4_.extent_int(dim);
141 case 5:
return data5_.extent_int(dim);
142 case 6:
return data6_.extent_int(dim);
143 case 7:
return data7_.extent_int(dim);
151 zeroView_ = ZeroView<DataScalar,DeviceType>::zeroView();
153 for (
int d=rank_; d<7; d++)
155 INTREPID2_TEST_FOR_EXCEPTION(extents_[d] > 1, std::invalid_argument,
"Nominal extents may not be > 1 in dimensions beyond the rank of the container");
159 int blockPlusDiagonalCount = 0;
160 underlyingMatchesLogical_ =
true;
161 for (ordinal_type i=0; i<7; i++)
163 if (variationType_[i] ==
GENERAL)
165 if (extents_[i] != 0)
167 variationModulus_[i] = extents_[i];
171 variationModulus_[i] = 1;
173 activeDims_[numActiveDims_] = i;
176 else if (variationType_[i] ==
MODULAR)
178 underlyingMatchesLogical_ =
false;
182 const int logicalExtent = extents_[i];
183 const int modulus = dataExtent;
185 INTREPID2_TEST_FOR_EXCEPTION( dataExtent * (logicalExtent / dataExtent) != logicalExtent, std::invalid_argument,
"data extent must evenly divide logical extent");
187 variationModulus_[i] = modulus;
191 variationModulus_[i] = extents_[i];
193 activeDims_[numActiveDims_] = i;
198 underlyingMatchesLogical_ =
false;
199 blockPlusDiagonalCount++;
200 if (blockPlusDiagonalCount == 1)
203#ifdef HAVE_INTREPID2_DEBUG
206 const int logicalExtent = extents_[i];
207 const int numDiagonalEntries = logicalExtent - (blockPlusDiagonalLastNonDiagonal_ + 1);
208 const int expectedDataExtent = numNondiagonalEntries + numDiagonalEntries;
209 INTREPID2_TEST_FOR_EXCEPTION(dataExtent != expectedDataExtent, std::invalid_argument, (
"BLOCK_PLUS_DIAGONAL data extent of " + std::to_string(dataExtent) +
" does not match expected based on blockPlusDiagonalLastNonDiagonal setting of " + std::to_string(blockPlusDiagonalLastNonDiagonal_)).c_str());
212 activeDims_[numActiveDims_] = i;
216 INTREPID2_TEST_FOR_EXCEPTION(variationType_[i+1] !=
BLOCK_PLUS_DIAGONAL, std::invalid_argument,
"BLOCK_PLUS_DIAGONAL ranks must be contiguous");
218 variationModulus_[i] = 1;
219 INTREPID2_TEST_FOR_EXCEPTION(blockPlusDiagonalCount > 1, std::invalid_argument,
"BLOCK_PLUS_DIAGONAL can only apply to two ranks");
225 underlyingMatchesLogical_ =
false;
227 variationModulus_[i] = 1;
231 if (rank_ != dataRank_)
233 underlyingMatchesLogical_ =
false;
236 for (
int d=numActiveDims_; d<7; d++)
242 for (
int d=0; d<7; d++)
244 INTREPID2_TEST_FOR_EXCEPTION(variationModulus_[d] == 0, std::logic_error,
"variationModulus should not ever be 0");
250 template<
class UnaryOperator>
253 using ExecutionSpace =
typename DeviceType::execution_space;
259 const int dataRank = 1;
263 Kokkos::RangePolicy<ExecutionSpace> policy(ExecutionSpace(),0,dataExtent);
264 Kokkos::parallel_for(
"apply operator in-place", policy,
265 KOKKOS_LAMBDA (
const int &i0) {
266 view(i0) = unaryOperator(view(i0));
273 const int dataRank = 2;
277 Kokkos::parallel_for(
"apply operator in-place", policy,
278 KOKKOS_LAMBDA (
const int &i0,
const int &i1) {
279 view(i0,i1) = unaryOperator(view(i0,i1));
285 const int dataRank = 3;
289 Kokkos::parallel_for(
"apply operator in-place", policy,
290 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2) {
291 view(i0,i1,i2) = unaryOperator(view(i0,i1,i2));
297 const int dataRank = 4;
301 Kokkos::parallel_for(
"apply operator in-place", policy,
302 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2,
const int &i3) {
303 view(i0,i1,i2,i3) = unaryOperator(view(i0,i1,i2,i3));
309 const int dataRank = 5;
313 Kokkos::parallel_for(
"apply operator in-place", policy,
314 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2,
const int &i3,
const int &i4) {
315 view(i0,i1,i2,i3,i4) = unaryOperator(view(i0,i1,i2,i3,i4));
321 const int dataRank = 6;
325 Kokkos::parallel_for(
"apply operator in-place", policy,
326 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2,
const int &i3,
const int &i4,
const int &i5) {
327 view(i0,i1,i2,i3,i4,i5) = unaryOperator(view(i0,i1,i2,i3,i4,i5));
333 const int dataRank = 7;
337 const int dim_i6 = view.extent_int(6);
339 Kokkos::parallel_for(
"apply operator in-place", policy6,
340 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2,
const int &i3,
const int &i4,
const int &i5) {
341 for (
int i6=0; i6<dim_i6; i6++)
343 view(i0,i1,i2,i3,i4,i5,i6) = unaryOperator(view(i0,i1,i2,i3,i4,i5,i6));
349 INTREPID2_TEST_FOR_EXCEPTION(
true,std::invalid_argument,
"Unsupported data rank");
354 template<
class ...IntArgs>
355 KOKKOS_INLINE_FUNCTION
358 #ifdef INTREPID2_HAVE_DEBUG
361 constexpr int numArgs =
sizeof...(intArgs);
362 if (underlyingMatchesLogical_)
369 using int_type = std::tuple_element_t<0, std::tuple<IntArgs...>>;
371 const Kokkos::Array<int_type, numArgs+1> args {intArgs...,0};
372 Kokkos::Array<int_type, 7> refEntry;
373 for (
int d=0; d<numArgs; d++)
375 switch (variationType_[d])
377 case CONSTANT: refEntry[d] = 0;
break;
378 case GENERAL: refEntry[d] = args[d];
break;
379 case MODULAR: refEntry[d] = args[d] % variationModulus_[d];
break;
382 if (passThroughBlockDiagonalArgs)
384 refEntry[d] = args[d];
385 refEntry[d+1] = args[d+1];
392 const int_type &i = args[d];
399 const int_type &j = args[d+1];
401 if ((i >
static_cast<int_type
>(blockPlusDiagonalLastNonDiagonal_)) || (j >
static_cast<int_type
>(blockPlusDiagonalLastNonDiagonal_)))
427 for (
int d=numArgs; d<7; d++)
434 return data1_(refEntry[activeDims_[0]]);
436 else if (dataRank_ == 2)
438 return data2_(refEntry[activeDims_[0]],refEntry[activeDims_[1]]);
440 else if (dataRank_ == 3)
442 return data3_(refEntry[activeDims_[0]],refEntry[activeDims_[1]],refEntry[activeDims_[2]]);
444 else if (dataRank_ == 4)
446 return data4_(refEntry[activeDims_[0]],refEntry[activeDims_[1]],refEntry[activeDims_[2]],refEntry[activeDims_[3]]);
448 else if (dataRank_ == 5)
450 return data5_(refEntry[activeDims_[0]],refEntry[activeDims_[1]],refEntry[activeDims_[2]],refEntry[activeDims_[3]],
451 refEntry[activeDims_[4]]);
453 else if (dataRank_ == 6)
455 return data6_(refEntry[activeDims_[0]],refEntry[activeDims_[1]],refEntry[activeDims_[2]],refEntry[activeDims_[3]],
456 refEntry[activeDims_[4]],refEntry[activeDims_[5]]);
460 return data7_(refEntry[activeDims_[0]],refEntry[activeDims_[1]],refEntry[activeDims_[2]],refEntry[activeDims_[3]],
461 refEntry[activeDims_[4]],refEntry[activeDims_[5]],refEntry[activeDims_[6]]);
467 template<
class ...IntArgs>
468 KOKKOS_INLINE_FUNCTION
475 template<
class ToContainer,
class FromContainer>
479 auto policy = Kokkos::MDRangePolicy<execution_space,Kokkos::Rank<6>>({0,0,0,0,0,0},{from.extent_int(0),from.extent_int(1),from.extent_int(2), from.extent_int(3), from.extent_int(4), from.extent_int(5)});
481 Kokkos::parallel_for(
"copyContainer", policy,
482 KOKKOS_LAMBDA (
const int &i0,
const int &i1,
const int &i2,
const int &i3,
const int &i4,
const int &i5) {
483 for (
int i6=0; i6<from.extent_int(6); i6++)
485 to.access(i0,i1,i2,i3,i4,i5,i6) = from.access(i0,i1,i2,i3,i4,i5,i6);
496 case 1: data1_ = Kokkos::View<DataScalar*, DeviceType>(
"Intrepid2 Data", data.extent_int(0));
break;
497 case 2: data2_ = Kokkos::View<DataScalar**, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1));
break;
498 case 3: data3_ = Kokkos::View<DataScalar***, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1), data.extent_int(2));
break;
499 case 4: data4_ = Kokkos::View<DataScalar****, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1), data.extent_int(2), data.extent_int(3));
break;
500 case 5: data5_ = Kokkos::View<DataScalar*****, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1), data.extent_int(2), data.extent_int(3), data.extent_int(4));
break;
501 case 6: data6_ = Kokkos::View<DataScalar******, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1), data.extent_int(2), data.extent_int(3), data.extent_int(4), data.extent_int(5));
break;
502 case 7: data7_ = Kokkos::View<DataScalar*******, DeviceType>(
"Intrepid2 Data", data.extent_int(0), data.extent_int(1), data.extent_int(2), data.extent_int(3), data.extent_int(4), data.extent_int(5), data.extent_int(6));
break;
503 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
515 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
520 Data(std::vector<DimensionInfo> dimInfoVector)
523 dataRank_(0), extents_({0,0,0,0,0,0,0}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(-1), rank_(dimInfoVector.size())
527 if (dimInfoVector.size() != 0)
529 std::vector<int> dataExtents;
531 bool blockPlusDiagonalEncountered =
false;
532 for (
int d=0; d<rank_; d++)
534 const DimensionInfo & dimInfo = dimInfoVector[d];
535 extents_[d] = dimInfo.logicalExtent;
536 variationType_[d] = dimInfo.variationType;
537 const bool isBlockPlusDiagonal = (variationType_[d] == BLOCK_PLUS_DIAGONAL);
538 const bool isSecondBlockPlusDiagonal = isBlockPlusDiagonal && blockPlusDiagonalEncountered;
539 if (isBlockPlusDiagonal)
541 blockPlusDiagonalEncountered =
true;
542 blockPlusDiagonalLastNonDiagonal_ = dimInfo.blockPlusDiagonalLastNonDiagonal;
544 if ((variationType_[d] != CONSTANT) && (!isSecondBlockPlusDiagonal))
546 dataExtents.push_back(dimInfo.dataExtent);
549 if (dataExtents.size() == 0)
552 dataExtents.push_back(1);
554 dataRank_ = dataExtents.size();
557 case 1: data1_ = Kokkos::View<DataScalar*, DeviceType>(
"Intrepid2 Data", dataExtents[0]);
break;
558 case 2: data2_ = Kokkos::View<DataScalar**, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1]);
break;
559 case 3: data3_ = Kokkos::View<DataScalar***, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1], dataExtents[2]);
break;
560 case 4: data4_ = Kokkos::View<DataScalar****, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1], dataExtents[2], dataExtents[3]);
break;
561 case 5: data5_ = Kokkos::View<DataScalar*****, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1], dataExtents[2], dataExtents[3], dataExtents[4]);
break;
562 case 6: data6_ = Kokkos::View<DataScalar******, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1], dataExtents[2], dataExtents[3], dataExtents[4], dataExtents[5]);
break;
563 case 7: data7_ = Kokkos::View<DataScalar*******, DeviceType>(
"Intrepid2 Data", dataExtents[0], dataExtents[1], dataExtents[2], dataExtents[3], dataExtents[4], dataExtents[5], dataExtents[6]);
break;
564 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
580 template<typename OtherDeviceType, class = typename std::enable_if< std::is_same<typename DeviceType::memory_space, typename OtherDeviceType::memory_space>::value>::type,
581 class = typename std::enable_if<!std::is_same<DeviceType,OtherDeviceType>::value>::type>
582 Data(const Data<DataScalar,OtherDeviceType> &data)
584 dataRank_(data.getUnderlyingViewRank()), extents_(data.getExtents()), variationType_(data.getVariationTypes()), blockPlusDiagonalLastNonDiagonal_(data.blockPlusDiagonalLastNonDiagonal()), rank_(data.rank())
589 const auto view = data.getUnderlyingView();
592 case 1: data1_ = data.getUnderlyingView1();
break;
593 case 2: data2_ = data.getUnderlyingView2();
break;
594 case 3: data3_ = data.getUnderlyingView3();
break;
595 case 4: data4_ = data.getUnderlyingView4();
break;
596 case 5: data5_ = data.getUnderlyingView5();
break;
597 case 6: data6_ = data.getUnderlyingView6();
break;
598 case 7: data7_ = data.getUnderlyingView7();
break;
599 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
606 template<typename OtherDeviceType, class = typename std::enable_if<!std::is_same<typename DeviceType::memory_space, typename OtherDeviceType::memory_space>::value>::type>
617 case 1: data1_ = Kokkos::View<DataScalar*, DeviceType>(
"Intrepid2 Data", view.extent_int(0));
break;
618 case 2: data2_ = Kokkos::View<DataScalar**, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1));
break;
619 case 3: data3_ = Kokkos::View<DataScalar***, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1), view.extent_int(2));
break;
620 case 4: data4_ = Kokkos::View<DataScalar****, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1), view.extent_int(2), view.extent_int(3));
break;
621 case 5: data5_ = Kokkos::View<DataScalar*****, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1), view.extent_int(2), view.extent_int(3), view.extent_int(4));
break;
622 case 6: data6_ = Kokkos::View<DataScalar******, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1), view.extent_int(2), view.extent_int(3), view.extent_int(4), view.extent_int(5));
break;
623 case 7: data7_ = Kokkos::View<DataScalar*******, DeviceType>(
"Intrepid2 Data", view.extent_int(0), view.extent_int(1), view.extent_int(2), view.extent_int(3), view.extent_int(4), view.extent_int(5), view.extent_int(6));
break;
624 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
630 using MemorySpace =
typename DeviceType::memory_space;
633 case 1: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView1());
copyContainer(data1_, dataViewMirror);}
break;
634 case 2: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView2());
copyContainer(data2_, dataViewMirror);}
break;
635 case 3: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView3());
copyContainer(data3_, dataViewMirror);}
break;
636 case 4: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView4());
copyContainer(data4_, dataViewMirror);}
break;
637 case 5: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView5());
copyContainer(data5_, dataViewMirror);}
break;
638 case 6: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView6());
copyContainer(data6_, dataViewMirror);}
break;
639 case 7: {
auto dataViewMirror = Kokkos::create_mirror_view_and_copy(MemorySpace(), data.
getUnderlyingView7());
copyContainer(data7_, dataViewMirror);}
break;
640 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
688 Data(ScalarView<DataScalar,DeviceType> data)
692 Kokkos::Array<int,7> {data.extent_int(0),data.extent_int(1),data.extent_int(2),data.extent_int(3),data.extent_int(4),data.extent_int(5),data.extent_int(6)},
697 template<
size_t rank,
class ...DynRankViewProperties>
698 Data(
const Kokkos::DynRankView<DataScalar,DeviceType, DynRankViewProperties...> &data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
700 dataRank_(data.
rank()), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
704 for (
unsigned d=0; d<
rank; d++)
706 extents_[d] = extents[d];
707 variationType_[d] = variationType[d];
712 template<
size_t rank,
class ...ViewProperties>
713 Data(Kokkos::View<DataScalar*,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
715 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
718 for (
unsigned d=0; d<
rank; d++)
720 extents_[d] = extents[d];
721 variationType_[d] = variationType[d];
726 template<
size_t rank,
class ...ViewProperties>
727 Data(Kokkos::View<DataScalar**,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
729 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
732 for (
unsigned d=0; d<
rank; d++)
734 extents_[d] = extents[d];
735 variationType_[d] = variationType[d];
740 template<
size_t rank,
class ...ViewProperties>
741 Data(Kokkos::View<DataScalar***,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
743 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
746 for (
unsigned d=0; d<
rank; d++)
748 extents_[d] = extents[d];
749 variationType_[d] = variationType[d];
754 template<
size_t rank,
class ...ViewProperties>
755 Data(Kokkos::View<DataScalar****,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
757 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
760 for (
unsigned d=0; d<
rank; d++)
762 extents_[d] = extents[d];
763 variationType_[d] = variationType[d];
768 template<
size_t rank,
class ...ViewProperties>
769 Data(Kokkos::View<DataScalar*****,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
771 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
774 for (
unsigned d=0; d<
rank; d++)
776 extents_[d] = extents[d];
777 variationType_[d] = variationType[d];
782 template<
size_t rank,
class ...ViewProperties>
783 Data(Kokkos::View<DataScalar******,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
785 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
788 for (
unsigned d=0; d<
rank; d++)
790 extents_[d] = extents[d];
791 variationType_[d] = variationType[d];
796 template<
size_t rank,
class ...ViewProperties>
797 Data(Kokkos::View<DataScalar*******,DeviceType, ViewProperties...> data, Kokkos::Array<int,rank> extents, Kokkos::Array<DataVariationType,rank> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
799 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
802 for (
unsigned d=0; d<
rank; d++)
804 extents_[d] = extents[d];
805 variationType_[d] = variationType[d];
811 template<
class ViewScalar,
class ...ViewProperties>
812 Data(
const unsigned rank, Kokkos::View<ViewScalar,DeviceType, ViewProperties...> data, Kokkos::Array<int,7> extents, Kokkos::Array<DataVariationType,7> variationType,
const int blockPlusDiagonalLastNonDiagonal = -1)
814 dataRank_(data.
rank), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(
blockPlusDiagonalLastNonDiagonal), rank_(
rank)
816 setUnderlyingView<data.rank>(data);
817 for (
unsigned d=0; d<
rank; d++)
819 extents_[d] = extents[d];
820 variationType_[d] = variationType[d];
826 template<
size_t rank>
827 Data(DataScalar constantValue, Kokkos::Array<int,rank> extents)
829 dataRank_(1), extents_({1,1,1,1,1,1,1}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(-1), rank_(
rank)
831 data1_ = Kokkos::View<DataScalar*,DeviceType>(
"Constant Data",1);
832 Kokkos::deep_copy(data1_, constantValue);
833 for (
unsigned d=0; d<
rank; d++)
835 extents_[d] = extents[d];
843 dataRank_(0), extents_({0,0,0,0,0,0,0}), variationType_({
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT,
CONSTANT}), blockPlusDiagonalLastNonDiagonal_(-1), rank_(0)
849 KOKKOS_INLINE_FUNCTION
852 return blockPlusDiagonalLastNonDiagonal_;
856 KOKKOS_INLINE_FUNCTION
863 KOKKOS_INLINE_FUNCTION
869 dimInfo.variationType = variationType_[dim];
871 dimInfo.variationModulus = variationModulus_[dim];
875 dimInfo.blockPlusDiagonalLastNonDiagonal = blockPlusDiagonalLastNonDiagonal_;
881 KOKKOS_INLINE_FUNCTION
892 KOKKOS_INLINE_FUNCTION
893 enable_if_t<rank==1, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
896 #ifdef HAVE_INTREPID2_DEBUG
904 KOKKOS_INLINE_FUNCTION
905 enable_if_t<rank==2, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
908 #ifdef HAVE_INTREPID2_DEBUG
916 KOKKOS_INLINE_FUNCTION
917 enable_if_t<rank==3, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
920 #ifdef HAVE_INTREPID2_DEBUG
928 KOKKOS_INLINE_FUNCTION
929 enable_if_t<rank==4, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
932 #ifdef HAVE_INTREPID2_DEBUG
940 KOKKOS_INLINE_FUNCTION
941 enable_if_t<rank==5, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
944 #ifdef HAVE_INTREPID2_DEBUG
952 KOKKOS_INLINE_FUNCTION
953 enable_if_t<rank==6, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
956 #ifdef HAVE_INTREPID2_DEBUG
964 KOKKOS_INLINE_FUNCTION
965 enable_if_t<rank==7, const Kokkos::View<typename RankExpander<DataScalar, rank>::value_type, DeviceType> &>
968 #ifdef HAVE_INTREPID2_DEBUG
975 KOKKOS_INLINE_FUNCTION
982 KOKKOS_INLINE_FUNCTION
989 KOKKOS_INLINE_FUNCTION
996 KOKKOS_INLINE_FUNCTION
1003 KOKKOS_INLINE_FUNCTION
1010 KOKKOS_INLINE_FUNCTION
1017 KOKKOS_INLINE_FUNCTION
1024 KOKKOS_INLINE_FUNCTION
1031 KOKKOS_INLINE_FUNCTION
1038 KOKKOS_INLINE_FUNCTION
1045 KOKKOS_INLINE_FUNCTION
1052 KOKKOS_INLINE_FUNCTION
1059 KOKKOS_INLINE_FUNCTION
1066 KOKKOS_INLINE_FUNCTION
1072 template<
int underlyingRank,
class ViewScalar>
1073 KOKKOS_INLINE_FUNCTION
1074 void setUnderlyingView(
const Kokkos::View<ViewScalar, DeviceType> & view)
1076 if constexpr (underlyingRank == 1)
1080 else if constexpr (underlyingRank == 2)
1084 else if constexpr (underlyingRank == 3)
1088 else if constexpr (underlyingRank == 4)
1092 else if constexpr (underlyingRank == 5)
1096 else if constexpr (underlyingRank == 6)
1100 else if constexpr (underlyingRank == 7)
1115 case 1:
return data1_;
1116 case 2:
return data2_;
1117 case 3:
return data3_;
1118 case 4:
return data4_;
1119 case 5:
return data5_;
1120 case 6:
return data6_;
1121 case 7:
return data7_;
1122 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
1127 KOKKOS_INLINE_FUNCTION
1134 KOKKOS_INLINE_FUNCTION
1137 ordinal_type size = 1;
1138 for (ordinal_type r=0; r<dataRank_; r++)
1152 case 3:
return getMatchingViewWithLabel(data3_,
"Intrepid2 Data", data3_.extent_int(0), data3_.extent_int(1), data3_.extent_int(2));
1153 case 4:
return getMatchingViewWithLabel(data4_,
"Intrepid2 Data", data4_.extent_int(0), data4_.extent_int(1), data4_.extent_int(2), data4_.extent_int(3));
1154 case 5:
return getMatchingViewWithLabel(data5_,
"Intrepid2 Data", data5_.extent_int(0), data5_.extent_int(1), data5_.extent_int(2), data5_.extent_int(3), data5_.extent_int(4));
1155 case 6:
return getMatchingViewWithLabel(data6_,
"Intrepid2 Data", data6_.extent_int(0), data6_.extent_int(1), data6_.extent_int(2), data6_.extent_int(3), data6_.extent_int(4), data6_.extent_int(5));
1156 case 7:
return getMatchingViewWithLabel(data7_,
"Intrepid2 Data", data7_.extent_int(0), data7_.extent_int(1), data7_.extent_int(2), data7_.extent_int(3), data7_.extent_int(4), data7_.extent_int(5), data7_.extent_int(6));
1157 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
1162 template<
class ... DimArgs>
1174 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
1183 case 1: Kokkos::deep_copy(data1_, 0.0);
break;
1184 case 2: Kokkos::deep_copy(data2_, 0.0);
break;
1185 case 3: Kokkos::deep_copy(data3_, 0.0);
break;
1186 case 4: Kokkos::deep_copy(data4_, 0.0);
break;
1187 case 5: Kokkos::deep_copy(data5_, 0.0);
break;
1188 case 6: Kokkos::deep_copy(data6_, 0.0);
break;
1189 case 7: Kokkos::deep_copy(data7_, 0.0);
break;
1190 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
1207 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Invalid data rank");
1214 for (
int i=0; i<numActiveDims_; i++)
1216 if (activeDims_[i] == d)
1220 else if (activeDims_[i] > d)
1239 KOKKOS_INLINE_FUNCTION
1242 return variationModulus_[d];
1246 KOKKOS_INLINE_FUNCTION
1249 return variationType_;
1253 template<
class ...IntArgs>
1254 KOKKOS_INLINE_FUNCTION
1261 template<
class ...IntArgs>
1262 KOKKOS_INLINE_FUNCTION
1270 template <
bool... v>
1273 template <
class ...IntArgs>
1274 using valid_args = all_true<std::is_integral<IntArgs>{}...>;
1276 static_assert(valid_args<int,long,unsigned>::value,
"valid args works");
1279 template <
class ...IntArgs>
1280 KOKKOS_INLINE_FUNCTION
1281#ifndef __INTEL_COMPILER
1285 enable_if_t<valid_args<IntArgs...>::value && (
sizeof...(IntArgs) <= 7),return_type>
1289 operator()(
const IntArgs&... intArgs)
const {
1294 KOKKOS_INLINE_FUNCTION
1300 template <
typename iType>
1301 KOKKOS_INLINE_FUNCTION
constexpr
1302 typename std::enable_if<std::is_integral<iType>::value,
size_t>::type
1303 extent(
const iType& r)
const {
1310 if (blockPlusDiagonalLastNonDiagonal_ >= 1)
return false;
1311 int numBlockPlusDiagonalTypes = 0;
1312 for (
unsigned r = 0; r<variationType_.size(); r++)
1314 const auto &entryType = variationType_[r];
1318 if (numBlockPlusDiagonalTypes == 2)
return true;
1319 else if (numBlockPlusDiagonalTypes == 0)
return false;
1341 std::vector<DimensionInfo> dimInfo(
rank);
1342 for (
int d=0; d<
rank; d++)
1362 const int D1_DIM = A_MatData.
rank() - 2;
1363 const int D2_DIM = A_MatData.
rank() - 1;
1365 const int A_rows = A_MatData.
extent_int(D1_DIM);
1366 const int A_cols = A_MatData.
extent_int(D2_DIM);
1367 const int B_rows = B_MatData.
extent_int(D1_DIM);
1368 const int B_cols = B_MatData.
extent_int(D2_DIM);
1370 const int leftRows = transposeA ? A_cols : A_rows;
1371 const int leftCols = transposeA ? A_rows : A_cols;
1372 const int rightRows = transposeB ? B_cols : B_rows;
1373 const int rightCols = transposeB ? B_rows : B_cols;
1375 INTREPID2_TEST_FOR_EXCEPTION(leftCols != rightRows, std::invalid_argument,
"incompatible matrix dimensions");
1377 Kokkos::Array<int,7> resultExtents;
1378 Kokkos::Array<DataVariationType,7> resultVariationTypes;
1380 resultExtents[D1_DIM] = leftRows;
1381 resultExtents[D2_DIM] = rightCols;
1382 int resultBlockPlusDiagonalLastNonDiagonal = -1;
1391 const int resultRank = A_MatData.
rank();
1396 Kokkos::Array<int,7> resultActiveDims;
1397 Kokkos::Array<int,7> resultDataDims;
1398 int resultNumActiveDims = 0;
1400 for (
int i=0; i<resultRank-2; i++)
1415 if ((A_VariationType ==
GENERAL) || (B_VariationType ==
GENERAL))
1417 resultVariationType =
GENERAL;
1418 dataSize = resultExtents[i];
1425 else if ((B_VariationType ==
MODULAR) && (A_VariationType ==
CONSTANT))
1427 resultVariationType =
MODULAR;
1430 else if ((B_VariationType ==
CONSTANT) && (A_VariationType ==
MODULAR))
1432 resultVariationType =
MODULAR;
1441 resultVariationType =
MODULAR;
1442 dataSize = A_Modulus;
1444 resultVariationTypes[i] = resultVariationType;
1446 if (resultVariationType !=
CONSTANT)
1448 resultActiveDims[resultNumActiveDims] = i;
1449 resultDataDims[resultNumActiveDims] = dataSize;
1450 resultNumActiveDims++;
1455 resultExtents[D1_DIM] = leftRows;
1456 resultExtents[D2_DIM] = rightCols;
1465 resultActiveDims[resultNumActiveDims] = resultRank - 2;
1467 const int numDiagonalEntries = leftRows - (resultBlockPlusDiagonalLastNonDiagonal + 1);
1468 const int numNondiagonalEntries = (resultBlockPlusDiagonalLastNonDiagonal + 1) * (resultBlockPlusDiagonalLastNonDiagonal + 1);
1470 resultDataDims[resultNumActiveDims] = numDiagonalEntries + numNondiagonalEntries;
1471 resultNumActiveDims++;
1476 resultVariationTypes[D1_DIM] =
GENERAL;
1477 resultVariationTypes[D2_DIM] =
GENERAL;
1479 resultActiveDims[resultNumActiveDims] = resultRank - 2;
1480 resultActiveDims[resultNumActiveDims+1] = resultRank - 1;
1482 resultDataDims[resultNumActiveDims] = leftRows;
1483 resultDataDims[resultNumActiveDims+1] = rightCols;
1484 resultNumActiveDims += 2;
1487 for (
int i=resultRank; i<7; i++)
1489 resultVariationTypes[i] =
CONSTANT;
1490 resultExtents[i] = 1;
1493 ScalarView<DataScalar,DeviceType> data;
1495 if (resultNumActiveDims == 1)
1499 else if (resultNumActiveDims == 2)
1503 else if (resultNumActiveDims == 3)
1505 data =
getMatchingViewWithLabel(viewToMatch,
"Data mat-mat result", resultDataDims[0], resultDataDims[1], resultDataDims[2]);
1507 else if (resultNumActiveDims == 4)
1509 data =
getMatchingViewWithLabel(viewToMatch,
"Data mat-mat result", resultDataDims[0], resultDataDims[1], resultDataDims[2],
1512 else if (resultNumActiveDims == 5)
1514 data =
getMatchingViewWithLabel(viewToMatch,
"Data mat-mat result", resultDataDims[0], resultDataDims[1], resultDataDims[2],
1515 resultDataDims[3], resultDataDims[4]);
1517 else if (resultNumActiveDims == 6)
1519 data =
getMatchingViewWithLabel(viewToMatch,
"Data mat-mat result", resultDataDims[0], resultDataDims[1], resultDataDims[2],
1520 resultDataDims[3], resultDataDims[4], resultDataDims[5]);
1524 data =
getMatchingViewWithLabel(viewToMatch,
"Data mat-mat result", resultDataDims[0], resultDataDims[1], resultDataDims[2],
1525 resultDataDims[3], resultDataDims[4], resultDataDims[5], resultDataDims[6]);
1541 const int resultRank =
rank - numContractionDims;
1542 std::vector<DimensionInfo> dimInfo(resultRank);
1543 for (
int d=0; d<resultRank; d++)
1570 const int D1_DIM = matData.
rank() - 2;
1571 const int D2_DIM = matData.
rank() - 1;
1573 const int matRows = matData.
extent_int(D1_DIM);
1574 const int matCols = matData.
extent_int(D2_DIM);
1576 const int rows = transposeMatrix ? matCols : matRows;
1577 const int cols = transposeMatrix ? matRows : matCols;
1579 const int resultRank = vecData.
rank();
1583 Kokkos::Array<int,7> resultExtents;
1584 Kokkos::Array<DataVariationType,7> resultVariationTypes;
1588 Kokkos::Array<int,7> resultActiveDims;
1589 Kokkos::Array<int,7> resultDataDims;
1590 int resultNumActiveDims = 0;
1592 for (
int i=0; i<resultRank-1; i++)
1606 if ((vecVariationType ==
GENERAL) || (matVariationType ==
GENERAL))
1608 resultVariationType =
GENERAL;
1609 dataSize = resultExtents[i];
1616 else if ((matVariationType ==
MODULAR) && (vecVariationType ==
CONSTANT))
1618 resultVariationType =
MODULAR;
1621 else if ((matVariationType ==
CONSTANT) && (vecVariationType ==
MODULAR))
1623 resultVariationType =
MODULAR;
1632 resultVariationType =
MODULAR;
1633 dataSize = matModulus;
1635 resultVariationTypes[i] = resultVariationType;
1637 if (resultVariationType !=
CONSTANT)
1639 resultActiveDims[resultNumActiveDims] = i;
1640 resultDataDims[resultNumActiveDims] = dataSize;
1641 resultNumActiveDims++;
1646 resultActiveDims[resultNumActiveDims] = resultRank - 1;
1647 resultDataDims[resultNumActiveDims] = rows;
1648 resultNumActiveDims++;
1650 for (
int i=resultRank; i<7; i++)
1652 resultVariationTypes[i] =
CONSTANT;
1653 resultExtents[i] = 1;
1655 resultVariationTypes[resultRank-1] =
GENERAL;
1656 resultExtents[resultRank-1] = rows;
1658 ScalarView<DataScalar,DeviceType> data;
1659 if (resultNumActiveDims == 1)
1663 else if (resultNumActiveDims == 2)
1667 else if (resultNumActiveDims == 3)
1671 else if (resultNumActiveDims == 4)
1676 else if (resultNumActiveDims == 5)
1679 resultDataDims[3], resultDataDims[4]);
1681 else if (resultNumActiveDims == 6)
1684 resultDataDims[3], resultDataDims[4], resultDataDims[5]);
1689 resultDataDims[3], resultDataDims[4], resultDataDims[5], resultDataDims[6]);
1697 enable_if_t<(rank!=1) && (rank!=7), Kokkos::MDRangePolicy<typename DeviceType::execution_space,Kokkos::Rank<rank>> >
1700 using ExecutionSpace =
typename DeviceType::execution_space;
1701 Kokkos::Array<int,rank> startingOrdinals;
1702 Kokkos::Array<int,rank> extents;
1704 for (
int d=0; d<
rank; d++)
1706 startingOrdinals[d] = 0;
1709 auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<rank>>(startingOrdinals,extents);
1715 enable_if_t<rank==7, Kokkos::MDRangePolicy<typename DeviceType::execution_space,Kokkos::Rank<6>> >
1718 using ExecutionSpace =
typename DeviceType::execution_space;
1719 Kokkos::Array<int,6> startingOrdinals;
1720 Kokkos::Array<int,6> extents;
1722 for (
int d=0; d<6; d++)
1724 startingOrdinals[d] = 0;
1727 auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<6>>(startingOrdinals,extents);
1733 enable_if_t<rank==1, Kokkos::RangePolicy<typename DeviceType::execution_space> >
1736 using ExecutionSpace =
typename DeviceType::execution_space;
1737 Kokkos::RangePolicy<ExecutionSpace> policy(ExecutionSpace(),0,
getDataExtent(0));
1742 Data shallowCopy(
const int rank,
const Kokkos::Array<int,7> &extents,
const Kokkos::Array<DataVariationType,7> &variationTypes)
const
1746 case 1:
return Data(
rank, data1_, extents, variationTypes);
1747 case 2:
return Data(
rank, data2_, extents, variationTypes);
1748 case 3:
return Data(
rank, data3_, extents, variationTypes);
1749 case 4:
return Data(
rank, data4_, extents, variationTypes);
1750 case 5:
return Data(
rank, data5_, extents, variationTypes);
1751 case 6:
return Data(
rank, data6_, extents, variationTypes);
1752 case 7:
return Data(
rank, data7_, extents, variationTypes);
1754 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unhandled dataRank_");
1761 const int D_DIM = A.
rank() - 1;
1763 const int vectorComponents = A.
extent_int(D_DIM);
1768 using ExecutionSpace =
typename DeviceType::execution_space;
1772 Kokkos::parallel_for(
"compute dot product",
getDataExtent(0),
1773 KOKKOS_LAMBDA (
const int &pointOrdinal) {
1776 for (
int i=0; i<vectorComponents; i++)
1778 val += A(pointOrdinal,i) * B(pointOrdinal,i);
1782 else if (rank_ == 2)
1786 Kokkos::parallel_for(
"compute dot product", policy,
1787 KOKKOS_LAMBDA (
const int &cellOrdinal,
const int &pointOrdinal) {
1790 for (
int i=0; i<vectorComponents; i++)
1792 val += A(cellOrdinal,pointOrdinal,i) * B(cellOrdinal,pointOrdinal,i);
1796 else if (rank_ == 3)
1799 Kokkos::parallel_for(
"compute dot product", policy,
1800 KOKKOS_LAMBDA (
const int &cellOrdinal,
const int &pointOrdinal,
const int &d) {
1803 for (
int i=0; i<vectorComponents; i++)
1805 val += A(cellOrdinal,pointOrdinal,d,i) * B(cellOrdinal,pointOrdinal,d,i);
1817 template<
class BinaryOperator>
1854 const int D1_DIM = matData.
rank() - 2;
1855 const int D2_DIM = matData.
rank() - 1;
1857 const int matRows = matData.
extent_int(D1_DIM);
1858 const int matCols = matData.
extent_int(D2_DIM);
1860 const int rows = transposeMatrix ? matCols : matRows;
1861 const int cols = transposeMatrix ? matRows : matCols;
1866 using ExecutionSpace =
typename DeviceType::execution_space;
1872 Kokkos::parallel_for(
"compute mat-vec", policy,
1873 KOKKOS_LAMBDA (
const int &cellOrdinal,
const int &pointOrdinal,
const int &i) {
1876 for (
int j=0; j<cols; j++)
1878 const auto & mat_ij = transposeMatrix ? matData(cellOrdinal,pointOrdinal,j,i) : matData(cellOrdinal,pointOrdinal,i,j);
1879 val_i += mat_ij * vecData(cellOrdinal,pointOrdinal,j);
1883 else if (rank_ == 2)
1886 auto policy = Kokkos::MDRangePolicy<ExecutionSpace,Kokkos::Rank<2>>({0,0},{
getDataExtent(0),rows});
1887 Kokkos::parallel_for(
"compute mat-vec", policy,
1888 KOKKOS_LAMBDA (
const int &vectorOrdinal,
const int &i) {
1891 for (
int j=0; j<cols; j++)
1893 const auto & mat_ij = transposeMatrix ? matData(vectorOrdinal,j,i) : matData(vectorOrdinal,i,j);
1894 val_i += mat_ij * vecData(vectorOrdinal,j);
1898 else if (rank_ == 1)
1901 Kokkos::RangePolicy<ExecutionSpace> policy(0,rows);
1902 Kokkos::parallel_for(
"compute mat-vec", policy,
1903 KOKKOS_LAMBDA (
const int &i) {
1906 for (
int j=0; j<cols; j++)
1908 const auto & mat_ij = transposeMatrix ? matData(j,i) : matData(i,j);
1909 val_i += mat_ij * vecData(j);
1934 const int D1_DIM = A_MatData.
rank() - 2;
1935 const int D2_DIM = A_MatData.
rank() - 1;
1937 const int A_rows = A_MatData.
extent_int(D1_DIM);
1938 const int A_cols = A_MatData.
extent_int(D2_DIM);
1939 const int B_rows = B_MatData.
extent_int(D1_DIM);
1940 const int B_cols = B_MatData.
extent_int(D2_DIM);
1942 const int leftRows = transposeA ? A_cols : A_rows;
1943 const int leftCols = transposeA ? A_rows : A_cols;
1944 const int rightCols = transposeB ? B_rows : B_cols;
1946#ifdef INTREPID2_HAVE_DEBUG
1947 const int rightRows = transposeB ? B_cols : B_rows;
1954 using ExecutionSpace =
typename DeviceType::execution_space;
1956 const int diagonalStart = (variationType_[D1_DIM] ==
BLOCK_PLUS_DIAGONAL) ? blockPlusDiagonalLastNonDiagonal_ + 1 : leftRows;
1961 auto policy = Kokkos::RangePolicy<ExecutionSpace>(0,
getDataExtent(0));
1962 Kokkos::parallel_for(
"compute mat-mat", policy,
1963 KOKKOS_LAMBDA (
const int &matrixOrdinal) {
1964 for (
int i=0; i<diagonalStart; i++)
1966 for (
int j=0; j<rightCols; j++)
1970 for (
int k=0; k<leftCols; k++)
1972 const auto & left = transposeA ? A_MatData(matrixOrdinal,k,i) : A_MatData(matrixOrdinal,i,k);
1973 const auto & right = transposeB ? B_MatData(matrixOrdinal,j,k) : B_MatData(matrixOrdinal,k,j);
1974 val_ij += left * right;
1978 for (
int i=diagonalStart; i<leftRows; i++)
1981 const auto & left = A_MatData(matrixOrdinal,i,i);
1982 const auto & right = B_MatData(matrixOrdinal,i,i);
1983 val_ii = left * right;
1987 else if (rank_ == 4)
1991 if (underlyingMatchesLogical_)
1993 Kokkos::parallel_for(
"compute mat-mat", policy,
1994 KOKKOS_LAMBDA (
const int &cellOrdinal,
const int &pointOrdinal) {
1995 for (
int i=0; i<leftRows; i++)
1997 for (
int j=0; j<rightCols; j++)
2001 for (
int k=0; k<leftCols; k++)
2003 const auto & left = transposeA ? A_MatData(cellOrdinal,pointOrdinal,k,i) : A_MatData(cellOrdinal,pointOrdinal,i,k);
2004 const auto & right = transposeB ? B_MatData(cellOrdinal,pointOrdinal,j,k) : B_MatData(cellOrdinal,pointOrdinal,k,j);
2005 val_ij += left * right;
2013 Kokkos::parallel_for(
"compute mat-mat", policy,
2014 KOKKOS_LAMBDA (
const int &cellOrdinal,
const int &pointOrdinal) {
2015 for (
int i=0; i<diagonalStart; i++)
2017 for (
int j=0; j<rightCols; j++)
2021 for (
int k=0; k<leftCols; k++)
2023 const auto & left = transposeA ? A_MatData(cellOrdinal,pointOrdinal,k,i) : A_MatData(cellOrdinal,pointOrdinal,i,k);
2024 const auto & right = transposeB ? B_MatData(cellOrdinal,pointOrdinal,j,k) : B_MatData(cellOrdinal,pointOrdinal,k,j);
2025 val_ij += left * right;
2029 for (
int i=diagonalStart; i<leftRows; i++)
2032 const auto & left = A_MatData(cellOrdinal,pointOrdinal,i,i);
2033 const auto & right = B_MatData(cellOrdinal,pointOrdinal,i,i);
2034 val_ii = left * right;
2047 KOKKOS_INLINE_FUNCTION
constexpr bool isValid()
const
2049 return extents_[0] > 0;
2053 KOKKOS_INLINE_FUNCTION
2065 void setExtent(
const ordinal_type &d,
const ordinal_type &newExtent)
2067 INTREPID2_TEST_FOR_EXCEPTION(variationType_[d] ==
BLOCK_PLUS_DIAGONAL, std::invalid_argument,
"setExtent is not supported for BLOCK_PLUS_DIAGONAL dimensions");
2069 if (variationType_[d] ==
MODULAR)
2071 bool dividesEvenly = ((newExtent / variationModulus_[d]) * variationModulus_[d] == newExtent);
2072 INTREPID2_TEST_FOR_EXCEPTION(!dividesEvenly, std::invalid_argument,
"when setExtent is called on dimenisions with MODULAR variation, the modulus must divide the new extent evenly");
2075 if ((newExtent != extents_[d]) && (variationType_[d] ==
GENERAL))
2078 std::vector<ordinal_type> newExtents(dataRank_,-1);
2079 for (
int r=0; r<dataRank_; r++)
2081 if (activeDims_[r] == d)
2084 newExtents[r] = newExtent;
2095 case 1: Kokkos::resize(data1_,newExtents[0]);
2097 case 2: Kokkos::resize(data2_,newExtents[0],newExtents[1]);
2099 case 3: Kokkos::resize(data3_,newExtents[0],newExtents[1],newExtents[2]);
2101 case 4: Kokkos::resize(data4_,newExtents[0],newExtents[1],newExtents[2],newExtents[3]);
2103 case 5: Kokkos::resize(data5_,newExtents[0],newExtents[1],newExtents[2],newExtents[3],newExtents[4]);
2105 case 6: Kokkos::resize(data6_,newExtents[0],newExtents[1],newExtents[2],newExtents[3],newExtents[4],newExtents[5]);
2107 case 7: Kokkos::resize(data7_,newExtents[0],newExtents[1],newExtents[2],newExtents[3],newExtents[4],newExtents[5],newExtents[6]);
2109 default: INTREPID2_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unexpected dataRank_ value");
2113 extents_[d] = newExtent;
2117 KOKKOS_INLINE_FUNCTION
2120 return underlyingMatchesLogical_;
2124 template<
class DataScalar,
typename DeviceType>
2125 KOKKOS_INLINE_FUNCTION
constexpr unsigned rank(
const Data<DataScalar, DeviceType>& D) {
Defines implementations for the Data class that are not present in the declaration.
Defines DimensionInfo struct that allows specification of a dimension within a Data object.
KOKKOS_INLINE_FUNCTION DimensionInfo combinedDimensionInfo(const DimensionInfo &myData, const DimensionInfo &otherData)
Returns DimensionInfo for a Data container that combines (through multiplication, say,...
Defines functors for use with Data objects: so far, we include simple arithmetical functors for sum,...
Defines DataVariationType enum that specifies the types of variation possible within a Data object.
@ GENERAL
arbitrary variation
@ BLOCK_PLUS_DIAGONAL
one of two dimensions in a matrix; bottom-right part of matrix is diagonal
@ MODULAR
varies according to modulus of the index
Header function for Intrepid2::Util class and other utility functions.
#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg)
Kokkos::DynRankView< typename ViewType::value_type, typename DeduceLayout< ViewType >::result_layout, typename ViewType::device_type > getMatchingViewWithLabel(const ViewType &view, const std::string &label, DimArgs... dims)
Creates and returns a view that matches the provided view in Kokkos Layout.
Wrapper around a Kokkos::View that allows data that is constant or repeating in various logical dimen...
void storeInPlaceProduct(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
stores the in-place (entrywise) product, A .* B, into this container.
static Data< DataScalar, DeviceType > allocateMatMatResult(const bool transposeA, const Data< DataScalar, DeviceType > &A_MatData, const bool transposeB, const Data< DataScalar, DeviceType > &B_MatData)
KOKKOS_INLINE_FUNCTION int getVariationModulus(const int &d) const
Variation modulus accessor.
KOKKOS_INLINE_FUNCTION void setUnderlyingView7(const Kokkos::View< DataScalar *******, DeviceType > &view)
sets the View that stores the unique data. For rank-7 underlying containers.
KOKKOS_INLINE_FUNCTION enable_if_t< rank==6, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 6.
KOKKOS_INLINE_FUNCTION void setUnderlyingView3(const Kokkos::View< DataScalar ***, DeviceType > &view)
sets the View that stores the unique data. For rank-3 underlying containers.
KOKKOS_INLINE_FUNCTION enable_if_t< rank==1, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 1.
KOKKOS_INLINE_FUNCTION reference_type getWritableEntry(const IntArgs... intArgs) const
Returns an l-value reference to the specified logical entry in the underlying view....
void copyDataFromDynRankViewMatchingUnderlying(const ScalarView< DataScalar, DeviceType > &dynRankView) const
Copies from the provided DynRankView into the underlying Kokkos::View container storing the unique da...
enable_if_t<(rank!=1) &&(rank!=7), Kokkos::MDRangePolicy< typename DeviceType::execution_space, Kokkos::Rank< rank > > > dataExtentRangePolicy()
returns an MDRangePolicy over the underlying data extents (but with the logical shape).
KOKKOS_INLINE_FUNCTION void setUnderlyingView1(const Kokkos::View< DataScalar *, DeviceType > &view)
sets the View that stores the unique data. For rank-1 underlying containers.
KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const
Returns the logical extent in the specified dimension.
KOKKOS_INLINE_FUNCTION reference_type getWritableEntryWithPassThroughOption(const bool &passThroughBlockDiagonalArgs, const IntArgs... intArgs) const
Returns an l-value reference to the specified logical entry in the underlying view....
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar **, DeviceType > & getUnderlyingView2() const
returns the View that stores the unique data. For rank-2 underlying containers.
KOKKOS_INLINE_FUNCTION enable_if_t< rank==2, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 2.
Data(const unsigned rank, Kokkos::View< ViewScalar, DeviceType, ViewProperties... > data, Kokkos::Array< int, 7 > extents, Kokkos::Array< DataVariationType, 7 > variationType, const int blockPlusDiagonalLastNonDiagonal=-1)
constructor with run-time rank (requires full-length extents, variationType inputs; those beyond the ...
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar ****, DeviceType > & getUnderlyingView4() const
returns the View that stores the unique data. For rank-4 underlying containers.
ScalarView< DataScalar, DeviceType > getUnderlyingView() const
Returns a DynRankView constructed atop the same underlying data as the fixed-rank Kokkos::View used i...
KOKKOS_INLINE_FUNCTION constexpr bool isValid() const
returns true for containers that have data; false for those that don't (namely, those that have been ...
static Data< DataScalar, DeviceType > allocateDotProductResult(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
Data()
default constructor (empty data)
static Data< DataScalar, DeviceType > allocateMatVecResult(const Data< DataScalar, DeviceType > &matData, const Data< DataScalar, DeviceType > &vecData, const bool transposeMatrix=false)
void storeMatVec(const Data< DataScalar, DeviceType > &matData, const Data< DataScalar, DeviceType > &vecData, const bool transposeMatrix=false)
Places the result of a matrix-vector multiply corresponding to the two provided containers into this ...
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar ***, DeviceType > & getUnderlyingView3() const
returns the View that stores the unique data. For rank-3 underlying containers.
void clear() const
Copies 0.0 to the underlying View.
KOKKOS_INLINE_FUNCTION enable_if_t< rank==7, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 7.
KOKKOS_INLINE_FUNCTION bool isDiagonal() const
returns true for containers that have two dimensions marked as BLOCK_PLUS_DIAGONAL for which the non-...
ScalarView< DataScalar, DeviceType > allocateDynRankViewMatchingUnderlying() const
Returns a DynRankView that matches the underlying Kokkos::View object in value_type,...
KOKKOS_INLINE_FUNCTION enable_if_t< rank==3, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 3.
KOKKOS_INLINE_FUNCTION return_type getEntry(const IntArgs &... intArgs) const
Returns a (read-only) value corresponding to the specified logical data location.
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar ******, DeviceType > & getUnderlyingView6() const
returns the View that stores the unique data. For rank-6 underlying containers.
Data(const ScalarView< DataScalar, DeviceType > &data, int rank, Kokkos::Array< int, 7 > extents, Kokkos::Array< DataVariationType, 7 > variationType, const int blockPlusDiagonalLastNonDiagonal=-1)
DynRankView constructor. Will copy to a View of appropriate rank.
static void copyContainer(ToContainer to, FromContainer from)
Generic data copying method to allow construction of Data object from DynRankViews for which deep_cop...
KOKKOS_INLINE_FUNCTION const int & blockPlusDiagonalLastNonDiagonal() const
For a Data object containing data with variation type BLOCK_PLUS_DIAGONAL, returns the row and column...
void storeInPlaceSum(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
stores the in-place (entrywise) sum, A .+ B, into this container.
void applyOperator(UnaryOperator unaryOperator)
applies the specified unary operator to each entry
static KOKKOS_INLINE_FUNCTION int blockPlusDiagonalDiagonalEntryIndex(const int &lastNondiagonal, const int &numNondiagonalEntries, const int &i)
Returns flattened index of the specified (i,i) matrix entry, assuming that i > lastNondiagonal....
static KOKKOS_INLINE_FUNCTION int blockPlusDiagonalNumNondiagonalEntries(const int &lastNondiagonal)
Returns the number of non-diagonal entries based on the last non-diagonal. Only applicable for BLOCK_...
Data(ScalarView< DataScalar, DeviceType > data)
copy constructor modeled after the copy-like constructor above. Not as efficient as the implicit copy...
KOKKOS_INLINE_FUNCTION ordinal_type getUnderlyingViewSize() const
returns the number of entries in the View that stores the unique data
KOKKOS_INLINE_FUNCTION enable_if_t< rank==5, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 5.
void storeInPlaceQuotient(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
stores the in-place (entrywise) quotient, A ./ B, into this container.
static Data< DataScalar, DeviceType > allocateInPlaceCombinationResult(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
KOKKOS_INLINE_FUNCTION const Kokkos::Array< DataVariationType, 7 > & getVariationTypes() const
Returns an array with the variation types in each logical dimension.
KOKKOS_INLINE_FUNCTION void setUnderlyingView5(const Kokkos::View< DataScalar *****, DeviceType > &view)
sets the View that stores the unique data. For rank-5 underlying containers.
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar *, DeviceType > & getUnderlyingView1() const
returns the View that stores the unique data. For rank-1 underlying containers.
KOKKOS_INLINE_FUNCTION int getDataExtent(const ordinal_type &d) const
returns the true extent of the data corresponding to the logical dimension provided; if the data does...
KOKKOS_INLINE_FUNCTION void setUnderlyingView6(const Kokkos::View< DataScalar ******, DeviceType > &view)
sets the View that stores the unique data. For rank-6 underlying containers.
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar *******, DeviceType > & getUnderlyingView7() const
returns the View that stores the unique data. For rank-7 underlying containers.
Data< DataScalar, DeviceType > allocateConstantData(const DataScalar &value)
KOKKOS_INLINE_FUNCTION void setUnderlyingView4(const Kokkos::View< DataScalar ****, DeviceType > &view)
sets the View that stores the unique data. For rank-4 underlying containers.
void storeMatMat(const bool transposeA, const Data< DataScalar, DeviceType > &A_MatData, const bool transposeB, const Data< DataScalar, DeviceType > &B_MatData)
KOKKOS_INLINE_FUNCTION Kokkos::Array< int, 7 > getExtents() const
Returns an array containing the logical extents in each dimension.
ScalarView< DataScalar, DeviceType > allocateDynRankViewMatchingUnderlying(DimArgs... dims) const
Returns a DynRankView that matches the underlying Kokkos::View object value_type and layout,...
KOKKOS_INLINE_FUNCTION enable_if_t< rank==4, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 4.
KOKKOS_INLINE_FUNCTION bool underlyingMatchesLogical() const
Returns true if the underlying container has exactly the same rank and extents as the logical contain...
KOKKOS_INLINE_FUNCTION ordinal_type getUnderlyingViewRank() const
returns the rank of the View that stores the unique data
void allocateAndCopyFromDynRankView(ScalarView< DataScalar, DeviceType > data)
allocate an underlying View that matches the provided DynRankView in dimensions, and copy....
void storeInPlaceDifference(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
stores the in-place (entrywise) difference, A .- B, into this container.
static KOKKOS_INLINE_FUNCTION int blockPlusDiagonalBlockEntryIndex(const int &lastNondiagonal, const int &numNondiagonalEntries, const int &i, const int &j)
//! Returns flattened index of the specified (i,j) matrix entry, assuming that i,j ≤ lastNondiagonal....
KOKKOS_INLINE_FUNCTION int getUnderlyingViewExtent(const int &dim) const
Returns the extent of the underlying view in the specified dimension.
void setActiveDims()
class initialization method. Called by constructors.
KOKKOS_INLINE_FUNCTION return_type getEntryWithPassThroughOption(const bool &passThroughBlockDiagonalArgs, const IntArgs &... intArgs) const
Returns a (read-only) value corresponding to the specified logical data location. If passThroughBlock...
Data(const Data< DataScalar, OtherDeviceType > &data)
copy-like constructor for differing execution spaces. This does a deep_copy of the underlying view.
KOKKOS_INLINE_FUNCTION void setUnderlyingView2(const Kokkos::View< DataScalar **, DeviceType > &view)
sets the View that stores the unique data. For rank-2 underlying containers.
void setExtent(const ordinal_type &d, const ordinal_type &newExtent)
sets the logical extent in the specified dimension. If needed, the underlying data container is resiz...
void storeInPlaceCombination(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B, BinaryOperator binaryOperator)
Places the result of an in-place combination (e.g., entrywise sum) into this data container.
KOKKOS_INLINE_FUNCTION DimensionInfo combinedDataDimensionInfo(const Data &otherData, const int &dim) const
Returns (DataVariationType, data extent) in the specified dimension for a Data container that combine...
static Data< DataScalar, DeviceType > allocateContractionResult(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B, const int &numContractionDims)
KOKKOS_INLINE_FUNCTION DimensionInfo getDimensionInfo(const int &dim) const
Returns an object fully specifying the indicated dimension. This is used in determining appropriate s...
KOKKOS_INLINE_FUNCTION const Kokkos::View< DataScalar *****, DeviceType > & getUnderlyingView5() const
returns the View that stores the unique data. For rank-5 underlying containers.
Data(std::vector< DimensionInfo > dimInfoVector)
Constructor in terms of DimensionInfo for each logical dimension; does not require a View to be speci...
enable_if_t< rank==7, Kokkos::MDRangePolicy< typename DeviceType::execution_space, Kokkos::Rank< 6 > > > dataExtentRangePolicy()
returns an MDRangePolicy over the first six underlying data extents (but with the logical shape).
Data(DataScalar constantValue, Kokkos::Array< int, rank > extents)
constructor for everywhere-constant data
Data(const Kokkos::DynRankView< DataScalar, DeviceType, DynRankViewProperties... > &data, Kokkos::Array< int, rank > extents, Kokkos::Array< DataVariationType, rank > variationType, const int blockPlusDiagonalLastNonDiagonal=-1)
Constructor that accepts a DynRankView as an argument. The data belonging to the DynRankView will be ...
Data shallowCopy(const int rank, const Kokkos::Array< int, 7 > &extents, const Kokkos::Array< DataVariationType, 7 > &variationTypes) const
Creates a new Data object with the same underlying view, but with the specified logical rank,...
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the logical rank of the Data container.
void storeDotProduct(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
Places the result of a contraction along the final dimension of A and B into this data container.
A singleton class for a DynRankView containing exactly one zero entry. (Technically,...
Struct expressing all variation information about a Data object in a single dimension,...