Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Serial.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_SERIAL_HPP
48 #define KOKKOS_SERIAL_HPP
49 
50 #include <Kokkos_Macros.hpp>
51 #if defined( KOKKOS_ENABLE_SERIAL )
52 
53 #include <cstddef>
54 #include <iosfwd>
55 #include <Kokkos_Parallel.hpp>
56 #include <Kokkos_TaskScheduler.hpp>
57 #include <Kokkos_Layout.hpp>
58 #include <Kokkos_HostSpace.hpp>
59 #include <Kokkos_ScratchSpace.hpp>
60 #include <Kokkos_MemoryTraits.hpp>
61 #include <impl/Kokkos_Tags.hpp>
62 #include <impl/Kokkos_HostThreadTeam.hpp>
63 #include <impl/Kokkos_FunctorAnalysis.hpp>
64 #include <impl/Kokkos_FunctorAdapter.hpp>
65 #include <impl/Kokkos_Profiling_Interface.hpp>
66 
67 #include <KokkosExp_MDRangePolicy.hpp>
68 
69 #include <Kokkos_UniqueToken.hpp>
70 
71 namespace Kokkos {
72 
85 class Serial {
86 public:
88 
89 
91  typedef Serial execution_space ;
93  typedef HostSpace::size_type size_type ;
95  typedef HostSpace memory_space ;
97  typedef Kokkos::Device<execution_space,memory_space> device_type;
98 
100  typedef LayoutRight array_layout ;
101 
103  typedef ScratchMemorySpace< Kokkos::Serial > scratch_memory_space ;
104 
106 
113  inline static int in_parallel() { return false ; }
114 
121  static void fence() {}
122 
124  static int concurrency() {return 1;};
125 
127  static void print_configuration( std::ostream & , const bool /* detail */ = false ) {}
128 
129 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
130  static bool sleep();
131  static bool wake();
132 
133  static void initialize( unsigned threads_count = 1 ,
134  unsigned use_numa_count = 0 ,
135  unsigned use_cores_per_numa = 0 ,
136  bool allow_asynchronous_threadpool = false);
137 
138  static bool is_initialized();
139 
141  static void finalize();
142 
143  //--------------------------------------------------------------------------
144 
145  inline static int thread_pool_size( int = 0 ) { return 1 ; }
146  KOKKOS_INLINE_FUNCTION static int thread_pool_rank() { return 0 ; }
147 
148  //--------------------------------------------------------------------------
149 
150  KOKKOS_INLINE_FUNCTION static unsigned hardware_thread_id() { return thread_pool_rank(); }
151  inline static unsigned max_hardware_threads() { return thread_pool_size(0); }
152 #else
153  static void impl_initialize();
154 
155  static bool impl_is_initialized();
156 
158  static void impl_finalize();
159 
160  //--------------------------------------------------------------------------
161 
162  inline static int impl_thread_pool_size( int = 0 ) { return 1 ; }
163  KOKKOS_INLINE_FUNCTION static int impl_thread_pool_rank() { return 0 ; }
164 
165  //--------------------------------------------------------------------------
166 
167  KOKKOS_INLINE_FUNCTION static unsigned impl_hardware_thread_id() { return impl_thread_pool_rank(); }
168  inline static unsigned impl_max_hardware_threads() { return impl_thread_pool_size(0); }
169 #endif
170 
171  static const char* name();
172  //--------------------------------------------------------------------------
173 };
174 
175 } // namespace Kokkos
176 
177 /*--------------------------------------------------------------------------*/
178 /*--------------------------------------------------------------------------*/
179 
180 namespace Kokkos {
181 namespace Impl {
182 
183 template<>
184 struct MemorySpaceAccess
185  < Kokkos::Serial::memory_space
186  , Kokkos::Serial::scratch_memory_space
187  >
188 {
189  enum { assignable = false };
190  enum { accessible = true };
191  enum { deepcopy = false };
192 };
193 
194 template<>
195 struct VerifyExecutionCanAccessMemorySpace
196  < Kokkos::Serial::memory_space
197  , Kokkos::Serial::scratch_memory_space
198  >
199 {
200  enum { value = true };
201  inline static void verify( void ) { }
202  inline static void verify( const void * ) { }
203 };
204 
205 } // namespace Impl
206 } // namespace Kokkos
207 
208 /*--------------------------------------------------------------------------*/
209 /*--------------------------------------------------------------------------*/
210 
211 namespace Kokkos {
212 namespace Impl {
213 
214 // Resize thread team data scratch memory
215 void serial_resize_thread_team_data( size_t pool_reduce_bytes
216  , size_t team_reduce_bytes
217  , size_t team_shared_bytes
218  , size_t thread_local_bytes );
219 
220 HostThreadTeamData * serial_get_thread_team_data();
221 
222 } /* namespace Impl */
223 } /* namespace Kokkos */
224 
225 
226 namespace Kokkos {
227 namespace Impl {
228 
229 /*
230  * < Kokkos::Serial , WorkArgTag >
231  * < WorkArgTag , Impl::enable_if< std::is_same< Kokkos::Serial , Kokkos::DefaultExecutionSpace >::value >::type >
232  *
233  */
234 template< class ... Properties >
235 class TeamPolicyInternal< Kokkos::Serial , Properties ... >:public PolicyTraits<Properties...>
236 {
237 private:
238 
239  size_t m_team_scratch_size[2] ;
240  size_t m_thread_scratch_size[2] ;
241  int m_league_size ;
242  int m_chunk_size;
243 
244 public:
245 
247  typedef TeamPolicyInternal execution_policy ;
248 
249  typedef PolicyTraits<Properties ... > traits;
250 
252  typedef Kokkos::Serial execution_space ;
253 
254  TeamPolicyInternal& operator = (const TeamPolicyInternal& p) {
255  m_league_size = p.m_league_size;
256  m_team_scratch_size[0] = p.m_team_scratch_size[0];
257  m_thread_scratch_size[0] = p.m_thread_scratch_size[0];
258  m_team_scratch_size[1] = p.m_team_scratch_size[1];
259  m_thread_scratch_size[1] = p.m_thread_scratch_size[1];
260  m_chunk_size = p.m_chunk_size;
261  return *this;
262  }
263 
264  //----------------------------------------
265 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
266  template< class FunctorType >
267  static
268  int team_size_max( const FunctorType & ) { return 1 ; }
269 
270  template< class FunctorType >
271  static
272  int team_size_recommended( const FunctorType & ) { return 1 ; }
273 
274  template< class FunctorType >
275  static
276  int team_size_recommended( const FunctorType & , const int& ) { return 1 ; }
277 #endif
278 
279  template<class FunctorType>
280  int team_size_max( const FunctorType&, const ParallelForTag& ) const { return 1 ; }
281  template<class FunctorType>
282  int team_size_max( const FunctorType&, const ParallelReduceTag& ) const { return 1 ; }
283  template<class FunctorType>
284  int team_size_recommended( const FunctorType&, const ParallelForTag& ) const { return 1 ; }
285  template<class FunctorType>
286  int team_size_recommended( const FunctorType&, const ParallelReduceTag& ) const { return 1 ; }
287 
288  //----------------------------------------
289 
290  inline int team_size() const { return 1 ; }
291  inline int league_size() const { return m_league_size ; }
292  inline size_t scratch_size(const int& level, int = 0) const { return m_team_scratch_size[level] + m_thread_scratch_size[level]; }
293 
294  inline static
295  int vector_length_max()
296  { return 1024; } // Use arbitrary large number, is meant as a vectorizable length
297 
298  inline static
299  int scratch_size_max(int level)
300  { return (level==0?
301  1024*32:
302  20*1024*1024);
303  }
305  TeamPolicyInternal( execution_space &
306  , int league_size_request
307 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
308  , int team_size_request
309 #else
310  , int /* team_size_request */
311 #endif
312  , int /* vector_length_request */ = 1 )
313  : m_team_scratch_size { 0 , 0 }
314  , m_thread_scratch_size { 0 , 0 }
315  , m_league_size( league_size_request )
316  , m_chunk_size ( 32 )
317  {
318  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
319  if(team_size_request > 1) Kokkos::abort("Kokkos::abort: Requested Team Size is too large!");
320  #endif
321  }
322 
323  TeamPolicyInternal( execution_space &
324  , int league_size_request
325  , const Kokkos::AUTO_t & /* team_size_request */
326  , int /* vector_length_request */ = 1 )
327  : m_team_scratch_size { 0 , 0 }
328  , m_thread_scratch_size { 0 , 0 }
329  , m_league_size( league_size_request )
330  , m_chunk_size ( 32 )
331  {}
332 
333  TeamPolicyInternal( int league_size_request
334 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
335  , int team_size_request
336 #else
337  , int /* team_size_request */
338 #endif
339  , int /* vector_length_request */ = 1 )
340  : m_team_scratch_size { 0 , 0 }
341  , m_thread_scratch_size { 0 , 0 }
342  , m_league_size( league_size_request )
343  , m_chunk_size ( 32 )
344  {
345  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
346  if(team_size_request > 1) Kokkos::abort("Kokkos::abort: Requested Team Size is too large!");
347  #endif
348  }
349 
350  TeamPolicyInternal( int league_size_request
351  , const Kokkos::AUTO_t & /* team_size_request */
352  , int /* vector_length_request */ = 1 )
353  : m_team_scratch_size { 0 , 0 }
354  , m_thread_scratch_size { 0 , 0 }
355  , m_league_size( league_size_request )
356  , m_chunk_size ( 32 )
357  {}
358 
359  inline int chunk_size() const { return m_chunk_size ; }
360 
361 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
362 
363  inline TeamPolicyInternal set_chunk_size(typename traits::index_type chunk_size_) const {
364  TeamPolicyInternal p = *this;
365  p.m_chunk_size = chunk_size_;
366  return p;
367  }
368 
370  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team) const {
371  TeamPolicyInternal p = *this;
372  p.m_team_scratch_size[level] = per_team.value;
373  return p;
374  }
375 
377  inline TeamPolicyInternal set_scratch_size(const int& level, const PerThreadValue& per_thread) const {
378  TeamPolicyInternal p = *this;
379  p.m_thread_scratch_size[level] = per_thread.value;
380  return p;
381  }
382 
384  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) const {
385  TeamPolicyInternal p = *this;
386  p.m_team_scratch_size[level] = per_team.value;
387  p.m_thread_scratch_size[level] = per_thread.value;
388  return p;
389  }
390 #else
391 
392  inline TeamPolicyInternal& set_chunk_size(typename traits::index_type chunk_size_) {
393  m_chunk_size = chunk_size_;
394  return *this;
395  }
396 
398  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerTeamValue& per_team) {
399  m_team_scratch_size[level] = per_team.value;
400  return *this;
401  }
402 
404  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerThreadValue& per_thread) {
405  m_thread_scratch_size[level] = per_thread.value;
406  return *this;
407  }
408 
410  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) {
411  m_team_scratch_size[level] = per_team.value;
412  m_thread_scratch_size[level] = per_thread.value;
413  return *this;
414  }
415 #endif
416 
417  typedef Impl::HostThreadTeamMember< Kokkos::Serial > member_type ;
418 
419 protected:
420 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
421 
422  inline TeamPolicyInternal internal_set_chunk_size(typename traits::index_type chunk_size_) {
423  m_chunk_size = chunk_size_;
424  return *this;
425  }
426 
428  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerTeamValue& per_team) {
429  m_team_scratch_size[level] = per_team.value;
430  return *this;
431  }
432 
434  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerThreadValue& per_thread) {
435  m_thread_scratch_size[level] = per_thread.value;
436  return *this;
437  }
438 
440  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) {
441  m_team_scratch_size[level] = per_team.value;
442  m_thread_scratch_size[level] = per_thread.value;
443  return *this;
444  }
445 #endif
446 };
447 } /* namespace Impl */
448 } /* namespace Kokkos */
449 
450 /*--------------------------------------------------------------------------*/
451 /*--------------------------------------------------------------------------*/
452 /* Parallel patterns for Kokkos::Serial with RangePolicy */
453 
454 namespace Kokkos {
455 namespace Impl {
456 
457 template< class FunctorType , class ... Traits >
458 class ParallelFor< FunctorType ,
459  Kokkos::RangePolicy< Traits ... > ,
460  Kokkos::Serial
461  >
462 {
463 private:
464 
465  typedef Kokkos::RangePolicy< Traits ... > Policy ;
466 
467  const FunctorType m_functor ;
468  const Policy m_policy ;
469 
470  template< class TagType >
471  typename std::enable_if< std::is_same< TagType , void >::value >::type
472  exec() const
473  {
474  const typename Policy::member_type e = m_policy.end();
475  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
476  m_functor( i );
477  }
478  }
479 
480  template< class TagType >
481  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
482  exec() const
483  {
484  const TagType t{} ;
485  const typename Policy::member_type e = m_policy.end();
486  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
487  m_functor( t , i );
488  }
489  }
490 
491 public:
492 
493  inline
494  void execute() const
495  { this-> template exec< typename Policy::work_tag >(); }
496 
497  inline
498  ParallelFor( const FunctorType & arg_functor
499  , const Policy & arg_policy )
500  : m_functor( arg_functor )
501  , m_policy( arg_policy )
502  {}
503 };
504 
505 /*--------------------------------------------------------------------------*/
506 
507 template< class FunctorType , class ReducerType , class ... Traits >
508 class ParallelReduce< FunctorType
509  , Kokkos::RangePolicy< Traits ... >
510  , ReducerType
511  , Kokkos::Serial
512  >
513 {
514 private:
515 
516  typedef Kokkos::RangePolicy< Traits ... > Policy ;
517  typedef typename Policy::work_tag WorkTag ;
518 
519  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
520 
521  typedef typename ReducerConditional::type ReducerTypeFwd;
522  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
523 
524  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
525 
526  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
527 
528  typedef typename Analysis::pointer_type pointer_type ;
529  typedef typename Analysis::reference_type reference_type ;
530 
531  const FunctorType m_functor ;
532  const Policy m_policy ;
533  const ReducerType m_reducer ;
534  const pointer_type m_result_ptr ;
535 
536  template< class TagType >
537  inline
538  typename std::enable_if< std::is_same< TagType , void >::value >::type
539  exec( reference_type update ) const
540  {
541  const typename Policy::member_type e = m_policy.end();
542  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
543  m_functor( i , update );
544  }
545  }
546 
547  template< class TagType >
548  inline
549  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
550  exec( reference_type update ) const
551  {
552  const TagType t{} ;
553 
554  const typename Policy::member_type e = m_policy.end();
555  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
556  m_functor( t , i , update );
557  }
558  }
559 
560 public:
561 
562  inline
563  void execute() const
564  {
565  const size_t pool_reduce_size =
566  Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) );
567  const size_t team_reduce_size = 0 ; // Never shrinks
568  const size_t team_shared_size = 0 ; // Never shrinks
569  const size_t thread_local_size = 0 ; // Never shrinks
570 
571  serial_resize_thread_team_data( pool_reduce_size
572  , team_reduce_size
573  , team_shared_size
574  , thread_local_size );
575 
576  HostThreadTeamData & data = *serial_get_thread_team_data();
577 
578  pointer_type ptr =
579  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
580 
581  reference_type update =
582  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
583 
584  this-> template exec< WorkTag >( update );
585 
586  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
587  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
588  }
589 
590  template< class HostViewType >
591  ParallelReduce( const FunctorType & arg_functor ,
592  const Policy & arg_policy ,
593  const HostViewType & arg_result_view ,
594  typename std::enable_if<
595  Kokkos::is_view< HostViewType >::value &&
596  !Kokkos::is_reducer_type<ReducerType>::value
597  ,void*>::type = NULL)
598  : m_functor( arg_functor )
599  , m_policy( arg_policy )
600  , m_reducer( InvalidType() )
601  , m_result_ptr( arg_result_view.data() )
602  {
603  static_assert( Kokkos::is_view< HostViewType >::value
604  , "Kokkos::Serial reduce result must be a View" );
605 
606  static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value
607  , "Kokkos::Serial reduce result must be a View in HostSpace" );
608  }
609 
610  inline
611  ParallelReduce( const FunctorType & arg_functor
612  , Policy arg_policy
613  , const ReducerType& reducer )
614  : m_functor( arg_functor )
615  , m_policy( arg_policy )
616  , m_reducer( reducer )
617  , m_result_ptr( reducer.view().data() )
618  {
619  /*static_assert( std::is_same< typename ViewType::memory_space
620  , Kokkos::HostSpace >::value
621  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
622  }
623 };
624 
625 
626 /*--------------------------------------------------------------------------*/
627 
628 template< class FunctorType , class ... Traits >
629 class ParallelScan< FunctorType
630  , Kokkos::RangePolicy< Traits ... >
631  , Kokkos::Serial
632  >
633 {
634 private:
635 
636  typedef Kokkos::RangePolicy< Traits ... > Policy ;
637  typedef typename Policy::work_tag WorkTag ;
638 
639  typedef FunctorAnalysis< FunctorPatternInterface::SCAN , Policy , FunctorType > Analysis ;
640 
641  typedef Kokkos::Impl::FunctorValueInit< FunctorType , WorkTag > ValueInit ;
642 
643  typedef typename Analysis::pointer_type pointer_type ;
644  typedef typename Analysis::reference_type reference_type ;
645 
646  const FunctorType m_functor ;
647  const Policy m_policy ;
648 
649  template< class TagType >
650  inline
651  typename std::enable_if< std::is_same< TagType , void >::value >::type
652  exec( reference_type update ) const
653  {
654  const typename Policy::member_type e = m_policy.end();
655  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
656  m_functor( i , update , true );
657  }
658  }
659 
660  template< class TagType >
661  inline
662  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
663  exec( reference_type update ) const
664  {
665  const TagType t{} ;
666  const typename Policy::member_type e = m_policy.end();
667  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
668  m_functor( t , i , update , true );
669  }
670  }
671 
672 public:
673 
674  inline
675  void execute() const
676  {
677  const size_t pool_reduce_size = Analysis::value_size( m_functor );
678  const size_t team_reduce_size = 0 ; // Never shrinks
679  const size_t team_shared_size = 0 ; // Never shrinks
680  const size_t thread_local_size = 0 ; // Never shrinks
681 
682  serial_resize_thread_team_data( pool_reduce_size
683  , team_reduce_size
684  , team_shared_size
685  , thread_local_size );
686 
687  HostThreadTeamData & data = *serial_get_thread_team_data();
688 
689  reference_type update =
690  ValueInit::init( m_functor , pointer_type(data.pool_reduce_local()) );
691 
692  this-> template exec< WorkTag >( update );
693  }
694 
695  inline
696  ParallelScan( const FunctorType & arg_functor
697  , const Policy & arg_policy
698  )
699  : m_functor( arg_functor )
700  , m_policy( arg_policy )
701  {}
702 };
703 
704 /*--------------------------------------------------------------------------*/
705 template< class FunctorType , class ReturnType, class ... Traits >
706 class ParallelScanWithTotal< FunctorType
707  , Kokkos::RangePolicy< Traits ... >
708  , ReturnType
709  , Kokkos::Serial
710  >
711 {
712 private:
713 
714  typedef Kokkos::RangePolicy< Traits ... > Policy ;
715  typedef typename Policy::work_tag WorkTag ;
716 
717  typedef FunctorAnalysis< FunctorPatternInterface::SCAN , Policy , FunctorType > Analysis ;
718 
719  typedef Kokkos::Impl::FunctorValueInit< FunctorType , WorkTag > ValueInit ;
720 
721  typedef typename Analysis::pointer_type pointer_type ;
722  typedef typename Analysis::reference_type reference_type ;
723 
724  const FunctorType m_functor ;
725  const Policy m_policy ;
726  ReturnType & m_returnvalue;
727 
728  template< class TagType >
729  inline
730  typename std::enable_if< std::is_same< TagType , void >::value >::type
731  exec( reference_type update ) const
732  {
733  const typename Policy::member_type e = m_policy.end();
734  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
735  m_functor( i , update , true );
736  }
737  }
738 
739  template< class TagType >
740  inline
741  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
742  exec( reference_type update ) const
743  {
744  const TagType t{} ;
745  const typename Policy::member_type e = m_policy.end();
746  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
747  m_functor( t , i , update , true );
748  }
749  }
750 
751 public:
752 
753  inline
754  void execute()
755  {
756  const size_t pool_reduce_size = Analysis::value_size( m_functor );
757  const size_t team_reduce_size = 0 ; // Never shrinks
758  const size_t team_shared_size = 0 ; // Never shrinks
759  const size_t thread_local_size = 0 ; // Never shrinks
760 
761  serial_resize_thread_team_data( pool_reduce_size
762  , team_reduce_size
763  , team_shared_size
764  , thread_local_size );
765 
766  HostThreadTeamData & data = *serial_get_thread_team_data();
767 
768  reference_type update =
769  ValueInit::init( m_functor , pointer_type(data.pool_reduce_local()) );
770 
771  this-> template exec< WorkTag >( update );
772 
773  m_returnvalue = update;
774  }
775 
776  inline
777  ParallelScanWithTotal( const FunctorType & arg_functor
778  , const Policy & arg_policy
779  , ReturnType & arg_returnvalue
780  )
781  : m_functor( arg_functor )
782  , m_policy( arg_policy )
783  , m_returnvalue( arg_returnvalue )
784  {}
785 };
786 
787 } // namespace Impl
788 } // namespace Kokkos
789 
790 
791 /*--------------------------------------------------------------------------*/
792 /*--------------------------------------------------------------------------*/
793 /* Parallel patterns for Kokkos::Serial with MDRangePolicy */
794 
795 namespace Kokkos {
796 namespace Impl {
797 
798 template< class FunctorType , class ... Traits >
799 class ParallelFor< FunctorType ,
800  Kokkos::MDRangePolicy< Traits ... > ,
801  Kokkos::Serial
802  >
803 {
804 private:
805 
806  typedef Kokkos::MDRangePolicy< Traits ... > MDRangePolicy ;
807  typedef typename MDRangePolicy::impl_range_policy Policy ;
808 
809  typedef typename Kokkos::Impl::HostIterateTile< MDRangePolicy, FunctorType, typename MDRangePolicy::work_tag, void > iterate_type;
810 
811  const FunctorType m_functor ;
812  const MDRangePolicy m_mdr_policy ;
813  const Policy m_policy ;
814 
815  void
816  exec() const
817  {
818  const typename Policy::member_type e = m_policy.end();
819  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
820  iterate_type( m_mdr_policy, m_functor )( i );
821  }
822  }
823 
824 public:
825 
826  inline
827  void execute() const
828  { this->exec(); }
829 
830  inline
831  ParallelFor( const FunctorType & arg_functor
832  , const MDRangePolicy & arg_policy )
833  : m_functor( arg_functor )
834  , m_mdr_policy( arg_policy )
835  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
836  {}
837 };
838 
839 
840 template< class FunctorType , class ReducerType , class ... Traits >
841 class ParallelReduce< FunctorType
842  , Kokkos::MDRangePolicy< Traits ... >
843  , ReducerType
844  , Kokkos::Serial
845  >
846 {
847 private:
848 
849  typedef Kokkos::MDRangePolicy< Traits ... > MDRangePolicy ;
850  typedef typename MDRangePolicy::impl_range_policy Policy ;
851 
852  typedef typename MDRangePolicy::work_tag WorkTag ;
853 
854  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
855  typedef typename ReducerConditional::type ReducerTypeFwd;
856  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
857 
858  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , MDRangePolicy , FunctorType > Analysis ;
859 
860  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
861 
862  typedef typename Analysis::pointer_type pointer_type ;
863  typedef typename Analysis::value_type value_type ;
864  typedef typename Analysis::reference_type reference_type ;
865 
866 
867  using iterate_type = typename Kokkos::Impl::HostIterateTile< MDRangePolicy
868  , FunctorType
869  , WorkTag
870  , reference_type
871  >;
872 
873 
874  const FunctorType m_functor ;
875  const MDRangePolicy m_mdr_policy ;
876  const Policy m_policy ;
877  const ReducerType m_reducer ;
878  const pointer_type m_result_ptr ;
879 
880  inline
881  void
882  exec( reference_type update ) const
883  {
884  const typename Policy::member_type e = m_policy.end();
885  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
886  iterate_type( m_mdr_policy, m_functor, update )( i );
887  }
888  }
889 
890 public:
891 
892  inline
893  void execute() const
894  {
895  const size_t pool_reduce_size =
896  Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) );
897  const size_t team_reduce_size = 0 ; // Never shrinks
898  const size_t team_shared_size = 0 ; // Never shrinks
899  const size_t thread_local_size = 0 ; // Never shrinks
900 
901  serial_resize_thread_team_data( pool_reduce_size
902  , team_reduce_size
903  , team_shared_size
904  , thread_local_size );
905 
906  HostThreadTeamData & data = *serial_get_thread_team_data();
907 
908  pointer_type ptr =
909  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
910 
911  reference_type update =
912  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
913 
914  this-> exec( update );
915 
916  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
917  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
918  }
919 
920  template< class HostViewType >
921  ParallelReduce( const FunctorType & arg_functor ,
922  const MDRangePolicy & arg_policy ,
923  const HostViewType & arg_result_view ,
924  typename std::enable_if<
925  Kokkos::is_view< HostViewType >::value &&
926  !Kokkos::is_reducer_type<ReducerType>::value
927  ,void*>::type = NULL)
928  : m_functor( arg_functor )
929  , m_mdr_policy( arg_policy )
930  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
931  , m_reducer( InvalidType() )
932  , m_result_ptr( arg_result_view.data() )
933  {
934  static_assert( Kokkos::is_view< HostViewType >::value
935  , "Kokkos::Serial reduce result must be a View" );
936 
937  static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value
938  , "Kokkos::Serial reduce result must be a View in HostSpace" );
939  }
940 
941  inline
942  ParallelReduce( const FunctorType & arg_functor
943  , MDRangePolicy arg_policy
944  , const ReducerType& reducer )
945  : m_functor( arg_functor )
946  , m_mdr_policy( arg_policy )
947  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
948  , m_reducer( reducer )
949  , m_result_ptr( reducer.view().data() )
950  {
951  /*static_assert( std::is_same< typename ViewType::memory_space
952  , Kokkos::HostSpace >::value
953  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
954  }
955 };
956 
957 
958 
959 } // namespace Impl
960 } // namespace Kokkos
961 
962 /*--------------------------------------------------------------------------*/
963 /*--------------------------------------------------------------------------*/
964 /* Parallel patterns for Kokkos::Serial with TeamPolicy */
965 
966 namespace Kokkos {
967 namespace Impl {
968 
969 template< class FunctorType , class ... Properties >
970 class ParallelFor< FunctorType
971  , Kokkos::TeamPolicy< Properties ... >
972  , Kokkos::Serial
973  >
974 {
975 private:
976 
977  enum { TEAM_REDUCE_SIZE = 512 };
978 
979  typedef TeamPolicyInternal< Kokkos::Serial , Properties ...> Policy ;
980  typedef typename Policy::member_type Member ;
981 
982  const FunctorType m_functor ;
983  const int m_league ;
984  const int m_shared ;
985 
986  template< class TagType >
987  inline
988  typename std::enable_if< std::is_same< TagType , void >::value >::type
989  exec( HostThreadTeamData & data ) const
990  {
991  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
992  m_functor( Member(data,ileague,m_league) );
993  }
994  }
995 
996  template< class TagType >
997  inline
998  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
999  exec( HostThreadTeamData & data ) const
1000  {
1001  const TagType t{} ;
1002  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
1003  m_functor( t , Member(data,ileague,m_league) );
1004  }
1005  }
1006 
1007 public:
1008 
1009  inline
1010  void execute() const
1011  {
1012  const size_t pool_reduce_size = 0 ; // Never shrinks
1013  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
1014  const size_t team_shared_size = m_shared ;
1015  const size_t thread_local_size = 0 ; // Never shrinks
1016 
1017  serial_resize_thread_team_data( pool_reduce_size
1018  , team_reduce_size
1019  , team_shared_size
1020  , thread_local_size );
1021 
1022  HostThreadTeamData & data = *serial_get_thread_team_data();
1023 
1024  this->template exec< typename Policy::work_tag >( data );
1025  }
1026 
1027  ParallelFor( const FunctorType & arg_functor
1028  , const Policy & arg_policy )
1029  : m_functor( arg_functor )
1030  , m_league( arg_policy.league_size() )
1031  , m_shared( arg_policy.scratch_size(0) +
1032  arg_policy.scratch_size(1) +
1033  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
1034  { }
1035 };
1036 
1037 /*--------------------------------------------------------------------------*/
1038 
1039 template< class FunctorType , class ReducerType , class ... Properties >
1040 class ParallelReduce< FunctorType
1041  , Kokkos::TeamPolicy< Properties ... >
1042  , ReducerType
1043  , Kokkos::Serial
1044  >
1045 {
1046 private:
1047 
1048  enum { TEAM_REDUCE_SIZE = 512 };
1049 
1050  typedef TeamPolicyInternal< Kokkos::Serial, Properties ... > Policy ;
1051 
1052  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
1053 
1054  typedef typename Policy::member_type Member ;
1055  typedef typename Policy::work_tag WorkTag ;
1056 
1057  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
1058  typedef typename ReducerConditional::type ReducerTypeFwd;
1059  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
1060 
1061  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
1062 
1063  typedef typename Analysis::pointer_type pointer_type ;
1064  typedef typename Analysis::reference_type reference_type ;
1065 
1066  const FunctorType m_functor ;
1067  const int m_league ;
1068  const ReducerType m_reducer ;
1069  pointer_type m_result_ptr ;
1070  const int m_shared ;
1071 
1072  template< class TagType >
1073  inline
1074  typename std::enable_if< std::is_same< TagType , void >::value >::type
1075  exec( HostThreadTeamData & data , reference_type update ) const
1076  {
1077  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
1078  m_functor( Member(data,ileague,m_league) , update );
1079  }
1080  }
1081 
1082  template< class TagType >
1083  inline
1084  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
1085  exec( HostThreadTeamData & data , reference_type update ) const
1086  {
1087  const TagType t{} ;
1088 
1089  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
1090  m_functor( t , Member(data,ileague,m_league) , update );
1091  }
1092  }
1093 
1094 public:
1095 
1096  inline
1097  void execute() const
1098  {
1099  const size_t pool_reduce_size =
1100  Analysis::value_size( ReducerConditional::select(m_functor, m_reducer));
1101 
1102  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
1103  const size_t team_shared_size = m_shared ;
1104  const size_t thread_local_size = 0 ; // Never shrinks
1105 
1106  serial_resize_thread_team_data( pool_reduce_size
1107  , team_reduce_size
1108  , team_shared_size
1109  , thread_local_size );
1110 
1111 
1112  HostThreadTeamData & data = *serial_get_thread_team_data();
1113 
1114  pointer_type ptr =
1115  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
1116 
1117  reference_type update =
1118  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
1119 
1120  this-> template exec< WorkTag >( data , update );
1121 
1122  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
1123  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
1124  }
1125 
1126  template< class ViewType >
1127  ParallelReduce( const FunctorType & arg_functor
1128  , const Policy & arg_policy
1129  , const ViewType & arg_result ,
1130  typename std::enable_if<
1131  Kokkos::is_view< ViewType >::value &&
1132  !Kokkos::is_reducer_type<ReducerType>::value
1133  ,void*>::type = NULL)
1134  : m_functor( arg_functor )
1135  , m_league( arg_policy.league_size() )
1136  , m_reducer( InvalidType() )
1137  , m_result_ptr( arg_result.data() )
1138  , m_shared( arg_policy.scratch_size(0) +
1139  arg_policy.scratch_size(1) +
1140  FunctorTeamShmemSize< FunctorType >::value( m_functor , 1 ) )
1141  {
1142  static_assert( Kokkos::is_view< ViewType >::value
1143  , "Reduction result on Kokkos::Serial must be a Kokkos::View" );
1144 
1145  static_assert( std::is_same< typename ViewType::memory_space
1146  , Kokkos::HostSpace >::value
1147  , "Reduction result on Kokkos::Serial must be a Kokkos::View in HostSpace" );
1148  }
1149 
1150  inline
1151  ParallelReduce( const FunctorType & arg_functor
1152  , Policy arg_policy
1153  , const ReducerType& reducer )
1154  : m_functor( arg_functor )
1155  , m_league( arg_policy.league_size() )
1156  , m_reducer( reducer )
1157  , m_result_ptr( reducer.view().data() )
1158  , m_shared( arg_policy.scratch_size(0) +
1159  arg_policy.scratch_size(1) +
1160  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
1161  {
1162  /*static_assert( std::is_same< typename ViewType::memory_space
1163  , Kokkos::HostSpace >::value
1164  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
1165  }
1166 
1167 };
1168 
1169 } // namespace Impl
1170 } // namespace Kokkos
1171 
1172 /*--------------------------------------------------------------------------*/
1173 /*--------------------------------------------------------------------------*/
1174 
1175 namespace Kokkos { namespace Experimental {
1176 
1177 template<>
1178 class UniqueToken< Serial, UniqueTokenScope::Instance>
1179 {
1180 public:
1181  using execution_space = Serial;
1182  using size_type = int;
1183 
1187  UniqueToken( execution_space const& = execution_space() ) noexcept {}
1188 
1190  KOKKOS_INLINE_FUNCTION
1191  int size() const noexcept { return 1; }
1192 
1194  KOKKOS_INLINE_FUNCTION
1195  int acquire() const noexcept { return 0; }
1196 
1198  KOKKOS_INLINE_FUNCTION
1199  void release( int ) const noexcept {}
1200 };
1201 
1202 template<>
1203 class UniqueToken< Serial, UniqueTokenScope::Global>
1204 {
1205 public:
1206  using execution_space = Serial;
1207  using size_type = int;
1208 
1212  UniqueToken( execution_space const& = execution_space() ) noexcept {}
1213 
1215  KOKKOS_INLINE_FUNCTION
1216  int size() const noexcept { return 1; }
1217 
1219  KOKKOS_INLINE_FUNCTION
1220  int acquire() const noexcept { return 0; }
1221 
1223  KOKKOS_INLINE_FUNCTION
1224  void release( int ) const noexcept {}
1225 };
1226 
1227 }} // namespace Kokkos::Experimental
1228 
1229 #include <impl/Kokkos_Serial_Task.hpp>
1230 
1231 #endif // defined( KOKKOS_ENABLE_SERIAL )
1232 #endif /* #define KOKKOS_SERIAL_HPP */
1233 
void print_configuration(std::ostream &, const bool detail=false)
Print &quot;Bill of Materials&quot;.
Memory management for host memory.
Declaration of various MemoryLayout options.
Declaration of parallel operators.
ReturnType
void finalize()
Finalize the spaces that were initialized via Kokkos::initialize.
Execution policy for work over a range of an integral type.