79 RankCombinationViewType rank_combination_types)
81 tensor_view_iterator_(tensor_view),
82 view1_iterator_(view1),
83 view2_iterator_(view2),
84 rank_combination_types_(rank_combination_types)
102 unsigned max_component_rank = (view1.rank() > view2.rank()) ? view1.rank() : view2.rank();
103 unsigned max_rank = (tensor_view.rank() > max_component_rank) ? tensor_view.rank() : max_component_rank;
107 unsigned expected_rank = 0;
108 bool contracting =
false;
109 for (
unsigned d=0; d<rank_combination_types.extent(0); d++)
111 if (rank_combination_types[d] == TENSOR_CONTRACTION)
122 if (rank_combination_types[d] == TENSOR_PRODUCT)
124 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(tensor_view.extent_int(d) != view1.extent_int(d) * view2.extent_int(d), std::invalid_argument,
"For TENSOR_PRODUCT rank combination, the tensor View must have length in that dimension equal to the product of the two component views in that dimension");
128 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(view1.extent_int(d) != view2.extent_int(d), std::invalid_argument,
"For DIMENSION_MATCH rank combination, all three views must have length equal to each other in that rank");
129 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(tensor_view.extent_int(d) != view1.extent_int(d), std::invalid_argument,
"For DIMENSION_MATCH rank combination, all three views must have length equal to each other in that rank");
146 int view2_next_increment_rank = view2_iterator_.nextIncrementRank();
147 int view1_next_increment_rank = view1_iterator_.nextIncrementRank();
148 if (view2_next_increment_rank > view1_next_increment_rank)
return view2_next_increment_rank;
149 else return view1_next_increment_rank;
167 int view2_next_increment_rank = view2_iterator_.nextIncrementRank();
168 int view1_next_increment_rank = view1_iterator_.nextIncrementRank();
169 if (view2_next_increment_rank > view1_next_increment_rank)
172 device_assert(rank_combination_types_[view2_next_increment_rank]==TENSOR_PRODUCT);
173 view1_iterator_.reset(view2_next_increment_rank);
174 view2_iterator_.increment();
175 tensor_view_iterator_.increment();
176 return view2_next_increment_rank;
180 int view1_rank_change = view1_iterator_.increment();
181 if (view1_rank_change >= 0)
183 switch (rank_combination_types_[view1_rank_change])
185 case DIMENSION_MATCH:
186 view2_iterator_.increment();
187 tensor_view_iterator_.increment();
191 tensor_view_iterator_.increment();
193 case TENSOR_CONTRACTION:
195 view2_iterator_.increment();
198 return view1_rank_change;
216 void setLocation(Kokkos::Array<int,7> location1, Kokkos::Array<int,7> location2)
218 view1_iterator_.setLocation(location1);
219 view2_iterator_.setLocation(location2);
220 Kokkos::Array<int,7> tensor_location = location1;
221 for (
unsigned d=0; d<rank_combination_types_.extent(0); d++)
223 switch (rank_combination_types_[d])
227 tensor_location[d] = location2[d] * view1_iterator_.getExtent(d) + location1[d];
229 case DIMENSION_MATCH:
232 case TENSOR_CONTRACTION:
233 tensor_location[d] = 0;
237#ifdef HAVE_INTREPID2_DEBUG
239 for (
unsigned d=0; d<rank_combination_types_.extent(0); d++)
241 switch (rank_combination_types_[d])
246 case DIMENSION_MATCH:
247 case TENSOR_CONTRACTION:
254 device_assert(tensor_location[d] < tensor_view_iterator_.getExtent(d));
257 tensor_view_iterator_.setLocation(tensor_location);