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 H. Carter Edwards (hcedwar@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 
70 namespace Kokkos {
71 
84 class Serial {
85 public:
87 
88 
90  typedef Serial execution_space ;
92  typedef HostSpace::size_type size_type ;
94  typedef HostSpace memory_space ;
97 
99  typedef LayoutRight array_layout ;
100 
102  typedef ScratchMemorySpace< Kokkos::Serial > scratch_memory_space ;
103 
105 
112  inline static int in_parallel() { return false ; }
113 
125  static bool sleep();
126 
132  static bool wake();
133 
140  static void fence() {}
141 
142  static void initialize( unsigned threads_count = 1 ,
143  unsigned use_numa_count = 0 ,
144  unsigned use_cores_per_numa = 0 ,
145  bool allow_asynchronous_threadpool = false);
146 
147  static int is_initialized();
148 
150  static int concurrency() {return 1;};
151 
153  static void finalize();
154 
156  static void print_configuration( std::ostream & , const bool /* detail */ = false ) {}
157 
158  //--------------------------------------------------------------------------
159 
160  inline static int thread_pool_size( int = 0 ) { return 1 ; }
161  KOKKOS_INLINE_FUNCTION static int thread_pool_rank() { return 0 ; }
162 
163  //--------------------------------------------------------------------------
164 
165  KOKKOS_INLINE_FUNCTION static unsigned hardware_thread_id() { return thread_pool_rank(); }
166  inline static unsigned max_hardware_threads() { return thread_pool_size(0); }
167 
168  static const char* name();
169  //--------------------------------------------------------------------------
170 };
171 
172 } // namespace Kokkos
173 
174 /*--------------------------------------------------------------------------*/
175 /*--------------------------------------------------------------------------*/
176 
177 namespace Kokkos {
178 namespace Impl {
179 
180 template<>
181 struct MemorySpaceAccess
182  < Kokkos::Serial::memory_space
183  , Kokkos::Serial::scratch_memory_space
184  >
185 {
186  enum { assignable = false };
187  enum { accessible = true };
188  enum { deepcopy = false };
189 };
190 
191 template<>
192 struct VerifyExecutionCanAccessMemorySpace
193  < Kokkos::Serial::memory_space
194  , Kokkos::Serial::scratch_memory_space
195  >
196 {
197  enum { value = true };
198  inline static void verify( void ) { }
199  inline static void verify( const void * ) { }
200 };
201 
202 } // namespace Impl
203 } // namespace Kokkos
204 
205 /*--------------------------------------------------------------------------*/
206 /*--------------------------------------------------------------------------*/
207 
208 namespace Kokkos {
209 namespace Impl {
210 
211 // Resize thread team data scratch memory
212 void serial_resize_thread_team_data( size_t pool_reduce_bytes
213  , size_t team_reduce_bytes
214  , size_t team_shared_bytes
215  , size_t thread_local_bytes );
216 
217 HostThreadTeamData * serial_get_thread_team_data();
218 
219 } /* namespace Impl */
220 } /* namespace Kokkos */
221 
222 
223 namespace Kokkos {
224 namespace Impl {
225 
226 /*
227  * < Kokkos::Serial , WorkArgTag >
228  * < WorkArgTag , Impl::enable_if< std::is_same< Kokkos::Serial , Kokkos::DefaultExecutionSpace >::value >::type >
229  *
230  */
231 template< class ... Properties >
232 class TeamPolicyInternal< Kokkos::Serial , Properties ... >:public PolicyTraits<Properties...>
233 {
234 private:
235 
236  size_t m_team_scratch_size[2] ;
237  size_t m_thread_scratch_size[2] ;
238  int m_league_size ;
239  int m_chunk_size;
240 
241 public:
242 
244  typedef TeamPolicyInternal execution_policy ;
245 
246  typedef PolicyTraits<Properties ... > traits;
247 
249  typedef Kokkos::Serial execution_space ;
250 
251  TeamPolicyInternal& operator = (const TeamPolicyInternal& p) {
252  m_league_size = p.m_league_size;
253  m_team_scratch_size[0] = p.m_team_scratch_size[0];
254  m_thread_scratch_size[0] = p.m_thread_scratch_size[0];
255  m_team_scratch_size[1] = p.m_team_scratch_size[1];
256  m_thread_scratch_size[1] = p.m_thread_scratch_size[1];
257  m_chunk_size = p.m_chunk_size;
258  return *this;
259  }
260 
261  //----------------------------------------
262 
263  template< class FunctorType >
264  static
265  int team_size_max( const FunctorType & ) { return 1 ; }
266 
267  template< class FunctorType >
268  static
269  int team_size_recommended( const FunctorType & ) { return 1 ; }
270 
271  template< class FunctorType >
272  static
273  int team_size_recommended( const FunctorType & , const int& ) { return 1 ; }
274 
275  //----------------------------------------
276 
277  inline int team_size() const { return 1 ; }
278  inline int league_size() const { return m_league_size ; }
279  inline size_t scratch_size(const int& level, int = 0) const { return m_team_scratch_size[level] + m_thread_scratch_size[level]; }
280 
282  TeamPolicyInternal( execution_space &
283  , int league_size_request
284  , int /* team_size_request */
285  , int /* vector_length_request */ = 1 )
286  : m_team_scratch_size { 0 , 0 }
287  , m_thread_scratch_size { 0 , 0 }
288  , m_league_size( league_size_request )
289  , m_chunk_size ( 32 )
290  {}
291 
292  TeamPolicyInternal( execution_space &
293  , int league_size_request
294  , const Kokkos::AUTO_t & /* team_size_request */
295  , int /* vector_length_request */ = 1 )
296  : m_team_scratch_size { 0 , 0 }
297  , m_thread_scratch_size { 0 , 0 }
298  , m_league_size( league_size_request )
299  , m_chunk_size ( 32 )
300  {}
301 
302  TeamPolicyInternal( int league_size_request
303  , int /* team_size_request */
304  , int /* vector_length_request */ = 1 )
305  : m_team_scratch_size { 0 , 0 }
306  , m_thread_scratch_size { 0 , 0 }
307  , m_league_size( league_size_request )
308  , m_chunk_size ( 32 )
309  {}
310 
311  TeamPolicyInternal( int league_size_request
312  , const Kokkos::AUTO_t & /* team_size_request */
313  , int /* vector_length_request */ = 1 )
314  : m_team_scratch_size { 0 , 0 }
315  , m_thread_scratch_size { 0 , 0 }
316  , m_league_size( league_size_request )
317  , m_chunk_size ( 32 )
318  {}
319 
320  inline int chunk_size() const { return m_chunk_size ; }
321 
323  inline TeamPolicyInternal set_chunk_size(typename traits::index_type chunk_size_) const {
324  TeamPolicyInternal p = *this;
325  p.m_chunk_size = chunk_size_;
326  return p;
327  }
328 
330  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team) const {
331  TeamPolicyInternal p = *this;
332  p.m_team_scratch_size[level] = per_team.value;
333  return p;
334  };
335 
337  inline TeamPolicyInternal set_scratch_size(const int& level, const PerThreadValue& per_thread) const {
338  TeamPolicyInternal p = *this;
339  p.m_thread_scratch_size[level] = per_thread.value;
340  return p;
341  };
342 
344  inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) const {
345  TeamPolicyInternal p = *this;
346  p.m_team_scratch_size[level] = per_team.value;
347  p.m_thread_scratch_size[level] = per_thread.value;
348  return p;
349  };
350 
351  typedef Impl::HostThreadTeamMember< Kokkos::Serial > member_type ;
352 };
353 } /* namespace Impl */
354 } /* namespace Kokkos */
355 
356 /*--------------------------------------------------------------------------*/
357 /*--------------------------------------------------------------------------*/
358 /* Parallel patterns for Kokkos::Serial with RangePolicy */
359 
360 namespace Kokkos {
361 namespace Impl {
362 
363 template< class FunctorType , class ... Traits >
364 class ParallelFor< FunctorType ,
365  Kokkos::RangePolicy< Traits ... > ,
366  Kokkos::Serial
367  >
368 {
369 private:
370 
371  typedef Kokkos::RangePolicy< Traits ... > Policy ;
372 
373  const FunctorType m_functor ;
374  const Policy m_policy ;
375 
376  template< class TagType >
377  typename std::enable_if< std::is_same< TagType , void >::value >::type
378  exec() const
379  {
380  const typename Policy::member_type e = m_policy.end();
381  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
382  m_functor( i );
383  }
384  }
385 
386  template< class TagType >
387  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
388  exec() const
389  {
390  const TagType t{} ;
391  const typename Policy::member_type e = m_policy.end();
392  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
393  m_functor( t , i );
394  }
395  }
396 
397 public:
398 
399  inline
400  void execute() const
401  { this-> template exec< typename Policy::work_tag >(); }
402 
403  inline
404  ParallelFor( const FunctorType & arg_functor
405  , const Policy & arg_policy )
406  : m_functor( arg_functor )
407  , m_policy( arg_policy )
408  {}
409 };
410 
411 /*--------------------------------------------------------------------------*/
412 
413 template< class FunctorType , class ReducerType , class ... Traits >
414 class ParallelReduce< FunctorType
415  , Kokkos::RangePolicy< Traits ... >
416  , ReducerType
417  , Kokkos::Serial
418  >
419 {
420 private:
421 
422  typedef Kokkos::RangePolicy< Traits ... > Policy ;
423  typedef typename Policy::work_tag WorkTag ;
424 
425  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
426  typedef typename ReducerConditional::type ReducerTypeFwd;
427 
428  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
429 
430  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTag > ValueInit ;
431 
432  typedef typename Analysis::pointer_type pointer_type ;
433  typedef typename Analysis::reference_type reference_type ;
434 
435  const FunctorType m_functor ;
436  const Policy m_policy ;
437  const ReducerType m_reducer ;
438  const pointer_type m_result_ptr ;
439 
440  template< class TagType >
441  inline
442  typename std::enable_if< std::is_same< TagType , void >::value >::type
443  exec( reference_type update ) const
444  {
445  const typename Policy::member_type e = m_policy.end();
446  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
447  m_functor( i , update );
448  }
449  }
450 
451  template< class TagType >
452  inline
453  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
454  exec( reference_type update ) const
455  {
456  const TagType t{} ;
457 
458  const typename Policy::member_type e = m_policy.end();
459  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
460  m_functor( t , i , update );
461  }
462  }
463 
464 public:
465 
466  inline
467  void execute() const
468  {
469  const size_t pool_reduce_size =
470  Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) );
471  const size_t team_reduce_size = 0 ; // Never shrinks
472  const size_t team_shared_size = 0 ; // Never shrinks
473  const size_t thread_local_size = 0 ; // Never shrinks
474 
475  serial_resize_thread_team_data( pool_reduce_size
476  , team_reduce_size
477  , team_shared_size
478  , thread_local_size );
479 
480  HostThreadTeamData & data = *serial_get_thread_team_data();
481 
482  pointer_type ptr =
483  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
484 
485  reference_type update =
486  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
487 
488  this-> template exec< WorkTag >( update );
489 
490  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::
491  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
492  }
493 
494  template< class HostViewType >
495  ParallelReduce( const FunctorType & arg_functor ,
496  const Policy & arg_policy ,
497  const HostViewType & arg_result_view ,
498  typename std::enable_if<
499  Kokkos::is_view< HostViewType >::value &&
500  !Kokkos::is_reducer_type<ReducerType>::value
501  ,void*>::type = NULL)
502  : m_functor( arg_functor )
503  , m_policy( arg_policy )
504  , m_reducer( InvalidType() )
505  , m_result_ptr( arg_result_view.data() )
506  {
507  static_assert( Kokkos::is_view< HostViewType >::value
508  , "Kokkos::Serial reduce result must be a View" );
509 
510  static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value
511  , "Kokkos::Serial reduce result must be a View in HostSpace" );
512  }
513 
514  inline
515  ParallelReduce( const FunctorType & arg_functor
516  , Policy arg_policy
517  , const ReducerType& reducer )
518  : m_functor( arg_functor )
519  , m_policy( arg_policy )
520  , m_reducer( reducer )
521  , m_result_ptr( reducer.view().data() )
522  {
523  /*static_assert( std::is_same< typename ViewType::memory_space
524  , Kokkos::HostSpace >::value
525  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
526  }
527 };
528 
529 /*--------------------------------------------------------------------------*/
530 
531 template< class FunctorType , class ... Traits >
532 class ParallelScan< FunctorType
533  , Kokkos::RangePolicy< Traits ... >
534  , Kokkos::Serial
535  >
536 {
537 private:
538 
539  typedef Kokkos::RangePolicy< Traits ... > Policy ;
540  typedef typename Policy::work_tag WorkTag ;
541 
542  typedef FunctorAnalysis< FunctorPatternInterface::SCAN , Policy , FunctorType > Analysis ;
543 
544  typedef Kokkos::Impl::FunctorValueInit< FunctorType , WorkTag > ValueInit ;
545 
546  typedef typename Analysis::pointer_type pointer_type ;
547  typedef typename Analysis::reference_type reference_type ;
548 
549  const FunctorType m_functor ;
550  const Policy m_policy ;
551 
552  template< class TagType >
553  inline
554  typename std::enable_if< std::is_same< TagType , void >::value >::type
555  exec( reference_type update ) const
556  {
557  const typename Policy::member_type e = m_policy.end();
558  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
559  m_functor( i , update , true );
560  }
561  }
562 
563  template< class TagType >
564  inline
565  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
566  exec( reference_type update ) const
567  {
568  const TagType t{} ;
569  const typename Policy::member_type e = m_policy.end();
570  for ( typename Policy::member_type i = m_policy.begin() ; i < e ; ++i ) {
571  m_functor( t , i , update , true );
572  }
573  }
574 
575 public:
576 
577  inline
578  void execute() const
579  {
580  const size_t pool_reduce_size = Analysis::value_size( m_functor );
581  const size_t team_reduce_size = 0 ; // Never shrinks
582  const size_t team_shared_size = 0 ; // Never shrinks
583  const size_t thread_local_size = 0 ; // Never shrinks
584 
585  serial_resize_thread_team_data( pool_reduce_size
586  , team_reduce_size
587  , team_shared_size
588  , thread_local_size );
589 
590  HostThreadTeamData & data = *serial_get_thread_team_data();
591 
592  reference_type update =
593  ValueInit::init( m_functor , pointer_type(data.pool_reduce_local()) );
594 
595  this-> template exec< WorkTag >( update );
596  }
597 
598  inline
599  ParallelScan( const FunctorType & arg_functor
600  , const Policy & arg_policy
601  )
602  : m_functor( arg_functor )
603  , m_policy( arg_policy )
604  {}
605 };
606 
607 } // namespace Impl
608 } // namespace Kokkos
609 
610 /*--------------------------------------------------------------------------*/
611 /*--------------------------------------------------------------------------*/
612 /* Parallel patterns for Kokkos::Serial with TeamPolicy */
613 
614 namespace Kokkos {
615 namespace Impl {
616 
617 template< class FunctorType , class ... Properties >
618 class ParallelFor< FunctorType
619  , Kokkos::TeamPolicy< Properties ... >
620  , Kokkos::Serial
621  >
622 {
623 private:
624 
625  enum { TEAM_REDUCE_SIZE = 512 };
626 
627  typedef TeamPolicyInternal< Kokkos::Serial , Properties ...> Policy ;
628  typedef typename Policy::member_type Member ;
629 
630  const FunctorType m_functor ;
631  const int m_league ;
632  const int m_shared ;
633 
634  template< class TagType >
635  inline
636  typename std::enable_if< std::is_same< TagType , void >::value >::type
637  exec( HostThreadTeamData & data ) const
638  {
639  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
640  m_functor( Member(data,ileague,m_league) );
641  }
642  }
643 
644  template< class TagType >
645  inline
646  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
647  exec( HostThreadTeamData & data ) const
648  {
649  const TagType t{} ;
650  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
651  m_functor( t , Member(data,ileague,m_league) );
652  }
653  }
654 
655 public:
656 
657  inline
658  void execute() const
659  {
660  const size_t pool_reduce_size = 0 ; // Never shrinks
661  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
662  const size_t team_shared_size = m_shared ;
663  const size_t thread_local_size = 0 ; // Never shrinks
664 
665  serial_resize_thread_team_data( pool_reduce_size
666  , team_reduce_size
667  , team_shared_size
668  , thread_local_size );
669 
670  HostThreadTeamData & data = *serial_get_thread_team_data();
671 
672  this->template exec< typename Policy::work_tag >( data );
673  }
674 
675  ParallelFor( const FunctorType & arg_functor
676  , const Policy & arg_policy )
677  : m_functor( arg_functor )
678  , m_league( arg_policy.league_size() )
679  , m_shared( arg_policy.scratch_size(0) +
680  arg_policy.scratch_size(1) +
681  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
682  { }
683 };
684 
685 /*--------------------------------------------------------------------------*/
686 
687 template< class FunctorType , class ReducerType , class ... Properties >
688 class ParallelReduce< FunctorType
689  , Kokkos::TeamPolicy< Properties ... >
690  , ReducerType
691  , Kokkos::Serial
692  >
693 {
694 private:
695 
696  enum { TEAM_REDUCE_SIZE = 512 };
697 
698  typedef TeamPolicyInternal< Kokkos::Serial, Properties ... > Policy ;
699 
700  typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ;
701 
702  typedef typename Policy::member_type Member ;
703  typedef typename Policy::work_tag WorkTag ;
704 
705  typedef Kokkos::Impl::if_c< std::is_same<InvalidType,ReducerType>::value, FunctorType, ReducerType> ReducerConditional;
706  typedef typename ReducerConditional::type ReducerTypeFwd;
707 
708  typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTag > ValueInit ;
709 
710  typedef typename Analysis::pointer_type pointer_type ;
711  typedef typename Analysis::reference_type reference_type ;
712 
713  const FunctorType m_functor ;
714  const int m_league ;
715  const ReducerType m_reducer ;
716  pointer_type m_result_ptr ;
717  const int m_shared ;
718 
719  template< class TagType >
720  inline
721  typename std::enable_if< std::is_same< TagType , void >::value >::type
722  exec( HostThreadTeamData & data , reference_type update ) const
723  {
724  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
725  m_functor( Member(data,ileague,m_league) , update );
726  }
727  }
728 
729  template< class TagType >
730  inline
731  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
732  exec( HostThreadTeamData & data , reference_type update ) const
733  {
734  const TagType t{} ;
735 
736  for ( int ileague = 0 ; ileague < m_league ; ++ileague ) {
737  m_functor( t , Member(data,ileague,m_league) , update );
738  }
739  }
740 
741 public:
742 
743  inline
744  void execute() const
745  {
746  const size_t pool_reduce_size =
747  Analysis::value_size( ReducerConditional::select(m_functor, m_reducer));
748 
749  const size_t team_reduce_size = TEAM_REDUCE_SIZE ;
750  const size_t team_shared_size = m_shared ;
751  const size_t thread_local_size = 0 ; // Never shrinks
752 
753  serial_resize_thread_team_data( pool_reduce_size
754  , team_reduce_size
755  , team_shared_size
756  , thread_local_size );
757 
758 
759  HostThreadTeamData & data = *serial_get_thread_team_data();
760 
761  pointer_type ptr =
762  m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
763 
764  reference_type update =
765  ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr );
766 
767  this-> template exec< WorkTag >( data , update );
768 
769  Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::
770  final( ReducerConditional::select(m_functor , m_reducer) , ptr );
771  }
772 
773  template< class ViewType >
774  ParallelReduce( const FunctorType & arg_functor
775  , const Policy & arg_policy
776  , const ViewType & arg_result ,
777  typename std::enable_if<
778  Kokkos::is_view< ViewType >::value &&
779  !Kokkos::is_reducer_type<ReducerType>::value
780  ,void*>::type = NULL)
781  : m_functor( arg_functor )
782  , m_league( arg_policy.league_size() )
783  , m_reducer( InvalidType() )
784  , m_result_ptr( arg_result.data() )
785  , m_shared( arg_policy.scratch_size(0) +
786  arg_policy.scratch_size(1) +
787  FunctorTeamShmemSize< FunctorType >::value( m_functor , 1 ) )
788  {
789  static_assert( Kokkos::is_view< ViewType >::value
790  , "Reduction result on Kokkos::Serial must be a Kokkos::View" );
791 
792  static_assert( std::is_same< typename ViewType::memory_space
793  , Kokkos::HostSpace >::value
794  , "Reduction result on Kokkos::Serial must be a Kokkos::View in HostSpace" );
795  }
796 
797  inline
798  ParallelReduce( const FunctorType & arg_functor
799  , Policy arg_policy
800  , const ReducerType& reducer )
801  : m_functor( arg_functor )
802  , m_league( arg_policy.league_size() )
803  , m_reducer( reducer )
804  , m_result_ptr( reducer.view().data() )
805  , m_shared( arg_policy.scratch_size(0) +
806  arg_policy.scratch_size(1) +
807  FunctorTeamShmemSize< FunctorType >::value( arg_functor , 1 ) )
808  {
809  /*static_assert( std::is_same< typename ViewType::memory_space
810  , Kokkos::HostSpace >::value
811  , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/
812  }
813 
814 };
815 
816 } // namespace Impl
817 } // namespace Kokkos
818 
819 /*--------------------------------------------------------------------------*/
820 /*--------------------------------------------------------------------------*/
821 
822 #include <impl/Kokkos_Serial_Task.hpp>
823 
824 #endif // defined( KOKKOS_ENABLE_SERIAL )
825 #endif /* #define KOKKOS_SERIAL_HPP */
826 
void print_configuration(std::ostream &, const bool detail=false)
Print "Bill of Materials".
Memory space for main process and CPU execution spaces.
Memory management for host memory.
Declaration of various MemoryLayout options.
Declaration of parallel operators.
void finalize()
Finalize the spaces that were initialized via Kokkos::initialize.
Execution policy for work over a range of an integral type.