Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Parallel.hpp
Go to the documentation of this file.
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  auto closure =
141  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
142  Impl::ParallelFor<FunctorType, ExecPolicy>>(functor, inner_policy);
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  auto closure =
356  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
357  Impl::ParallelScan<FunctorType, ExecutionPolicy>>(functor,
358  inner_policy);
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  auto closure =
402  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
403  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy,
404  typename ReturnType::value_type>>(
405  functor, inner_policy, return_value);
406  closure.execute();
407  } else {
409  auto closure =
410  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
411  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy,
412  ReturnType>>(functor, inner_policy,
413  view);
414  closure.execute();
415  }
416 
417  Kokkos::Tools::Impl::end_parallel_scan(inner_policy, functor, str, kpID);
418 
419  if (!Kokkos::is_view<ReturnType>::value)
420  policy.space().fence(
421  "Kokkos::parallel_scan: fence due to result being a value, not a view");
422 }
423 
424 template <class ExecutionPolicy, class FunctorType, class ReturnType>
425 inline void parallel_scan(
426  const ExecutionPolicy& policy, const FunctorType& functor,
427  ReturnType& return_value,
428  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>* = nullptr) {
429  ::Kokkos::parallel_scan("", policy, functor, return_value);
430 }
431 
432 template <class FunctorType, class ReturnType>
433 inline void parallel_scan(const std::string& str, const size_t work_count,
434  const FunctorType& functor,
435  ReturnType& return_value) {
436  using execution_space =
437  typename Kokkos::Impl::FunctorPolicyExecutionSpace<FunctorType,
438  void>::execution_space;
439 
441 
442  policy execution_policy(0, work_count);
443  parallel_scan(str, execution_policy, functor, return_value);
444 }
445 
446 template <class FunctorType, class ReturnType>
447 inline void parallel_scan(const size_t work_count, const FunctorType& functor,
448  ReturnType& return_value) {
449  ::Kokkos::parallel_scan("", work_count, functor, return_value);
450 }
451 
452 } // namespace Kokkos
453 
454 //----------------------------------------------------------------------------
455 //----------------------------------------------------------------------------
456 
457 namespace Kokkos {
458 namespace Impl {
459 
460 template <class FunctorType,
461  bool HasTeamShmemSize =
462  has_member_team_shmem_size<FunctorType>::value,
463  bool HasShmemSize = has_member_shmem_size<FunctorType>::value>
464 struct FunctorTeamShmemSize {
465  KOKKOS_INLINE_FUNCTION static size_t value(const FunctorType&, int) {
466  return 0;
467  }
468 };
469 
470 template <class FunctorType>
471 struct FunctorTeamShmemSize<FunctorType, true, false> {
472  static inline size_t value(const FunctorType& f, int team_size) {
473  return f.team_shmem_size(team_size);
474  }
475 };
476 
477 template <class FunctorType>
478 struct FunctorTeamShmemSize<FunctorType, false, true> {
479  static inline size_t value(const FunctorType& f, int team_size) {
480  return f.shmem_size(team_size);
481  }
482 };
483 template <class FunctorType>
484 struct FunctorTeamShmemSize<FunctorType, true, true> {
485  static inline size_t value(const FunctorType& /*f*/, int /*team_size*/) {
486  Kokkos::abort(
487  "Functor with both team_shmem_size and shmem_size defined is "
488  "not allowed");
489  return 0;
490  }
491 };
492 
493 } // namespace Impl
494 } // namespace Kokkos
495 
496 //----------------------------------------------------------------------------
497 //----------------------------------------------------------------------------
498 
499 #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.