Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_ExecPolicy.hpp
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 
44 #ifndef KOKKOS_EXECPOLICY_HPP
45 #define KOKKOS_EXECPOLICY_HPP
46 
47 #include <Kokkos_Core_fwd.hpp>
48 #include <impl/Kokkos_Traits.hpp>
49 #include <impl/Kokkos_Error.hpp>
50 #include <impl/Kokkos_Tags.hpp>
51 #include <impl/Kokkos_AnalyzePolicy.hpp>
52 #include <Kokkos_Concepts.hpp>
53 #include <iostream>
54 #if defined(KOKKOS_ENABLE_PROFILING)
55 #include <typeinfo>
56 #endif // KOKKOS_ENABLE_PROFILING
57 
58 //----------------------------------------------------------------------------
59 
60 namespace Kokkos {
61 
62 struct ParallelForTag {};
63 struct ParallelScanTag {};
64 struct ParallelReduceTag {};
65 
66 struct ChunkSize {
67  int value;
68  ChunkSize(int value_):value(value_) {}
69 };
70 
92 template<class ... Properties>
94  : public Impl::PolicyTraits<Properties ... >
95 {
96 public:
97  typedef Impl::PolicyTraits<Properties ... > traits;
98 private:
99 
100  typename traits::execution_space m_space ;
101  typename traits::index_type m_begin ;
102  typename traits::index_type m_end ;
103  typename traits::index_type m_granularity ;
104  typename traits::index_type m_granularity_mask ;
105 
106  template<class ... OtherProperties>
107  friend class RangePolicy;
108 
109 public:
112  typedef typename traits::index_type member_type ;
113  typedef typename traits::index_type index_type;
114 
115  KOKKOS_INLINE_FUNCTION const typename traits::execution_space & space() const { return m_space ; }
116  KOKKOS_INLINE_FUNCTION member_type begin() const { return m_begin ; }
117  KOKKOS_INLINE_FUNCTION member_type end() const { return m_end ; }
118 
119  //TODO: find a better workaround for Clangs weird instantiation order
120  // This thing is here because of an instantiation error, where the RangePolicy is inserted into FunctorValue Traits, which
121  // tries decltype on the operator. It tries to do this even though the first argument of parallel for clearly doesn't match.
122  void operator()(const int&) const {}
123 
124  RangePolicy(const RangePolicy&) = default;
125  RangePolicy(RangePolicy&&) = default;
126 
127  template<class ... OtherProperties>
128  RangePolicy(const RangePolicy<OtherProperties...> p) {
129  m_space = p.m_space;
130  m_begin = p.m_begin;
131  m_end = p.m_end;
132  m_granularity = p.m_granularity;
133  m_granularity_mask = p.m_granularity_mask;
134  }
135 
136  inline RangePolicy() : m_space(), m_begin(0), m_end(0) {}
137 
139  inline
140  RangePolicy( const typename traits::execution_space & work_space
141  , const member_type work_begin
142  , const member_type work_end
143  )
144  : m_space( work_space )
145  , m_begin( work_begin < work_end ? work_begin : 0 )
146  , m_end( work_begin < work_end ? work_end : 0 )
147  , m_granularity(0)
148  , m_granularity_mask(0)
149  {
150  set_auto_chunk_size();
151  }
152 
154  inline
155  RangePolicy( const member_type work_begin
156  , const member_type work_end
157  )
158  : RangePolicy( typename traits::execution_space()
159  , work_begin , work_end )
160  {
161  set_auto_chunk_size();
162  }
163 
165  template<class ... Args>
166  inline
167  RangePolicy( const typename traits::execution_space & work_space
168  , const member_type work_begin
169  , const member_type work_end
170  , Args ... args
171  )
172  : m_space( work_space )
173  , m_begin( work_begin < work_end ? work_begin : 0 )
174  , m_end( work_begin < work_end ? work_end : 0 )
175  , m_granularity(0)
176  , m_granularity_mask(0)
177  {
178  set_auto_chunk_size();
179  set(args...);
180  }
181 
183  template<class ... Args>
184  inline
185  RangePolicy( const member_type work_begin
186  , const member_type work_end
187  , Args ... args
188  )
189  : RangePolicy( typename traits::execution_space()
190  , work_begin , work_end )
191  {
192  set_auto_chunk_size();
193  set(args...);
194  }
195 
196 private:
197  inline void set() {}
198 
199 public:
200  template<class ... Args>
201  inline void set(Args ...) {
202  static_assert( 0 == sizeof...(Args), "Kokkos::RangePolicy: unhandled constructor arguments encountered.");
203  }
204 
205  template<class ... Args>
206  inline void set(const ChunkSize& chunksize, Args ... args) {
207  m_granularity = chunksize.value;
208  m_granularity_mask = m_granularity - 1;
209  }
210 
211 public:
213  inline member_type chunk_size() const {
214  return m_granularity;
215  }
216 
218  inline RangePolicy set_chunk_size(int chunk_size_) const {
219  RangePolicy p = *this;
220  p.m_granularity = chunk_size_;
221  p.m_granularity_mask = p.m_granularity - 1;
222  return p;
223  }
224 
225 private:
227  inline void set_auto_chunk_size() {
228 
229  typename traits::index_type concurrency = traits::execution_space::concurrency();
230  if( concurrency==0 ) concurrency=1;
231 
232  if(m_granularity > 0) {
233  if(!Impl::is_integral_power_of_two( m_granularity ))
234  Kokkos::abort("RangePolicy blocking granularity must be power of two" );
235  }
236 
237  member_type new_chunk_size = 1;
238  while(new_chunk_size*100*concurrency < m_end-m_begin)
239  new_chunk_size *= 2;
240  if(new_chunk_size < 128) {
241  new_chunk_size = 1;
242  while( (new_chunk_size*40*concurrency < m_end-m_begin ) && (new_chunk_size<128) )
243  new_chunk_size*=2;
244  }
245  m_granularity = new_chunk_size;
246  m_granularity_mask = m_granularity - 1;
247  }
248 
249 public:
254  struct WorkRange {
255  typedef typename RangePolicy::work_tag work_tag ;
256  typedef typename RangePolicy::member_type member_type ;
257 
258  KOKKOS_INLINE_FUNCTION member_type begin() const { return m_begin ; }
259  KOKKOS_INLINE_FUNCTION member_type end() const { return m_end ; }
260 
265  KOKKOS_INLINE_FUNCTION
266  WorkRange( const RangePolicy & range
267  , const int part_rank
268  , const int part_size
269  )
270  : m_begin(0), m_end(0)
271  {
272  if ( part_size ) {
273 
274  // Split evenly among partitions, then round up to the granularity.
275  const member_type work_part =
276  ( ( ( ( range.end() - range.begin() ) + ( part_size - 1 ) ) / part_size )
277  + range.m_granularity_mask ) & ~member_type(range.m_granularity_mask);
278 
279  m_begin = range.begin() + work_part * part_rank ;
280  m_end = m_begin + work_part ;
281 
282  if ( range.end() < m_begin ) m_begin = range.end() ;
283  if ( range.end() < m_end ) m_end = range.end() ;
284  }
285  }
286 
287  private:
288  member_type m_begin ;
289  member_type m_end ;
290  WorkRange();
291  WorkRange & operator = ( const WorkRange & );
292  };
293 };
294 
295 } // namespace Kokkos
296 
297 //----------------------------------------------------------------------------
298 //----------------------------------------------------------------------------
299 
300 namespace Kokkos {
301 
302 namespace Impl {
303 
304 template< class ExecSpace, class ... Properties>
305 class TeamPolicyInternal: public Impl::PolicyTraits<Properties ... > {
306 private:
307  typedef Impl::PolicyTraits<Properties ... > traits;
308 
309 public:
310 
311  typedef typename traits::index_type index_type;
312 
313  //----------------------------------------
324  template< class FunctorType >
325  static int team_size_max( const FunctorType & );
326 
337  template< class FunctorType >
338  static int team_size_recommended( const FunctorType & );
339 
340  template< class FunctorType >
341  static int team_size_recommended( const FunctorType & , const int&);
342 
343  template<class FunctorType>
344  int team_size_recommended( const FunctorType & functor , const int vector_length);
345 
346  //----------------------------------------
348  TeamPolicyInternal( const typename traits::execution_space & , int league_size_request , int team_size_request , int vector_length_request = 1 );
349 
350  TeamPolicyInternal( const typename traits::execution_space & , int league_size_request , const Kokkos::AUTO_t & , int vector_length_request = 1 );
351 
353  TeamPolicyInternal( int league_size_request , int team_size_request , int vector_length_request = 1 );
354 
355  TeamPolicyInternal( int league_size_request , const Kokkos::AUTO_t & , int vector_length_request = 1 );
356 
357 /* TeamPolicyInternal( int league_size_request , int team_size_request );
358 
359  TeamPolicyInternal( int league_size_request , const Kokkos::AUTO_t & );*/
360 
366  KOKKOS_INLINE_FUNCTION int league_size() const ;
367 
373  KOKKOS_INLINE_FUNCTION int team_size() const ;
374 
375  inline typename traits::index_type chunk_size() const ;
376 
377 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
378  inline TeamPolicyInternal set_chunk_size(int chunk_size) const ;
379 #else
380  inline TeamPolicyInternal& set_chunk_size(int chunk_size);
381 #endif
382 
386  struct member_type {
387 
389  KOKKOS_INLINE_FUNCTION
390  typename traits::execution_space::scratch_memory_space team_shmem() const ;
391 
393  KOKKOS_INLINE_FUNCTION int league_rank() const ;
394 
396  KOKKOS_INLINE_FUNCTION int league_size() const ;
397 
399  KOKKOS_INLINE_FUNCTION int team_rank() const ;
400 
402  KOKKOS_INLINE_FUNCTION int team_size() const ;
403 
405  KOKKOS_INLINE_FUNCTION void team_barrier() const ;
406 
408  template< class JoinOp >
409  KOKKOS_INLINE_FUNCTION
410  typename JoinOp::value_type team_reduce( const typename JoinOp::value_type
411  , const JoinOp & ) const ;
412 
418  template< typename Type >
419  KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value ) const ;
420 
430  template< typename Type >
431  KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value , Type * const global_accum ) const ;
432  };
433 };
434 
435 
436  struct PerTeamValue {
437  int value;
438  PerTeamValue(int arg);
439  };
440 
441  struct PerThreadValue {
442  int value;
443  PerThreadValue(int arg);
444  };
445 
446  template<class iType, class ... Args>
447  struct ExtractVectorLength {
448  static inline iType value(typename std::enable_if<std::is_integral<iType>::value,iType>::type val, Args...) {
449  return val;
450  }
451  static inline typename std::enable_if<!std::is_integral<iType>::value,int>::type value(typename std::enable_if<!std::is_integral<iType>::value,iType>::type, Args...) {
452  return 1;
453  }
454  };
455 
456  template<class iType, class ... Args>
457  inline typename std::enable_if<std::is_integral<iType>::value,iType>::type extract_vector_length(iType val, Args...) {
458  return val;
459  }
460 
461  template<class iType, class ... Args>
462  inline typename std::enable_if<!std::is_integral<iType>::value,int>::type extract_vector_length(iType, Args...) {
463  return 1;
464  }
465 
466 }
467 
468 Impl::PerTeamValue PerTeam(const int& arg);
469 Impl::PerThreadValue PerThread(const int& arg);
470 
471 struct ScratchRequest {
472  int level;
473 
474  int per_team;
475  int per_thread;
476 
477  inline
478  ScratchRequest(const int& level_, const Impl::PerTeamValue& team_value) {
479  level = level_;
480  per_team = team_value.value;
481  per_thread = 0;
482  }
483 
484  inline
485  ScratchRequest(const int& level_, const Impl::PerThreadValue& thread_value) {
486  level = level_;
487  per_team = 0;
488  per_thread = thread_value.value;;
489  }
490 
491  inline
492  ScratchRequest(const int& level_, const Impl::PerTeamValue& team_value, const Impl::PerThreadValue& thread_value) {
493  level = level_;
494  per_team = team_value.value;
495  per_thread = thread_value.value;;
496  }
497 
498  inline
499  ScratchRequest(const int& level_, const Impl::PerThreadValue& thread_value, const Impl::PerTeamValue& team_value) {
500  level = level_;
501  per_team = team_value.value;
502  per_thread = thread_value.value;;
503  }
504 
505 };
506 
507 
532 template< class ... Properties>
533 class TeamPolicy: public
534  Impl::TeamPolicyInternal<
535  typename Impl::PolicyTraits<Properties ... >::execution_space,
536  Properties ...> {
537  typedef Impl::TeamPolicyInternal<
538  typename Impl::PolicyTraits<Properties ... >::execution_space,
539  Properties ...> internal_policy;
540 
541  template<class ... OtherProperties>
542  friend class TeamPolicy;
543 
544 public:
545  typedef Impl::PolicyTraits<Properties ... > traits;
546 
548 
549  TeamPolicy& operator = (const TeamPolicy&) = default;
550 
552  TeamPolicy( const typename traits::execution_space & space_ , int league_size_request , int team_size_request , int vector_length_request = 1 )
553  : internal_policy(space_,league_size_request,team_size_request, vector_length_request) {first_arg = false;}
554 
555  TeamPolicy( const typename traits::execution_space & space_, int league_size_request , const Kokkos::AUTO_t & , int vector_length_request = 1 )
556  : internal_policy(space_,league_size_request,Kokkos::AUTO(), vector_length_request) {first_arg = false;}
557 
559  TeamPolicy( int league_size_request , int team_size_request , int vector_length_request = 1 )
560  : internal_policy(league_size_request,team_size_request, vector_length_request) {first_arg = false;}
561 
562  TeamPolicy( int league_size_request , const Kokkos::AUTO_t & , int vector_length_request = 1 )
563  : internal_policy(league_size_request,Kokkos::AUTO(), vector_length_request) {first_arg = false;}
564 
565 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
566 
567  template<class ... Args>
568  TeamPolicy( const typename traits::execution_space & , int league_size_request , int team_size_request , int vector_length_request,
569  Args ... args)
570  : internal_policy(typename traits::execution_space(),league_size_request,team_size_request, vector_length_request) {
571  first_arg = false;
572  set(args...);
573  }
574 
575  template<class ... Args>
576  TeamPolicy( const typename traits::execution_space & , int league_size_request , const Kokkos::AUTO_t & , int vector_length_request ,
577  Args ... args)
578  : internal_policy(typename traits::execution_space(),league_size_request,Kokkos::AUTO(), vector_length_request) {
579  first_arg = false;
580  set(args...);
581  }
582 
584  template<class ... Args>
585  TeamPolicy( int league_size_request , int team_size_request , int vector_length_request ,
586  Args ... args)
587  : internal_policy(league_size_request,team_size_request, vector_length_request) {
588  first_arg = false;
589  set(args...);
590  }
591 
592  template<class ... Args>
593  TeamPolicy( int league_size_request , const Kokkos::AUTO_t & , int vector_length_request ,
594  Args ... args)
595  : internal_policy(league_size_request,Kokkos::AUTO(), vector_length_request) {
596  first_arg = false;
597  set(args...);
598  }
599 
601  template<class ... Args>
602  TeamPolicy( const typename traits::execution_space & , int league_size_request , int team_size_request ,
603  Args ... args)
604  : internal_policy(typename traits::execution_space(),league_size_request,team_size_request,
605  Kokkos::Impl::extract_vector_length<Args...>(args...)) {
606  first_arg = true;
607  set(args...);
608  }
609 
610  template<class ... Args>
611  TeamPolicy( const typename traits::execution_space & , int league_size_request , const Kokkos::AUTO_t & ,
612  Args ... args)
613  : internal_policy(typename traits::execution_space(),league_size_request,Kokkos::AUTO(),
614  Kokkos::Impl::extract_vector_length<Args...>(args...)) {
615  first_arg = true;
616  set(args...);
617  }
618 
620  template<class ... Args>
621  TeamPolicy( int league_size_request , int team_size_request ,
622  Args ... args)
623  : internal_policy(league_size_request,team_size_request,
624  Kokkos::Impl::extract_vector_length<Args...>(args...)) {
625  first_arg = true;
626  set(args...);
627  }
628 
629  template<class ... Args>
630  TeamPolicy( int league_size_request , const Kokkos::AUTO_t & ,
631  Args ... args)
632  : internal_policy(league_size_request,Kokkos::AUTO(),
633  Kokkos::Impl::extract_vector_length<Args...>(args...)) {
634  first_arg = true;
635  set(args...);
636  }
637 #endif
638 
639  template<class ... OtherProperties>
640  TeamPolicy(const TeamPolicy<OtherProperties...> p):internal_policy(p) {
641  first_arg = p.first_arg;
642  }
643 
644 private:
645  bool first_arg;
646  TeamPolicy(const internal_policy& p):internal_policy(p) {first_arg = false;}
647 
648 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
649  inline void set() {}
650 #endif
651 
652 public:
653 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
654  template<class ... Args>
655  inline void set(Args ...) {
656  static_assert( 0 == sizeof...(Args), "Kokkos::TeamPolicy: unhandled constructor arguments encountered.");
657  }
658 
659  template<class iType, class ... Args>
660  inline typename std::enable_if<std::is_integral<iType>::value>::type set(iType, Args ... args) {
661  if(first_arg) {
662  first_arg = false;
663  set(args...);
664  } else {
665  first_arg = false;
666  Kokkos::Impl::throw_runtime_exception("Kokkos::TeamPolicy: integer argument to constructor in illegal place.");
667  }
668  }
669 
670  template<class ... Args>
671  inline void set(const ChunkSize& chunksize, Args ... args) {
672  first_arg = false;
673  internal_policy::internal_set_chunk_size(chunksize.value);
674  set(args...);
675  }
676 
677  template<class ... Args>
678  inline void set(const ScratchRequest& scr_request, Args ... args) {
679  first_arg = false;
680  internal_policy::internal_set_scratch_size(scr_request.level,Impl::PerTeamValue(scr_request.per_team),
681  Impl::PerThreadValue(scr_request.per_thread));
682  set(args...);
683  }
684 
685  inline TeamPolicy set_chunk_size(int chunk) const {
686  return TeamPolicy(internal_policy::set_chunk_size(chunk));
687  }
688 
689  inline TeamPolicy set_scratch_size(const int& level, const Impl::PerTeamValue& per_team) const {
690  return TeamPolicy(internal_policy::set_scratch_size(level,per_team));
691  }
692  inline TeamPolicy set_scratch_size(const int& level, const Impl::PerThreadValue& per_thread) const {
693  return TeamPolicy(internal_policy::set_scratch_size(level,per_thread));
694  }
695  inline TeamPolicy set_scratch_size(const int& level, const Impl::PerTeamValue& per_team, const Impl::PerThreadValue& per_thread) const {
696  return TeamPolicy(internal_policy::set_scratch_size(level, per_team, per_thread));
697  }
698  inline TeamPolicy set_scratch_size(const int& level, const Impl::PerThreadValue& per_thread, const Impl::PerTeamValue& per_team) const {
699  return TeamPolicy(internal_policy::set_scratch_size(level, per_team, per_thread));
700  }
701 
702 #else
703  inline TeamPolicy& set_chunk_size(int chunk) {
704  static_assert(std::is_same<decltype(internal_policy::set_chunk_size(chunk)), internal_policy&>::value, "internal set_chunk_size should return a reference");
705  return static_cast<TeamPolicy&>(internal_policy::set_chunk_size(chunk));
706  }
707 
708  inline TeamPolicy& set_scratch_size(const int& level, const Impl::PerTeamValue& per_team) {
709  static_assert(std::is_same<decltype(internal_policy::set_scratch_size(level,per_team)), internal_policy&>::value, "internal set_chunk_size should return a reference");
710  return static_cast<TeamPolicy&>(internal_policy::set_scratch_size(level,per_team));
711  }
712  inline TeamPolicy& set_scratch_size(const int& level, const Impl::PerThreadValue& per_thread) {
713  return static_cast<TeamPolicy&>(internal_policy::set_scratch_size(level,per_thread));
714  }
715  inline TeamPolicy& set_scratch_size(const int& level, const Impl::PerTeamValue& per_team, const Impl::PerThreadValue& per_thread) {
716  return static_cast<TeamPolicy&>(internal_policy::set_scratch_size(level, per_team, per_thread));
717  }
718  inline TeamPolicy& set_scratch_size(const int& level, const Impl::PerThreadValue& per_thread, const Impl::PerTeamValue& per_team) {
719  return static_cast<TeamPolicy&>(internal_policy::set_scratch_size(level, per_team, per_thread));
720  }
721 #endif
722 
723 };
724 
725 namespace Impl {
726 
727 template<typename iType, class TeamMemberType>
728 struct TeamThreadRangeBoundariesStruct {
729 private:
730 
731  KOKKOS_INLINE_FUNCTION static
732  iType ibegin( const iType & arg_begin
733  , const iType & arg_end
734  , const iType & arg_rank
735  , const iType & arg_size
736  )
737  {
738  return arg_begin + ( ( arg_end - arg_begin + arg_size - 1 ) / arg_size ) * arg_rank ;
739  }
740 
741  KOKKOS_INLINE_FUNCTION static
742  iType iend( const iType & arg_begin
743  , const iType & arg_end
744  , const iType & arg_rank
745  , const iType & arg_size
746  )
747  {
748  const iType end_ = arg_begin + ( ( arg_end - arg_begin + arg_size - 1 ) / arg_size ) * ( arg_rank + 1 );
749  return end_ < arg_end ? end_ : arg_end ;
750  }
751 
752 public:
753 
754  typedef iType index_type;
755  const iType start;
756  const iType end;
757  enum {increment = 1};
758  const TeamMemberType& thread;
759 
760  KOKKOS_INLINE_FUNCTION
761  TeamThreadRangeBoundariesStruct( const TeamMemberType& arg_thread
762  , const iType& arg_end
763  )
764  : start( ibegin( 0 , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
765  , end( iend( 0 , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
766  , thread( arg_thread )
767  {}
768 
769  KOKKOS_INLINE_FUNCTION
770  TeamThreadRangeBoundariesStruct( const TeamMemberType& arg_thread
771  , const iType& arg_begin
772  , const iType& arg_end
773  )
774  : start( ibegin( arg_begin , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
775  , end( iend( arg_begin , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
776  , thread( arg_thread )
777  {}
778 };
779 
780 template<typename iType, class TeamMemberType>
781 struct TeamVectorRangeBoundariesStruct {
782 private:
783 
784  KOKKOS_INLINE_FUNCTION static
785  iType ibegin( const iType & arg_begin
786  , const iType & arg_end
787  , const iType & arg_rank
788  , const iType & arg_size
789  )
790  {
791  return arg_begin + ( ( arg_end - arg_begin + arg_size - 1 ) / arg_size ) * arg_rank ;
792  }
793 
794  KOKKOS_INLINE_FUNCTION static
795  iType iend( const iType & arg_begin
796  , const iType & arg_end
797  , const iType & arg_rank
798  , const iType & arg_size
799  )
800  {
801  const iType end_ = arg_begin + ( ( arg_end - arg_begin + arg_size - 1 ) / arg_size ) * ( arg_rank + 1 );
802  return end_ < arg_end ? end_ : arg_end ;
803  }
804 
805 public:
806 
807  typedef iType index_type;
808  const iType start;
809  const iType end;
810  enum {increment = 1};
811  const TeamMemberType& thread;
812 
813  KOKKOS_INLINE_FUNCTION
814  TeamVectorRangeBoundariesStruct( const TeamMemberType& arg_thread
815  , const iType& arg_end
816  )
817  : start( ibegin( 0 , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
818  , end( iend( 0 , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
819  , thread( arg_thread )
820  {}
821 
822  KOKKOS_INLINE_FUNCTION
823  TeamVectorRangeBoundariesStruct( const TeamMemberType& arg_thread
824  , const iType& arg_begin
825  , const iType& arg_end
826  )
827  : start( ibegin( arg_begin , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
828  , end( iend( arg_begin , arg_end , arg_thread.team_rank() , arg_thread.team_size() ) )
829  , thread( arg_thread )
830  {}
831 };
832 
833 template<typename iType, class TeamMemberType>
834 struct ThreadVectorRangeBoundariesStruct {
835  typedef iType index_type;
836  const index_type start;
837  const index_type end;
838  enum {increment = 1};
839 
840  KOKKOS_INLINE_FUNCTION
841  constexpr ThreadVectorRangeBoundariesStruct ( const TeamMemberType, const index_type& count ) noexcept
842  : start( static_cast<index_type>(0) )
843  , end( count ) {}
844 
845  KOKKOS_INLINE_FUNCTION
846  constexpr ThreadVectorRangeBoundariesStruct ( const index_type& count ) noexcept
847  : start( static_cast<index_type>(0) )
848  , end( count ) {}
849 
850  KOKKOS_INLINE_FUNCTION
851  constexpr ThreadVectorRangeBoundariesStruct ( const TeamMemberType, const index_type& arg_begin, const index_type& arg_end ) noexcept
852  : start( static_cast<index_type>(arg_begin) )
853  , end( arg_end ) {}
854 
855  KOKKOS_INLINE_FUNCTION
856  constexpr ThreadVectorRangeBoundariesStruct ( const index_type& arg_begin, const index_type& arg_end ) noexcept
857  : start( static_cast<index_type>(arg_begin) )
858  , end( arg_end ) {}
859 };
860 
861 template<class TeamMemberType>
862 struct ThreadSingleStruct {
863  const TeamMemberType& team_member;
864  KOKKOS_INLINE_FUNCTION
865  ThreadSingleStruct( const TeamMemberType& team_member_ ) : team_member( team_member_ ) {}
866 };
867 
868 template<class TeamMemberType>
869 struct VectorSingleStruct {
870  const TeamMemberType& team_member;
871  KOKKOS_INLINE_FUNCTION
872  VectorSingleStruct( const TeamMemberType& team_member_ ) : team_member( team_member_ ) {}
873 };
874 
875 } // namespace Impl
876 
883 template<typename iType, class TeamMemberType, class _never_use_this_overload>
884 KOKKOS_INLINE_FUNCTION_DELETED
885 Impl::TeamThreadRangeBoundariesStruct<iType,TeamMemberType>
886 TeamThreadRange( const TeamMemberType&, const iType& count ) = delete;
887 
894 template<typename iType1, typename iType2, class TeamMemberType, class _never_use_this_overload>
895 KOKKOS_INLINE_FUNCTION_DELETED
896 Impl::TeamThreadRangeBoundariesStruct<typename std::common_type<iType1, iType2>::type, TeamMemberType>
897 TeamThreadRange( const TeamMemberType&, const iType1& begin, const iType2& end ) = delete;
898 
905 template<typename iType, class TeamMemberType, class _never_use_this_overload>
906 KOKKOS_INLINE_FUNCTION_DELETED
907 Impl::TeamThreadRangeBoundariesStruct<iType,TeamMemberType>
908 TeamVectorRange( const TeamMemberType&, const iType& count ) = delete;
909 
916 template<typename iType1, typename iType2, class TeamMemberType, class _never_use_this_overload>
917 KOKKOS_INLINE_FUNCTION_DELETED
918 Impl::TeamThreadRangeBoundariesStruct<typename std::common_type<iType1, iType2>::type, TeamMemberType>
919 TeamVectorRange( const TeamMemberType&, const iType1& begin, const iType2& end ) = delete;
920 
927 template<typename iType, class TeamMemberType, class _never_use_this_overload>
928 KOKKOS_INLINE_FUNCTION_DELETED
929 Impl::ThreadVectorRangeBoundariesStruct<iType,TeamMemberType>
930 ThreadVectorRange( const TeamMemberType&, const iType& count ) = delete;
931 
932 template<typename iType, class TeamMemberType, class _never_use_this_overload>
933 KOKKOS_INLINE_FUNCTION_DELETED
934 Impl::ThreadVectorRangeBoundariesStruct<iType,TeamMemberType>
935 ThreadVectorRange( const TeamMemberType&, const iType& arg_begin, const iType& arg_end ) = delete;
936 
937 #if defined(KOKKOS_ENABLE_PROFILING)
938 namespace Impl {
939 
940 template<typename FunctorType, typename TagType,
941  bool HasTag = !std::is_same<TagType, void>::value >
942 struct ParallelConstructName;
943 
944 template<typename FunctorType, typename TagType>
945 struct ParallelConstructName<FunctorType, TagType, true> {
946  ParallelConstructName(std::string const& label):label_ref(label) {
947  if (label.empty()) {
948  default_name = std::string(typeid(FunctorType).name()) + "/" +
949  typeid(TagType).name();
950  }
951  }
952  std::string const& get() {
953  return (label_ref.empty()) ? default_name : label_ref;
954  }
955  std::string const& label_ref;
956  std::string default_name;
957 };
958 
959 template<typename FunctorType, typename TagType>
960 struct ParallelConstructName<FunctorType, TagType, false> {
961  ParallelConstructName(std::string const& label):label_ref(label) {
962  if (label.empty()) {
963  default_name = std::string(typeid(FunctorType).name());
964  }
965  }
966  std::string const& get() {
967  return (label_ref.empty()) ? default_name : label_ref;
968  }
969  std::string const& label_ref;
970  std::string default_name;
971 };
972 
973 } // namespace Impl
974 #endif /* defined KOKKOS_ENABLE_PROFILING */
975 
976 } // namespace Kokkos
977 
978 namespace Kokkos {
979 namespace Experimental {
980 
981 namespace Impl {
982  template<class Property,class Policy>
983  struct PolicyPropertyAdaptor;
984 
985  template<unsigned long P, class ... Properties>
986  struct PolicyPropertyAdaptor<WorkItemProperty::ImplWorkItemProperty<P>,RangePolicy<Properties...>> {
987  typedef RangePolicy<Properties...> policy_in_t;
988  typedef RangePolicy<typename policy_in_t::traits::execution_space,
989  typename policy_in_t::traits::schedule_type,
990  typename policy_in_t::traits::work_tag,
991  typename policy_in_t::traits::index_type,
992  typename policy_in_t::traits::iteration_pattern,
993  typename policy_in_t::traits::launch_bounds,
994  WorkItemProperty::ImplWorkItemProperty<P>> policy_out_t;
995  };
996 
997  template<unsigned long P, class ... Properties>
998  struct PolicyPropertyAdaptor<WorkItemProperty::ImplWorkItemProperty<P>,TeamPolicy<Properties...>> {
999  typedef TeamPolicy<Properties...> policy_in_t;
1000  typedef TeamPolicy<typename policy_in_t::traits::execution_space,
1001  typename policy_in_t::traits::schedule_type,
1002  typename policy_in_t::traits::work_tag,
1003  typename policy_in_t::traits::index_type,
1004  typename policy_in_t::traits::iteration_pattern,
1005  typename policy_in_t::traits::launch_bounds,
1006  WorkItemProperty::ImplWorkItemProperty<P>> policy_out_t;
1007  };
1008 }
1009 
1010 template<class PolicyType,unsigned long P>
1011 constexpr typename Impl::PolicyPropertyAdaptor<WorkItemProperty::ImplWorkItemProperty<P>,PolicyType>::policy_out_t
1012  require(const PolicyType p, WorkItemProperty::ImplWorkItemProperty<P>){
1013  return typename Impl::PolicyPropertyAdaptor<WorkItemProperty::ImplWorkItemProperty<P>,PolicyType>::policy_out_t(p);
1014 }
1015 } //Experimental
1016 } //Kokkos
1017 #endif /* #define KOKKOS_EXECPOLICY_HPP */
1018 
KOKKOS_INLINE_FUNCTION void team_barrier() const
Barrier among the threads of this team.
KOKKOS_INLINE_FUNCTION_DELETED Impl::TeamThreadRangeBoundariesStruct< iType, TeamMemberType > TeamThreadRange(const TeamMemberType &, const iType &count)=delete
Execution policy for parallel work over a threads within a team.
KOKKOS_INLINE_FUNCTION int team_rank() const
Rank of this thread within this team.
TeamPolicy(int league_size_request, int team_size_request, int vector_length_request=1)
Construct policy with the default instance of the execution space.
KOKKOS_INLINE_FUNCTION int team_size() const
Number of threads in this team.
RangePolicy set_chunk_size(int chunk_size_) const
set chunk_size to a discrete value
RangePolicy execution_policy
Tag this class as an execution policy.
RangePolicy(const typename traits::execution_space &work_space, const member_type work_begin, const member_type work_end)
Total range.
KOKKOS_INLINE_FUNCTION JoinOp::value_type team_reduce(const typename JoinOp::value_type, const JoinOp &) const
Intra-team reduction. Returns join of all values of the team members.
KOKKOS_INLINE_FUNCTION int league_rank() const
Rank of this team within the league of teams.
member_type chunk_size() const
return chunk_size
TeamPolicy(const typename traits::execution_space &space_, int league_size_request, int team_size_request, int vector_length_request=1)
Construct policy with the given instance of the execution space.
KOKKOS_INLINE_FUNCTION traits::execution_space::scratch_memory_space team_shmem() const
Handle to the currently executing team shared scratch memory.
KOKKOS_INLINE_FUNCTION_DELETED Impl::ThreadVectorRangeBoundariesStruct< iType, TeamMemberType > ThreadVectorRange(const TeamMemberType &, const iType &count)=delete
Execution policy for a vector parallel loop.
KOKKOS_INLINE_FUNCTION Type team_scan(const Type &value) const
Intra-team exclusive prefix sum with team_rank() ordering.
KOKKOS_INLINE_FUNCTION WorkRange(const RangePolicy &range, const int part_rank, const int part_size)
Subrange for a partition&#39;s rank and size.
RangePolicy(const member_type work_begin, const member_type work_end, Args...args)
Total range.
RangePolicy(const typename traits::execution_space &work_space, const member_type work_begin, const member_type work_end, Args...args)
Total range.
RangePolicy(const member_type work_begin, const member_type work_end)
Total range.
Execution policy for work over a range of an integral type.
Subrange for a partition&#39;s rank and size.
KOKKOS_INLINE_FUNCTION int league_size() const
Number of teams in the league.
Execution policy for parallel work over a league of teams of threads.
Parallel execution of a functor calls the functor once with each member of the execution policy...
KOKKOS_INLINE_FUNCTION_DELETED Impl::TeamThreadRangeBoundariesStruct< iType, TeamMemberType > TeamVectorRange(const TeamMemberType &, const iType &count)=delete
Execution policy for parallel work over a threads within a team.