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