1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 //                        Kokkos v. 3.0
6 //       Copyright (2020) National Technology & Engineering
7 //               Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
45 #include <stdexcept>
46 #include <sstream>
47 #include <iostream>
48 #include <limits>
49 
50 #include <Kokkos_Core.hpp>
51 
52 namespace Test {
53 
54 namespace ReduceCombinatorical {
55 
56 template <class Scalar, class Space = Kokkos::HostSpace>
57 struct AddPlus {
58  public:
59   // Required.
60   using reducer    = AddPlus;
61   using value_type = Scalar;
62 
63   using result_view_type =
64       Kokkos::View<value_type, Space, Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
65 
66  private:
67   result_view_type result;
68 
69  public:
AddPlusTest::ReduceCombinatorical::AddPlus70   AddPlus(value_type& result_) : result(&result_) {}
71 
72   // Required.
73   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::AddPlus74   void join(value_type& dest, const value_type& src) const { dest += src + 1; }
75 
76   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::AddPlus77   void join(volatile value_type& dest, const volatile value_type& src) const {
78     dest += src + 1;
79   }
80 
81   // Optional.
82   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::AddPlus83   void init(value_type& val) const { val = value_type(); }
84 
85   KOKKOS_INLINE_FUNCTION
referenceTest::ReduceCombinatorical::AddPlus86   value_type& reference() const { return result(); }
87 
88   KOKKOS_INLINE_FUNCTION
viewTest::ReduceCombinatorical::AddPlus89   result_view_type view() const { return result; }
90 };
91 
92 template <int ISTEAM>
93 struct FunctorScalar;
94 
95 template <>
96 struct FunctorScalar<0> {
97   Kokkos::View<double> result;
98 
FunctorScalarTest::ReduceCombinatorical::FunctorScalar99   FunctorScalar(Kokkos::View<double> r) : result(r) {}
100 
101   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalar102   void operator()(const int& i, double& update) const { update += i; }
103 };
104 
105 template <>
106 struct FunctorScalar<1> {
107   using team_type = Kokkos::TeamPolicy<>::member_type;
108 
109   Kokkos::View<double> result;
110 
FunctorScalarTest::ReduceCombinatorical::FunctorScalar111   FunctorScalar(Kokkos::View<double> r) : result(r) {}
112 
113   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalar114   void operator()(const team_type& team, double& update) const {
115     update += 1.0 / team.team_size() * team.league_rank();
116   }
117 };
118 
119 template <int ISTEAM>
120 struct FunctorScalarInit;
121 
122 template <>
123 struct FunctorScalarInit<0> {
124   Kokkos::View<double> result;
125 
FunctorScalarInitTest::ReduceCombinatorical::FunctorScalarInit126   FunctorScalarInit(Kokkos::View<double> r) : result(r) {}
127 
128   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarInit129   void operator()(const int& i, double& update) const { update += i; }
130 
131   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarInit132   void init(double& update) const { update = 0.0; }
133 };
134 
135 template <>
136 struct FunctorScalarInit<1> {
137   using team_type = Kokkos::TeamPolicy<>::member_type;
138 
139   Kokkos::View<double> result;
140 
FunctorScalarInitTest::ReduceCombinatorical::FunctorScalarInit141   FunctorScalarInit(Kokkos::View<double> r) : result(r) {}
142 
143   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarInit144   void operator()(const team_type& team, double& update) const {
145     update += 1.0 / team.team_size() * team.league_rank();
146   }
147 
148   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarInit149   void init(double& update) const { update = 0.0; }
150 };
151 
152 template <int ISTEAM>
153 struct FunctorScalarFinal;
154 
155 template <>
156 struct FunctorScalarFinal<0> {
157   Kokkos::View<double> result;
158 
FunctorScalarFinalTest::ReduceCombinatorical::FunctorScalarFinal159   FunctorScalarFinal(Kokkos::View<double> r) : result(r) {}
160 
161   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarFinal162   void operator()(const int& i, double& update) const { update += i; }
163 
164   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarFinal165   void final(double& update) const { result() = update; }
166 };
167 
168 template <>
169 struct FunctorScalarFinal<1> {
170   using team_type = Kokkos::TeamPolicy<>::member_type;
171 
172   Kokkos::View<double> result;
173 
FunctorScalarFinalTest::ReduceCombinatorical::FunctorScalarFinal174   FunctorScalarFinal(Kokkos::View<double> r) : result(r) {}
175 
176   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarFinal177   void operator()(const team_type& team, double& update) const {
178     update += 1.0 / team.team_size() * team.league_rank();
179   }
180 
181   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarFinal182   void final(double& update) const { result() = update; }
183 };
184 
185 template <int ISTEAM>
186 struct FunctorScalarJoin;
187 
188 template <>
189 struct FunctorScalarJoin<0> {
190   Kokkos::View<double> result;
191 
FunctorScalarJoinTest::ReduceCombinatorical::FunctorScalarJoin192   FunctorScalarJoin(Kokkos::View<double> r) : result(r) {}
193 
194   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoin195   void operator()(const int& i, double& update) const { update += i; }
196 
197   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoin198   void join(volatile double& dst, const volatile double& update) const {
199     dst += update;
200   }
201 };
202 
203 template <>
204 struct FunctorScalarJoin<1> {
205   using team_type = Kokkos::TeamPolicy<>::member_type;
206 
207   Kokkos::View<double> result;
208 
FunctorScalarJoinTest::ReduceCombinatorical::FunctorScalarJoin209   FunctorScalarJoin(Kokkos::View<double> r) : result(r) {}
210 
211   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoin212   void operator()(const team_type& team, double& update) const {
213     update += 1.0 / team.team_size() * team.league_rank();
214   }
215 
216   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoin217   void join(volatile double& dst, const volatile double& update) const {
218     dst += update;
219   }
220 };
221 
222 template <int ISTEAM>
223 struct FunctorScalarJoinFinal;
224 
225 template <>
226 struct FunctorScalarJoinFinal<0> {
227   Kokkos::View<double> result;
228 
FunctorScalarJoinFinalTest::ReduceCombinatorical::FunctorScalarJoinFinal229   FunctorScalarJoinFinal(Kokkos::View<double> r) : result(r) {}
230 
231   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinFinal232   void operator()(const int& i, double& update) const { update += i; }
233 
234   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinFinal235   void join(volatile double& dst, const volatile double& update) const {
236     dst += update;
237   }
238 
239   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarJoinFinal240   void final(double& update) const { result() = update; }
241 };
242 
243 template <>
244 struct FunctorScalarJoinFinal<1> {
245   using team_type = Kokkos::TeamPolicy<>::member_type;
246 
247   Kokkos::View<double> result;
248 
FunctorScalarJoinFinalTest::ReduceCombinatorical::FunctorScalarJoinFinal249   FunctorScalarJoinFinal(Kokkos::View<double> r) : result(r) {}
250 
251   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinFinal252   void operator()(const team_type& team, double& update) const {
253     update += 1.0 / team.team_size() * team.league_rank();
254   }
255 
256   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinFinal257   void join(volatile double& dst, const volatile double& update) const {
258     dst += update;
259   }
260 
261   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarJoinFinal262   void final(double& update) const { result() = update; }
263 };
264 
265 template <int ISTEAM>
266 struct FunctorScalarJoinInit;
267 
268 template <>
269 struct FunctorScalarJoinInit<0> {
270   Kokkos::View<double> result;
271 
FunctorScalarJoinInitTest::ReduceCombinatorical::FunctorScalarJoinInit272   FunctorScalarJoinInit(Kokkos::View<double> r) : result(r) {}
273 
274   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinInit275   void operator()(const int& i, double& update) const { update += i; }
276 
277   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinInit278   void join(volatile double& dst, const volatile double& update) const {
279     dst += update;
280   }
281 
282   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarJoinInit283   void init(double& update) const { update = 0.0; }
284 };
285 
286 template <>
287 struct FunctorScalarJoinInit<1> {
288   using team_type = Kokkos::TeamPolicy<>::member_type;
289 
290   Kokkos::View<double> result;
291 
FunctorScalarJoinInitTest::ReduceCombinatorical::FunctorScalarJoinInit292   FunctorScalarJoinInit(Kokkos::View<double> r) : result(r) {}
293 
294   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinInit295   void operator()(const team_type& team, double& update) const {
296     update += 1.0 / team.team_size() * team.league_rank();
297   }
298 
299   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinInit300   void join(volatile double& dst, const volatile double& update) const {
301     dst += update;
302   }
303 
304   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarJoinInit305   void init(double& update) const { update = 0.0; }
306 };
307 
308 template <int ISTEAM>
309 struct FunctorScalarJoinFinalInit;
310 
311 template <>
312 struct FunctorScalarJoinFinalInit<0> {
313   Kokkos::View<double> result;
314 
FunctorScalarJoinFinalInitTest::ReduceCombinatorical::FunctorScalarJoinFinalInit315   FunctorScalarJoinFinalInit(Kokkos::View<double> r) : result(r) {}
316 
317   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinFinalInit318   void operator()(const int& i, double& update) const { update += i; }
319 
320   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinFinalInit321   void join(volatile double& dst, const volatile double& update) const {
322     dst += update;
323   }
324 
325   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarJoinFinalInit326   void final(double& update) const { result() = update; }
327 
328   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarJoinFinalInit329   void init(double& update) const { update = 0.0; }
330 };
331 
332 template <>
333 struct FunctorScalarJoinFinalInit<1> {
334   using team_type = Kokkos::TeamPolicy<>::member_type;
335 
336   Kokkos::View<double> result;
337 
FunctorScalarJoinFinalInitTest::ReduceCombinatorical::FunctorScalarJoinFinalInit338   FunctorScalarJoinFinalInit(Kokkos::View<double> r) : result(r) {}
339 
340   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::FunctorScalarJoinFinalInit341   void operator()(const team_type& team, double& update) const {
342     update += 1.0 / team.team_size() * team.league_rank();
343   }
344 
345   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::FunctorScalarJoinFinalInit346   void join(volatile double& dst, const volatile double& update) const {
347     dst += update;
348   }
349 
350   KOKKOS_INLINE_FUNCTION
finalTest::ReduceCombinatorical::FunctorScalarJoinFinalInit351   void final(double& update) const { result() = update; }
352 
353   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::FunctorScalarJoinFinalInit354   void init(double& update) const { update = 0.0; }
355 };
356 
357 struct Functor1 {
358   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::Functor1359   void operator()(const int& i, double& update) const { update += i; }
360 };
361 
362 struct Functor2 {
363   using value_type = double[];
364 
365   const unsigned value_count;
366 
Functor2Test::ReduceCombinatorical::Functor2367   Functor2(unsigned n) : value_count(n) {}
368 
369   KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceCombinatorical::Functor2370   void operator()(const unsigned& i, double update[]) const {
371     for (unsigned j = 0; j < value_count; j++) {
372       update[j] += i;
373     }
374   }
375 
376   KOKKOS_INLINE_FUNCTION
initTest::ReduceCombinatorical::Functor2377   void init(double dst[]) const {
378     for (unsigned i = 0; i < value_count; ++i) dst[i] = 0;
379   }
380 
381   KOKKOS_INLINE_FUNCTION
joinTest::ReduceCombinatorical::Functor2382   void join(volatile double dst[], const volatile double src[]) const {
383     for (unsigned i = 0; i < value_count; ++i) dst[i] += src[i];
384   }
385 };
386 
387 }  // namespace ReduceCombinatorical
388 
389 template <class ExecSpace = Kokkos::DefaultExecutionSpace>
390 struct TestReduceCombinatoricalInstantiation {
391   template <class... Args>
CallParallelReduceTest::TestReduceCombinatoricalInstantiation392   static void CallParallelReduce(Args... args) {
393     Kokkos::parallel_reduce(args...);
394   }
395 
396   template <class... Args>
AddReturnArgumentTest::TestReduceCombinatoricalInstantiation397   static void AddReturnArgument(int N, Args... args) {
398     Kokkos::View<double, Kokkos::HostSpace> result_view("ResultViewHost");
399     Kokkos::View<double, ExecSpace> result_view_device("ResultViewDevice");
400     double expected_result = (1.0 * N) * (1.0 * N - 1.0) / 2.0;
401 
402     double value = 99;
403     Kokkos::parallel_reduce(args..., value);
404     ASSERT_EQ(expected_result, value);
405 
406     result_view() = 99;
407     CallParallelReduce(args..., result_view);
408     Kokkos::fence();
409     ASSERT_EQ(expected_result, result_view());
410 
411 #ifndef KOKKOS_ENABLE_OPENMPTARGET
412     result_view() = 99;
413     CallParallelReduce(args..., result_view_device);
414     Kokkos::fence();
415     Kokkos::deep_copy(result_view, result_view_device);
416     ASSERT_EQ(expected_result, result_view());
417 #endif
418 
419     value = 99;
420     CallParallelReduce(
421         args...,
422         Kokkos::View<double, Kokkos::HostSpace,
423                      Kokkos::MemoryTraits<Kokkos::Unmanaged> >(&value));
424     Kokkos::fence();
425     ASSERT_EQ(expected_result, value);
426 
427     result_view() = 99;
428     const Kokkos::View<double, Kokkos::HostSpace,
429                        Kokkos::MemoryTraits<Kokkos::Unmanaged> >
430         result_view_const_um = result_view;
431     CallParallelReduce(args..., result_view_const_um);
432     Kokkos::fence();
433     ASSERT_EQ(expected_result, result_view_const_um());
434 
435     value = 99;
436 // WORKAROUND OPENMPTARGET Custom Reducers not implemented
437 #ifndef KOKKOS_ENABLE_OPENMPTARGET
438     CallParallelReduce(args...,
439                        Test::ReduceCombinatorical::AddPlus<double>(value));
440     if ((Kokkos::DefaultExecutionSpace::concurrency() > 1) &&
441         (ExecSpace::concurrency() > 1) && (expected_result > 0)) {
442       ASSERT_TRUE(expected_result < value);
443     } else if (((Kokkos::DefaultExecutionSpace::concurrency() > 1) ||
444                 (ExecSpace::concurrency() > 1)) &&
445                (expected_result > 0)) {
446       ASSERT_TRUE(expected_result <= value);
447     } else {
448       ASSERT_EQ(expected_result, value);
449     }
450 
451     value = 99;
452     Test::ReduceCombinatorical::AddPlus<double> add(value);
453     CallParallelReduce(args..., add);
454     if ((Kokkos::DefaultExecutionSpace::concurrency() > 1) &&
455         (ExecSpace::concurrency() > 1) && (expected_result > 0)) {
456       ASSERT_TRUE(expected_result < value);
457     } else if (((Kokkos::DefaultExecutionSpace::concurrency() > 1) ||
458                 (ExecSpace::concurrency() > 1)) &&
459                (expected_result > 0)) {
460       ASSERT_TRUE(expected_result <= value);
461     } else {
462       ASSERT_EQ(expected_result, value);
463     }
464 #endif
465   }
466 
467   template <class... Args>
AddLambdaRangeTest::TestReduceCombinatoricalInstantiation468   static void AddLambdaRange(int N, void*, Args... args) {
469     AddReturnArgument(
470         N, args..., KOKKOS_LAMBDA(const int& i, double& lsum) { lsum += i; });
471   }
472 
473   template <class... Args>
AddLambdaTeamTest::TestReduceCombinatoricalInstantiation474   static void AddLambdaTeam(int N, void*, Args... args) {
475     AddReturnArgument(
476         N, args...,
477         KOKKOS_LAMBDA(const Kokkos::TeamPolicy<>::member_type& team,
478                       double& update) {
479           update += 1.0 / team.team_size() * team.league_rank();
480         });
481   }
482 
483   template <class... Args>
AddLambdaRangeTest::TestReduceCombinatoricalInstantiation484   static void AddLambdaRange(int, Kokkos::InvalidType, Args... /*args*/) {}
485 
486   template <class... Args>
AddLambdaTeamTest::TestReduceCombinatoricalInstantiation487   static void AddLambdaTeam(int, Kokkos::InvalidType, Args... /*args*/) {}
488 
489   template <int ISTEAM, class... Args>
AddFunctorTest::TestReduceCombinatoricalInstantiation490   static void AddFunctor(int N, Args... args) {
491     Kokkos::View<double, ExecSpace> result_view("FunctorView");
492     auto h_r = Kokkos::create_mirror_view(result_view);
493     Test::ReduceCombinatorical::FunctorScalar<ISTEAM> functor(result_view);
494 
495     AddReturnArgument(N, args..., functor);
496     AddReturnArgument(
497         N, args...,
498         Test::ReduceCombinatorical::FunctorScalar<ISTEAM>(result_view));
499 // WORKAROUND OPENMPTARGET: reductions with functor join/init/final
500 // not implemented
501 #if !defined(KOKKOS_ENABLE_OPENMPTARGET)
502     AddReturnArgument(
503         N, args...,
504         Test::ReduceCombinatorical::FunctorScalarInit<ISTEAM>(result_view));
505     AddReturnArgument(
506         N, args...,
507         Test::ReduceCombinatorical::FunctorScalarJoin<ISTEAM>(result_view));
508     AddReturnArgument(
509         N, args...,
510         Test::ReduceCombinatorical::FunctorScalarJoinInit<ISTEAM>(result_view));
511     double expected_result = (1.0 * N) * (1.0 * N - 1.0) / 2.0;
512 
513     h_r() = 0;
514     Kokkos::deep_copy(result_view, h_r);
515     CallParallelReduce(
516         args...,
517         Test::ReduceCombinatorical::FunctorScalarFinal<ISTEAM>(result_view));
518     Kokkos::fence();
519     Kokkos::deep_copy(h_r, result_view);
520     ASSERT_EQ(expected_result, h_r());
521 
522     h_r() = 0;
523     Kokkos::deep_copy(result_view, h_r);
524     CallParallelReduce(
525         args..., Test::ReduceCombinatorical::FunctorScalarJoinFinal<ISTEAM>(
526                      result_view));
527     Kokkos::fence();
528     Kokkos::deep_copy(h_r, result_view);
529     ASSERT_EQ(expected_result, h_r());
530 
531     h_r() = 0;
532     Kokkos::deep_copy(result_view, h_r);
533     CallParallelReduce(
534         args..., Test::ReduceCombinatorical::FunctorScalarJoinFinalInit<ISTEAM>(
535                      result_view));
536     Kokkos::fence();
537     Kokkos::deep_copy(h_r, result_view);
538     ASSERT_EQ(expected_result, h_r());
539 #endif
540   }
541 
542   template <class... Args>
AddFunctorLambdaRangeTest::TestReduceCombinatoricalInstantiation543   static void AddFunctorLambdaRange(int N, Args... args) {
544     AddFunctor<0, Args...>(N, args...);
545 #ifdef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
546     AddLambdaRange(
547         N,
548         typename std::conditional<
549             std::is_same<ExecSpace, Kokkos::DefaultExecutionSpace>::value,
550             void*, Kokkos::InvalidType>::type(),
551         args...);
552 #endif
553   }
554 
555   template <class... Args>
AddFunctorLambdaTeamTest::TestReduceCombinatoricalInstantiation556   static void AddFunctorLambdaTeam(int N, Args... args) {
557     AddFunctor<1, Args...>(N, args...);
558 #ifdef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
559     AddLambdaTeam(
560         N,
561         typename std::conditional<
562             std::is_same<ExecSpace, Kokkos::DefaultExecutionSpace>::value,
563             void*, Kokkos::InvalidType>::type(),
564         args...);
565 #endif
566   }
567 
568   template <class... Args>
AddPolicy_1Test::TestReduceCombinatoricalInstantiation569   static void AddPolicy_1(int N, Args... args) {
570     Kokkos::RangePolicy<ExecSpace> policy(0, N);
571 
572     AddFunctorLambdaRange(1000, args..., 1000);
573     AddFunctorLambdaRange(N, args..., N);
574     AddFunctorLambdaRange(N, args..., policy);
575   }
576 
577   template <class... Args>
AddPolicy_2Test::TestReduceCombinatoricalInstantiation578   static void AddPolicy_2(int N, Args... args) {
579     AddFunctorLambdaRange(N, args..., Kokkos::RangePolicy<ExecSpace>(0, N));
580     AddFunctorLambdaRange(
581         N, args...,
582         Kokkos::RangePolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >(0,
583                                                                            N));
584     AddFunctorLambdaRange(
585         N, args...,
586         Kokkos::RangePolicy<ExecSpace, Kokkos::Schedule<Kokkos::Static> >(0, N)
587             .set_chunk_size(16));
588     AddFunctorLambdaRange(
589         N, args...,
590         Kokkos::RangePolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >(0, N)
591             .set_chunk_size(16));
592   }
593 
594   template <class... Args>
AddPolicy_3Test::TestReduceCombinatoricalInstantiation595   static void AddPolicy_3(int N, Args... args) {
596     AddFunctorLambdaTeam(N, args...,
597                          Kokkos::TeamPolicy<ExecSpace>(N, Kokkos::AUTO));
598     AddFunctorLambdaTeam(
599         N, args...,
600         Kokkos::TeamPolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >(
601             N, Kokkos::AUTO));
602     AddFunctorLambdaTeam(
603         N, args...,
604         Kokkos::TeamPolicy<ExecSpace, Kokkos::Schedule<Kokkos::Static> >(
605             N, Kokkos::AUTO)
606             .set_chunk_size(16));
607     AddFunctorLambdaTeam(
608         N, args...,
609         Kokkos::TeamPolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >(
610             N, Kokkos::AUTO)
611             .set_chunk_size(16));
612   }
613 
execute_a1Test::TestReduceCombinatoricalInstantiation614   static void execute_a1() { AddPolicy_1(1000); }
615 
execute_b1Test::TestReduceCombinatoricalInstantiation616   static void execute_b1() {
617     std::string s("Std::String");
618     AddPolicy_1(1000, s.c_str());
619     AddPolicy_1(1000, "Char Constant");
620 #ifndef KOKKOS_ENABLE_OPENMPTARGET
621     AddPolicy_1(0, "Char Constant");
622 #endif
623   }
624 
execute_c1Test::TestReduceCombinatoricalInstantiation625   static void execute_c1() {
626     std::string s("Std::String");
627     AddPolicy_1(1000, s);
628   }
629 
execute_a2Test::TestReduceCombinatoricalInstantiation630   static void execute_a2() { AddPolicy_2(1000); }
631 
execute_b2Test::TestReduceCombinatoricalInstantiation632   static void execute_b2() {
633     std::string s("Std::String");
634     AddPolicy_2(1000, s.c_str());
635     AddPolicy_2(1000, "Char Constant");
636 #ifndef KOKKOS_ENABLE_OPENMPTARGET
637     AddPolicy_2(0, "Char Constant");
638 #endif
639   }
640 
execute_c2Test::TestReduceCombinatoricalInstantiation641   static void execute_c2() {
642     std::string s("Std::String");
643     AddPolicy_2(1000, s);
644   }
645 
execute_a3Test::TestReduceCombinatoricalInstantiation646   static void execute_a3() {
647 #ifndef KOKKOS_ENABLE_OPENMPTARGET
648     AddPolicy_3(1000);
649 #endif
650   }
651 
execute_b3Test::TestReduceCombinatoricalInstantiation652   static void execute_b3() {
653 #ifndef KOKKOS_ENABLE_OPENMPTARGET
654     std::string s("Std::String");
655     AddPolicy_3(1000, s.c_str());
656     AddPolicy_3(1000, "Char Constant");
657     AddPolicy_3(0, "Char Constant");
658 #endif
659   }
660 
execute_c3Test::TestReduceCombinatoricalInstantiation661   static void execute_c3() {
662 #ifndef KOKKOS_ENABLE_OPENMPTARGET
663     std::string s("Std::String");
664     AddPolicy_3(1000, s);
665 #endif
666   }
667 };
668 
669 }  // namespace Test
670