Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 Christian R. Trott (crtrott@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 template<class Scalar, class Space>
66 struct Sum {
67 public:
68  //Required
69  typedef Sum reducer;
70  typedef typename std::remove_cv<Scalar>::type value_type;
71 
73 
74 private:
75  value_type* value;
76 
77 public:
78 
79  KOKKOS_INLINE_FUNCTION
80  Sum(value_type& value_): value(&value_) {}
81 
82  KOKKOS_INLINE_FUNCTION
83  Sum(const result_view_type& value_): value(value_.data()) {}
84 
85  //Required
86  KOKKOS_INLINE_FUNCTION
87  void join(value_type& dest, const value_type& src) const {
88  dest += src;
89  }
90 
91  KOKKOS_INLINE_FUNCTION
92  void join(volatile value_type& dest, const volatile value_type& src) const {
93  dest += src;
94  }
95 
96  KOKKOS_INLINE_FUNCTION
97  void init( value_type& val) const {
98  val = reduction_identity<value_type>::sum();
99  }
100 
101  KOKKOS_INLINE_FUNCTION
102  value_type& reference() const {
103  return *value;
104  }
105 
106  KOKKOS_INLINE_FUNCTION
107  result_view_type view() const {
108  return result_view_type(value);
109  }
110 };
111 
112 template<class Scalar, class Space>
113 struct Prod {
114 public:
115  //Required
116  typedef Prod reducer;
117  typedef typename std::remove_cv<Scalar>::type value_type;
118 
120 
121 private:
122  value_type* value;
123 
124 public:
125 
126  KOKKOS_INLINE_FUNCTION
127  Prod(value_type& value_): value(&value_) {}
128 
129  KOKKOS_INLINE_FUNCTION
130  Prod(const result_view_type& value_): value(value_.data()) {}
131 
132  //Required
133  KOKKOS_INLINE_FUNCTION
134  void join(value_type& dest, const value_type& src) const {
135  dest *= src;
136  }
137 
138  KOKKOS_INLINE_FUNCTION
139  void join(volatile value_type& dest, const volatile value_type& src) const {
140  dest *= src;
141  }
142 
143  KOKKOS_INLINE_FUNCTION
144  void init( value_type& val) const {
145  val = reduction_identity<value_type>::prod();
146  }
147 
148  KOKKOS_INLINE_FUNCTION
149  value_type& reference() const {
150  return *value;
151  }
152 
153  KOKKOS_INLINE_FUNCTION
154  result_view_type view() const {
155  return result_view_type(value);
156  }
157 };
158 
159 template<class Scalar, class Space>
160 struct Min {
161 public:
162  //Required
163  typedef Min reducer;
164  typedef typename std::remove_cv<Scalar>::type value_type;
165 
167 
168 private:
169  value_type* value;
170 
171 public:
172 
173  KOKKOS_INLINE_FUNCTION
174  Min(value_type& value_): value(&value_) {}
175 
176  KOKKOS_INLINE_FUNCTION
177  Min(const result_view_type& value_): value(value_.data()) {}
178 
179  //Required
180  KOKKOS_INLINE_FUNCTION
181  void join(value_type& dest, const value_type& src) const {
182  if ( src < dest )
183  dest = src;
184  }
185 
186  KOKKOS_INLINE_FUNCTION
187  void join(volatile value_type& dest, const volatile value_type& src) const {
188  if ( src < dest )
189  dest = src;
190  }
191 
192  KOKKOS_INLINE_FUNCTION
193  void init( value_type& val) const {
194  val = reduction_identity<value_type>::min();
195  }
196 
197  KOKKOS_INLINE_FUNCTION
198  value_type& reference() const {
199  return *value;
200  }
201 
202  KOKKOS_INLINE_FUNCTION
203  result_view_type view() const {
204  return result_view_type(value);
205  }
206 };
207 
208 template<class Scalar, class Space>
209 struct Max {
210 public:
211  //Required
212  typedef Max reducer;
213  typedef typename std::remove_cv<Scalar>::type value_type;
214 
216 
217 private:
218  value_type* value;
219 
220 public:
221 
222  KOKKOS_INLINE_FUNCTION
223  Max(value_type& value_): value(&value_) {}
224 
225  KOKKOS_INLINE_FUNCTION
226  Max(const result_view_type& value_): value(value_.data()) {}
227 
228  //Required
229  KOKKOS_INLINE_FUNCTION
230  void join(value_type& dest, const value_type& src) const {
231  if ( src > dest )
232  dest = src;
233  }
234 
235  KOKKOS_INLINE_FUNCTION
236  void join(volatile value_type& dest, const volatile value_type& src) const {
237  if ( src > dest )
238  dest = src;
239  }
240 
241  //Required
242  KOKKOS_INLINE_FUNCTION
243  void init( value_type& val) const {
244  val = reduction_identity<value_type>::max();
245  }
246 
247  KOKKOS_INLINE_FUNCTION
248  value_type& reference() const {
249  return *value;
250  }
251 
252  KOKKOS_INLINE_FUNCTION
253  result_view_type view() const {
254  return result_view_type(value);
255  }
256 };
257 
258 template<class Scalar, class Space>
259 struct LAnd {
260 public:
261  //Required
262  typedef LAnd reducer;
263  typedef typename std::remove_cv<Scalar>::type value_type;
264 
266 
267 private:
268  value_type* value;
269 
270 public:
271 
272  KOKKOS_INLINE_FUNCTION
273  LAnd(value_type& value_): value(&value_) {}
274 
275  KOKKOS_INLINE_FUNCTION
276  LAnd(const result_view_type& value_): value(value_.data()) {}
277 
278  KOKKOS_INLINE_FUNCTION
279  void join(value_type& dest, const value_type& src) const {
280  dest = dest && src;
281  }
282 
283  KOKKOS_INLINE_FUNCTION
284  void join(volatile value_type& dest, const volatile value_type& src) const {
285  dest = dest && src;
286  }
287 
288  KOKKOS_INLINE_FUNCTION
289  void init( value_type& val) const {
290  val = reduction_identity<value_type>::land();
291  }
292 
293  KOKKOS_INLINE_FUNCTION
294  value_type& reference() const {
295  return *value;
296  }
297 
298  KOKKOS_INLINE_FUNCTION
299  result_view_type view() const {
300  return result_view_type(value);
301  }
302 };
303 
304 template<class Scalar, class Space>
305 struct LOr {
306 public:
307  //Required
308  typedef LOr reducer;
309  typedef typename std::remove_cv<Scalar>::type value_type;
310 
312 
313 private:
314  value_type* value;
315 
316 public:
317 
318  KOKKOS_INLINE_FUNCTION
319  LOr(value_type& value_): value(&value_) {}
320 
321  KOKKOS_INLINE_FUNCTION
322  LOr(const result_view_type& value_): value(value_.data()) {}
323 
324  //Required
325  KOKKOS_INLINE_FUNCTION
326  void join(value_type& dest, const value_type& src) const {
327  dest = dest || src;
328  }
329 
330  KOKKOS_INLINE_FUNCTION
331  void join(volatile value_type& dest, const volatile value_type& src) const {
332  dest = dest || src;
333  }
334 
335  KOKKOS_INLINE_FUNCTION
336  void init( value_type& val) const {
337  val = reduction_identity<value_type>::lor();
338  }
339 
340  KOKKOS_INLINE_FUNCTION
341  value_type& reference() const {
342  return *value;
343  }
344 
345  KOKKOS_INLINE_FUNCTION
346  result_view_type view() const {
347  return result_view_type(value);
348  }
349 };
350 
351 template<class Scalar, class Space>
352 struct BAnd {
353 public:
354  //Required
355  typedef BAnd reducer;
356  typedef typename std::remove_cv<Scalar>::type value_type;
357 
359 
360 private:
361  value_type* value;
362 
363 public:
364 
365  KOKKOS_INLINE_FUNCTION
366  BAnd(value_type& value_): value(&value_) {}
367 
368  KOKKOS_INLINE_FUNCTION
369  BAnd(const result_view_type& value_): value(value_.data()) {}
370 
371  //Required
372  KOKKOS_INLINE_FUNCTION
373  void join(value_type& dest, const value_type& src) const {
374  dest = dest & src;
375  }
376 
377  KOKKOS_INLINE_FUNCTION
378  void join(volatile value_type& dest, const volatile value_type& src) const {
379  dest = dest & src;
380  }
381 
382  KOKKOS_INLINE_FUNCTION
383  void init( value_type& val) const {
384  val = reduction_identity<value_type>::band();
385  }
386 
387  KOKKOS_INLINE_FUNCTION
388  value_type& reference() const {
389  return *value;
390  }
391 
392  KOKKOS_INLINE_FUNCTION
393  result_view_type view() const {
394  return result_view_type(value);
395  }
396 };
397 
398 template<class Scalar, class Space>
399 struct BOr {
400 public:
401  //Required
402  typedef BOr reducer;
403  typedef typename std::remove_cv<Scalar>::type value_type;
404 
406 
407 private:
408  value_type* value;
409 
410 public:
411 
412  KOKKOS_INLINE_FUNCTION
413  BOr(value_type& value_): value(&value_) {}
414 
415  KOKKOS_INLINE_FUNCTION
416  BOr(const result_view_type& value_): value(value_.data()) {}
417 
418  //Required
419  KOKKOS_INLINE_FUNCTION
420  void join(value_type& dest, const value_type& src) const {
421  dest = dest | src;
422  }
423 
424  KOKKOS_INLINE_FUNCTION
425  void join(volatile value_type& dest, const volatile value_type& src) const {
426  dest = dest | src;
427  }
428 
429  KOKKOS_INLINE_FUNCTION
430  void init( value_type& val) const {
431  val = reduction_identity<value_type>::bor();
432  }
433 
434  KOKKOS_INLINE_FUNCTION
435  value_type& reference() const {
436  return *value;
437  }
438 
439  KOKKOS_INLINE_FUNCTION
440  result_view_type view() const {
441  return result_view_type(value);
442  }
443 };
444 
445 template<class Scalar, class Index>
446 struct ValLocScalar {
447  Scalar val;
448  Index loc;
449 
450  KOKKOS_INLINE_FUNCTION
451  void operator = (const ValLocScalar& rhs) {
452  val = rhs.val;
453  loc = rhs.loc;
454  }
455 
456  KOKKOS_INLINE_FUNCTION
457  void operator = (const volatile ValLocScalar& rhs) volatile {
458  val = rhs.val;
459  loc = rhs.loc;
460  }
461 };
462 
463 template<class Scalar, class Index, class Space>
464 struct MinLoc {
465 private:
466  typedef typename std::remove_cv<Scalar>::type scalar_type;
467  typedef typename std::remove_cv<Index>::type index_type;
468 
469 public:
470  //Required
471  typedef MinLoc reducer;
472  typedef ValLocScalar<scalar_type,index_type> value_type;
473 
475 
476 private:
477  value_type* value;
478 
479 public:
480 
481  KOKKOS_INLINE_FUNCTION
482  MinLoc(value_type& value_): value(&value_) {}
483 
484  KOKKOS_INLINE_FUNCTION
485  MinLoc(const result_view_type& value_): value(value_.data()) {}
486 
487 
488  //Required
489  KOKKOS_INLINE_FUNCTION
490  void join(value_type& dest, const value_type& src) const {
491  if ( src.val < dest.val )
492  dest = src;
493  }
494 
495  KOKKOS_INLINE_FUNCTION
496  void join(volatile value_type& dest, const volatile value_type& src) const {
497  if ( src.val < dest.val )
498  dest = src;
499  }
500 
501  KOKKOS_INLINE_FUNCTION
502  void init( value_type& val) const {
503  val.val = reduction_identity<scalar_type>::min();
504  val.loc = reduction_identity<index_type>::min();
505  }
506 
507  KOKKOS_INLINE_FUNCTION
508  value_type& reference() const {
509  return *value;
510  }
511 
512  KOKKOS_INLINE_FUNCTION
513  result_view_type view() const {
514  return result_view_type(value);
515  }
516 };
517 
518 template<class Scalar, class Index, class Space>
519 struct MaxLoc {
520 private:
521  typedef typename std::remove_cv<Scalar>::type scalar_type;
522  typedef typename std::remove_cv<Index>::type index_type;
523 
524 public:
525  //Required
526  typedef MaxLoc reducer;
527  typedef ValLocScalar<scalar_type,index_type> value_type;
528 
530 
531 private:
532  value_type* value;
533 
534 public:
535 
536  KOKKOS_INLINE_FUNCTION
537  MaxLoc(value_type& value_): value(&value_) {}
538 
539  KOKKOS_INLINE_FUNCTION
540  MaxLoc(const result_view_type& value_): value(value_.data()) {}
541 
542  //Required
543  KOKKOS_INLINE_FUNCTION
544  void join(value_type& dest, const value_type& src) const {
545  if ( src.val > dest.val )
546  dest = src;
547  }
548 
549  KOKKOS_INLINE_FUNCTION
550  void join(volatile value_type& dest, const volatile value_type& src) const {
551  if ( src.val > dest.val )
552  dest = src;
553  }
554 
555  KOKKOS_INLINE_FUNCTION
556  void init( value_type& val) const {
557  val.val = reduction_identity<scalar_type>::max();;
558  val.loc = reduction_identity<index_type>::min();
559  }
560 
561  KOKKOS_INLINE_FUNCTION
562  value_type& reference() const {
563  return *value;
564  }
565 
566  KOKKOS_INLINE_FUNCTION
567  result_view_type view() const {
568  return result_view_type(value);
569  }
570 };
571 
572 template<class Scalar>
573 struct MinMaxScalar {
574  Scalar min_val,max_val;
575 
576  KOKKOS_INLINE_FUNCTION
577  void operator = (const MinMaxScalar& rhs) {
578  min_val = rhs.min_val;
579  max_val = rhs.max_val;
580  }
581 
582  KOKKOS_INLINE_FUNCTION
583  void operator = (const volatile MinMaxScalar& rhs) volatile {
584  min_val = rhs.min_val;
585  max_val = rhs.max_val;
586  }
587 };
588 
589 template<class Scalar, class Space>
590 struct MinMax {
591 private:
592  typedef typename std::remove_cv<Scalar>::type scalar_type;
593 
594 public:
595  //Required
596  typedef MinMax reducer;
597  typedef MinMaxScalar<scalar_type> value_type;
598 
600 
601 private:
602  value_type* value;
603 
604 public:
605 
606  KOKKOS_INLINE_FUNCTION
607  MinMax(value_type& value_): value(&value_) {}
608 
609  KOKKOS_INLINE_FUNCTION
610  MinMax(const result_view_type& value_): value(value_.data()) {}
611 
612  //Required
613  KOKKOS_INLINE_FUNCTION
614  void join(value_type& dest, const value_type& src) const {
615  if ( src.min_val < dest.min_val ) {
616  dest.min_val = src.min_val;
617  }
618  if ( src.max_val > dest.max_val ) {
619  dest.max_val = src.max_val;
620  }
621  }
622 
623  KOKKOS_INLINE_FUNCTION
624  void join(volatile value_type& dest, const volatile value_type& src) const {
625  if ( src.min_val < dest.min_val ) {
626  dest.min_val = src.min_val;
627  }
628  if ( src.max_val > dest.max_val ) {
629  dest.max_val = src.max_val;
630  }
631  }
632 
633  KOKKOS_INLINE_FUNCTION
634  void init( value_type& val) const {
635  val.max_val = reduction_identity<scalar_type>::max();;
636  val.min_val = reduction_identity<scalar_type>::min();
637  }
638 
639  KOKKOS_INLINE_FUNCTION
640  value_type& reference() const {
641  return *value;
642  }
643 
644  KOKKOS_INLINE_FUNCTION
645  result_view_type view() const {
646  return result_view_type(value);
647  }
648 };
649 
650 template<class Scalar, class Index>
651 struct MinMaxLocScalar {
652  Scalar min_val,max_val;
653  Index min_loc,max_loc;
654 
655  KOKKOS_INLINE_FUNCTION
656  void operator = (const MinMaxLocScalar& rhs) {
657  min_val = rhs.min_val;
658  min_loc = rhs.min_loc;
659  max_val = rhs.max_val;
660  max_loc = rhs.max_loc;
661  }
662 
663  KOKKOS_INLINE_FUNCTION
664  void operator = (const volatile MinMaxLocScalar& rhs) volatile {
665  min_val = rhs.min_val;
666  min_loc = rhs.min_loc;
667  max_val = rhs.max_val;
668  max_loc = rhs.max_loc;
669  }
670 };
671 
672 template<class Scalar, class Index, class Space>
673 struct MinMaxLoc {
674 private:
675  typedef typename std::remove_cv<Scalar>::type scalar_type;
676  typedef typename std::remove_cv<Index>::type index_type;
677 
678 public:
679  //Required
680  typedef MinMaxLoc reducer;
681  typedef MinMaxLocScalar<scalar_type,index_type> value_type;
682 
684 
685 private:
686  value_type* value;
687 
688 public:
689 
690  KOKKOS_INLINE_FUNCTION
691  MinMaxLoc(value_type& value_): value(&value_) {}
692 
693  KOKKOS_INLINE_FUNCTION
694  MinMaxLoc(const result_view_type& value_): value(value_.data()) {}
695 
696  //Required
697  KOKKOS_INLINE_FUNCTION
698  void join(value_type& dest, const value_type& src) const {
699  if ( src.min_val < dest.min_val ) {
700  dest.min_val = src.min_val;
701  dest.min_loc = src.min_loc;
702  }
703  if ( src.max_val > dest.max_val ) {
704  dest.max_val = src.max_val;
705  dest.max_loc = src.max_loc;
706  }
707  }
708 
709  KOKKOS_INLINE_FUNCTION
710  void join(volatile value_type& dest, const volatile value_type& src) const {
711  if ( src.min_val < dest.min_val ) {
712  dest.min_val = src.min_val;
713  dest.min_loc = src.min_loc;
714  }
715  if ( src.max_val > dest.max_val ) {
716  dest.max_val = src.max_val;
717  dest.max_loc = src.max_loc;
718  }
719  }
720 
721  KOKKOS_INLINE_FUNCTION
722  void init( value_type& val) const {
723  val.max_val = reduction_identity<scalar_type>::max();;
724  val.min_val = reduction_identity<scalar_type>::min();
725  val.max_loc = reduction_identity<index_type>::min();
726  val.min_loc = reduction_identity<index_type>::min();
727  }
728 
729  KOKKOS_INLINE_FUNCTION
730  value_type& reference() const {
731  return *value;
732  }
733 
734  KOKKOS_INLINE_FUNCTION
735  result_view_type view() const {
736  return result_view_type(value);
737  }
738 };
739 }
740 namespace Kokkos{
741 namespace Impl {
742 
743 template< class T, class ReturnType , class ValueTraits>
744 struct ParallelReduceReturnValue;
745 
746 template< class ReturnType , class FunctorType >
747 struct ParallelReduceReturnValue<typename std::enable_if<Kokkos::is_view<ReturnType>::value>::type, ReturnType, FunctorType> {
748  typedef ReturnType return_type;
749  typedef InvalidType reducer_type;
750 
751  typedef typename return_type::value_type value_type_scalar;
752  typedef typename return_type::value_type* const value_type_array;
753 
754  typedef typename if_c<return_type::rank==0,value_type_scalar,value_type_array>::type value_type;
755 
756  static return_type& return_value(ReturnType& return_val, const FunctorType&) {
757  return return_val;
758  }
759 };
760 
761 template< class ReturnType , class FunctorType>
762 struct ParallelReduceReturnValue<typename std::enable_if<
763  !Kokkos::is_view<ReturnType>::value &&
764  (!std::is_array<ReturnType>::value && !std::is_pointer<ReturnType>::value) &&
765  !Kokkos::is_reducer_type<ReturnType>::value
766  >::type, ReturnType, FunctorType> {
767  typedef Kokkos::View< ReturnType
769  , Kokkos::MemoryUnmanaged
770  > return_type;
771 
772  typedef InvalidType reducer_type;
773 
774  typedef typename return_type::value_type value_type;
775 
776  static return_type return_value(ReturnType& return_val, const FunctorType&) {
777  return return_type(&return_val);
778  }
779 };
780 
781 template< class ReturnType , class FunctorType>
782 struct ParallelReduceReturnValue<typename std::enable_if<
783  (is_array<ReturnType>::value || std::is_pointer<ReturnType>::value)
784  >::type, ReturnType, FunctorType> {
787  , Kokkos::MemoryUnmanaged
788  > return_type;
789 
790  typedef InvalidType reducer_type;
791 
792  typedef typename return_type::value_type value_type[];
793 
794  static return_type return_value(ReturnType& return_val,
795  const FunctorType& functor) {
796 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
797  return return_type(return_val,functor.value_count);
798 #else
799  if ( is_array<ReturnType>::value )
800  return return_type(return_val);
801  else
802  return return_type(return_val,functor.value_count);
803 #endif
804  }
805 };
806 
807 template< class ReturnType , class FunctorType>
808 struct ParallelReduceReturnValue<typename std::enable_if<
809  Kokkos::is_reducer_type<ReturnType>::value
810  >::type, ReturnType, FunctorType> {
811  typedef ReturnType return_type;
812  typedef ReturnType reducer_type;
813  typedef typename return_type::value_type value_type;
814 
815  static return_type return_value(ReturnType& return_val,
816  const FunctorType& functor) {
817  return return_val;
818  }
819 };
820 
821 template< class T, class ReturnType , class FunctorType>
822 struct ParallelReducePolicyType;
823 
824 template< class PolicyType , class FunctorType >
825 struct ParallelReducePolicyType<typename std::enable_if<Kokkos::Impl::is_execution_policy<PolicyType>::value>::type, PolicyType,FunctorType> {
826 
827  typedef PolicyType policy_type;
828  static PolicyType policy(const PolicyType& policy_) {
829  return policy_;
830  }
831 };
832 
833 template< class PolicyType , class FunctorType >
834 struct ParallelReducePolicyType<typename std::enable_if<std::is_integral<PolicyType>::value>::type, PolicyType,FunctorType> {
835  typedef typename
836  Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
837  execution_space ;
838 
839  typedef Kokkos::RangePolicy<execution_space> policy_type;
840 
841  static policy_type policy(const PolicyType& policy_) {
842  return policy_type(0,policy_);
843  }
844 };
845 
846 
847  template< class FunctorType, class ExecPolicy, class ValueType, class ExecutionSpace>
848  struct ParallelReduceFunctorType {
849  typedef FunctorType functor_type;
850  static const functor_type& functor(const functor_type& functor) {
851  return functor;
852  }
853  };
854 
855  template< class PolicyType, class FunctorType, class ReturnType >
856  struct ParallelReduceAdaptor {
857  typedef Impl::ParallelReduceReturnValue<void,ReturnType,FunctorType> return_value_adapter;
858  #ifdef KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER
859  typedef Impl::ParallelReduceFunctorType<FunctorType,PolicyType,
860  typename return_value_adapter::value_type,
861  typename PolicyType::execution_space> functor_adaptor;
862  #endif
863  static inline
864  void execute(const std::string& label,
865  const PolicyType& policy,
866  const FunctorType& functor,
867  ReturnType& return_value) {
868  #if defined(KOKKOS_ENABLE_PROFILING)
869  uint64_t kpID = 0;
870  if(Kokkos::Profiling::profileLibraryLoaded()) {
871  Kokkos::Impl::ParallelConstructName<FunctorType, typename PolicyType::work_tag> name(label);
872  Kokkos::Profiling::beginParallelReduce(name.get(), 0, &kpID);
873  }
874  #endif
875 
876  Kokkos::Impl::shared_allocation_tracking_disable();
877  #ifdef KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER
878  Impl::ParallelReduce<typename functor_adaptor::functor_type, PolicyType, typename return_value_adapter::reducer_type >
879  closure(functor_adaptor::functor(functor),
880  policy,
881  return_value_adapter::return_value(return_value,functor));
882  #else
883  Impl::ParallelReduce<FunctorType, PolicyType, typename return_value_adapter::reducer_type >
884  closure(functor,
885  policy,
886  return_value_adapter::return_value(return_value,functor));
887  #endif
888  Kokkos::Impl::shared_allocation_tracking_enable();
889  closure.execute();
890 
891  #if defined(KOKKOS_ENABLE_PROFILING)
892  if(Kokkos::Profiling::profileLibraryLoaded()) {
893  Kokkos::Profiling::endParallelReduce(kpID);
894  }
895  #endif
896  }
897 
898  };
899 }
900 
901 //----------------------------------------------------------------------------
902 
950 // ReturnValue is scalar or array: take by reference
951 
952 template< class PolicyType, class FunctorType, class ReturnType >
953 inline
954 void parallel_reduce(const std::string& label,
955  const PolicyType& policy,
956  const FunctorType& functor,
957  ReturnType& return_value,
958  typename Impl::enable_if<
959  Kokkos::Impl::is_execution_policy<PolicyType>::value
960  >::type * = 0) {
961  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute(label,policy,functor,return_value);
962 }
963 
964 template< class PolicyType, class FunctorType, class ReturnType >
965 inline
966 void parallel_reduce(const PolicyType& policy,
967  const FunctorType& functor,
968  ReturnType& return_value,
969  typename Impl::enable_if<
970  Kokkos::Impl::is_execution_policy<PolicyType>::value
971  >::type * = 0) {
972  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute("",policy,functor,return_value);
973 }
974 
975 template< class FunctorType, class ReturnType >
976 inline
977 void parallel_reduce(const size_t& policy,
978  const FunctorType& functor,
979  ReturnType& return_value) {
980  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
981  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute("",policy_type(0,policy),functor,return_value);
982 }
983 
984 template< class FunctorType, class ReturnType >
985 inline
986 void parallel_reduce(const std::string& label,
987  const size_t& policy,
988  const FunctorType& functor,
989  ReturnType& return_value) {
990  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
991  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute(label,policy_type(0,policy),functor,return_value);
992 }
993 
994 // ReturnValue as View or Reducer: take by copy to allow for inline construction
995 
996 template< class PolicyType, class FunctorType, class ReturnType >
997 inline
998 void parallel_reduce(const std::string& label,
999  const PolicyType& policy,
1000  const FunctorType& functor,
1001  const ReturnType& return_value,
1002  typename Impl::enable_if<
1003  Kokkos::Impl::is_execution_policy<PolicyType>::value
1004  >::type * = 0) {
1005  ReturnType return_value_impl = return_value;
1006  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute(label,policy,functor,return_value_impl);
1007 }
1008 
1009 template< class PolicyType, class FunctorType, class ReturnType >
1010 inline
1011 void parallel_reduce(const PolicyType& policy,
1012  const FunctorType& functor,
1013  const ReturnType& return_value,
1014  typename Impl::enable_if<
1015  Kokkos::Impl::is_execution_policy<PolicyType>::value
1016  >::type * = 0) {
1017  ReturnType return_value_impl = return_value;
1018  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,ReturnType>::execute("",policy,functor,return_value_impl);
1019 }
1020 
1021 template< class FunctorType, class ReturnType >
1022 inline
1023 void parallel_reduce(const size_t& policy,
1024  const FunctorType& functor,
1025  const ReturnType& return_value) {
1026  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1027  ReturnType return_value_impl = return_value;
1028  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute("",policy_type(0,policy),functor,return_value_impl);
1029 }
1030 
1031 template< class FunctorType, class ReturnType >
1032 inline
1033 void parallel_reduce(const std::string& label,
1034  const size_t& policy,
1035  const FunctorType& functor,
1036  const ReturnType& return_value) {
1037  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1038  ReturnType return_value_impl = return_value;
1039  Impl::ParallelReduceAdaptor<policy_type,FunctorType,ReturnType>::execute(label,policy_type(0,policy),functor,return_value_impl);
1040 }
1041 
1042 // No Return Argument
1043 
1044 template< class PolicyType, class FunctorType>
1045 inline
1046 void parallel_reduce(const std::string& label,
1047  const PolicyType& policy,
1048  const FunctorType& functor,
1049  typename Impl::enable_if<
1050  Kokkos::Impl::is_execution_policy<PolicyType>::value
1051  >::type * = 0) {
1052  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1053  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1054  , typename ValueTraits::value_type
1055  , typename ValueTraits::pointer_type
1056  >::type value_type ;
1057 
1058  static_assert(Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE,PolicyType,FunctorType>::
1059  has_final_member_function,"Calling parallel_reduce without either return value or final function.");
1060 
1061  typedef Kokkos::View< value_type
1063  , Kokkos::MemoryUnmanaged
1064  > result_view_type;
1065  result_view_type result_view ;
1066 
1067  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,result_view_type>::execute(label,policy,functor,result_view);
1068 }
1069 
1070 template< class PolicyType, class FunctorType >
1071 inline
1072 void parallel_reduce(const PolicyType& policy,
1073  const FunctorType& functor,
1074  typename Impl::enable_if<
1075  Kokkos::Impl::is_execution_policy<PolicyType>::value
1076  >::type * = 0) {
1077  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1078  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1079  , typename ValueTraits::value_type
1080  , typename ValueTraits::pointer_type
1081  >::type value_type ;
1082 
1083  static_assert(Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE,PolicyType,FunctorType>::
1084  has_final_member_function,"Calling parallel_reduce without either return value or final function.");
1085 
1086  typedef Kokkos::View< value_type
1088  , Kokkos::MemoryUnmanaged
1089  > result_view_type;
1090  result_view_type result_view ;
1091 
1092  Impl::ParallelReduceAdaptor<PolicyType,FunctorType,result_view_type>::execute("",policy,functor,result_view);
1093 }
1094 
1095 template< class FunctorType >
1096 inline
1097 void parallel_reduce(const size_t& policy,
1098  const FunctorType& functor) {
1099  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1100  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1101  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1102  , typename ValueTraits::value_type
1103  , typename ValueTraits::pointer_type
1104  >::type value_type ;
1105 
1106  static_assert(Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE,RangePolicy<>,FunctorType>::
1107  has_final_member_function,"Calling parallel_reduce without either return value or final function.");
1108 
1109  typedef Kokkos::View< value_type
1111  , Kokkos::MemoryUnmanaged
1112  > result_view_type;
1113  result_view_type result_view ;
1114 
1115  Impl::ParallelReduceAdaptor<policy_type,FunctorType,result_view_type>::execute("",policy_type(0,policy),functor,result_view);
1116 }
1117 
1118 template< class FunctorType>
1119 inline
1120 void parallel_reduce(const std::string& label,
1121  const size_t& policy,
1122  const FunctorType& functor) {
1123  typedef typename Impl::ParallelReducePolicyType<void,size_t,FunctorType>::policy_type policy_type;
1124  typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ;
1125  typedef typename Kokkos::Impl::if_c< (ValueTraits::StaticValueSize != 0)
1126  , typename ValueTraits::value_type
1127  , typename ValueTraits::pointer_type
1128  >::type value_type ;
1129 
1130  static_assert(Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE,RangePolicy<>,FunctorType>::
1131  has_final_member_function,"Calling parallel_reduce without either return value or final function.");
1132 
1133  typedef Kokkos::View< value_type
1134  , Kokkos::HostSpace
1135  , Kokkos::MemoryUnmanaged
1136  > result_view_type;
1137  result_view_type result_view ;
1138 
1139  Impl::ParallelReduceAdaptor<policy_type,FunctorType,result_view_type>::execute(label,policy_type(0,policy),functor,result_view);
1140 }
1141 
1142 } //namespace Kokkos
1143 
1144 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
1145 //backwards compatiblity for Kokkos::Experimental reducers
1146 namespace Kokkos { namespace Experimental {
1147 using Kokkos::Sum;
1148 using Kokkos::Prod;
1149 using Kokkos::Min;
1150 using Kokkos::Max;
1151 using Kokkos::LAnd;
1152 using Kokkos::LOr;
1153 using Kokkos::BAnd;
1154 using Kokkos::BOr;
1155 using Kokkos::ValLocScalar;
1156 using Kokkos::MinLoc;
1157 using Kokkos::MaxLoc;
1158 using Kokkos::MinMaxScalar;
1159 using Kokkos::MinMax;
1160 using Kokkos::MinMaxLocScalar;
1161 using Kokkos::MinMaxLoc;
1162 }} //namespace Kokkos::Experimental
1163 #endif
1164 
1165 #endif // KOKKOS_PARALLEL_REDUCE_HPP
1166 
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.