Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Parallel.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
19 
20 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
21 #include <Kokkos_Macros.hpp>
22 static_assert(false,
23  "Including non-public Kokkos header files is not allowed.");
24 #endif
25 #ifndef KOKKOS_PARALLEL_HPP
26 #define KOKKOS_PARALLEL_HPP
27 
28 #include <Kokkos_Core_fwd.hpp>
29 #include <Kokkos_DetectionIdiom.hpp>
30 #include <Kokkos_ExecPolicy.hpp>
31 #include <Kokkos_View.hpp>
32 
33 #include <impl/Kokkos_Tools.hpp>
34 #include <impl/Kokkos_Tools_Generic.hpp>
35 
36 #include <impl/Kokkos_Traits.hpp>
37 #include <impl/Kokkos_FunctorAnalysis.hpp>
38 
39 #include <cstddef>
40 #include <type_traits>
41 #include <typeinfo>
42 
43 //----------------------------------------------------------------------------
44 //----------------------------------------------------------------------------
45 
46 namespace Kokkos {
47 namespace Impl {
48 
49 template <class T>
50 using execution_space_t = typename T::execution_space;
51 
52 template <class T>
53 using device_type_t = typename T::device_type;
54 
55 //----------------------------------------------------------------------------
64 template <class Functor, class Policy>
65 struct FunctorPolicyExecutionSpace {
66  using policy_execution_space = detected_t<execution_space_t, Policy>;
67  using functor_execution_space = detected_t<execution_space_t, Functor>;
68  using functor_device_type = detected_t<device_type_t, Functor>;
69  using functor_device_type_execution_space =
70  detected_t<execution_space_t, functor_device_type>;
71 
72  static_assert(
73  !is_detected<execution_space_t, Policy>::value ||
74  !is_detected<execution_space_t, Functor>::value ||
75  std::is_same<policy_execution_space, functor_execution_space>::value,
76  "A policy with an execution space and a functor with an execution space "
77  "are given but the execution space types do not match!");
78  static_assert(!is_detected<execution_space_t, Policy>::value ||
79  !is_detected<device_type_t, Functor>::value ||
80  std::is_same<policy_execution_space,
81  functor_device_type_execution_space>::value,
82  "A policy with an execution space and a functor with a device "
83  "type are given but the execution space types do not match!");
84  static_assert(!is_detected<device_type_t, Functor>::value ||
85  !is_detected<execution_space_t, Functor>::value ||
86  std::is_same<functor_device_type_execution_space,
87  functor_execution_space>::value,
88  "A functor with both an execution space and device type is "
89  "given but their execution space types do not match!");
90 
91  using execution_space = detected_or_t<
92  detected_or_t<
93  std::conditional_t<
94  is_detected<device_type_t, Functor>::value,
95  detected_t<execution_space_t, detected_t<device_type_t, Functor>>,
96  Kokkos::DefaultExecutionSpace>,
97  execution_space_t, Functor>,
98  execution_space_t, Policy>;
99 };
100 
101 } // namespace Impl
102 } // namespace Kokkos
103 
104 //----------------------------------------------------------------------------
105 //----------------------------------------------------------------------------
106 
107 namespace Kokkos {
108 
130 template <
131  class ExecPolicy, class FunctorType,
132  class Enable = std::enable_if_t<is_execution_policy<ExecPolicy>::value>>
133 inline void parallel_for(const std::string& str, const ExecPolicy& policy,
134  const FunctorType& functor) {
135  uint64_t kpID = 0;
136 
137  ExecPolicy inner_policy = policy;
138  Kokkos::Tools::Impl::begin_parallel_for(inner_policy, functor, str, kpID);
139 
140  Kokkos::Impl::shared_allocation_tracking_disable();
141  Impl::ParallelFor<FunctorType, ExecPolicy> closure(functor, inner_policy);
142  Kokkos::Impl::shared_allocation_tracking_enable();
143 
144  closure.execute();
145 
146  Kokkos::Tools::Impl::end_parallel_for(inner_policy, functor, str, kpID);
147 }
148 
149 template <class ExecPolicy, class FunctorType>
150 inline void parallel_for(
151  const ExecPolicy& policy, const FunctorType& functor,
152  std::enable_if_t<is_execution_policy<ExecPolicy>::value>* = nullptr) {
153  Kokkos::parallel_for("", policy, functor);
154 }
155 
156 template <class FunctorType>
157 inline void parallel_for(const std::string& str, const size_t work_count,
158  const FunctorType& functor) {
159  using execution_space =
160  typename Impl::FunctorPolicyExecutionSpace<FunctorType,
161  void>::execution_space;
162  using policy = RangePolicy<execution_space>;
163 
164  policy execution_policy = policy(0, work_count);
165  ::Kokkos::parallel_for(str, execution_policy, functor);
166 }
167 
168 template <class FunctorType>
169 inline void parallel_for(const size_t work_count, const FunctorType& functor) {
170  ::Kokkos::parallel_for("", work_count, functor);
171 }
172 
173 } // namespace Kokkos
174 
175 #include <Kokkos_Parallel_Reduce.hpp>
176 //----------------------------------------------------------------------------
177 //----------------------------------------------------------------------------
178 
179 namespace Kokkos {
180 
219 // const value_type& input) const
329 // i/ }
346 template <class ExecutionPolicy, class FunctorType,
347  class Enable =
348  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>>
349 inline void parallel_scan(const std::string& str, const ExecutionPolicy& policy,
350  const FunctorType& functor) {
351  uint64_t kpID = 0;
352  ExecutionPolicy inner_policy = policy;
353  Kokkos::Tools::Impl::begin_parallel_scan(inner_policy, functor, str, kpID);
354 
355  Kokkos::Impl::shared_allocation_tracking_disable();
356  Impl::ParallelScan<FunctorType, ExecutionPolicy> closure(functor,
357  inner_policy);
358  Kokkos::Impl::shared_allocation_tracking_enable();
359 
360  closure.execute();
361 
362  Kokkos::Tools::Impl::end_parallel_scan(inner_policy, functor, str, kpID);
363 }
364 
365 template <class ExecutionPolicy, class FunctorType>
366 inline void parallel_scan(
367  const ExecutionPolicy& policy, const FunctorType& functor,
368  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>* = nullptr) {
369  ::Kokkos::parallel_scan("", policy, functor);
370 }
371 
372 template <class FunctorType>
373 inline void parallel_scan(const std::string& str, const size_t work_count,
374  const FunctorType& functor) {
375  using execution_space =
376  typename Kokkos::Impl::FunctorPolicyExecutionSpace<FunctorType,
377  void>::execution_space;
378 
380 
381  policy execution_policy(0, work_count);
382  parallel_scan(str, execution_policy, functor);
383 }
384 
385 template <class FunctorType>
386 inline void parallel_scan(const size_t work_count, const FunctorType& functor) {
387  ::Kokkos::parallel_scan("", work_count, functor);
388 }
389 
390 template <class ExecutionPolicy, class FunctorType, class ReturnType,
391  class Enable =
392  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>>
393 inline void parallel_scan(const std::string& str, const ExecutionPolicy& policy,
394  const FunctorType& functor,
395  ReturnType& return_value) {
396  uint64_t kpID = 0;
397  ExecutionPolicy inner_policy = policy;
398  Kokkos::Tools::Impl::begin_parallel_scan(inner_policy, functor, str, kpID);
399 
400  if constexpr (Kokkos::is_view<ReturnType>::value) {
401  Kokkos::Impl::shared_allocation_tracking_disable();
402  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy,
403  typename ReturnType::value_type>
404  closure(functor, inner_policy, return_value);
405  Kokkos::Impl::shared_allocation_tracking_enable();
406  closure.execute();
407  } else {
408  Kokkos::Impl::shared_allocation_tracking_disable();
410  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy, ReturnType>
411  closure(functor, inner_policy, view);
412  Kokkos::Impl::shared_allocation_tracking_enable();
413  closure.execute();
414  }
415 
416  Kokkos::Tools::Impl::end_parallel_scan(inner_policy, functor, str, kpID);
417 
418  if (!Kokkos::is_view<ReturnType>::value)
419  policy.space().fence(
420  "Kokkos::parallel_scan: fence due to result being a value, not a view");
421 }
422 
423 template <class ExecutionPolicy, class FunctorType, class ReturnType>
424 inline void parallel_scan(
425  const ExecutionPolicy& policy, const FunctorType& functor,
426  ReturnType& return_value,
427  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>* = nullptr) {
428  ::Kokkos::parallel_scan("", policy, functor, return_value);
429 }
430 
431 template <class FunctorType, class ReturnType>
432 inline void parallel_scan(const std::string& str, const size_t work_count,
433  const FunctorType& functor,
434  ReturnType& return_value) {
435  using execution_space =
436  typename Kokkos::Impl::FunctorPolicyExecutionSpace<FunctorType,
437  void>::execution_space;
438 
440 
441  policy execution_policy(0, work_count);
442  parallel_scan(str, execution_policy, functor, return_value);
443 }
444 
445 template <class FunctorType, class ReturnType>
446 inline void parallel_scan(const size_t work_count, const FunctorType& functor,
447  ReturnType& return_value) {
448  ::Kokkos::parallel_scan("", work_count, functor, return_value);
449 }
450 
451 } // namespace Kokkos
452 
453 //----------------------------------------------------------------------------
454 //----------------------------------------------------------------------------
455 
456 namespace Kokkos {
457 namespace Impl {
458 
459 template <class FunctorType,
460  bool HasTeamShmemSize =
461  has_member_team_shmem_size<FunctorType>::value,
462  bool HasShmemSize = has_member_shmem_size<FunctorType>::value>
463 struct FunctorTeamShmemSize {
464  KOKKOS_INLINE_FUNCTION static size_t value(const FunctorType&, int) {
465  return 0;
466  }
467 };
468 
469 template <class FunctorType>
470 struct FunctorTeamShmemSize<FunctorType, true, false> {
471  static inline size_t value(const FunctorType& f, int team_size) {
472  return f.team_shmem_size(team_size);
473  }
474 };
475 
476 template <class FunctorType>
477 struct FunctorTeamShmemSize<FunctorType, false, true> {
478  static inline size_t value(const FunctorType& f, int team_size) {
479  return f.shmem_size(team_size);
480  }
481 };
482 template <class FunctorType>
483 struct FunctorTeamShmemSize<FunctorType, true, true> {
484  static inline size_t value(const FunctorType& /*f*/, int /*team_size*/) {
485  Kokkos::abort(
486  "Functor with both team_shmem_size and shmem_size defined is "
487  "not allowed");
488  return 0;
489  }
490 };
491 
492 } // namespace Impl
493 } // namespace Kokkos
494 
495 //----------------------------------------------------------------------------
496 //----------------------------------------------------------------------------
497 
498 #endif /* KOKKOS_PARALLEL_HPP */
View to an array of data.
ReturnType
Given a Functor and Execution Policy query an execution space.
Execution policy for work over a range of an integral type.