Kokkos Core Kernels Package  Version of the Day
Kokkos_Parallel_Reduce.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_PARALLEL_REDUCE_HPP
45 #define KOKKOS_PARALLEL_REDUCE_HPP
46 
47 #include <Kokkos_NumericTraits.hpp>
48 
49 namespace Kokkos {
50 
51 template<class T, class Enable = void>
52 struct is_reducer_type {
53  enum { value = 0 };
54 };
55 
56 
57 template<class T>
58 struct is_reducer_type<T,typename std::enable_if<
59  std::is_same<typename std::remove_cv<T>::type,
60  typename std::remove_cv<typename T::reducer>::type>::value
61  >::type> {
62  enum { value = 1 };
63 };
64 
65 namespace Experimental {
66 
67 
68 template<class Scalar, class Space>
69 struct Sum {
70 public:
71  //Required
72  typedef Sum reducer;
73  typedef typename std::remove_cv<Scalar>::type value_type;
74 
76 
77 private:
78  value_type* value;
79 
80 public:
81 
82  KOKKOS_INLINE_FUNCTION
83  Sum(value_type& value_): value(&value_) {}
84 
85  KOKKOS_INLINE_FUNCTION
86  Sum(const result_view_type& value_): value(value_.data()) {}
87 
88  //Required
89  KOKKOS_INLINE_FUNCTION
90  void join(value_type& dest, const value_type& src) const {
91  dest += src;
92  }
93 
94  KOKKOS_INLINE_FUNCTION
95  void join(volatile value_type& dest, const volatile value_type& src) const {
96  dest += src;
97  }
98 
99  KOKKOS_INLINE_FUNCTION
100  void init( value_type& val) const {
101  val = reduction_identity<value_type>::sum();
102  }
103 
104  KOKKOS_INLINE_FUNCTION
105  value_type& reference() const {
106  return *value;
107  }
108 
109  KOKKOS_INLINE_FUNCTION
110  result_view_type view() const {
111  return result_view_type(value);
112  }
113 };
114 
115 template<class Scalar, class Space>
116 struct Prod {
117 public:
118  //Required
119  typedef Prod reducer;
120  typedef typename std::remove_cv<Scalar>::type value_type;
121 
123 
124 private:
125  value_type* value;
126 
127 public:
128 
129  KOKKOS_INLINE_FUNCTION
130  Prod(value_type& value_): value(&value_) {}
131 
132  KOKKOS_INLINE_FUNCTION
133  Prod(const result_view_type& value_): value(value_.data()) {}
134 
135  //Required
136  KOKKOS_INLINE_FUNCTION
137  void join(value_type& dest, const value_type& src) const {
138  dest *= src;
139  }
140 
141  KOKKOS_INLINE_FUNCTION
142  void join(volatile value_type& dest, const volatile value_type& src) const {
143  dest *= src;
144  }
145 
146  KOKKOS_INLINE_FUNCTION
147  void init( value_type& val) const {
148  val = reduction_identity<value_type>::prod();
149  }
150 
151  KOKKOS_INLINE_FUNCTION
152  value_type& reference() const {
153  return *value;
154  }
155 
156  KOKKOS_INLINE_FUNCTION
157  result_view_type view() const {
158  return result_view_type(value);
159  }
160 };
161 
162 template<class Scalar, class Space>
163 struct Min {
164 public:
165  //Required
166  typedef Min reducer;
167  typedef typename std::remove_cv<Scalar>::type value_type;
168 
170 
171 private:
172  value_type* value;
173 
174 public:
175 
176  KOKKOS_INLINE_FUNCTION
177  Min(value_type& value_): value(&value_) {}
178 
179  KOKKOS_INLINE_FUNCTION
180  Min(const result_view_type& value_): value(value_.data()) {}
181 
182  //Required
183  KOKKOS_INLINE_FUNCTION
184  void join(value_type& dest, const value_type& src) const {
185  if ( src < dest )
186  dest = src;
187  }
188 
189  KOKKOS_INLINE_FUNCTION
190  void join(volatile value_type& dest, const volatile value_type& src) const {
191  if ( src < dest )
192  dest = src;
193  }
194 
195  KOKKOS_INLINE_FUNCTION
196  void init( value_type& val) const {
197  val = reduction_identity<value_type>::min();
198  }
199 
200  KOKKOS_INLINE_FUNCTION
201  value_type& reference() const {
202  return *value;
203  }
204 
205  KOKKOS_INLINE_FUNCTION
206  result_view_type view() const {
207  return result_view_type(value);
208  }
209 };
210 
211 template<class Scalar, class Space>
212 struct Max {
213 public:
214  //Required
215  typedef Max reducer;
216  typedef typename std::remove_cv<Scalar>::type value_type;
217 
219 
220 private:
221  value_type* value;
222 
223 public:
224 
225  KOKKOS_INLINE_FUNCTION
226  Max(value_type& value_): value(&value_) {}
227 
228  KOKKOS_INLINE_FUNCTION
229  Max(const result_view_type& value_): value(value_.data()) {}
230 
231  //Required
232  KOKKOS_INLINE_FUNCTION
233  void join(value_type& dest, const value_type& src) const {
234  if ( src > dest )
235  dest = src;
236  }
237 
238  KOKKOS_INLINE_FUNCTION
239  void join(volatile value_type& dest, const volatile value_type& src) const {
240  if ( src > dest )
241  dest = src;
242  }
243 
244  //Required
245  KOKKOS_INLINE_FUNCTION
246  void init( value_type& val) const {
247  val = reduction_identity<value_type>::max();
248  }
249 
250  KOKKOS_INLINE_FUNCTION
251  value_type& reference() const {
252  return *value;
253  }
254 
255  KOKKOS_INLINE_FUNCTION
256  result_view_type view() const {
257  return result_view_type(value);
258  }
259 };
260 
261 template<class Scalar, class Space>
262 struct LAnd {
263 public:
264  //Required
265  typedef LAnd reducer;
266  typedef typename std::remove_cv<Scalar>::type value_type;
267 
269 
270 private:
271  value_type* value;
272 
273 public:
274 
275  KOKKOS_INLINE_FUNCTION
276  LAnd(value_type& value_): value(&value_) {}
277 
278  KOKKOS_INLINE_FUNCTION
279  LAnd(const result_view_type& value_): value(value_.data()) {}
280 
281  KOKKOS_INLINE_FUNCTION
282  void join(value_type& dest, const value_type& src) const {
283  dest = dest && src;
284  }
285 
286  KOKKOS_INLINE_FUNCTION
287  void join(volatile value_type& dest, const volatile value_type& src) const {
288  dest = dest && src;
289  }
290 
291  KOKKOS_INLINE_FUNCTION
292  void init( value_type& val) const {
293  val = reduction_identity<value_type>::land();
294  }
295 
296  KOKKOS_INLINE_FUNCTION
297  value_type& reference() const {
298  return *value;
299  }
300 
301  KOKKOS_INLINE_FUNCTION
302  result_view_type view() const {
303  return result_view_type(value);
304  }
305 };
306 
307 template<class Scalar, class Space>
308 struct LOr {
309 public:
310  //Required
311  typedef LOr reducer;
312  typedef typename std::remove_cv<Scalar>::type value_type;
313 
315 
316 private:
317  value_type* value;
318 
319 public:
320 
321  KOKKOS_INLINE_FUNCTION
322  LOr(value_type& value_): value(&value_) {}
323 
324  KOKKOS_INLINE_FUNCTION
325  LOr(const result_view_type& value_): value(value_.data()) {}
326 
327  //Required
328  KOKKOS_INLINE_FUNCTION
329  void join(value_type& dest, const value_type& src) const {
330  dest = dest || src;
331  }
332 
333  KOKKOS_INLINE_FUNCTION
334  void join(volatile value_type& dest, const volatile value_type& src) const {
335  dest = dest || src;
336  }
337 
338  KOKKOS_INLINE_FUNCTION
339  void init( value_type& val) const {
340  val = reduction_identity<value_type>::lor();
341  }
342 
343  KOKKOS_INLINE_FUNCTION
344  value_type& reference() const {
345  return *value;
346  }
347 
348  KOKKOS_INLINE_FUNCTION
349  result_view_type view() const {
350  return result_view_type(value);
351  }
352 };
353 
354 template<class Scalar, class Space>
355 struct BAnd {
356 public:
357  //Required
358  typedef BAnd reducer;
359  typedef typename std::remove_cv<Scalar>::type value_type;
360 
362 
363 private:
364  value_type* value;
365 
366 public:
367 
368  KOKKOS_INLINE_FUNCTION
369  BAnd(value_type& value_): value(&value_) {}
370 
371  KOKKOS_INLINE_FUNCTION
372  BAnd(const result_view_type& value_): value(value_.data()) {}
373 
374  //Required
375  KOKKOS_INLINE_FUNCTION
376  void join(value_type& dest, const value_type& src) const {
377  dest = dest & src;
378  }
379 
380  KOKKOS_INLINE_FUNCTION
381  void join(volatile value_type& dest, const volatile value_type& src) const {
382  dest = dest & src;
383  }
384 
385  KOKKOS_INLINE_FUNCTION
386  void init( value_type& val) const {
387  val = reduction_identity<value_type>::band();
388  }
389 
390  KOKKOS_INLINE_FUNCTION
391  value_type& reference() const {
392  return *value;
393  }
394 
395  KOKKOS_INLINE_FUNCTION
396  result_view_type view() const {
397  return result_view_type(value);
398  }
399 };
400 
401 template<class Scalar, class Space>
402 struct BOr {
403 public:
404  //Required
405  typedef BOr reducer;
406  typedef typename std::remove_cv<Scalar>::type value_type;
407 
409 
410 private:
411  value_type* value;
412 
413 public:
414 
415  KOKKOS_INLINE_FUNCTION
416  BOr(value_type& value_): value(&value_) {}
417 
418  KOKKOS_INLINE_FUNCTION
419  BOr(const result_view_type& value_): value(value_.data()) {}
420 
421  //Required
422  KOKKOS_INLINE_FUNCTION
423  void join(value_type& dest, const value_type& src) const {
424  dest = dest | src;
425  }
426 
427  KOKKOS_INLINE_FUNCTION
428  void join(volatile value_type& dest, const volatile value_type& src) const {
429  dest = dest | src;
430  }
431 
432  KOKKOS_INLINE_FUNCTION
433  void init( value_type& val) const {
434  val = reduction_identity<value_type>::bor();
435  }
436 
437  KOKKOS_INLINE_FUNCTION
438  value_type& reference() const {
439  return *value;
440  }
441 
442  KOKKOS_INLINE_FUNCTION
443  result_view_type view() const {
444  return result_view_type(value);
445  }
446 };
447 
448 template<class Scalar, class Index>
449 struct ValLocScalar {
450  Scalar val;
451  Index loc;
452 
453  KOKKOS_INLINE_FUNCTION
454  void operator = (const ValLocScalar& rhs) {
455  val = rhs.val;
456  loc = rhs.loc;
457  }
458 
459  KOKKOS_INLINE_FUNCTION
460  void operator = (const volatile ValLocScalar& rhs) volatile {
461  val = rhs.val;
462  loc = rhs.loc;
463  }
464 };
465 
466 template<class Scalar, class Index, class Space>
467 struct MinLoc {
468 private:
469  typedef typename std::remove_cv<Scalar>::type scalar_type;
470  typedef typename std::remove_cv<Index>::type index_type;
471 
472 public:
473  //Required
474  typedef MinLoc reducer;
475  typedef ValLocScalar<scalar_type,index_type> value_type;
476 
478 
479 private:
480  value_type* value;
481 
482 public:
483 
484  KOKKOS_INLINE_FUNCTION
485  MinLoc(value_type& value_): value(&value_) {}
486 
487  KOKKOS_INLINE_FUNCTION
488  MinLoc(const result_view_type& value_): value(value_.data()) {}
489 
490 
491  //Required
492  KOKKOS_INLINE_FUNCTION
493  void join(value_type& dest, const value_type& src) const {
494  if ( src.val < dest.val )
495  dest = src;
496  }
497 
498  KOKKOS_INLINE_FUNCTION
499  void join(volatile value_type& dest, const volatile value_type& src) const {
500  if ( src.val < dest.val )
501  dest = src;
502  }
503 
504  KOKKOS_INLINE_FUNCTION
505  void init( value_type& val) const {
506  val.val = reduction_identity<scalar_type>::min();
507  val.loc = reduction_identity<index_type>::min();
508  }
509 
510  KOKKOS_INLINE_FUNCTION
511  value_type& reference() {
512  return *value;
513  }
514 
515  KOKKOS_INLINE_FUNCTION
516  result_view_type view() const {
517  return result_view_type(value);
518  }
519 };
520 
521 template<class Scalar, class Index, class Space>
522 struct MaxLoc {
523 private:
524  typedef typename std::remove_cv<Scalar>::type scalar_type;
525  typedef typename std::remove_cv<Index>::type index_type;
526 
527 public:
528  //Required
529  typedef MaxLoc reducer;
530  typedef ValLocScalar<scalar_type,index_type> value_type;
531 
533 
534 private:
535  value_type* value;
536 
537 public:
538 
539  KOKKOS_INLINE_FUNCTION
540  MaxLoc(value_type& value_): value(&value_) {}
541 
542  KOKKOS_INLINE_FUNCTION
543  MaxLoc(const result_view_type& value_): value(value_.data()) {}
544 
545  //Required
546  KOKKOS_INLINE_FUNCTION
547  void join(value_type& dest, const value_type& src) const {
548  if ( src.val > dest.val )
549  dest = src;
550  }
551 
552  KOKKOS_INLINE_FUNCTION
553  void join(volatile value_type& dest, const volatile value_type& src) const {
554  if ( src.val > dest.val )
555  dest = src;
556  }
557 
558  KOKKOS_INLINE_FUNCTION
559  void init( value_type& val) const {
560  val.val = reduction_identity<scalar_type>::max();;
561  val.loc = reduction_identity<index_type>::min();
562  }
563 
564  KOKKOS_INLINE_FUNCTION
565  value_type& reference() {
566  return *value;
567  }
568 
569  KOKKOS_INLINE_FUNCTION
570  result_view_type view() const {
571  return result_view_type(value);
572  }
573 };
574 
575 template<class Scalar>
576 struct MinMaxScalar {
577  Scalar min_val,max_val;
578 
579  KOKKOS_INLINE_FUNCTION
580  void operator = (const MinMaxScalar& rhs) {
581  min_val = rhs.min_val;
582  max_val = rhs.max_val;
583  }
584 
585  KOKKOS_INLINE_FUNCTION
586  void operator = (const volatile MinMaxScalar& rhs) volatile {
587  min_val = rhs.min_val;
588  max_val = rhs.max_val;
589  }
590 };
591 
592 template<class Scalar, class Space>
593 struct MinMax {
594 private:
595  typedef typename std::remove_cv<Scalar>::type scalar_type;
596 
597 public:
598  //Required
599  typedef MinMax reducer;
600  typedef MinMaxScalar<scalar_type> value_type;
601 
603 
604 private:
605  value_type* value;
606 
607 public:
608 
609  KOKKOS_INLINE_FUNCTION
610  MinMax(value_type& value_): value(&value_) {}
611 
612  KOKKOS_INLINE_FUNCTION
613  MinMax(const result_view_type& value_): value(value_.data()) {}
614 
615  //Required
616  KOKKOS_INLINE_FUNCTION
617  void join(value_type& dest, const value_type& src) const {
618  if ( src.min_val < dest.min_val ) {
619  dest.min_val = src.min_val;
620  }
621  if ( src.max_val > dest.max_val ) {
622  dest.max_val = src.max_val;
623  }
624  }
625 
626  KOKKOS_INLINE_FUNCTION
627  void join(volatile value_type& dest, const volatile value_type& src) const {
628  if ( src.min_val < dest.min_val ) {
629  dest.min_val = src.min_val;
630  }
631  if ( src.max_val > dest.max_val ) {
632  dest.max_val = src.max_val;
633  }
634  }
635 
636  KOKKOS_INLINE_FUNCTION
637  void init( value_type& val) const {
638  val.max_val = reduction_identity<scalar_type>::max();;
639  val.min_val = reduction_identity<scalar_type>::min();
640  }
641 
642  KOKKOS_INLINE_FUNCTION
643  value_type& reference() {
644  return *value;
645  }
646 
647  KOKKOS_INLINE_FUNCTION
648  result_view_type view() const {
649  return result_view_type(value);
650  }
651 };
652 
653 template<class Scalar, class Index>
654 struct MinMaxLocScalar {
655  Scalar min_val,max_val;
656  Index min_loc,max_loc;
657 
658  KOKKOS_INLINE_FUNCTION
659  void operator = (const MinMaxLocScalar& rhs) {
660  min_val = rhs.min_val;
661  min_loc = rhs.min_loc;
662  max_val = rhs.max_val;
663  max_loc = rhs.max_loc;
664  }
665 
666  KOKKOS_INLINE_FUNCTION
667  void operator = (const volatile MinMaxLocScalar& rhs) volatile {
668  min_val = rhs.min_val;
669  min_loc = rhs.min_loc;
670  max_val = rhs.max_val;
671  max_loc = rhs.max_loc;
672  }
673 };
674 
675 template<class Scalar, class Index, class Space>
676 struct MinMaxLoc {
677 private:
678  typedef typename std::remove_cv<Scalar>::type scalar_type;
679  typedef typename std::remove_cv<Index>::type index_type;
680 
681 public:
682  //Required
683  typedef MinMaxLoc reducer;
684  typedef MinMaxLocScalar<scalar_type,index_type> value_type;
685 
687 
688 private:
689  value_type* value;
690 
691 public:
692 
693  KOKKOS_INLINE_FUNCTION
694  MinMaxLoc(value_type& value_): value(&value_) {}
695 
696  KOKKOS_INLINE_FUNCTION
697  MinMaxLoc(const result_view_type& value_): value(value_.data()) {}
698 
699  //Required
700  KOKKOS_INLINE_FUNCTION
701  void join(value_type& dest, const value_type& src) const {
702  if ( src.min_val < dest.min_val ) {
703  dest.min_val = src.min_val;
704  dest.min_loc = src.min_loc;
705  }
706  if ( src.max_val > dest.max_val ) {
707  dest.max_val = src.max_val;
708  dest.max_loc = src.max_loc;
709  }
710  }
711 
712  KOKKOS_INLINE_FUNCTION
713  void join(volatile value_type& dest, const volatile value_type& src) const {
714  if ( src.min_val < dest.min_val ) {
715  dest.min_val = src.min_val;
716  dest.min_loc = src.min_loc;
717  }
718  if ( src.max_val > dest.max_val ) {
719  dest.max_val = src.max_val;
720  dest.max_loc = src.max_loc;
721  }
722  }
723 
724  KOKKOS_INLINE_FUNCTION
725  void init( value_type& val) const {
726  val.max_val = reduction_identity<scalar_type>::max();;
727  val.min_val = reduction_identity<scalar_type>::min();
728  val.max_loc = reduction_identity<index_type>::min();
729  val.min_loc = reduction_identity<index_type>::min();
730  }
731 
732  KOKKOS_INLINE_FUNCTION
733  value_type& reference() {
734  return *value;
735  }
736 
737  KOKKOS_INLINE_FUNCTION
738  result_view_type view() const {
739  return result_view_type(value);
740  }
741 };
742 }
743 }
744 
745 
746 namespace Kokkos {
747 namespace Impl {
748 
749 template< class T, class ReturnType , class ValueTraits>
750 struct ParallelReduceReturnValue;
751 
752 template< class ReturnType , class FunctorType >
753 struct ParallelReduceReturnValue<typename std::enable_if<Kokkos::is_view<ReturnType>::value>::type, ReturnType, FunctorType> {
754  typedef ReturnType return_type;
755  typedef InvalidType reducer_type;
756 
757  typedef typename return_type::value_type value_type_scalar;
758  typedef typename return_type::value_type* const value_type_array;
759 
760  typedef typename if_c<return_type::rank==0,value_type_scalar,value_type_array>::type value_type;
761 
762  static return_type& return_value(ReturnType& return_val, const FunctorType&) {
763  return return_val;
764  }
765 };
766 
767 template< class ReturnType , class FunctorType>
768 struct ParallelReduceReturnValue<typename std::enable_if<
769  !Kokkos::is_view<ReturnType>::value &&
770  (!std::is_array<ReturnType>::value && !std::is_pointer<ReturnType>::value) &&
771  !Kokkos::is_reducer_type<ReturnType>::value
772  >::type, ReturnType, FunctorType> {
773  typedef Kokkos::View< ReturnType
775  , Kokkos::MemoryUnmanaged
776  > return_type;
777 
778  typedef InvalidType reducer_type;
779 
780  typedef typename return_type::value_type value_type;
781 
782  static return_type return_value(ReturnType& return_val, const FunctorType&) {
783  return return_type(&return_val);
784  }
785 };
786 
787 template< class ReturnType , class FunctorType>
788 struct ParallelReduceReturnValue<typename std::enable_if<
789  (is_array<ReturnType>::value || std::is_pointer<ReturnType>::value)
790  >::type, ReturnType, FunctorType> {
793  , Kokkos::MemoryUnmanaged
794  > return_type;
795 
796  typedef InvalidType reducer_type;
797 
798  typedef typename return_type::value_type value_type[];
799 
800  static return_type return_value(ReturnType& return_val,
801  const FunctorType& functor) {
802  return return_type(return_val,functor.value_count);
803  }
804 };
805 
806 template< class ReturnType , class FunctorType>
807 struct ParallelReduceReturnValue<typename std::enable_if<
808  Kokkos::is_reducer_type<ReturnType>::value
809  >::type, ReturnType, FunctorType> {
810  typedef ReturnType return_type;
811  typedef ReturnType reducer_type;
812  typedef typename return_type::value_type value_type;
813 
814  static return_type return_value(ReturnType& return_val,
815  const FunctorType& functor) {
816  return return_val;
817  }
818 };
819 }
820 
821 namespace Impl {
822 template< class T, class ReturnType , class FunctorType>
823 struct ParallelReducePolicyType;
824 
825 template< class PolicyType , class FunctorType >
826 struct ParallelReducePolicyType<typename std::enable_if<Kokkos::Impl::is_execution_policy<PolicyType>::value>::type, PolicyType,FunctorType> {
827 
828  typedef PolicyType policy_type;
829  static PolicyType policy(const PolicyType& policy_) {
830  return policy_;
831  }
832 };
833 
834 template< class PolicyType , class FunctorType >
835 struct ParallelReducePolicyType<typename std::enable_if<std::is_integral<PolicyType>::value>::type, PolicyType,FunctorType> {
836  typedef typename
837  Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
838  execution_space ;
839 
840  typedef Kokkos::RangePolicy<execution_space> policy_type;
841 
842  static policy_type policy(const PolicyType& policy_) {
843  return policy_type(0,policy_);
844  }
845 };
846 
847 }
848 
849 namespace Impl {
850  template< class FunctorType, class ExecPolicy, class ValueType, class ExecutionSpace>
851  struct ParallelReduceFunctorType {
852  typedef FunctorType functor_type;
853  static const functor_type& functor(const functor_type& functor) {
854  return functor;
855  }
856  };
857 }
858 
859 namespace Impl {
860 
861  template< class PolicyType, class FunctorType, class ReturnType >
862  struct ParallelReduceAdaptor {
863  typedef Impl::ParallelReduceReturnValue<void,ReturnType,FunctorType> return_value_adapter;
864  #ifdef KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER
865  typedef Impl::ParallelReduceFunctorType<FunctorType,PolicyType,
866  typename return_value_adapter::value_type,
867  typename PolicyType::execution_space> functor_adaptor;
868  #endif
869  static inline
870  void execute(const std::string& label,
871  const PolicyType& policy,
872  const FunctorType& functor,
873  ReturnType& return_value) {
874  #if defined(KOKKOS_ENABLE_PROFILING)
875  uint64_t kpID = 0;
876  if(Kokkos::Profiling::profileLibraryLoaded()) {
877  Kokkos::Profiling::beginParallelReduce("" == label ? typeid(FunctorType).name() : label, 0, &kpID);
878  }
879  #endif
880 
881  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
882  #ifdef KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER
883  Impl::ParallelReduce<typename functor_adaptor::functor_type, PolicyType, typename return_value_adapter::reducer_type >
884  closure(functor_adaptor::functor(functor),
885  policy,
886  return_value_adapter::return_value(return_value,functor));
887  #else
888  Impl::ParallelReduce<FunctorType, PolicyType, typename return_value_adapter::reducer_type >
889  closure(functor,
890  policy,
891  return_value_adapter::return_value(return_value,functor));
892  #endif
893  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
894  closure.execute();
895 
896  #if defined(KOKKOS_ENABLE_PROFILING)
897  if(Kokkos::Profiling::profileLibraryLoaded()) {
898  Kokkos::Profiling::endParallelReduce(kpID);
899  }
900  #endif
901  }
902 
903  };
904 }
905 
906 //----------------------------------------------------------------------------
907 
908 #if 0
909 
910 //----------------------------------------------------------------------------
911 
912 namespace Impl {
913 
914 template< class OutType , class InType >
915 inline
916 typename std::enable_if
917  < std::is_same< OutType , InType >::value , InType const & >::type
918 forward_execution_policy( InType const & p ) { return p ; }
919 
920 template< class OutType , class InType >
921 inline
922 typename std::enable_if
923  < ! std::is_same< OutType , InType >::value , OutType >::type
924 forward_execution_policy( InType const & p ) { return OutType(p); }
925 
926 
927 template< class OutType , class InType >
928 inline
929 typename std::enable_if
930  < std::is_same< OutType , InType >::value , InType const & >::type
931 forward_reducer( InType const & r ) { return r ; }
932 
933 template< class OutType , class InType >
934 inline
935 typename std::enable_if< Kokkos::is_view< InType >::value , OutType >::type
936 forward_reducer( InType const & v )
937 { return OutType( v.data() ); }
938 
939 template< class OutType >
940 inline
941 OutType
942 forward_reducer( typename OutType::reference ref )
943 { return OutType( ref ); }
944 
945 } /* namespace Impl */
946 
947 //----------------------------------------------------------------------------
948 // parallel_reduce with 4 args: label, policy, closure, and reducer
949 
951 template< class PolicyType , class ClosureType , class ReduceType >
952 inline
953 typename std::enable_if< Kokkos::is_reducer< ReduceType >::value >::type
954 parallel_reduce( std::string const & arg_label
955  , PolicyType && arg_policy
956  , ClosureType && arg_closure
957  , ReduceType && arg_reduce
958  )
959 {
960  //------------------------------
961 
962  using input_policy_type =
963  typename std::remove_const<
964  typename std::remove_reference< PolicyType >::type >::type ;
965 
966  using input_reduce_type =
967  typename std::remove_const<
968  typename std::remove_reference< ReduceType >::type >::type ;
969 
970  using Analysis = Kokkos::Impl::FunctorAnalysis
971  < Kokkos::Impl::FunctorPatternInterface::REDUCE
972  , input_policy_type
973  , ClosureType
974  > ;
975 
976  //------------------------------
977  // Policy is either given or an integer value
978  // If an integer value then is a RangePolicy with queried execution space
979 
980  enum { is_policy = Kokkos::is_execution_policy< input_policy_type >::value };
981  enum { is_intval = std::is_integral< input_policy_type >::value };
982 
983  static_assert( is_policy || is_intval ,
984  "Kokkos::parallel_reduce 2nd argument must be execution policy or integral value" );
985 
986  using policy_type = typename std::conditional
987  < is_policy , input_policy_type
989  >::type ;
990 
991  //------------------------------
992  // ReduceType is either a reducer, view, or value reference
993 
994  enum { is_reducer = Kokkos::is_reducer< input_reduce_type >::value };
995  enum { is_view = Kokkos::is_view< input_reduce_type >::value };
996  enum { is_ref = std::is_same< ReduceType
997  , typename Analysis::reference_type
998  >::value };
999 
1000  static_assert( is_reducer || is_view || is_ref ,
1001  "Kokkos::parallel_reduce 4th argument must be reducer, output View, or output variable" );
1002 
1003  // If input_reducer_type is_view or is_ref then need its memory_space.
1004  // A View has a memory_space, a reference is in the HostSpace.
1005 
1006  using has_space = typename std::conditional
1007  < is_view , input_reduce_type , Kokkos::HostSpace >::type ;
1008 
1009  using memory_space = typename has_space::memory_space ;
1010 
1011  using reduce_type = typename std::conditional
1012  < is_reducer , input_reduce_type
1013  , typename Analysis::Reducer< memory_space >
1014  >::type ;
1015 
1016  //------------------------------
1017 
1018  #if (KOKKOS_ENABLE_PROFILING)
1019  uint64_t kpID = 0;
1020  if(Kokkos::Profiling::profileLibraryLoaded()) {
1021  Kokkos::Profiling::beginParallelReduce(arg_label, 0, &kpID);
1022  }
1023  #endif
1024 
1025  //------------------------------
1026  // Disable tracking while creating the closure:
1027 
1028  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
1029 
1030  Kokkos::Impl::ParallelReduce< ClosureType , policy_type, reduce_type
1031  , typename Analysis::execution_space >
1032  closure( arg_closure
1033  , forward_execution_policy< policy_type >( arg_policy )
1034  , forward_reducer< reduce_type >( arg_reduce ) );
1035 
1036  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
1037 
1038  // Enable tracking after creating the closure
1039 
1040  closure.execute();
1041 
1042  //------------------------------
1043 
1044  #if (KOKKOS_ENABLE_PROFILING)
1045  if(Kokkos::Profiling::profileLibraryLoaded()) {
1046  Kokkos::Profiling::endParallelReduce(kpID);
1047  }
1048  #endif
1049 }
1050 
1051 //----------------------------------------------------------------------------
1052 // parallel_reduce with 3 args: policy, closure, and reducer
1053 
1054 template< class PolicyType , class ClosureType , class ReduceType >
1055 inline
1056 typename std::enable_if
1057  < Kokkos::is_execution_policy<
1058  typename std::remove_const<
1059  typename std::remove_reference< PolicyType >::type >::type
1060  >::value
1061  ||
1062  std::is_integral<
1063  typename std::remove_const<
1064  typename std::remove_reference< PolicyType >::type >::type
1065  >::value
1066  >::type ;
1067 parallel_reduce( PolicyType && arg_policy
1068  , ClosureType && arg_closure
1069  , ReduceType && arg_reduce
1070  )
1071 {
1072  parallel_reduce( typeid(ClosureType).name()
1073  , std::forward< PolicyType >( arg_policy )
1074  , std::forward< ClosureType >( arg_closure )
1075  , std::forward< ReduceType >( arg_reduce ) );
1076 }
1077 
1078 // parallel_reduce with 3 args: label, policy, and closure
1079 
1080 template< class PolicyType , class ClosureType >
1081 inline
1082 void
1083 parallel_reduce( std::string const & arg_label
1084  , PolicyType && arg_policy
1085  , ClosureType && arg_closure
1086  )
1087 {
1088  // Deduce a Reducer from the Closure
1089 
1090  using input_policy_type =
1091  typename std::remove_const<
1092  typename std::remove_reference< PolicyType >::type >::type ;
1093 
1094  using Analysis = Kokkos::Impl::FunctorAnalysis
1095  < Kokkos::Impl::FunctorPatternInterface::REDUCE
1096  , input_policy_type
1097  , ClosureType
1098  > ;
1099 
1100  static_assert( Analysis::has_final_member_function ,
1101  "Kokkos::parallel_reduce functor does not have a final member function" );
1102 
1103  parallel_reduce( arg_label
1104  , std::forward< PolicyType >( arg_policy )
1105  , std::forward< ClosureType >( arg_closure )
1106  , typename Analysis::Reducer<>() );
1107 }
1108 
1109 //----------------------------------------------------------------------------
1110 // parallel_reduce with 2 arguments: policy and closure:
1111 
1113 template< class PolicyType , class ClosureType >
1114 inline
1115 parallel_reduce( PolicyType && arg_policy
1116  , ClosureType && arg_closure )
1117 {
1118  // Deduce a Reducer from the Closure
1119 
1120  using input_policy_type =
1121  typename std::remove_const<
1122  typename std::remove_reference< PolicyType >::type >::type ;
1123 
1124  using Analysis = Kokkos::Impl::FunctorAnalysis
1125  < Kokkos::Impl::FunctorPatternInterface::REDUCE
1126  , input_policy_type
1127  , ClosureType
1128  > ;
1129 
1130  static_assert( Analysis::has_final_member_function ,
1131  "Kokkos::parallel_reduce functor does not have a final member function" );
1132 
1133  parallel_reduce( typeid(ClosureType).name()
1134  , std::forward< PolicyType >( arg_policy )
1135  , std::forward< ClosureType >( arg_closure )
1136  , typename Analysis::Reducer<>() );
1137 }
1138 
1139 #endif
1140 
1141 //----------------------------------------------------------------------------
1142 
1190 // ReturnValue is scalar or array: take by reference
1191 
1192 template< class PolicyType, class FunctorType, class ReturnType >
1193 inline
1194 void parallel_reduce(const std::string& label,
1195  const PolicyType& policy,
1196  const FunctorType& functor,
1197  ReturnType& return_value,
1198  typename Impl::enable_if<
1199  Kokkos::Impl::is_execution_policy<PolicyType>::value
1200  >::type * = 0) {
1201  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute(label,policy,functor,return_value);
1202 }
1203 
1204 template< class PolicyType, class FunctorType, class ReturnType >
1205 inline
1206 void parallel_reduce(const PolicyType& policy,
1207  const FunctorType& functor,
1208  ReturnType& return_value,
1209  typename Impl::enable_if<
1210  Kokkos::Impl::is_execution_policy<PolicyType>::value
1211  >::type * = 0) {
1212  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute("",policy,functor,return_value);
1213 }
1214 
1215 template< class FunctorType, class ReturnType >
1216 inline
1217 void parallel_reduce(const size_t& policy,
1218  const FunctorType& functor,
1219  ReturnType& return_value) {
1220  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1221  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute("",policy_type(0,policy),functor,return_value);
1222 }
1223 
1224 template< class FunctorType, class ReturnType >
1225 inline
1226 void parallel_reduce(const std::string& label,
1227  const size_t& policy,
1228  const FunctorType& functor,
1229  ReturnType& return_value) {
1230  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1231  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute(label,policy_type(0,policy),functor,return_value);
1232 }
1233 
1234 // ReturnValue as View or Reducer: take by copy to allow for inline construction
1235 
1236 template< class PolicyType, class FunctorType, class ReturnType >
1237 inline
1238 void parallel_reduce(const std::string& label,
1239  const PolicyType& policy,
1240  const FunctorType& functor,
1241  const ReturnType& return_value,
1242  typename Impl::enable_if<
1243  Kokkos::Impl::is_execution_policy<PolicyType>::value
1244  >::type * = 0) {
1245  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,const ReturnType>::execute(label,policy,functor,return_value);
1246 }
1247 
1248 template< class PolicyType, class FunctorType, class ReturnType >
1249 inline
1250 void parallel_reduce(const PolicyType& policy,
1251  const FunctorType& functor,
1252  const ReturnType& return_value,
1253  typename Impl::enable_if<
1254  Kokkos::Impl::is_execution_policy<PolicyType>::value
1255  >::type * = 0) {
1256  ReturnType return_value_impl = return_value;
1257  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute("",policy,functor,return_value_impl);
1258 }
1259 
1260 template< class FunctorType, class ReturnType >
1261 inline
1262 void parallel_reduce(const size_t& policy,
1263  const FunctorType& functor,
1264  const ReturnType& return_value) {
1265  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1266  ReturnType return_value_impl = return_value;
1267  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute("",policy_type(0,policy),functor,return_value_impl);
1268 }
1269 
1270 template< class FunctorType, class ReturnType >
1271 inline
1272 void parallel_reduce(const std::string& label,
1273  const size_t& policy,
1274  const FunctorType& functor,
1275  const ReturnType& return_value) {
1276  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1277  ReturnType return_value_impl = return_value;
1278  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute(label,policy_type(0,policy),functor,return_value_impl);
1279 }
1280 
1281 // No Return Argument
1282 
1283 template< class PolicyType, class FunctorType>
1284 inline
1285 void parallel_reduce(const std::string& label,
1286  const PolicyType& policy,
1287  const FunctorType& functor,
1288  typename Impl::enable_if<
1289  Kokkos::Impl::is_execution_policy<PolicyType>::value
1290  >::type * = 0) {
1291  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1292  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1293  , typename ValueTraits::value_type
1294  , typename ValueTraits::pointer_type
1295  >::type value_type ;
1296 
1297  typedef Kokkos::View< value_type
1299  , Kokkos::MemoryUnmanaged
1300  > result_view_type;
1301  result_view_type result_view ;
1302 
1303  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,result_view_type>::execute(label,policy,functor,result_view);
1304 }
1305 
1306 template< class PolicyType, class FunctorType >
1307 inline
1308 void parallel_reduce(const PolicyType& policy,
1309  const FunctorType& functor,
1310  typename Impl::enable_if<
1311  Kokkos::Impl::is_execution_policy<PolicyType>::value
1312  >::type * = 0) {
1313  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1314  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1315  , typename ValueTraits::value_type
1316  , typename ValueTraits::pointer_type
1317  >::type value_type ;
1318 
1319  typedef Kokkos::View< value_type
1321  , Kokkos::MemoryUnmanaged
1322  > result_view_type;
1323  result_view_type result_view ;
1324 
1325  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,result_view_type>::execute("",policy,functor,result_view);
1326 }
1327 
1328 template< class FunctorType >
1329 inline
1330 void parallel_reduce(const size_t& policy,
1331  const FunctorType& functor) {
1332  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1333  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1334  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1335  , typename ValueTraits::value_type
1336  , typename ValueTraits::pointer_type
1337  >::type value_type ;
1338 
1339  typedef Kokkos::View< value_type
1341  , Kokkos::MemoryUnmanaged
1342  > result_view_type;
1343  result_view_type result_view ;
1344 
1345  Impl::ParallelReduceAdaptor<policy_type,FunctorType,result_view_type>::execute("",policy_type(0,policy),functor,result_view);
1346 }
1347 
1348 template< class FunctorType>
1349 inline
1350 void parallel_reduce(const std::string& label,
1351  const size_t& policy,
1352  const FunctorType& functor) {
1353  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1354  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1355  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1356  , typename ValueTraits::value_type
1357  , typename ValueTraits::pointer_type
1358  >::type value_type ;
1359 
1360  typedef Kokkos::View< value_type
1362  , Kokkos::MemoryUnmanaged
1363  > result_view_type;
1364  result_view_type result_view ;
1365 
1366  Impl::ParallelReduceAdaptor<policy_type,FunctorType,result_view_type>::execute(label,policy_type(0,policy),functor,result_view);
1367 }
1368 
1369 } //namespace Kokkos
1370 
1371 #endif // KOKKOS_PARALLEL_REDUCE_HPP
1372 
void parallel_reduce(const std::string &label, const PolicyType &policy, const FunctorType &functor, ReturnType &return_value, typename Impl::enable_if< Kokkos::Impl::is_execution_policy< PolicyType >::value >::type *=0)
Parallel reduction.
View to an array of data.
Memory management for host memory.
ReturnType
Execution policy for work over a range of an integral type.
Implementation detail of parallel_reduce.