Kokkos Core Kernels Package  Version of the Day
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 H. Carter Edwards (hcedwar@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 (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_FunctorAdapter.hpp>
63 
64 #ifdef KOKKOS_HAVE_DEBUG
65 #include<iostream>
66 #endif
67 
68 //----------------------------------------------------------------------------
69 //----------------------------------------------------------------------------
70 
71 namespace Kokkos {
72 namespace Impl {
73 
74 //----------------------------------------------------------------------------
82 template< class Functor
83  , class Policy
84  , class EnableFunctor
85  , class EnablePolicy
86  >
87 struct FunctorPolicyExecutionSpace {
88  typedef Kokkos::DefaultExecutionSpace execution_space ;
89 };
90 
91 template< class Functor , class Policy >
92 struct FunctorPolicyExecutionSpace
93  < Functor , Policy
94  , typename enable_if_type< typename Functor::device_type >::type
95  , typename enable_if_type< typename Policy ::execution_space >::type
96  >
97 {
98  typedef typename Policy ::execution_space execution_space ;
99 };
100 
101 template< class Functor , class Policy >
102 struct FunctorPolicyExecutionSpace
103  < Functor , Policy
104  , typename enable_if_type< typename Functor::execution_space >::type
105  , typename enable_if_type< typename Policy ::execution_space >::type
106  >
107 {
108  typedef typename Policy ::execution_space execution_space ;
109 };
110 
111 template< class Functor , class Policy , class EnableFunctor >
112 struct FunctorPolicyExecutionSpace
113  < Functor , Policy
114  , EnableFunctor
115  , typename enable_if_type< typename Policy::execution_space >::type
116  >
117 {
118  typedef typename Policy ::execution_space execution_space ;
119 };
120 
121 template< class Functor , class Policy , class EnablePolicy >
122 struct FunctorPolicyExecutionSpace
123  < Functor , Policy
124  , typename enable_if_type< typename Functor::device_type >::type
125  , EnablePolicy
126  >
127 {
128  typedef typename Functor::device_type execution_space ;
129 };
130 
131 template< class Functor , class Policy , class EnablePolicy >
132 struct FunctorPolicyExecutionSpace
133  < Functor , Policy
134  , typename enable_if_type< typename Functor::execution_space >::type
135  , EnablePolicy
136  >
137 {
138  typedef typename Functor::execution_space execution_space ;
139 };
140 
141 } // namespace Impl
142 } // namespace Kokkos
143 
144 //----------------------------------------------------------------------------
145 //----------------------------------------------------------------------------
146 
147 namespace Kokkos {
148 
170 template< class ExecPolicy , class FunctorType >
171 inline
172 void parallel_for( const ExecPolicy & policy
173  , const FunctorType & functor
174  , const std::string& str = ""
175  , typename Impl::enable_if< ! Impl::is_integral< ExecPolicy >::value >::type * = 0
176  )
177 {
178 #if (KOKKOS_ENABLE_PROFILING)
179  uint64_t kpID = 0;
180  if(Kokkos::Profiling::profileLibraryLoaded()) {
181  Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
182  }
183 #endif
184 
185  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
186  Impl::ParallelFor< FunctorType , ExecPolicy > closure( functor , policy );
187  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
188 
189  closure.execute();
190 
191 #if (KOKKOS_ENABLE_PROFILING)
192  if(Kokkos::Profiling::profileLibraryLoaded()) {
193  Kokkos::Profiling::endParallelFor(kpID);
194  }
195 #endif
196 }
197 
198 template< class FunctorType >
199 inline
200 void parallel_for( const size_t work_count
201  , const FunctorType & functor
202  , const std::string& str = ""
203  )
204 {
205  typedef typename
206  Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
207  execution_space ;
208  typedef RangePolicy< execution_space > policy ;
209 
210 #if (KOKKOS_ENABLE_PROFILING)
211  uint64_t kpID = 0;
212  if(Kokkos::Profiling::profileLibraryLoaded()) {
213  Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
214  }
215 #endif
216 
217  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
218  Impl::ParallelFor< FunctorType , policy > closure( functor , policy(0,work_count) );
219  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
220 
221  closure.execute();
222 
223 #if (KOKKOS_ENABLE_PROFILING)
224  if(Kokkos::Profiling::profileLibraryLoaded()) {
225  Kokkos::Profiling::endParallelFor(kpID);
226  }
227 #endif
228 }
229 
230 template< class ExecPolicy , class FunctorType >
231 inline
232 void parallel_for( const std::string & str
233  , const ExecPolicy & policy
234  , const FunctorType & functor )
235 {
236  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
237  Kokkos::fence();
238  std::cout << "KOKKOS_DEBUG Start parallel_for kernel: " << str << std::endl;
239  #endif
240 
241  parallel_for(policy,functor,str);
242 
243  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
244  Kokkos::fence();
245  std::cout << "KOKKOS_DEBUG End parallel_for kernel: " << str << std::endl;
246  #endif
247  (void) str;
248 }
249 
250 }
251 
252 #include <Kokkos_Parallel_Reduce.hpp>
253 //----------------------------------------------------------------------------
254 //----------------------------------------------------------------------------
255 
256 namespace Kokkos {
257 
412 template< class ExecutionPolicy , class FunctorType >
413 inline
414 void parallel_scan( const ExecutionPolicy & policy
415  , const FunctorType & functor
416  , const std::string& str = ""
417  , typename Impl::enable_if< ! Impl::is_integral< ExecutionPolicy >::value >::type * = 0
418  )
419 {
420 #if (KOKKOS_ENABLE_PROFILING)
421  uint64_t kpID = 0;
422  if(Kokkos::Profiling::profileLibraryLoaded()) {
423  Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
424  }
425 #endif
426 
427  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
428  Impl::ParallelScan< FunctorType , ExecutionPolicy > closure( functor , policy );
429  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
430 
431  closure.execute();
432 
433 #if (KOKKOS_ENABLE_PROFILING)
434  if(Kokkos::Profiling::profileLibraryLoaded()) {
435  Kokkos::Profiling::endParallelScan(kpID);
436  }
437 #endif
438 
439 }
440 
441 template< class FunctorType >
442 inline
443 void parallel_scan( const size_t work_count
444  , const FunctorType & functor
445  , const std::string& str = "" )
446 {
447  typedef typename
448  Kokkos::Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
449  execution_space ;
450 
452 
453 #if (KOKKOS_ENABLE_PROFILING)
454  uint64_t kpID = 0;
455  if(Kokkos::Profiling::profileLibraryLoaded()) {
456  Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
457  }
458 #endif
459 
460  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
461  Impl::ParallelScan< FunctorType , policy > closure( functor , policy(0,work_count) );
462  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
463 
464  closure.execute();
465 
466 #if (KOKKOS_ENABLE_PROFILING)
467  if(Kokkos::Profiling::profileLibraryLoaded()) {
468  Kokkos::Profiling::endParallelScan(kpID);
469  }
470 #endif
471 
472 }
473 
474 template< class ExecutionPolicy , class FunctorType >
475 inline
476 void parallel_scan( const std::string& str
477  , const ExecutionPolicy & policy
478  , const FunctorType & functor)
479 {
480  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
481  Kokkos::fence();
482  std::cout << "KOKKOS_DEBUG Start parallel_scan kernel: " << str << std::endl;
483  #endif
484 
485  parallel_scan(policy,functor,str);
486 
487  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
488  Kokkos::fence();
489  std::cout << "KOKKOS_DEBUG End parallel_scan kernel: " << str << std::endl;
490  #endif
491  (void) str;
492 }
493 
494 } // namespace Kokkos
495 
496 //----------------------------------------------------------------------------
497 //----------------------------------------------------------------------------
498 
499 namespace Kokkos {
500 namespace Impl {
501 
502 template< class FunctorType , class Enable = void >
503 struct FunctorTeamShmemSize
504 {
505  KOKKOS_INLINE_FUNCTION static size_t value( const FunctorType & , int ) { return 0 ; }
506 };
507 
508 template< class FunctorType >
509 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::team_shmem_size ) >::type >
510 {
511  static inline size_t value( const FunctorType & f , int team_size ) { return f.team_shmem_size( team_size ) ; }
512 };
513 
514 template< class FunctorType >
515 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::shmem_size ) >::type >
516 {
517  static inline size_t value( const FunctorType & f , int team_size ) { return f.shmem_size( team_size ) ; }
518 };
519 
520 } // namespace Impl
521 } // namespace Kokkos
522 
523 //----------------------------------------------------------------------------
524 //----------------------------------------------------------------------------
525 
526 #endif /* KOKKOS_PARALLEL_HPP */
527 
Implementation of the ParallelFor operator that has a partial specialization for the device...
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< ! Impl::is_integral< ExecPolicy >::value >::type *=0)
Execute functor in parallel according to the execution policy.
Execution policy for work over a range of an integral type.