Intrepid
Intrepid_ArrayToolsDefScalar_Kokkos.hpp
1 #ifndef INTREPID_ARRAYTOOLSDEFSCALAR_KOKKOS_HPP
2 #define INTREPID_ARRAYTOOLSDEFSCALAR_KOKKOS_HPP
3 
4 #ifdef HAVE_INTREPID_KOKKOSCORE
5 
7 
8 namespace Intrepid{
9 
10 
11 //Functors for parallel_for rank 2_2
12 //Below you can find the switch staments and paralle fors that call
13 //The functors.
14 template<class ViewType, class ViewType1,class ViewType2>
15 struct PFor__Recip_Not_Const2_2 {
16  ViewType outputData;
17  typename ViewType1::const_type inputDataLeft;
18  typename ViewType2::const_type inputDataRight;
19  PFor__Recip_Not_Const2_2(ViewType outputData_, ViewType1 inputDataLeft_,
20  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
21 
22  KOKKOS_INLINE_FUNCTION
23  void operator() (int i) const {
24  for(int j = 0; j < outputData.dimension_1(); j++){
25  outputData(i,j) = inputDataRight(i,j)/inputDataLeft(i,j);
26  }
27  }
28 };
29 template<class ViewType, class ViewType1,class ViewType2>
30 struct PFor_Not_Recip_Not_Const2_2 {
31  ViewType outputData;
32  typename ViewType1::const_type inputDataLeft;
33  typename ViewType2::const_type inputDataRight;
34  PFor_Not_Recip_Not_Const2_2(ViewType outputData_, ViewType1 inputDataLeft_,
35  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
36 
37  KOKKOS_INLINE_FUNCTION
38  void operator() (int i) const {
39  for(int j = 0; j < outputData.dimension_1(); j++){
40  outputData(i,j) = inputDataRight(i,j)*inputDataLeft(i,j);
41  }
42  }
43 };
44 template<class ViewType, class ViewType1,class ViewType2>
45 struct PFor__Recip__Const2_2 {
46  ViewType outputData;
47  typename ViewType1::const_type inputDataLeft;
48  typename ViewType2::const_type inputDataRight;
49  PFor__Recip__Const2_2(ViewType outputData_, ViewType1 inputDataLeft_,
50  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
51 
52  KOKKOS_INLINE_FUNCTION
53  void operator() (int i) const {
54  for(int j = 0; j < outputData.dimension_1(); j++){
55  outputData(i,j) = inputDataRight(i,j)/inputDataLeft(i,0);
56  }
57  }
58 };
59 template<class ViewType, class ViewType1,class ViewType2>
60 struct PFor_Not_Recip__Const2_2 {
61  ViewType outputData;
62  typename ViewType1::const_type inputDataLeft;
63  typename ViewType2::const_type inputDataRight;
64  PFor_Not_Recip__Const2_2(ViewType outputData_, ViewType1 inputDataLeft_,
65  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
66 
67  KOKKOS_INLINE_FUNCTION
68  void operator() (int i) const {
69  for(int j = 0; j < outputData.dimension_1(); j++){
70  outputData(i,j) = inputDataRight(i,j)*inputDataLeft(i,0);
71  }
72  }
73 };
74 //End Functors for parallel_for rank 2_2
75 
76 //Partially specialized implementation of scalarMultiplyDataData with rank 2_2
77 
78  template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
79 struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,2,2>{
80  scalarMultiplyDataData2Kokkos(ArrayOutData & outputData,
81  ArrayInDataLeft & inputDataLeft,
82  ArrayInDataRight & inputDataRight,
83  const bool reciprocal){
84 
85 #ifdef HAVE_INTREPID_DEBUG
86  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
87  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
88  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 2)), std::invalid_argument,
89  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2.");
90  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()), std::invalid_argument,
91  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank.");
92  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != inputDataLeft.dimension(0) ), std::invalid_argument,
93  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
94  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
95  ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree or first dimension of the left data input container must be 1!");
96  for (int i=0; i<inputDataRight.rank(); i++) {
97  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimension ";
98  errmsg += (char)(48+i);
99  errmsg += " of the right input and output data containers must agree!";
100  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
101  }
102 
103 
104 #endif
105 
106  // get sizes
107 
108  int numCells = outputData.dimension(0);
109  int numDataPoints = inputDataLeft.dimension(1);
110 
111  if (numDataPoints != 1) {
112  if (reciprocal) {
113  Kokkos::parallel_for(numCells,PFor__Recip_Not_Const2_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
114  inputDataRight));
115 
116  }
117  else {
118  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const2_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
119  inputDataRight));
120  }
121  }
122  else{
123  if (reciprocal) {
124  Kokkos::parallel_for(numCells,PFor__Recip__Const2_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
125  inputDataRight));
126  }
127  else {
128  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const2_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
129  inputDataRight));
130  }
131  }
132 
133  }
134  };
135 
136 //This is a test that uses nested paralleism
137 //Functors for parallel_for rank 3_3
138 #if defined( KOKKOS_HAVE_CXX11 )
139 #define VECTOR_LENGTH 32
140 typedef Kokkos::TeamVectorPolicy<8> team_policy;
141 typedef team_policy::member_type team_member ;
142 
143 
144 template<class ViewType, class ViewType1,class ViewType2>
145 struct PFor__Recip_Not_Const3_3 {
146  ViewType outputData;
147  typename ViewType1::const_type inputDataLeft;
148  typename ViewType2::const_type inputDataRight;
149  PFor__Recip_Not_Const3_3(ViewType outputData_, ViewType1 inputDataLeft_,
150  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
151 
152  KOKKOS_INLINE_FUNCTION
153  void operator() (const team_member & thread) const {
154  int i = thread.league_rank();
155  thread.team_par_for(outputData.dimension_1(),[&] (const int& j){
156  thread.vector_par_for(outputData.dimension_2(),[&] (const int& k){
157  outputData(i,j,k) = inputDataRight(i,j,k)/inputDataLeft(i,j);
158  });
159  });
160  /* for(int j = 0; j < outputData.dimension_1(); j++){
161  for(int k = 0; k < outputData.dimension_2(); k++){
162  outputData(i,j,k) = inputDataRight(i,j,k)/inputDataLeft(i,j);
163  }
164  }*/
165  }
166 };
167 #endif
168 /*
169 template<class ViewType, class ViewType1,class ViewType2>
170 struct PFor__Recip_Not_Const3_3 {
171  ViewType outputData;
172  typename ViewType1::const_type inputDataLeft;
173  typename ViewType2::const_type inputDataRight;
174  PFor__Recip_Not_Const3_3(ViewType outputData_, ViewType1 inputDataLeft_,
175  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
176 
177  KOKKOS_INLINE_FUNCTION
178  void operator() (int i) const {
179 
180  for(int j = 0; j < outputData.dimension_1(); j++){
181  for(int k = 0; k < outputData.dimension_2(); k++){
182  outputData(i,j,k) = inputDataRight(i,j,k)/inputDataLeft(i,j);
183  }
184  }
185  }
186 };
187 */
188 
189 template<class ViewType, class ViewType1,class ViewType2>
190 struct PFor_Not_Recip_Not_Const3_3 {
191  ViewType outputData;
192  typename ViewType1::const_type inputDataLeft;
193  typename ViewType2::const_type inputDataRight;
194  PFor_Not_Recip_Not_Const3_3(ViewType outputData_, ViewType1 inputDataLeft_,
195  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
196 
197  KOKKOS_INLINE_FUNCTION
198  void operator() (int i) const {
199  for(int j = 0; j < outputData.dimension_1(); j++){
200  for(int k = 0; k < outputData.dimension_2(); k++){
201  outputData(i,j,k) = inputDataRight(i,j,k)*inputDataLeft(i,j);
202  }
203  }
204  }
205 };
206 template<class ViewType, class ViewType1,class ViewType2>
207 struct PFor__Recip__Const3_3 {
208  ViewType outputData;
209  typename ViewType1::const_type inputDataLeft;
210  typename ViewType2::const_type inputDataRight;
211  PFor__Recip__Const3_3(ViewType outputData_, ViewType1 inputDataLeft_,
212  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
213 
214  KOKKOS_INLINE_FUNCTION
215  void operator() (int i) const {
216  for(int j = 0; j < outputData.dimension_1(); j++){
217  for(int k = 0; k < outputData.dimension_2(); k++){
218  outputData(i,j,k) = inputDataRight(i,j,k)/inputDataLeft(i,0);
219  }
220  }
221  }
222 };
223 
224 template<class ViewType, class ViewType1,class ViewType2>
225 struct PFor_Not_Recip__Const3_3 {
226  ViewType outputData;
227  typename ViewType1::const_type inputDataLeft;
228  typename ViewType2::const_type inputDataRight;
229  PFor_Not_Recip__Const3_3(ViewType outputData_, ViewType1 inputDataLeft_,
230  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
231 
232  KOKKOS_INLINE_FUNCTION
233  void operator() (int i) const {
234  for(int j = 0; j < outputData.dimension_1(); j++){
235  for(int k = 0; k < outputData.dimension_2(); k++){
236  outputData(i,j,k) = inputDataRight(i,j,k)*inputDataLeft(i,0);
237  }
238  }
239  }
240 };
241 //End Functors for parallel_for rank 3_3
242 
243 //Partially specialized implementation of scalarMultiplyDataData with rank 3_3
244 
245 template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
246  struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,3,3>{
247  scalarMultiplyDataData2Kokkos(ArrayOutData & outputData,
248  ArrayInDataLeft & inputDataLeft,
249  ArrayInDataRight & inputDataRight,
250  const bool reciprocal){
251  #ifdef HAVE_INTREPID_DEBUG
252  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
253  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
254  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 3)), std::invalid_argument,
255  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 3.");
256  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()), std::invalid_argument,
257  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank of 3.");
258  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != inputDataLeft.dimension(0) ), std::invalid_argument,
259  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
260  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
261  ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree or first dimension of the left data input container must be 1!");
262  for (int i=0; i<inputDataRight.rank(); i++) {
263  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimension ";
264  errmsg += (char)(48+i);
265  errmsg += " of the right input and output data containers must agree!";
266  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
267  }
268 
269 
270 #endif
271 
272  // get sizes
273 
274  int numCells = outputData.dimension(0);
275  int numDataPoints = inputDataLeft.dimension(1);
276 
277  if (numDataPoints != 1) {
278 
279  if (reciprocal) {
280 #if defined( KOKKOS_HAVE_CXX11 )
281  const team_policy policy( numCells , 2 );
282  Kokkos::parallel_for(policy,PFor__Recip_Not_Const3_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft, inputDataRight));
283 #endif
284  }
285  else {
286 
287  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const3_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
288  inputDataRight));
289  }
290  }
291  else{
292 
293  if (reciprocal) {
294 
295  Kokkos::parallel_for(numCells,PFor__Recip__Const3_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
296  inputDataRight));
297  }
298  else {
299 
300  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const3_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
301  inputDataRight));
302  }
303  }
304  }
305  };
306 
307 
308 //Functors for parallel_for rank 4_4
309 template<class ViewType, class ViewType1,class ViewType2>
310 struct PFor__Recip_Not_Const4_4 {
311  ViewType outputData;
312  typename ViewType1::const_type inputDataLeft;
313  typename ViewType2::const_type inputDataRight;
314  PFor__Recip_Not_Const4_4(ViewType outputData_, ViewType1 inputDataLeft_,
315  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
316 
317  KOKKOS_INLINE_FUNCTION
318  void operator() (int i) const {
319  for(int j = 0; j < outputData.dimension_1(); j++){
320  for(int k = 0; k < outputData.dimension_2(); k++){
321  for(int l = 0; l < outputData.dimension_3(); l++){
322  outputData(i,j,k,l) = inputDataRight(i,j,k,l)/inputDataLeft(i,j);
323  }
324  }
325  }
326  }
327 };
328 template<class ViewType, class ViewType1,class ViewType2>
329 struct PFor_Not_Recip_Not_Const4_4 {
330  ViewType outputData;
331  typename ViewType1::const_type inputDataLeft;
332  typename ViewType2::const_type inputDataRight;
333  PFor_Not_Recip_Not_Const4_4(ViewType outputData_, ViewType1 inputDataLeft_,
334  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
335 
336  KOKKOS_INLINE_FUNCTION
337  void operator() (int i) const {
338  for(int j = 0; j < outputData.dimension_1(); j++){
339  for(int k = 0; k < outputData.dimension_2(); k++){
340  for(int l = 0; l < outputData.dimension_3(); l++){
341  outputData(i,j,k,l) = inputDataRight(i,j,k,l)*inputDataLeft(i,j);
342  }
343  }
344  }
345  }
346 };
347 template<class ViewType, class ViewType1,class ViewType2>
348 struct PFor__Recip__Const4_4 {
349  ViewType outputData;
350  typename ViewType1::const_type inputDataLeft;
351  typename ViewType2::const_type inputDataRight;
352  PFor__Recip__Const4_4(ViewType outputData_, ViewType1 inputDataLeft_,
353  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
354 
355  KOKKOS_INLINE_FUNCTION
356  void operator() (int i) const {
357  for(int j = 0; j < outputData.dimension_1(); j++){
358  for(int k = 0; k < outputData.dimension_2(); k++){
359  for(int l = 0; l < outputData.dimension_3(); l++){
360  outputData(i,j,k,l) = inputDataRight(i,j,k,l)/inputDataLeft(i,0);
361  }
362  }
363  }
364  }
365 };
366 template<class ViewType, class ViewType1,class ViewType2>
367 struct PFor_Not_Recip__Const4_4 {
368  ViewType outputData;
369  typename ViewType1::const_type inputDataLeft;
370  typename ViewType2::const_type inputDataRight;
371  PFor_Not_Recip__Const4_4(ViewType outputData_, ViewType1 inputDataLeft_,
372  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
373 
374  KOKKOS_INLINE_FUNCTION
375  void operator() (int i) const {
376  for(int j = 0; j < outputData.dimension_1(); j++){
377  for(int k = 0; k < outputData.dimension_2(); k++){
378  for(int l = 0; l < outputData.dimension_3(); l++){
379  outputData(i,j,k,l) = inputDataRight(i,j,k,l)/inputDataLeft(i,0);
380  }
381  }
382  }
383  }
384 };
385 //End Functors for parallel_for rank 4_4
386 
387 
388 //Partially specialized implementation of scalarMultiplyDataData with rank 4_4
389 
390 template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
391  struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,4,4>{
392  scalarMultiplyDataData2Kokkos(ArrayOutData& outputData,
393  ArrayInDataLeft& inputDataLeft,
394  ArrayInDataRight& inputDataRight,
395  const bool reciprocal){
396  #ifdef HAVE_INTREPID_DEBUG
397  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
398  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
399  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 4)), std::invalid_argument,
400  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 4.");
401  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()), std::invalid_argument,
402  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank of 4.");
403  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != inputDataLeft.dimension(0) ), std::invalid_argument,
404  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
405  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
406  ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree or first dimension of the left data input container must be 1!");
407  for (int i=0; i<inputDataRight.rank(); i++) {
408  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimension ";
409  errmsg += (char)(48+i);
410  errmsg += " of the right input and output data containers must agree!";
411  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
412  }
413 
414 
415 #endif
416  // get sizes
417 
418  int numCells = outputData.dimension(0);
419  int numDataPoints = inputDataLeft.dimension(1);
420 
421  if (numDataPoints != 1) {
422  if (reciprocal) {
423  Kokkos::parallel_for(numCells,PFor__Recip_Not_Const4_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
424  inputDataRight));
425  }
426  else {
427  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const4_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
428  inputDataRight));
429  }
430  }
431  else{
432 
433  if (reciprocal) {
434 
435  Kokkos::parallel_for(numCells,PFor__Recip__Const4_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
436  inputDataRight));
437  }
438  else {
439  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const4_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
440  inputDataRight));
441  }
442  }
443  }
444 
445 };
446 
447 
448 //Functors for parallel_for rank 1_2
449 template<class ViewType, class ViewType1,class ViewType2>
450 struct PFor__Recip_Not_Const1_2 {
451  ViewType outputData;
452  typename ViewType1::const_type inputDataLeft;
453  typename ViewType2::const_type inputDataRight;
454  PFor__Recip_Not_Const1_2(ViewType outputData_, ViewType1 inputDataLeft_,
455  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
456 
457  KOKKOS_INLINE_FUNCTION
458  void operator() (int i) const {
459  for(int j = 0; j < outputData.dimension_1(); j++){
460  outputData(i,j) = inputDataRight(j)/inputDataLeft(i,j);
461  }
462  }
463 };
464 template<class ViewType, class ViewType1,class ViewType2>
465 struct PFor_Not_Recip_Not_Const1_2 {
466  ViewType outputData;
467  typename ViewType1::const_type inputDataLeft;
468  typename ViewType2::const_type inputDataRight;
469  PFor_Not_Recip_Not_Const1_2(ViewType outputData_, ViewType1 inputDataLeft_,
470  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
471 
472  KOKKOS_INLINE_FUNCTION
473  void operator() (int i) const {
474  for(int j = 0; j < outputData.dimension_1(); j++){
475  outputData(i,j) = inputDataRight(j)*inputDataLeft(i,j);
476  }
477  }
478 };
479 template<class ViewType, class ViewType1,class ViewType2>
480 struct PFor__Recip__Const1_2 {
481  ViewType outputData;
482  typename ViewType1::const_type inputDataLeft;
483  typename ViewType2::const_type inputDataRight;
484  PFor__Recip__Const1_2(ViewType outputData_, ViewType1 inputDataLeft_,
485  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
486 
487  KOKKOS_INLINE_FUNCTION
488  void operator() (int i) const {
489  for(int j = 0; j < outputData.dimension_1(); j++){
490  outputData(i,j) = inputDataRight(j)/inputDataLeft(i,0);
491  }
492  }
493 };
494 template<class ViewType, class ViewType1,class ViewType2>
495 struct PFor_Not_Recip__Const1_2 {
496  ViewType outputData;
497  typename ViewType1::const_type inputDataLeft;
498  typename ViewType2::const_type inputDataRight;
499  PFor_Not_Recip__Const1_2(ViewType outputData_, ViewType1 inputDataLeft_,
500  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
501 
502  KOKKOS_INLINE_FUNCTION
503  void operator() (int i) const {
504  for(int j = 0; j < outputData.dimension_1(); j++){
505  outputData(i,j) = inputDataRight(j)*inputDataLeft(i,0);
506  }
507  }
508 };
509 //End Functors for parallel_for rank 1_2
510 
511 //Partially specialized implementation of scalarMultiplyDataData with rank 1_2
512 
513  template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
514  struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,1,2>{
515  scalarMultiplyDataData2Kokkos(ArrayOutData& outputData,
516  ArrayInDataLeft& inputDataLeft,
517  ArrayInDataRight& inputDataRight,
518  const bool reciprocal){
519  #ifdef HAVE_INTREPID_DEBUG
520  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
521  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
522  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 1) ), std::invalid_argument,
523  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 1.");
524  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()+1), std::invalid_argument,
525  ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
526  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
527  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!");
528  TEUCHOS_TEST_FOR_EXCEPTION( ( inputDataLeft.dimension(0) != outputData.dimension(0) ), std::invalid_argument,
529  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
530  for (int i=0; i<inputDataRight.rank(); i++) {
531  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimensions ";
532  errmsg += (char)(48+i);
533  errmsg += " and ";
534  errmsg += (char)(48+i+1);
535  errmsg += " of the right input and output data containers must agree!";
536  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i+1)), std::invalid_argument, errmsg );
537  }
538  #endif
539 
540  // get sizes
541  int numCells = outputData.dimension(0);
542  int numDataPoints = inputDataLeft.dimension(1);
543 
544  if (numDataPoints != 1) {
545  if (reciprocal) {
546  Kokkos::parallel_for(numCells,PFor__Recip_Not_Const1_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
547  inputDataRight));
548  }
549  else {
550  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const1_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
551  inputDataRight));
552  }
553  }
554  else{
555  if (reciprocal) {
556  Kokkos::parallel_for(numCells,PFor__Recip__Const1_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
557  inputDataRight));
558  }
559  else {
560  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const1_2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
561  inputDataRight));
562  }
563  }
564  }
565  };
566 
567 //Functors for parallel_for rank 2_3
568 template<class ViewType, class ViewType1,class ViewType2>
569 struct PFor__Recip_Not_Const2_3 {
570  ViewType outputData;
571  typename ViewType1::const_type inputDataLeft;
572  typename ViewType2::const_type inputDataRight;
573  PFor__Recip_Not_Const2_3(ViewType outputData_, ViewType1 inputDataLeft_,
574  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
575 
576  KOKKOS_INLINE_FUNCTION
577  void operator() (int i) const {
578 
579  for(int j = 0; j < outputData.dimension_1(); j++){
580  for(int k = 0; k < outputData.dimension_2(); k++){
581  outputData(i,j,k) = inputDataRight(j,k)/inputDataLeft(i,j);
582  }
583  }
584  }
585 };
586 template<class ViewType, class ViewType1,class ViewType2>
587 struct PFor_Not_Recip_Not_Const2_3 {
588  ViewType outputData;
589  typename ViewType1::const_type inputDataLeft;
590  typename ViewType2::const_type inputDataRight;
591  PFor_Not_Recip_Not_Const2_3(ViewType outputData_, ViewType1 inputDataLeft_,
592  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
593 
594  KOKKOS_INLINE_FUNCTION
595  void operator() (int i) const {
596  for(int j = 0; j < outputData.dimension_1(); j++){
597  for(int k = 0; k < outputData.dimension_2(); k++){
598  outputData(i,j,k) = inputDataRight(j,k)*inputDataLeft(i,j);
599  }
600  }
601  }
602 };
603 template<class ViewType, class ViewType1,class ViewType2>
604 struct PFor__Recip__Const2_3 {
605  ViewType outputData;
606  typename ViewType1::const_type inputDataLeft;
607  typename ViewType2::const_type inputDataRight;
608  PFor__Recip__Const2_3(ViewType outputData_, ViewType1 inputDataLeft_,
609  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
610 
611  KOKKOS_INLINE_FUNCTION
612  void operator() (int i) const {
613  for(int j = 0; j < outputData.dimension_1(); j++){
614  for(int k = 0; k < outputData.dimension_2(); k++){
615  outputData(i,j,k) = inputDataRight(j,k)/inputDataLeft(i,0);
616  }
617  }
618  }
619 };
620 template<class ViewType, class ViewType1,class ViewType2>
621 struct PFor_Not_Recip__Const2_3 {
622  ViewType outputData;
623  typename ViewType1::const_type inputDataLeft;
624  typename ViewType2::const_type inputDataRight;
625  PFor_Not_Recip__Const2_3(ViewType outputData_, ViewType1 inputDataLeft_,
626  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
627 
628  KOKKOS_INLINE_FUNCTION
629  void operator() (int i) const {
630  for(int j = 0; j < outputData.dimension_1(); j++){
631  for(int k = 0; k < outputData.dimension_2(); k++){
632  outputData(i,j,k) = inputDataRight(j,k)*inputDataLeft(i,0);
633  }
634  }
635  }
636 };
637 //End Functors for parallel_for rank 2_3
638 
639 //Partially specialized implementation of scalarMultiplyDataData with rank 2_3
640 
641  template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
642 struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,2,3>{
643  scalarMultiplyDataData2Kokkos(ArrayOutData& outputData,
644  ArrayInDataLeft& inputDataLeft,
645  ArrayInDataRight& inputDataRight,
646  const bool reciprocal){
647 
648 #ifdef HAVE_INTREPID_DEBUG
649  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
650  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
651  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 2) ), std::invalid_argument,
652  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2.");
653  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()+1), std::invalid_argument,
654  ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
655  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
656  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!");
657  TEUCHOS_TEST_FOR_EXCEPTION( ( inputDataLeft.dimension(0) != outputData.dimension(0) ), std::invalid_argument,
658  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
659  for (int i=0; i<inputDataRight.rank(); i++) {
660  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimensions ";
661  errmsg += (char)(48+i);
662  errmsg += " and ";
663  errmsg += (char)(48+i+1);
664  errmsg += " of the right input and output data containers must agree!";
665  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i+1)), std::invalid_argument, errmsg );
666  }
667 #endif
668  // get sizes
669  int numCells = outputData.dimension(0);
670  int numDataPoints = inputDataLeft.dimension(1);
671  if (numDataPoints != 1) {
672  if (reciprocal) {
673  Kokkos::parallel_for(numCells,PFor__Recip_Not_Const2_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
674  inputDataRight));
675  }
676  else {
677  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const2_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
678  inputDataRight));
679  }
680  }
681  else{
682  if (reciprocal) {
683  Kokkos::parallel_for(numCells,PFor__Recip__Const2_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
684  inputDataRight));
685  }
686  else {
687  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const2_3<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
688  inputDataRight));
689  }
690  }
691 
692  }
693  };
694 
695 //Functors for parallel_for rank 3_4
696 template<class ViewType, class ViewType1,class ViewType2>
697 struct PFor__Recip_Not_Const3_4 {
698  ViewType outputData;
699  typename ViewType1::const_type inputDataLeft;
700  typename ViewType2::const_type inputDataRight;
701  PFor__Recip_Not_Const3_4(ViewType outputData_, ViewType1 inputDataLeft_,
702  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
703 
704  KOKKOS_INLINE_FUNCTION
705  void operator() (int i) const {
706  for(int j = 0; j < outputData.dimension_1(); j++){
707  for(int k = 0; k < outputData.dimension_2(); k++){
708  for(int l = 0; l < outputData.dimension_3(); l++){
709  outputData(i,j,k,l) = inputDataRight(j,k,l)/inputDataLeft(i,j);
710  }
711  }
712  }
713  }
714 };
715 template<class ViewType, class ViewType1,class ViewType2>
716 struct PFor_Not_Recip_Not_Const3_4 {
717  ViewType outputData;
718  typename ViewType1::const_type inputDataLeft;
719  typename ViewType2::const_type inputDataRight;
720  PFor_Not_Recip_Not_Const3_4(ViewType outputData_, ViewType1 inputDataLeft_,
721  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
722 
723  KOKKOS_INLINE_FUNCTION
724  void operator() (int i) const {
725  for(int j = 0; j < outputData.dimension_1(); j++){
726  for(int k = 0; k < outputData.dimension_2(); k++){
727  for(int l = 0; l < outputData.dimension_3(); l++){
728  outputData(i,j,k,l) = inputDataRight(j,k,l)*inputDataLeft(i,j);
729  }
730  }
731  }
732  }
733 };
734 template<class ViewType, class ViewType1,class ViewType2>
735 struct PFor__Recip__Const3_4 {
736  ViewType outputData;
737  typename ViewType1::const_type inputDataLeft;
738  typename ViewType2::const_type inputDataRight;
739  PFor__Recip__Const3_4(ViewType outputData_, ViewType1 inputDataLeft_,
740  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
741 
742  KOKKOS_INLINE_FUNCTION
743  void operator() (int i) const {
744  for(int j = 0; j < outputData.dimension_1(); j++){
745  for(int k = 0; k < outputData.dimension_2(); k++){
746  for(int l = 0; l < outputData.dimension_3(); l++){
747  outputData(i,j,k,l) = inputDataRight(j,k,l)/inputDataLeft(i,0);
748  }
749  }
750  }
751  }
752 };
753 template<class ViewType, class ViewType1,class ViewType2>
754 struct PFor_Not_Recip__Const3_4 {
755  ViewType outputData;
756  typename ViewType1::const_type inputDataLeft;
757  typename ViewType2::const_type inputDataRight;
758  PFor_Not_Recip__Const3_4(ViewType outputData_, ViewType1 inputDataLeft_,
759  ViewType2 inputDataRight_):outputData(outputData_),inputDataLeft(inputDataLeft_),inputDataRight(inputDataRight_) {}
760 
761  KOKKOS_INLINE_FUNCTION
762  void operator() (int i) const {
763  for(int j = 0; j < outputData.dimension_1(); j++){
764  for(int k = 0; k < outputData.dimension_2(); k++){
765  for(int l = 0; l < outputData.dimension_3(); l++){
766  outputData(i,j,k,l) = inputDataRight(j,k,l)/inputDataLeft(i,0);
767  }
768  }
769  }
770  }
771 };
772 //End Functors for parallel_for rank 3_4
773 
774 //Partially specialized implementation of scalarMultiplyDataData with rank 3_4
775 
776  template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
777 struct ArrayTools::scalarMultiplyDataData2Kokkos<ArrayOutData, ArrayInDataLeft, ArrayInDataRight, Layout, MemorySpace,3,4>{
778  scalarMultiplyDataData2Kokkos(ArrayOutData& outputData,
779  ArrayInDataLeft& inputDataLeft,
780  ArrayInDataRight& inputDataRight,
781  const bool reciprocal){
782 #ifdef HAVE_INTREPID_DEBUG
783  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
784  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
785  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.rank() != 3) ), std::invalid_argument,
786  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 3.");
787  TEUCHOS_TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()+1), std::invalid_argument,
788  ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
789  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
790  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!");
791  TEUCHOS_TEST_FOR_EXCEPTION( ( inputDataLeft.dimension(0) != outputData.dimension(0) ), std::invalid_argument,
792  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
793  for (int i=0; i<inputDataRight.rank(); i++) {
794  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimensions ";
795  errmsg += (char)(48+i);
796  errmsg += " and ";
797  errmsg += (char)(48+i+1);
798  errmsg += " of the right input and output data containers must agree!";
799  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i+1)), std::invalid_argument, errmsg );
800  }
801 #endif
802 
803 
804  int numCells = outputData.dimension(0);
805  int numDataPoints = inputDataLeft.dimension(1);
806 
807 
808 
809  if (numDataPoints != 1) {
810  if (reciprocal) {
811  Kokkos::parallel_for(numCells,PFor__Recip_Not_Const3_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
812  inputDataRight));
813  }
814  else {
815  Kokkos::parallel_for(numCells,PFor_Not_Recip_Not_Const3_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight >(outputData, inputDataLeft,
816  inputDataRight));
817  }
818  }
819  else{
820  if (reciprocal) {
821  Kokkos::parallel_for(numCells,PFor__Recip__Const3_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
822  inputDataRight));
823  }
824  else {
825  Kokkos::parallel_for(numCells,PFor_Not_Recip__Const3_4<ArrayOutData,ArrayInDataLeft,ArrayInDataRight>(outputData, inputDataLeft,
826  inputDataRight));
827  }
828  }
829  }
830  };
831 
832  }//end namespace
833 #endif
834 #endif
Definition file for scalar multiply operations of the array tools interface.