Kokkos Core Kernels Package  Version of the Day
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 
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 
278  //----------------------------------------
279 
280  inline int team_size() const { return 1 ; }
281  inline int league_size() const { return m_league_size ; }
282  inline size_t scratch_size(const int& level, int = 0) const { return m_team_scratch_size[level] + m_thread_scratch_size[level]; }
283 
285  TeamPolicyInternal( execution_space &
286  , int league_size_request
287 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
288  , int team_size_request
289 #else
290  , int /* team_size_request */
291 #endif
292  , int /* vector_length_request */ = 1 )
293  : m_team_scratch_size { 0 , 0 }
294  , m_thread_scratch_size { 0 , 0 }
295  , m_league_size( league_size_request )
296  , m_chunk_size ( 32 )
297  {
298  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
299  if(team_size_request > 1) Kokkos::abort("Kokkos::abort: Requested Team Size is too large!");
300  #endif
301  }
302 
303  TeamPolicyInternal( execution_space &
304  , int league_size_request
305  , const Kokkos::AUTO_t & /* team_size_request */
306  , int /* vector_length_request */ = 1 )
307  : m_team_scratch_size { 0 , 0 }
308  , m_thread_scratch_size { 0 , 0 }
309  , m_league_size( league_size_request )
310  , m_chunk_size ( 32 )
311  {}
312 
313  TeamPolicyInternal( int league_size_request
314 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
315  , int team_size_request
316 #else
317  , int /* team_size_request */
318 #endif
319  , int /* vector_length_request */ = 1 )
320  : m_team_scratch_size { 0 , 0 }
321  , m_thread_scratch_size { 0 , 0 }
322  , m_league_size( league_size_request )
323  , m_chunk_size ( 32 )
324  {
325  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
326  if(team_size_request > 1) Kokkos::abort("Kokkos::abort: Requested Team Size is too large!");
327  #endif
328  }
329 
330  TeamPolicyInternal( int league_size_request
331  , const Kokkos::AUTO_t & /* team_size_request */
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 
339  inline int chunk_size() const { return m_chunk_size ; }
340 
341 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
342 
343  inline TeamPolicyInternal set_chunk_size(typename traits::index_type chunk_size_) const {
344  TeamPolicyInternal p = *this;
345  p.m_chunk_size = chunk_size_;
346  return p;
347  }
348 
350  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team) const {
351  TeamPolicyInternal p = *this;
352  p.m_team_scratch_size[level] = per_team.value;
353  return p;
354  }
355 
357  inline TeamPolicyInternal set_scratch_size(const int& level, const PerThreadValue& per_thread) const {
358  TeamPolicyInternal p = *this;
359  p.m_thread_scratch_size[level] = per_thread.value;
360  return p;
361  }
362 
364  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) const {
365  TeamPolicyInternal p = *this;
366  p.m_team_scratch_size[level] = per_team.value;
367  p.m_thread_scratch_size[level] = per_thread.value;
368  return p;
369  }
370 #else
371 
372  inline TeamPolicyInternal& set_chunk_size(typename traits::index_type chunk_size_) {
373  m_chunk_size = chunk_size_;
374  return *this;
375  }
376 
378  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerTeamValue& per_team) {
379  m_team_scratch_size[level] = per_team.value;
380  return *this;
381  }
382 
384  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerThreadValue& per_thread) {
385  m_thread_scratch_size[level] = per_thread.value;
386  return *this;
387  }
388 
390  inline TeamPolicyInternal& set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) {
391  m_team_scratch_size[level] = per_team.value;
392  m_thread_scratch_size[level] = per_thread.value;
393  return *this;
394  }
395 #endif
396 
397  typedef Impl::HostThreadTeamMember< Kokkos::Serial > member_type ;
398 
399 protected:
400 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
401 
402  inline TeamPolicyInternal internal_set_chunk_size(typename traits::index_type chunk_size_) {
403  m_chunk_size = chunk_size_;
404  return *this;
405  }
406 
408  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerTeamValue& per_team) {
409  m_team_scratch_size[level] = per_team.value;
410  return *this;
411  }
412 
414  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerThreadValue& per_thread) {
415  m_thread_scratch_size[level] = per_thread.value;
416  return *this;
417  }
418 
420  inline TeamPolicyInternal internal_set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) {
421  m_team_scratch_size[level] = per_team.value;
422  m_thread_scratch_size[level] = per_thread.value;
423  return *this;
424  }
425 #endif
426 };
427 } /* namespace Impl */
428 } /* namespace Kokkos */
429 
430 /*--------------------------------------------------------------------------*/
431 /*--------------------------------------------------------------------------*/
432 /* Parallel patterns for Kokkos::Serial with RangePolicy */
433 
434 namespace Kokkos {
435 namespace Impl {
436 
437 template< class FunctorType , class ... Traits >
438 class ParallelFor< FunctorType ,
439  Kokkos::RangePolicy< Traits ... > ,
440  Kokkos::Serial
441  >
442 {
443 private:
444 
445  typedef Kokkos::RangePolicy< Traits ... > Policy ;
446 
447  const FunctorType m_functor ;
448  const Policy m_policy ;
449 
450  template< class TagType >
451  typename std::enable_if< std::is_same< TagType , void >::value >::type
452  exec() const
453  {
454  const typename Policy::member_type e = m_policy.end();
455  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
456  m_functor( i );
457  }
458  }
459 
460  template< class TagType >
461  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
462  exec() const
463  {
464  const TagType t{} ;
465  const typename Policy::member_type e = m_policy.end();
466  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
467  m_functor( t , i );
468  }
469  }
470 
471 public:
472 
473  inline
474  void execute() const
475  { this-> template exec< typename Policy::work_tag >(); }
476 
477  inline
478  ParallelFor( const FunctorType & arg_functor
479  , const Policy & arg_policy )
480  : m_functor( arg_functor )
481  , m_policy( arg_policy )
482  {}
483 };
484 
485 /*--------------------------------------------------------------------------*/
486 
487 template< class FunctorType , class ReducerType , class ... Traits >
488 class ParallelReduce< FunctorType
489  , Kokkos::RangePolicy< Traits ... >
490  , ReducerType
491  , Kokkos::Serial
492  >
493 {
494 private:
495 
496  typedef Kokkos::RangePolicy< Traits ... > Policy ;
497  typedef typename Policy::work_tag WorkTag ;
498 
499  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
500 
501  typedef typename ReducerConditional::type ReducerTypeFwd;
502  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
503 
504  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
505 
506  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
507 
508  typedef typename Analysis::pointer_type pointer_type ;
509  typedef typename Analysis::reference_type reference_type ;
510 
511  const FunctorType m_functor ;
512  const Policy m_policy ;
513  const ReducerType m_reducer ;
514  const pointer_type m_result_ptr ;
515 
516  template< class TagType >
517  inline
518  typename std::enable_if< std::is_same< TagType , void >::value >::type
519  exec( reference_type update ) const
520  {
521  const typename Policy::member_type e = m_policy.end();
522  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
523  m_functor( i , update );
524  }
525  }
526 
527  template< class TagType >
528  inline
529  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
530  exec( reference_type update ) const
531  {
532  const TagType t{} ;
533 
534  const typename Policy::member_type e = m_policy.end();
535  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
536  m_functor( t , i , update );
537  }
538  }
539 
540 public:
541 
542  inline
543  void execute() const
544  {
545  const size_t pool_reduce_size =
546  Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) );
547  const size_t team_reduce_size = 0 ; // Never shrinks
548  const size_t team_shared_size = 0 ; // Never shrinks
549  const size_t thread_local_size = 0 ; // Never shrinks
550 
551  serial_resize_thread_team_data( pool_reduce_size
552  , team_reduce_size
553  , team_shared_size
554  , thread_local_size );
555 
556  HostThreadTeamData & data = *serial_get_thread_team_data();
557 
558  pointer_type ptr =
559  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
560 
561  reference_type update =
562  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
563 
564  this-> template exec< WorkTag >( update );
565 
566  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
567  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
568  }
569 
570  template< class HostViewType >
571  ParallelReduce( const FunctorType & arg_functor ,
572  const Policy & arg_policy ,
573  const HostViewType & arg_result_view ,
574  typename std::enable_if<
575  Kokkos::is_view< HostViewType >::value &&
576  !Kokkos::is_reducer_type<ReducerType>::value
577  ,void*>::type = NULL)
578  : m_functor( arg_functor )
579  , m_policy( arg_policy )
580  , m_reducer( InvalidType() )
581  , m_result_ptr( arg_result_view.data() )
582  {
583  static_assert( Kokkos::is_view< HostViewType >::value
584  , "Kokkos::Serial reduce result must be a View" );
585 
586  static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value
587  , "Kokkos::Serial reduce result must be a View in HostSpace" );
588  }
589 
590  inline
591  ParallelReduce( const FunctorType & arg_functor
592  , Policy arg_policy
593  , const ReducerType& reducer )
594  : m_functor( arg_functor )
595  , m_policy( arg_policy )
596  , m_reducer( reducer )
597  , m_result_ptr( reducer.view().data() )
598  {
599  /*static_assert( std::is_same< typename ViewType::memory_space
600  , Kokkos::HostSpace >::value
601  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
602  }
603 };
604 
605 
606 /*--------------------------------------------------------------------------*/
607 
608 template< class FunctorType , class ... Traits >
609 class ParallelScan< FunctorType
610  , Kokkos::RangePolicy< Traits ... >
611  , Kokkos::Serial
612  >
613 {
614 private:
615 
616  typedef Kokkos::RangePolicy< Traits ... > Policy ;
617  typedef typename Policy::work_tag WorkTag ;
618 
619  typedef FunctorAnalysis< FunctorPatternInterface::SCAN , Policy , FunctorType > Analysis ;
620 
621  typedef Kokkos::Impl::FunctorValueInit< FunctorType , WorkTag > ValueInit ;
622 
623  typedef typename Analysis::pointer_type pointer_type ;
624  typedef typename Analysis::reference_type reference_type ;
625 
626  const FunctorType m_functor ;
627  const Policy m_policy ;
628 
629  template< class TagType >
630  inline
631  typename std::enable_if< std::is_same< TagType , void >::value >::type
632  exec( reference_type update ) const
633  {
634  const typename Policy::member_type e = m_policy.end();
635  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
636  m_functor( i , update , true );
637  }
638  }
639 
640  template< class TagType >
641  inline
642  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
643  exec( reference_type update ) const
644  {
645  const TagType t{} ;
646  const typename Policy::member_type e = m_policy.end();
647  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
648  m_functor( t , i , update , true );
649  }
650  }
651 
652 public:
653 
654  inline
655  void execute() const
656  {
657  const size_t pool_reduce_size = Analysis::value_size( m_functor );
658  const size_t team_reduce_size = 0 ; // Never shrinks
659  const size_t team_shared_size = 0 ; // Never shrinks
660  const size_t thread_local_size = 0 ; // Never shrinks
661 
662  serial_resize_thread_team_data( pool_reduce_size
663  , team_reduce_size
664  , team_shared_size
665  , thread_local_size );
666 
667  HostThreadTeamData & data = *serial_get_thread_team_data();
668 
669  reference_type update =
670  ValueInit::init( m_functor , pointer_type(data.pool_reduce_local()) );
671 
672  this-> template exec< WorkTag >( update );
673  }
674 
675  inline
676  ParallelScan( const FunctorType & arg_functor
677  , const Policy & arg_policy
678  )
679  : m_functor( arg_functor )
680  , m_policy( arg_policy )
681  {}
682 };
683 
684 /*--------------------------------------------------------------------------*/
685 template< class FunctorType , class ReturnType, class ... Traits >
686 class ParallelScanWithTotal< FunctorType
687  , Kokkos::RangePolicy< Traits ... >
688  , ReturnType
689  , Kokkos::Serial
690  >
691 {
692 private:
693 
694  typedef Kokkos::RangePolicy< Traits ... > Policy ;
695  typedef typename Policy::work_tag WorkTag ;
696 
697  typedef FunctorAnalysis< FunctorPatternInterface::SCAN , Policy , FunctorType > Analysis ;
698 
699  typedef Kokkos::Impl::FunctorValueInit< FunctorType , WorkTag > ValueInit ;
700 
701  typedef typename Analysis::pointer_type pointer_type ;
702  typedef typename Analysis::reference_type reference_type ;
703 
704  const FunctorType m_functor ;
705  const Policy m_policy ;
706  ReturnType & m_returnvalue;
707 
708  template< class TagType >
709  inline
710  typename std::enable_if< std::is_same< TagType , void >::value >::type
711  exec( reference_type update ) const
712  {
713  const typename Policy::member_type e = m_policy.end();
714  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
715  m_functor( i , update , true );
716  }
717  }
718 
719  template< class TagType >
720  inline
721  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
722  exec( reference_type update ) const
723  {
724  const TagType t{} ;
725  const typename Policy::member_type e = m_policy.end();
726  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
727  m_functor( t , i , update , true );
728  }
729  }
730 
731 public:
732 
733  inline
734  void execute()
735  {
736  const size_t pool_reduce_size = Analysis::value_size( m_functor );
737  const size_t team_reduce_size = 0 ; // Never shrinks
738  const size_t team_shared_size = 0 ; // Never shrinks
739  const size_t thread_local_size = 0 ; // Never shrinks
740 
741  serial_resize_thread_team_data( pool_reduce_size
742  , team_reduce_size
743  , team_shared_size
744  , thread_local_size );
745 
746  HostThreadTeamData & data = *serial_get_thread_team_data();
747 
748  reference_type update =
749  ValueInit::init( m_functor , pointer_type(data.pool_reduce_local()) );
750 
751  this-> template exec< WorkTag >( update );
752 
753  m_returnvalue = update;
754  }
755 
756  inline
757  ParallelScanWithTotal( const FunctorType & arg_functor
758  , const Policy & arg_policy
759  , ReturnType & arg_returnvalue
760  )
761  : m_functor( arg_functor )
762  , m_policy( arg_policy )
763  , m_returnvalue( arg_returnvalue )
764  {}
765 };
766 
767 } // namespace Impl
768 } // namespace Kokkos
769 
770 
771 /*--------------------------------------------------------------------------*/
772 /*--------------------------------------------------------------------------*/
773 /* Parallel patterns for Kokkos::Serial with MDRangePolicy */
774 
775 namespace Kokkos {
776 namespace Impl {
777 
778 template< class FunctorType , class ... Traits >
779 class ParallelFor< FunctorType ,
780  Kokkos::MDRangePolicy< Traits ... > ,
781  Kokkos::Serial
782  >
783 {
784 private:
785 
786  typedef Kokkos::MDRangePolicy< Traits ... > MDRangePolicy ;
787  typedef typename MDRangePolicy::impl_range_policy Policy ;
788 
789  typedef typename Kokkos::Impl::HostIterateTile< MDRangePolicy, FunctorType, typename MDRangePolicy::work_tag, void > iterate_type;
790 
791  const FunctorType m_functor ;
792  const MDRangePolicy m_mdr_policy ;
793  const Policy m_policy ;
794 
795  void
796  exec() const
797  {
798  const typename Policy::member_type e = m_policy.end();
799  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
800  iterate_type( m_mdr_policy, m_functor )( i );
801  }
802  }
803 
804 public:
805 
806  inline
807  void execute() const
808  { this->exec(); }
809 
810  inline
811  ParallelFor( const FunctorType & arg_functor
812  , const MDRangePolicy & arg_policy )
813  : m_functor( arg_functor )
814  , m_mdr_policy( arg_policy )
815  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
816  {}
817 };
818 
819 
820 template< class FunctorType , class ReducerType , class ... Traits >
821 class ParallelReduce< FunctorType
822  , Kokkos::MDRangePolicy< Traits ... >
823  , ReducerType
824  , Kokkos::Serial
825  >
826 {
827 private:
828 
829  typedef Kokkos::MDRangePolicy< Traits ... > MDRangePolicy ;
830  typedef typename MDRangePolicy::impl_range_policy Policy ;
831 
832  typedef typename MDRangePolicy::work_tag WorkTag ;
833 
834  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
835  typedef typename ReducerConditional::type ReducerTypeFwd;
836  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
837 
838  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , MDRangePolicy , FunctorType > Analysis ;
839 
840  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
841 
842  typedef typename Analysis::pointer_type pointer_type ;
843  typedef typename Analysis::value_type value_type ;
844  typedef typename Analysis::reference_type reference_type ;
845 
846 
847  using iterate_type = typename Kokkos::Impl::HostIterateTile< MDRangePolicy
848  , FunctorType
849  , WorkTag
850  , reference_type
851  >;
852 
853 
854  const FunctorType m_functor ;
855  const MDRangePolicy m_mdr_policy ;
856  const Policy m_policy ;
857  const ReducerType m_reducer ;
858  const pointer_type m_result_ptr ;
859 
860  inline
861  void
862  exec( reference_type update ) const
863  {
864  const typename Policy::member_type e = m_policy.end();
865  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
866  iterate_type( m_mdr_policy, m_functor, update )( i );
867  }
868  }
869 
870 public:
871 
872  inline
873  void execute() const
874  {
875  const size_t pool_reduce_size =
876  Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) );
877  const size_t team_reduce_size = 0 ; // Never shrinks
878  const size_t team_shared_size = 0 ; // Never shrinks
879  const size_t thread_local_size = 0 ; // Never shrinks
880 
881  serial_resize_thread_team_data( pool_reduce_size
882  , team_reduce_size
883  , team_shared_size
884  , thread_local_size );
885 
886  HostThreadTeamData & data = *serial_get_thread_team_data();
887 
888  pointer_type ptr =
889  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
890 
891  reference_type update =
892  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
893 
894  this-> exec( update );
895 
896  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
897  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
898  }
899 
900  template< class HostViewType >
901  ParallelReduce( const FunctorType & arg_functor ,
902  const MDRangePolicy & arg_policy ,
903  const HostViewType & arg_result_view ,
904  typename std::enable_if<
905  Kokkos::is_view< HostViewType >::value &&
906  !Kokkos::is_reducer_type<ReducerType>::value
907  ,void*>::type = NULL)
908  : m_functor( arg_functor )
909  , m_mdr_policy( arg_policy )
910  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
911  , m_reducer( InvalidType() )
912  , m_result_ptr( arg_result_view.data() )
913  {
914  static_assert( Kokkos::is_view< HostViewType >::value
915  , "Kokkos::Serial reduce result must be a View" );
916 
917  static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value
918  , "Kokkos::Serial reduce result must be a View in HostSpace" );
919  }
920 
921  inline
922  ParallelReduce( const FunctorType & arg_functor
923  , MDRangePolicy arg_policy
924  , const ReducerType& reducer )
925  : m_functor( arg_functor )
926  , m_mdr_policy( arg_policy )
927  , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) )
928  , m_reducer( reducer )
929  , m_result_ptr( reducer.view().data() )
930  {
931  /*static_assert( std::is_same< typename ViewType::memory_space
932  , Kokkos::HostSpace >::value
933  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
934  }
935 };
936 
937 
938 
939 } // namespace Impl
940 } // namespace Kokkos
941 
942 /*--------------------------------------------------------------------------*/
943 /*--------------------------------------------------------------------------*/
944 /* Parallel patterns for Kokkos::Serial with TeamPolicy */
945 
946 namespace Kokkos {
947 namespace Impl {
948 
949 template< class FunctorType , class ... Properties >
950 class ParallelFor< FunctorType
951  , Kokkos::TeamPolicy< Properties ... >
952  , Kokkos::Serial
953  >
954 {
955 private:
956 
957  enum { TEAM_REDUCE_SIZE = 512 };
958 
959  typedef TeamPolicyInternal< Kokkos::Serial , Properties ...> Policy ;
960  typedef typename Policy::member_type Member ;
961 
962  const FunctorType m_functor ;
963  const int m_league ;
964  const int m_shared ;
965 
966  template< class TagType >
967  inline
968  typename std::enable_if< std::is_same< TagType , void >::value >::type
969  exec( HostThreadTeamData & data ) const
970  {
971  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
972  m_functor( Member(data,ileague,m_league) );
973  }
974  }
975 
976  template< class TagType >
977  inline
978  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
979  exec( HostThreadTeamData & data ) const
980  {
981  const TagType t{} ;
982  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
983  m_functor( t , Member(data,ileague,m_league) );
984  }
985  }
986 
987 public:
988 
989  inline
990  void execute() const
991  {
992  const size_t pool_reduce_size = 0 ; // Never shrinks
993  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
994  const size_t team_shared_size = m_shared ;
995  const size_t thread_local_size = 0 ; // Never shrinks
996 
997  serial_resize_thread_team_data( pool_reduce_size
998  , team_reduce_size
999  , team_shared_size
1000  , thread_local_size );
1001 
1002  HostThreadTeamData & data = *serial_get_thread_team_data();
1003 
1004  this->template exec< typename Policy::work_tag >( data );
1005  }
1006 
1007  ParallelFor( const FunctorType & arg_functor
1008  , const Policy & arg_policy )
1009  : m_functor( arg_functor )
1010  , m_league( arg_policy.league_size() )
1011  , m_shared( arg_policy.scratch_size(0) +
1012  arg_policy.scratch_size(1) +
1013  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
1014  { }
1015 };
1016 
1017 /*--------------------------------------------------------------------------*/
1018 
1019 template< class FunctorType , class ReducerType , class ... Properties >
1020 class ParallelReduce< FunctorType
1021  , Kokkos::TeamPolicy< Properties ... >
1022  , ReducerType
1023  , Kokkos::Serial
1024  >
1025 {
1026 private:
1027 
1028  enum { TEAM_REDUCE_SIZE = 512 };
1029 
1030  typedef TeamPolicyInternal< Kokkos::Serial, Properties ... > Policy ;
1031 
1032  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
1033 
1034  typedef typename Policy::member_type Member ;
1035  typedef typename Policy::work_tag WorkTag ;
1036 
1037  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
1038  typedef typename ReducerConditional::type ReducerTypeFwd;
1039  typedef typename Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, WorkTag, void>::type WorkTagFwd;
1040 
1041  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTagFwd > ValueInit ;
1042 
1043  typedef typename Analysis::pointer_type pointer_type ;
1044  typedef typename Analysis::reference_type reference_type ;
1045 
1046  const FunctorType m_functor ;
1047  const int m_league ;
1048  const ReducerType m_reducer ;
1049  pointer_type m_result_ptr ;
1050  const int m_shared ;
1051 
1052  template< class TagType >
1053  inline
1054  typename std::enable_if< std::is_same< TagType , void >::value >::type
1055  exec( HostThreadTeamData & data , reference_type update ) const
1056  {
1057  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
1058  m_functor( Member(data,ileague,m_league) , update );
1059  }
1060  }
1061 
1062  template< class TagType >
1063  inline
1064  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
1065  exec( HostThreadTeamData & data , reference_type update ) const
1066  {
1067  const TagType t{} ;
1068 
1069  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
1070  m_functor( t , Member(data,ileague,m_league) , update );
1071  }
1072  }
1073 
1074 public:
1075 
1076  inline
1077  void execute() const
1078  {
1079  const size_t pool_reduce_size =
1080  Analysis::value_size( ReducerConditional::select(m_functor, m_reducer));
1081 
1082  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
1083  const size_t team_shared_size = m_shared ;
1084  const size_t thread_local_size = 0 ; // Never shrinks
1085 
1086  serial_resize_thread_team_data( pool_reduce_size
1087  , team_reduce_size
1088  , team_shared_size
1089  , thread_local_size );
1090 
1091 
1092  HostThreadTeamData & data = *serial_get_thread_team_data();
1093 
1094  pointer_type ptr =
1095  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
1096 
1097  reference_type update =
1098  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
1099 
1100  this-> template exec< WorkTag >( data , update );
1101 
1102  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTagFwd >::
1103  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
1104  }
1105 
1106  template< class ViewType >
1107  ParallelReduce( const FunctorType & arg_functor
1108  , const Policy & arg_policy
1109  , const ViewType & arg_result ,
1110  typename std::enable_if<
1111  Kokkos::is_view< ViewType >::value &&
1112  !Kokkos::is_reducer_type<ReducerType>::value
1113  ,void*>::type = NULL)
1114  : m_functor( arg_functor )
1115  , m_league( arg_policy.league_size() )
1116  , m_reducer( InvalidType() )
1117  , m_result_ptr( arg_result.data() )
1118  , m_shared( arg_policy.scratch_size(0) +
1119  arg_policy.scratch_size(1) +
1120  FunctorTeamShmemSize< FunctorType >::value( m_functor , 1 ) )
1121  {
1122  static_assert( Kokkos::is_view< ViewType >::value
1123  , "Reduction result on Kokkos::Serial must be a Kokkos::View" );
1124 
1125  static_assert( std::is_same< typename ViewType::memory_space
1126  , Kokkos::HostSpace >::value
1127  , "Reduction result on Kokkos::Serial must be a Kokkos::View in HostSpace" );
1128  }
1129 
1130  inline
1131  ParallelReduce( const FunctorType & arg_functor
1132  , Policy arg_policy
1133  , const ReducerType& reducer )
1134  : m_functor( arg_functor )
1135  , m_league( arg_policy.league_size() )
1136  , m_reducer( reducer )
1137  , m_result_ptr( reducer.view().data() )
1138  , m_shared( arg_policy.scratch_size(0) +
1139  arg_policy.scratch_size(1) +
1140  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
1141  {
1142  /*static_assert( std::is_same< typename ViewType::memory_space
1143  , Kokkos::HostSpace >::value
1144  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
1145  }
1146 
1147 };
1148 
1149 } // namespace Impl
1150 } // namespace Kokkos
1151 
1152 /*--------------------------------------------------------------------------*/
1153 /*--------------------------------------------------------------------------*/
1154 
1155 namespace Kokkos { namespace Experimental {
1156 
1157 template<>
1158 class UniqueToken< Serial, UniqueTokenScope::Instance>
1159 {
1160 public:
1161  using execution_space = Serial;
1162  using size_type = int;
1163 
1167  UniqueToken( execution_space const& = execution_space() ) noexcept {}
1168 
1170  KOKKOS_INLINE_FUNCTION
1171  int size() const noexcept { return 1; }
1172 
1174  KOKKOS_INLINE_FUNCTION
1175  int acquire() const noexcept { return 0; }
1176 
1178  KOKKOS_INLINE_FUNCTION
1179  void release( int ) const noexcept {}
1180 };
1181 
1182 template<>
1183 class UniqueToken< Serial, UniqueTokenScope::Global>
1184 {
1185 public:
1186  using execution_space = Serial;
1187  using size_type = int;
1188 
1192  UniqueToken( execution_space const& = execution_space() ) noexcept {}
1193 
1195  KOKKOS_INLINE_FUNCTION
1196  int size() const noexcept { return 1; }
1197 
1199  KOKKOS_INLINE_FUNCTION
1200  int acquire() const noexcept { return 0; }
1201 
1203  KOKKOS_INLINE_FUNCTION
1204  void release( int ) const noexcept {}
1205 };
1206 
1207 }} // namespace Kokkos::Experimental
1208 
1209 #include <impl/Kokkos_Serial_Task.hpp>
1210 
1211 #endif // defined( KOKKOS_ENABLE_SERIAL )
1212 #endif /* #define KOKKOS_SERIAL_HPP */
1213 
void print_configuration(std::ostream &, const bool detail=false)
Print "Bill of Materials".
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.
void update(double alpha, const BlockedMultiVector &x, double beta, BlockedMultiVector &y)
Execution policy for work over a range of an integral type.