Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Parallel.hpp
Go to the documentation of this file.
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 
46 
47 #ifndef KOKKOS_PARALLEL_HPP
48 #define KOKKOS_PARALLEL_HPP
49 
50 #include <cstddef>
51 #include <Kokkos_Core_fwd.hpp>
52 #include <Kokkos_View.hpp>
53 #include <Kokkos_ExecPolicy.hpp>
54 
55 #if defined(KOKKOS_ENABLE_PROFILING)
56 #include <impl/Kokkos_Profiling_Interface.hpp>
57 #include <typeinfo>
58 #endif
59 
60 #include <impl/Kokkos_Tags.hpp>
61 #include <impl/Kokkos_Traits.hpp>
62 #include <impl/Kokkos_FunctorAnalysis.hpp>
63 #include <impl/Kokkos_FunctorAdapter.hpp>
64 
65 #ifdef KOKKOS_DEBUG
66 #include<iostream>
67 #endif
68 
69 //----------------------------------------------------------------------------
70 //----------------------------------------------------------------------------
71 
72 namespace Kokkos {
73 namespace Impl {
74 
75 //----------------------------------------------------------------------------
83 template< class Functor
84  , class Policy
85  , class EnableFunctor
86  , class EnablePolicy
87  >
88 struct FunctorPolicyExecutionSpace {
89  typedef Kokkos::DefaultExecutionSpace execution_space ;
90 };
91 
92 template< class Functor , class Policy >
93 struct FunctorPolicyExecutionSpace
94  < Functor , Policy
95  , typename enable_if_type< typename Functor::device_type >::type
96  , typename enable_if_type< typename Policy ::execution_space >::type
97  >
98 {
99  typedef typename Policy ::execution_space execution_space ;
100 };
101 
102 template< class Functor , class Policy >
103 struct FunctorPolicyExecutionSpace
104  < Functor , Policy
105  , typename enable_if_type< typename Functor::execution_space >::type
106  , typename enable_if_type< typename Policy ::execution_space >::type
107  >
108 {
109  typedef typename Policy ::execution_space execution_space ;
110 };
111 
112 template< class Functor , class Policy , class EnableFunctor >
113 struct FunctorPolicyExecutionSpace
114  < Functor , Policy
115  , EnableFunctor
116  , typename enable_if_type< typename Policy::execution_space >::type
117  >
118 {
119  typedef typename Policy ::execution_space execution_space ;
120 };
121 
122 template< class Functor , class Policy , class EnablePolicy >
123 struct FunctorPolicyExecutionSpace
124  < Functor , Policy
125  , typename enable_if_type< typename Functor::device_type >::type
126  , EnablePolicy
127  >
128 {
129  typedef typename Functor::device_type execution_space ;
130 };
131 
132 template< class Functor , class Policy , class EnablePolicy >
133 struct FunctorPolicyExecutionSpace
134  < Functor , Policy
135  , typename enable_if_type< typename Functor::execution_space >::type
136  , EnablePolicy
137  >
138 {
139  typedef typename Functor::execution_space execution_space ;
140 };
141 
142 } // namespace Impl
143 } // namespace Kokkos
144 
145 //----------------------------------------------------------------------------
146 //----------------------------------------------------------------------------
147 
148 namespace Kokkos {
149 
171 template< class ExecPolicy , class FunctorType >
172 inline
173 void parallel_for( const ExecPolicy & policy
174  , const FunctorType & functor
175  , const std::string& str = ""
176  , typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type * = 0
177  )
178 {
179 #if defined(KOKKOS_ENABLE_PROFILING)
180  uint64_t kpID = 0;
181  if(Kokkos::Profiling::profileLibraryLoaded()) {
182  Kokkos::Impl::ParallelConstructName<FunctorType, typename ExecPolicy::work_tag> name(str);
183  Kokkos::Profiling::beginParallelFor(name.get(), 0, &kpID);
184  }
185 #endif
186 
187  Kokkos::Impl::shared_allocation_tracking_disable();
188  Impl::ParallelFor< FunctorType , ExecPolicy > closure( functor , policy );
189  Kokkos::Impl::shared_allocation_tracking_enable();
190 
191  closure.execute();
192 
193 #if defined(KOKKOS_ENABLE_PROFILING)
194  if(Kokkos::Profiling::profileLibraryLoaded()) {
195  Kokkos::Profiling::endParallelFor(kpID);
196  }
197 #endif
198 }
199 
200 template< class FunctorType >
201 inline
202 void parallel_for( const size_t work_count
203  , const FunctorType & functor
204  , const std::string& str = ""
205  )
206 {
207  typedef typename
208  Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
209  execution_space ;
210  typedef RangePolicy< execution_space > policy ;
211 
212 #if defined(KOKKOS_ENABLE_PROFILING)
213  uint64_t kpID = 0;
214  if(Kokkos::Profiling::profileLibraryLoaded()) {
215  Kokkos::Impl::ParallelConstructName<FunctorType, void> name(str);
216  Kokkos::Profiling::beginParallelFor(name.get(), 0, &kpID);
217  }
218 #endif
219 
220  Kokkos::Impl::shared_allocation_tracking_disable();
221  Impl::ParallelFor< FunctorType , policy > closure( functor , policy(0,work_count) );
222  Kokkos::Impl::shared_allocation_tracking_enable();
223 
224  closure.execute();
225 
226 #if defined(KOKKOS_ENABLE_PROFILING)
227  if(Kokkos::Profiling::profileLibraryLoaded()) {
228  Kokkos::Profiling::endParallelFor(kpID);
229  }
230 #endif
231 }
232 
233 template< class ExecPolicy , class FunctorType >
234 inline
235 void parallel_for( const std::string & str
236  , const ExecPolicy & policy
237  , const FunctorType & functor )
238 {
239  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
240  Kokkos::fence();
241  std::cout << "KOKKOS_DEBUG Start parallel_for kernel: " << str << std::endl;
242  #endif
243 
244  ::Kokkos::parallel_for(policy,functor,str);
245 
246  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
247  Kokkos::fence();
248  std::cout << "KOKKOS_DEBUG End parallel_for kernel: " << str << std::endl;
249  #endif
250  (void) str;
251 }
252 
253 }
254 
255 #include <Kokkos_Parallel_Reduce.hpp>
256 //----------------------------------------------------------------------------
257 //----------------------------------------------------------------------------
258 
259 namespace Kokkos {
260 
399 //i/ }
415 template< class ExecutionPolicy , class FunctorType >
416 inline
417 void parallel_scan( const ExecutionPolicy & policy
418  , const FunctorType & functor
419  , const std::string& str = ""
420  , typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecutionPolicy >::value >::type * = 0
421  )
422 {
423 #if defined(KOKKOS_ENABLE_PROFILING)
424  uint64_t kpID = 0;
425  if(Kokkos::Profiling::profileLibraryLoaded()) {
426  Kokkos::Impl::ParallelConstructName<FunctorType, typename ExecutionPolicy::work_tag> name(str);
427  Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID);
428  }
429 #endif
430 
431  Kokkos::Impl::shared_allocation_tracking_disable();
432  Impl::ParallelScan< FunctorType , ExecutionPolicy > closure( functor , policy );
433  Kokkos::Impl::shared_allocation_tracking_enable();
434 
435  closure.execute();
436 
437 #if defined(KOKKOS_ENABLE_PROFILING)
438  if(Kokkos::Profiling::profileLibraryLoaded()) {
439  Kokkos::Profiling::endParallelScan(kpID);
440  }
441 #endif
442 
443 }
444 
445 template< class FunctorType >
446 inline
447 void parallel_scan( const size_t work_count
448  , const FunctorType & functor
449  , const std::string& str = "" )
450 {
451  typedef typename
452  Kokkos::Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
453  execution_space ;
454 
456 
457 #if defined(KOKKOS_ENABLE_PROFILING)
458  uint64_t kpID = 0;
459  if(Kokkos::Profiling::profileLibraryLoaded()) {
460  Kokkos::Impl::ParallelConstructName<FunctorType, void> name(str);
461  Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID);
462  }
463 #endif
464 
465  Kokkos::Impl::shared_allocation_tracking_disable();
466  Impl::ParallelScan< FunctorType , policy > closure( functor , policy(0,work_count) );
467  Kokkos::Impl::shared_allocation_tracking_enable();
468 
469  closure.execute();
470 
471 #if defined(KOKKOS_ENABLE_PROFILING)
472  if(Kokkos::Profiling::profileLibraryLoaded()) {
473  Kokkos::Profiling::endParallelScan(kpID);
474  }
475 #endif
476 
477 }
478 
479 template< class ExecutionPolicy , class FunctorType >
480 inline
481 void parallel_scan( const std::string& str
482  , const ExecutionPolicy & policy
483  , const FunctorType & functor)
484 {
485  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
486  Kokkos::fence();
487  std::cout << "KOKKOS_DEBUG Start parallel_scan kernel: " << str << std::endl;
488  #endif
489 
490  ::Kokkos::parallel_scan(policy,functor,str);
491 
492  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
493  Kokkos::fence();
494  std::cout << "KOKKOS_DEBUG End parallel_scan kernel: " << str << std::endl;
495  #endif
496  (void) str;
497 }
498 
499 
500 template< class ExecutionPolicy , class FunctorType, class ReturnType >
501 inline
502 void parallel_scan( const ExecutionPolicy & policy
503  , const FunctorType & functor
504  , ReturnType & return_value
505  , const std::string& str = ""
506  , typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecutionPolicy >::value >::type * = 0
507  )
508 {
509 #if defined(KOKKOS_ENABLE_PROFILING)
510  uint64_t kpID = 0;
511  if(Kokkos::Profiling::profileLibraryLoaded()) {
512  Kokkos::Impl::ParallelConstructName<FunctorType, typename ExecutionPolicy::work_tag> name(str);
513  Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID);
514  }
515 #endif
516 
517  Kokkos::Impl::shared_allocation_tracking_disable();
518  Impl::ParallelScanWithTotal< FunctorType , ExecutionPolicy, ReturnType > closure( functor, policy, return_value );
519  Kokkos::Impl::shared_allocation_tracking_enable();
520 
521  closure.execute();
522 
523 #if defined(KOKKOS_ENABLE_PROFILING)
524  if(Kokkos::Profiling::profileLibraryLoaded()) {
525  Kokkos::Profiling::endParallelScan(kpID);
526  }
527 #endif
528  Kokkos::fence();
529 }
530 
531 template< class FunctorType, class ReturnType >
532 inline
533 void parallel_scan( const size_t work_count
534  , const FunctorType & functor
535  , ReturnType & return_value
536  , const std::string & str = "" )
537 {
538  typedef typename
539  Kokkos::Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
540  execution_space ;
541 
543 
544 #if defined(KOKKOS_ENABLE_PROFILING)
545  uint64_t kpID = 0;
546  if(Kokkos::Profiling::profileLibraryLoaded()) {
547  Kokkos::Impl::ParallelConstructName<FunctorType, void> name(str);
548  Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID);
549  }
550 #endif
551 
552  Kokkos::Impl::shared_allocation_tracking_disable();
553  Impl::ParallelScanWithTotal< FunctorType, policy, ReturnType > closure( functor, policy(0,work_count), return_value );
554  Kokkos::Impl::shared_allocation_tracking_enable();
555 
556  closure.execute();
557 
558 #if defined(KOKKOS_ENABLE_PROFILING)
559  if(Kokkos::Profiling::profileLibraryLoaded()) {
560  Kokkos::Profiling::endParallelScan(kpID);
561  }
562 #endif
563  Kokkos::fence();
564 }
565 
566 template< class ExecutionPolicy, class FunctorType, class ReturnType >
567 inline
568 void parallel_scan( const std::string& str
569  , const ExecutionPolicy & policy
570  , const FunctorType & functor
571  , ReturnType & return_value)
572 {
573  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
574  Kokkos::fence();
575  std::cout << "KOKKOS_DEBUG Start parallel_scan kernel: " << str << std::endl;
576  #endif
577 
578  ::Kokkos::parallel_scan(policy,functor,return_value,str);
579 
580  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
581  Kokkos::fence();
582  std::cout << "KOKKOS_DEBUG End parallel_scan kernel: " << str << std::endl;
583  #endif
584  (void) str;
585 }
586 
587 
588 
589 } // namespace Kokkos
590 
591 //----------------------------------------------------------------------------
592 //----------------------------------------------------------------------------
593 
594 namespace Kokkos {
595 namespace Impl {
596 
597 template< class FunctorType , class Enable = void >
598 struct FunctorTeamShmemSize
599 {
600  KOKKOS_INLINE_FUNCTION static size_t value( const FunctorType & , int ) { return 0 ; }
601 };
602 
603 template< class FunctorType >
604 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::team_shmem_size ) >::type >
605 {
606  static inline size_t value( const FunctorType & f , int team_size ) { return f.team_shmem_size( team_size ) ; }
607 };
608 
609 template< class FunctorType >
610 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::shmem_size ) >::type >
611 {
612  static inline size_t value( const FunctorType & f , int team_size ) { return f.shmem_size( team_size ) ; }
613 };
614 
615 } // namespace Impl
616 } // namespace Kokkos
617 
618 //----------------------------------------------------------------------------
619 //----------------------------------------------------------------------------
620 
621 #endif /* KOKKOS_PARALLEL_HPP */
622 
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=0)
Execute functor in parallel according to the execution policy.
Implementation of the ParallelFor operator that has a partial specialization for the device...
ReturnType
Execution policy for work over a range of an integral type.