48 #ifndef KOKKOS_SERIAL_HPP 49 #define KOKKOS_SERIAL_HPP 51 #include <Kokkos_Macros.hpp> 52 #if defined(KOKKOS_ENABLE_SERIAL) 56 #include <Kokkos_Core_fwd.hpp> 58 #include <Kokkos_TaskScheduler.hpp> 60 #include <Kokkos_HostSpace.hpp> 61 #include <Kokkos_ScratchSpace.hpp> 62 #include <Kokkos_MemoryTraits.hpp> 63 #include <impl/Kokkos_Tags.hpp> 64 #include <impl/Kokkos_HostThreadTeam.hpp> 65 #include <impl/Kokkos_FunctorAnalysis.hpp> 66 #include <impl/Kokkos_FunctorAdapter.hpp> 67 #include <impl/Kokkos_Tools.hpp> 68 #include <impl/Kokkos_ExecSpaceInitializer.hpp> 70 #include <KokkosExp_MDRangePolicy.hpp> 72 #include <Kokkos_UniqueToken.hpp> 94 using execution_space = Serial;
98 using size_type = memory_space::size_type;
100 using device_type = Kokkos::Device<execution_space, memory_space>;
103 using array_layout = LayoutRight;
106 using scratch_memory_space = ScratchMemorySpace<Kokkos::Serial>;
116 inline static int in_parallel() {
return false; }
124 static void impl_static_fence() {}
126 void fence()
const {}
129 static int concurrency() {
return 1; }
132 static void print_configuration(std::ostream&,
133 const bool =
false) {}
135 static void impl_initialize();
137 static bool impl_is_initialized();
140 static void impl_finalize();
144 inline static int impl_thread_pool_size(
int = 0) {
return 1; }
145 KOKKOS_INLINE_FUNCTION
static int impl_thread_pool_rank() {
return 0; }
149 KOKKOS_INLINE_FUNCTION
static unsigned impl_hardware_thread_id() {
150 return impl_thread_pool_rank();
152 inline static unsigned impl_max_hardware_threads() {
153 return impl_thread_pool_size(0);
156 uint32_t impl_instance_id() const noexcept {
return 0; }
158 static const char* name();
165 struct DeviceTypeTraits<Serial> {
166 static constexpr DeviceType
id = DeviceType::Serial;
173 class SerialSpaceInitializer :
public ExecSpaceInitializerBase {
175 SerialSpaceInitializer() =
default;
176 ~SerialSpaceInitializer() =
default;
177 void initialize(
const InitArguments& args)
final;
178 void finalize(
const bool)
final;
180 void print_configuration(std::ostream& msg, const
bool detail) final;
193 struct MemorySpaceAccess<
Kokkos::Serial::memory_space,
194 Kokkos::Serial::scratch_memory_space> {
195 enum :
bool { assignable =
false };
196 enum :
bool { accessible =
true };
197 enum :
bool { deepcopy =
false };
210 void serial_resize_thread_team_data(
size_t pool_reduce_bytes,
211 size_t team_reduce_bytes,
212 size_t team_shared_bytes,
213 size_t thread_local_bytes);
215 HostThreadTeamData* serial_get_thread_team_data();
229 template <
class... Properties>
230 class TeamPolicyInternal<
Kokkos::Serial, Properties...>
231 :
public PolicyTraits<Properties...> {
233 size_t m_team_scratch_size[2];
234 size_t m_thread_scratch_size[2];
240 using execution_policy = TeamPolicyInternal;
242 using traits = PolicyTraits<Properties...>;
245 using execution_space = Kokkos::Serial;
247 const typename traits::execution_space& space()
const {
248 static typename traits::execution_space m_space;
252 template <
class ExecSpace,
class... OtherProperties>
253 friend class TeamPolicyInternal;
255 template <
class... OtherProperties>
257 const TeamPolicyInternal<Kokkos::Serial, OtherProperties...>& p) {
258 m_league_size = p.m_league_size;
259 m_team_scratch_size[0] = p.m_team_scratch_size[0];
260 m_thread_scratch_size[0] = p.m_thread_scratch_size[0];
261 m_team_scratch_size[1] = p.m_team_scratch_size[1];
262 m_thread_scratch_size[1] = p.m_thread_scratch_size[1];
263 m_chunk_size = p.m_chunk_size;
268 template <
class FunctorType>
269 int team_size_max(
const FunctorType&,
const ParallelForTag&)
const {
272 template <
class FunctorType>
273 int team_size_max(
const FunctorType&,
const ParallelReduceTag&)
const {
276 template <
class FunctorType,
class ReducerType>
277 int team_size_max(
const FunctorType&,
const ReducerType&,
278 const ParallelReduceTag&)
const {
281 template <
class FunctorType>
282 int team_size_recommended(
const FunctorType&,
const ParallelForTag&)
const {
285 template <
class FunctorType>
286 int team_size_recommended(
const FunctorType&,
287 const ParallelReduceTag&)
const {
290 template <
class FunctorType,
class ReducerType>
291 int team_size_recommended(
const FunctorType&,
const ReducerType&,
292 const ParallelReduceTag&)
const {
298 inline int team_size()
const {
return 1; }
299 inline bool impl_auto_team_size()
const {
return false; }
300 inline bool impl_auto_vector_length()
const {
return false; }
301 inline void impl_set_team_size(
size_t) {}
302 inline void impl_set_vector_length(
size_t) {}
303 inline int league_size()
const {
return m_league_size; }
304 inline size_t scratch_size(
const int& level,
int = 0)
const {
305 return m_team_scratch_size[level] + m_thread_scratch_size[level];
308 inline int impl_vector_length()
const {
return 1; }
309 inline static int vector_length_max() {
313 inline static int scratch_size_max(
int level) {
314 return (level == 0 ? 1024 * 32 : 20 * 1024 * 1024);
317 TeamPolicyInternal(
const execution_space&,
int league_size_request,
318 int team_size_request,
int = 1)
319 : m_team_scratch_size{0, 0},
320 m_thread_scratch_size{0, 0},
321 m_league_size(league_size_request),
323 if (team_size_request > 1)
324 Kokkos::abort(
"Kokkos::abort: Requested Team Size is too large!");
327 TeamPolicyInternal(
const execution_space& space,
int league_size_request,
328 const Kokkos::AUTO_t& ,
329 int vector_length_request = 1)
330 : TeamPolicyInternal(space, league_size_request, -1,
331 vector_length_request) {}
333 TeamPolicyInternal(
const execution_space& space,
int league_size_request,
334 const Kokkos::AUTO_t&
336 const Kokkos::AUTO_t&
338 : TeamPolicyInternal(space, league_size_request, -1, -1) {}
340 TeamPolicyInternal(
const execution_space& space,
int league_size_request,
341 int team_size_request,
342 const Kokkos::AUTO_t&
344 : TeamPolicyInternal(space, league_size_request, team_size_request, -1) {}
346 TeamPolicyInternal(
int league_size_request,
347 const Kokkos::AUTO_t& team_size_request,
348 int vector_length_request = 1)
349 : TeamPolicyInternal(typename traits::execution_space(),
350 league_size_request, team_size_request,
351 vector_length_request) {}
353 TeamPolicyInternal(
int league_size_request,
354 const Kokkos::AUTO_t& team_size_request,
355 const Kokkos::AUTO_t& vector_length_request)
356 : TeamPolicyInternal(typename traits::execution_space(),
357 league_size_request, team_size_request,
358 vector_length_request) {}
359 TeamPolicyInternal(
int league_size_request,
int team_size_request,
360 const Kokkos::AUTO_t& vector_length_request)
361 : TeamPolicyInternal(typename traits::execution_space(),
362 league_size_request, team_size_request,
363 vector_length_request) {}
365 TeamPolicyInternal(
int league_size_request,
int team_size_request,
366 int vector_length_request = 1)
367 : TeamPolicyInternal(typename traits::execution_space(),
368 league_size_request, team_size_request,
369 vector_length_request) {}
371 inline int chunk_size()
const {
return m_chunk_size; }
374 inline TeamPolicyInternal& set_chunk_size(
375 typename traits::index_type chunk_size_) {
376 m_chunk_size = chunk_size_;
382 inline TeamPolicyInternal& set_scratch_size(
const int& level,
383 const PerTeamValue& per_team) {
384 m_team_scratch_size[level] = per_team.value;
390 inline TeamPolicyInternal& set_scratch_size(
391 const int& level,
const PerThreadValue& per_thread) {
392 m_thread_scratch_size[level] = per_thread.value;
398 inline TeamPolicyInternal& set_scratch_size(
399 const int& level,
const PerTeamValue& per_team,
400 const PerThreadValue& per_thread) {
401 m_team_scratch_size[level] = per_team.value;
402 m_thread_scratch_size[level] = per_thread.value;
406 using member_type = Impl::HostThreadTeamMember<Kokkos::Serial>;
418 template <
class FunctorType,
class... Traits>
419 class ParallelFor<FunctorType,
Kokkos::RangePolicy<Traits...>, Kokkos::Serial> {
423 const FunctorType m_functor;
424 const Policy m_policy;
426 template <
class TagType>
427 typename std::enable_if<std::is_same<TagType, void>::value>::type exec()
429 const typename Policy::member_type e = m_policy.end();
430 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
435 template <
class TagType>
436 typename std::enable_if<!std::is_same<TagType, void>::value>::type exec()
439 const typename Policy::member_type e = m_policy.end();
440 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
446 inline void execute()
const {
447 this->
template exec<typename Policy::work_tag>();
450 inline ParallelFor(
const FunctorType& arg_functor,
const Policy& arg_policy)
451 : m_functor(arg_functor), m_policy(arg_policy) {}
456 template <
class FunctorType,
class ReducerType,
class... Traits>
457 class ParallelReduce<FunctorType,
Kokkos::RangePolicy<Traits...>, ReducerType,
461 using WorkTag =
typename Policy::work_tag;
463 using ReducerConditional =
464 Kokkos::Impl::if_c<std::is_same<InvalidType, ReducerType>::value,
465 FunctorType, ReducerType>;
467 using ReducerTypeFwd =
typename ReducerConditional::type;
469 std::conditional_t<std::is_same<InvalidType, ReducerType>::value, WorkTag,
473 FunctorAnalysis<FunctorPatternInterface::REDUCE, Policy, FunctorType>;
475 using ValueInit = Kokkos::Impl::FunctorValueInit<ReducerTypeFwd, WorkTagFwd>;
477 using pointer_type =
typename Analysis::pointer_type;
478 using reference_type =
typename Analysis::reference_type;
480 const FunctorType m_functor;
481 const Policy m_policy;
482 const ReducerType m_reducer;
483 const pointer_type m_result_ptr;
485 template <
class TagType>
486 inline typename std::enable_if<std::is_same<TagType, void>::value>::type exec(
487 reference_type update)
const {
488 const typename Policy::member_type e = m_policy.end();
489 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
490 m_functor(i, update);
494 template <
class TagType>
495 inline typename std::enable_if<!std::is_same<TagType, void>::value>::type
496 exec(reference_type update)
const {
499 const typename Policy::member_type e = m_policy.end();
500 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
501 m_functor(t, i, update);
506 inline void execute()
const {
507 const size_t pool_reduce_size =
508 Analysis::value_size(ReducerConditional::select(m_functor, m_reducer));
509 const size_t team_reduce_size = 0;
510 const size_t team_shared_size = 0;
511 const size_t thread_local_size = 0;
513 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
514 team_shared_size, thread_local_size);
516 HostThreadTeamData& data = *serial_get_thread_team_data();
519 m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
521 reference_type update =
522 ValueInit::init(ReducerConditional::select(m_functor, m_reducer), ptr);
524 this->
template exec<WorkTag>(update);
526 Kokkos::Impl::FunctorFinal<ReducerTypeFwd, WorkTagFwd>::final(
527 ReducerConditional::select(m_functor, m_reducer), ptr);
530 template <
class HostViewType>
532 const FunctorType& arg_functor,
const Policy& arg_policy,
533 const HostViewType& arg_result_view,
534 typename std::enable_if<Kokkos::is_view<HostViewType>::value &&
535 !Kokkos::is_reducer_type<ReducerType>::value,
536 void*>::type =
nullptr)
537 : m_functor(arg_functor),
538 m_policy(arg_policy),
539 m_reducer(InvalidType()),
540 m_result_ptr(arg_result_view.data()) {
541 static_assert(Kokkos::is_view<HostViewType>::value,
542 "Kokkos::Serial reduce result must be a View");
547 "Kokkos::Serial reduce result must be a View in HostSpace");
550 inline ParallelReduce(
const FunctorType& arg_functor, Policy arg_policy,
551 const ReducerType& reducer)
552 : m_functor(arg_functor),
553 m_policy(arg_policy),
555 m_result_ptr(reducer.view().data()) {
565 template <
class FunctorType,
class... Traits>
566 class ParallelScan<FunctorType,
Kokkos::RangePolicy<Traits...>,
570 using WorkTag =
typename Policy::work_tag;
573 FunctorAnalysis<FunctorPatternInterface::SCAN, Policy, FunctorType>;
575 using ValueInit = Kokkos::Impl::FunctorValueInit<FunctorType, WorkTag>;
577 using pointer_type =
typename Analysis::pointer_type;
578 using reference_type =
typename Analysis::reference_type;
580 const FunctorType m_functor;
581 const Policy m_policy;
583 template <
class TagType>
584 inline typename std::enable_if<std::is_same<TagType, void>::value>::type exec(
585 reference_type update)
const {
586 const typename Policy::member_type e = m_policy.end();
587 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
588 m_functor(i, update,
true);
592 template <
class TagType>
593 inline typename std::enable_if<!std::is_same<TagType, void>::value>::type
594 exec(reference_type update)
const {
596 const typename Policy::member_type e = m_policy.end();
597 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
598 m_functor(t, i, update,
true);
603 inline void execute()
const {
604 const size_t pool_reduce_size = Analysis::value_size(m_functor);
605 const size_t team_reduce_size = 0;
606 const size_t team_shared_size = 0;
607 const size_t thread_local_size = 0;
609 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
610 team_shared_size, thread_local_size);
612 HostThreadTeamData& data = *serial_get_thread_team_data();
614 reference_type update =
615 ValueInit::init(m_functor, pointer_type(data.pool_reduce_local()));
617 this->
template exec<WorkTag>(update);
620 inline ParallelScan(
const FunctorType& arg_functor,
const Policy& arg_policy)
621 : m_functor(arg_functor), m_policy(arg_policy) {}
625 template <
class FunctorType,
class ReturnType,
class... Traits>
626 class ParallelScanWithTotal<FunctorType,
Kokkos::RangePolicy<Traits...>,
630 using WorkTag =
typename Policy::work_tag;
633 FunctorAnalysis<FunctorPatternInterface::SCAN, Policy, FunctorType>;
635 using ValueInit = Kokkos::Impl::FunctorValueInit<FunctorType, WorkTag>;
637 using pointer_type =
typename Analysis::pointer_type;
638 using reference_type =
typename Analysis::reference_type;
640 const FunctorType m_functor;
641 const Policy m_policy;
644 template <
class TagType>
645 inline typename std::enable_if<std::is_same<TagType, void>::value>::type exec(
646 reference_type update)
const {
647 const typename Policy::member_type e = m_policy.end();
648 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
649 m_functor(i, update,
true);
653 template <
class TagType>
654 inline typename std::enable_if<!std::is_same<TagType, void>::value>::type
655 exec(reference_type update)
const {
657 const typename Policy::member_type e = m_policy.end();
658 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
659 m_functor(t, i, update,
true);
664 inline void execute() {
665 const size_t pool_reduce_size = Analysis::value_size(m_functor);
666 const size_t team_reduce_size = 0;
667 const size_t team_shared_size = 0;
668 const size_t thread_local_size = 0;
670 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
671 team_shared_size, thread_local_size);
673 HostThreadTeamData& data = *serial_get_thread_team_data();
675 reference_type update =
676 ValueInit::init(m_functor, pointer_type(data.pool_reduce_local()));
678 this->
template exec<WorkTag>(update);
680 m_returnvalue = update;
683 inline ParallelScanWithTotal(
const FunctorType& arg_functor,
684 const Policy& arg_policy,
686 : m_functor(arg_functor),
687 m_policy(arg_policy),
688 m_returnvalue(arg_returnvalue) {}
701 template <
class FunctorType,
class... Traits>
702 class ParallelFor<FunctorType,
Kokkos::MDRangePolicy<Traits...>,
705 using MDRangePolicy = Kokkos::MDRangePolicy<Traits...>;
706 using Policy =
typename MDRangePolicy::impl_range_policy;
708 using iterate_type =
typename Kokkos::Impl::HostIterateTile<
709 MDRangePolicy, FunctorType,
typename MDRangePolicy::work_tag,
void>;
711 const FunctorType m_functor;
712 const MDRangePolicy m_mdr_policy;
713 const Policy m_policy;
716 const typename Policy::member_type e = m_policy.end();
717 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
718 iterate_type(m_mdr_policy, m_functor)(i);
723 inline void execute()
const { this->exec(); }
724 template <
typename Policy,
typename Functor>
725 static int max_tile_size_product(
const Policy&,
const Functor&) {
733 inline ParallelFor(
const FunctorType& arg_functor,
734 const MDRangePolicy& arg_policy)
735 : m_functor(arg_functor),
736 m_mdr_policy(arg_policy),
737 m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)) {}
740 template <
class FunctorType,
class ReducerType,
class... Traits>
741 class ParallelReduce<FunctorType,
Kokkos::MDRangePolicy<Traits...>, ReducerType,
744 using MDRangePolicy = Kokkos::MDRangePolicy<Traits...>;
745 using Policy =
typename MDRangePolicy::impl_range_policy;
747 using WorkTag =
typename MDRangePolicy::work_tag;
749 using ReducerConditional =
750 Kokkos::Impl::if_c<std::is_same<InvalidType, ReducerType>::value,
751 FunctorType, ReducerType>;
752 using ReducerTypeFwd =
typename ReducerConditional::type;
754 std::conditional_t<std::is_same<InvalidType, ReducerType>::value, WorkTag,
757 using Analysis = FunctorAnalysis<FunctorPatternInterface::REDUCE,
758 MDRangePolicy, FunctorType>;
760 using ValueInit = Kokkos::Impl::FunctorValueInit<ReducerTypeFwd, WorkTagFwd>;
762 using pointer_type =
typename Analysis::pointer_type;
763 using value_type =
typename Analysis::value_type;
764 using reference_type =
typename Analysis::reference_type;
767 typename Kokkos::Impl::HostIterateTile<MDRangePolicy, FunctorType,
768 WorkTag, reference_type>;
770 const FunctorType m_functor;
771 const MDRangePolicy m_mdr_policy;
772 const Policy m_policy;
773 const ReducerType m_reducer;
774 const pointer_type m_result_ptr;
776 inline void exec(reference_type update)
const {
777 const typename Policy::member_type e = m_policy.end();
778 for (
typename Policy::member_type i = m_policy.begin(); i < e; ++i) {
779 iterate_type(m_mdr_policy, m_functor, update)(i);
784 template <
typename Policy,
typename Functor>
785 static int max_tile_size_product(
const Policy&,
const Functor&) {
793 inline void execute()
const {
794 const size_t pool_reduce_size =
795 Analysis::value_size(ReducerConditional::select(m_functor, m_reducer));
796 const size_t team_reduce_size = 0;
797 const size_t team_shared_size = 0;
798 const size_t thread_local_size = 0;
800 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
801 team_shared_size, thread_local_size);
803 HostThreadTeamData& data = *serial_get_thread_team_data();
806 m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
808 reference_type update =
809 ValueInit::init(ReducerConditional::select(m_functor, m_reducer), ptr);
813 Kokkos::Impl::FunctorFinal<ReducerTypeFwd, WorkTagFwd>::final(
814 ReducerConditional::select(m_functor, m_reducer), ptr);
817 template <
class HostViewType>
819 const FunctorType& arg_functor,
const MDRangePolicy& arg_policy,
820 const HostViewType& arg_result_view,
821 typename std::enable_if<Kokkos::is_view<HostViewType>::value &&
822 !Kokkos::is_reducer_type<ReducerType>::value,
823 void*>::type =
nullptr)
824 : m_functor(arg_functor),
825 m_mdr_policy(arg_policy),
826 m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)),
827 m_reducer(InvalidType()),
828 m_result_ptr(arg_result_view.data()) {
829 static_assert(Kokkos::is_view<HostViewType>::value,
830 "Kokkos::Serial reduce result must be a View");
835 "Kokkos::Serial reduce result must be a View in HostSpace");
838 inline ParallelReduce(
const FunctorType& arg_functor,
839 MDRangePolicy arg_policy,
const ReducerType& reducer)
840 : m_functor(arg_functor),
841 m_mdr_policy(arg_policy),
842 m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)),
844 m_result_ptr(reducer.view().data()) {
862 template <
class FunctorType,
class... Properties>
863 class ParallelFor<FunctorType,
Kokkos::TeamPolicy<Properties...>,
866 enum { TEAM_REDUCE_SIZE = 512 };
868 using Policy = TeamPolicyInternal<Kokkos::Serial, Properties...>;
869 using Member =
typename Policy::member_type;
871 const FunctorType m_functor;
875 template <
class TagType>
876 inline typename std::enable_if<std::is_same<TagType, void>::value>::type exec(
877 HostThreadTeamData& data)
const {
878 for (
int ileague = 0; ileague < m_league; ++ileague) {
879 m_functor(Member(data, ileague, m_league));
883 template <
class TagType>
884 inline typename std::enable_if<!std::is_same<TagType, void>::value>::type
885 exec(HostThreadTeamData& data)
const {
887 for (
int ileague = 0; ileague < m_league; ++ileague) {
888 m_functor(t, Member(data, ileague, m_league));
893 inline void execute()
const {
894 const size_t pool_reduce_size = 0;
895 const size_t team_reduce_size = TEAM_REDUCE_SIZE;
896 const size_t team_shared_size = m_shared;
897 const size_t thread_local_size = 0;
899 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
900 team_shared_size, thread_local_size);
902 HostThreadTeamData& data = *serial_get_thread_team_data();
904 this->
template exec<typename Policy::work_tag>(data);
907 ParallelFor(
const FunctorType& arg_functor,
const Policy& arg_policy)
908 : m_functor(arg_functor),
909 m_league(arg_policy.league_size()),
910 m_shared(arg_policy.scratch_size(0) + arg_policy.scratch_size(1) +
911 FunctorTeamShmemSize<FunctorType>::value(arg_functor, 1)) {}
916 template <
class FunctorType,
class ReducerType,
class... Properties>
917 class ParallelReduce<FunctorType,
Kokkos::TeamPolicy<Properties...>,
918 ReducerType, Kokkos::Serial> {
920 enum { TEAM_REDUCE_SIZE = 512 };
922 using Policy = TeamPolicyInternal<Kokkos::Serial, Properties...>;
925 FunctorAnalysis<FunctorPatternInterface::REDUCE, Policy, FunctorType>;
927 using Member =
typename Policy::member_type;
928 using WorkTag =
typename Policy::work_tag;
930 using ReducerConditional =
931 Kokkos::Impl::if_c<std::is_same<InvalidType, ReducerType>::value,
932 FunctorType, ReducerType>;
933 using ReducerTypeFwd =
typename ReducerConditional::type;
935 std::conditional_t<std::is_same<InvalidType, ReducerType>::value, WorkTag,
938 using ValueInit = Kokkos::Impl::FunctorValueInit<ReducerTypeFwd, WorkTagFwd>;
940 using pointer_type =
typename Analysis::pointer_type;
941 using reference_type =
typename Analysis::reference_type;
943 const FunctorType m_functor;
945 const ReducerType m_reducer;
946 pointer_type m_result_ptr;
949 template <
class TagType>
950 inline typename std::enable_if<std::is_same<TagType, void>::value>::type exec(
951 HostThreadTeamData& data, reference_type update)
const {
952 for (
int ileague = 0; ileague < m_league; ++ileague) {
953 m_functor(Member(data, ileague, m_league), update);
957 template <
class TagType>
958 inline typename std::enable_if<!std::is_same<TagType, void>::value>::type
959 exec(HostThreadTeamData& data, reference_type update)
const {
962 for (
int ileague = 0; ileague < m_league; ++ileague) {
963 m_functor(t, Member(data, ileague, m_league), update);
968 inline void execute()
const {
969 const size_t pool_reduce_size =
970 Analysis::value_size(ReducerConditional::select(m_functor, m_reducer));
972 const size_t team_reduce_size = TEAM_REDUCE_SIZE;
973 const size_t team_shared_size = m_shared;
974 const size_t thread_local_size = 0;
976 serial_resize_thread_team_data(pool_reduce_size, team_reduce_size,
977 team_shared_size, thread_local_size);
979 HostThreadTeamData& data = *serial_get_thread_team_data();
982 m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local());
984 reference_type update =
985 ValueInit::init(ReducerConditional::select(m_functor, m_reducer), ptr);
987 this->
template exec<WorkTag>(data, update);
989 Kokkos::Impl::FunctorFinal<ReducerTypeFwd, WorkTagFwd>::final(
990 ReducerConditional::select(m_functor, m_reducer), ptr);
993 template <
class ViewType>
995 const FunctorType& arg_functor,
const Policy& arg_policy,
996 const ViewType& arg_result,
997 typename std::enable_if<Kokkos::is_view<ViewType>::value &&
998 !Kokkos::is_reducer_type<ReducerType>::value,
999 void*>::type =
nullptr)
1000 : m_functor(arg_functor),
1001 m_league(arg_policy.league_size()),
1002 m_reducer(InvalidType()),
1003 m_result_ptr(arg_result.data()),
1004 m_shared(arg_policy.scratch_size(0) + arg_policy.scratch_size(1) +
1005 FunctorTeamShmemSize<FunctorType>::value(m_functor, 1)) {
1006 static_assert(Kokkos::is_view<ViewType>::value,
1007 "Reduction result on Kokkos::Serial must be a Kokkos::View");
1012 "Reduction result on Kokkos::Serial must be a Kokkos::View in " 1016 inline ParallelReduce(
const FunctorType& arg_functor, Policy arg_policy,
1017 const ReducerType& reducer)
1018 : m_functor(arg_functor),
1019 m_league(arg_policy.league_size()),
1021 m_result_ptr(reducer.view().data()),
1022 m_shared(arg_policy.scratch_size(0) + arg_policy.scratch_size(1) +
1023 FunctorTeamShmemSize<FunctorType>::value(arg_functor, 1)) {
1041 class UniqueToken<Serial, UniqueTokenScope::Instance> {
1043 using execution_space = Serial;
1044 using size_type = int;
1049 UniqueToken(execution_space
const& = execution_space()) noexcept {}
1054 UniqueToken(size_type, execution_space
const& = execution_space()) {}
1057 KOKKOS_INLINE_FUNCTION
1058 int size() const noexcept {
return 1; }
1061 KOKKOS_INLINE_FUNCTION
1062 int acquire() const noexcept {
return 0; }
1065 KOKKOS_INLINE_FUNCTION
1066 void release(
int)
const noexcept {}
1070 class UniqueToken<Serial, UniqueTokenScope::Global> {
1072 using execution_space = Serial;
1073 using size_type = int;
1078 UniqueToken(execution_space
const& = execution_space()) noexcept {}
1081 KOKKOS_INLINE_FUNCTION
1082 int size() const noexcept {
return 1; }
1085 KOKKOS_INLINE_FUNCTION
1086 int acquire() const noexcept {
return 0; }
1089 KOKKOS_INLINE_FUNCTION
1090 void release(
int)
const noexcept {}
1096 #include <impl/Kokkos_Serial_Task.hpp> 1098 #endif // defined( KOKKOS_ENABLE_SERIAL )
Memory management for host memory.
Declaration of various MemoryLayout options.
Declaration of parallel operators.
Execution policy for work over a range of an integral type.
Access relationship between DstMemorySpace and SrcMemorySpace.