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