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 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< ! Impl::is_integral< ExecPolicy >::value >::type * = 0
177  )
178 {
179 #if defined(KOKKOS_ENABLE_PROFILING)
180  uint64_t kpID = 0;
181  if(Kokkos::Profiling::profileLibraryLoaded()) {
182  Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
183  }
184 #endif
185 
186  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
187  Impl::ParallelFor< FunctorType , ExecPolicy > closure( functor , policy );
188  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
189 
190  closure.execute();
191 
192 #if defined(KOKKOS_ENABLE_PROFILING)
193  if(Kokkos::Profiling::profileLibraryLoaded()) {
194  Kokkos::Profiling::endParallelFor(kpID);
195  }
196 #endif
197 }
198 
199 template< class FunctorType >
200 inline
201 void parallel_for( const size_t work_count
202  , const FunctorType & functor
203  , const std::string& str = ""
204  )
205 {
206  typedef typename
207  Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
208  execution_space ;
209  typedef RangePolicy< execution_space > policy ;
210 
211 #if defined(KOKKOS_ENABLE_PROFILING)
212  uint64_t kpID = 0;
213  if(Kokkos::Profiling::profileLibraryLoaded()) {
214  Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
215  }
216 #endif
217 
218  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
219  Impl::ParallelFor< FunctorType , policy > closure( functor , policy(0,work_count) );
220  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
221 
222  closure.execute();
223 
224 #if defined(KOKKOS_ENABLE_PROFILING)
225  if(Kokkos::Profiling::profileLibraryLoaded()) {
226  Kokkos::Profiling::endParallelFor(kpID);
227  }
228 #endif
229 }
230 
231 template< class ExecPolicy , class FunctorType >
232 inline
233 void parallel_for( const std::string & str
234  , const ExecPolicy & policy
235  , const FunctorType & functor )
236 {
237  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
238  Kokkos::fence();
239  std::cout << "KOKKOS_DEBUG Start parallel_for kernel: " << str << std::endl;
240  #endif
241 
242  parallel_for(policy,functor,str);
243 
244  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
245  Kokkos::fence();
246  std::cout << "KOKKOS_DEBUG End parallel_for kernel: " << str << std::endl;
247  #endif
248  (void) str;
249 }
250 
251 }
252 
253 #include <Kokkos_Parallel_Reduce.hpp>
254 //----------------------------------------------------------------------------
255 //----------------------------------------------------------------------------
256 
257 namespace Kokkos {
258 
413 template< class ExecutionPolicy , class FunctorType >
414 inline
415 void parallel_scan( const ExecutionPolicy & policy
416  , const FunctorType & functor
417  , const std::string& str = ""
418  , typename Impl::enable_if< ! Impl::is_integral< ExecutionPolicy >::value >::type * = 0
419  )
420 {
421 #if defined(KOKKOS_ENABLE_PROFILING)
422  uint64_t kpID = 0;
423  if(Kokkos::Profiling::profileLibraryLoaded()) {
424  Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
425  }
426 #endif
427 
428  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
429  Impl::ParallelScan< FunctorType , ExecutionPolicy > closure( functor , policy );
430  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
431 
432  closure.execute();
433 
434 #if defined(KOKKOS_ENABLE_PROFILING)
435  if(Kokkos::Profiling::profileLibraryLoaded()) {
436  Kokkos::Profiling::endParallelScan(kpID);
437  }
438 #endif
439 
440 }
441 
442 template< class FunctorType >
443 inline
444 void parallel_scan( const size_t work_count
445  , const FunctorType & functor
446  , const std::string& str = "" )
447 {
448  typedef typename
449  Kokkos::Impl::FunctorPolicyExecutionSpace< FunctorType , void >::execution_space
450  execution_space ;
451 
453 
454 #if defined(KOKKOS_ENABLE_PROFILING)
455  uint64_t kpID = 0;
456  if(Kokkos::Profiling::profileLibraryLoaded()) {
457  Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID);
458  }
459 #endif
460 
461  Kokkos::Impl::shared_allocation_tracking_claim_and_disable();
462  Impl::ParallelScan< FunctorType , policy > closure( functor , policy(0,work_count) );
463  Kokkos::Impl::shared_allocation_tracking_release_and_enable();
464 
465  closure.execute();
466 
467 #if defined(KOKKOS_ENABLE_PROFILING)
468  if(Kokkos::Profiling::profileLibraryLoaded()) {
469  Kokkos::Profiling::endParallelScan(kpID);
470  }
471 #endif
472 
473 }
474 
475 template< class ExecutionPolicy , class FunctorType >
476 inline
477 void parallel_scan( const std::string& str
478  , const ExecutionPolicy & policy
479  , const FunctorType & functor)
480 {
481  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
482  Kokkos::fence();
483  std::cout << "KOKKOS_DEBUG Start parallel_scan kernel: " << str << std::endl;
484  #endif
485 
486  parallel_scan(policy,functor,str);
487 
488  #if KOKKOS_ENABLE_DEBUG_PRINT_KERNEL_NAMES
489  Kokkos::fence();
490  std::cout << "KOKKOS_DEBUG End parallel_scan kernel: " << str << std::endl;
491  #endif
492  (void) str;
493 }
494 
495 } // namespace Kokkos
496 
497 //----------------------------------------------------------------------------
498 //----------------------------------------------------------------------------
499 
500 namespace Kokkos {
501 namespace Impl {
502 
503 template< class FunctorType , class Enable = void >
504 struct FunctorTeamShmemSize
505 {
506  KOKKOS_INLINE_FUNCTION static size_t value( const FunctorType & , int ) { return 0 ; }
507 };
508 
509 template< class FunctorType >
510 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::team_shmem_size ) >::type >
511 {
512  static inline size_t value( const FunctorType & f , int team_size ) { return f.team_shmem_size( team_size ) ; }
513 };
514 
515 template< class FunctorType >
516 struct FunctorTeamShmemSize< FunctorType , typename Impl::enable_if< 0 < sizeof( & FunctorType::shmem_size ) >::type >
517 {
518  static inline size_t value( const FunctorType & f , int team_size ) { return f.shmem_size( team_size ) ; }
519 };
520 
521 } // namespace Impl
522 } // namespace Kokkos
523 
524 //----------------------------------------------------------------------------
525 //----------------------------------------------------------------------------
526 
527 #endif /* KOKKOS_PARALLEL_HPP */
528 
Implementation detail of parallel_scan.
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.