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_v<policy_execution_space, functor_execution_space>,
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_v<policy_execution_space,
81  functor_device_type_execution_space>,
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_v<functor_device_type_execution_space,
87  functor_execution_space>,
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 
138  const auto& response =
139  Kokkos::Tools::Impl::begin_parallel_for(policy, functor, str, kpID);
140  const auto& inner_policy = response.policy;
141 
142  auto closure =
143  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
144  Impl::ParallelFor<FunctorType, ExecPolicy>>(functor, inner_policy);
145 
146  closure.execute();
147 
148  Kokkos::Tools::Impl::end_parallel_for(inner_policy, functor, str, kpID);
149 }
150 
151 template <class ExecPolicy, class FunctorType>
152 inline void parallel_for(
153  const ExecPolicy& policy, const FunctorType& functor,
154  std::enable_if_t<is_execution_policy<ExecPolicy>::value>* = nullptr) {
155  Kokkos::parallel_for("", policy, functor);
156 }
157 
158 template <class FunctorType>
159 inline void parallel_for(const std::string& str, const size_t work_count,
160  const FunctorType& functor) {
161  using execution_space =
162  typename Impl::FunctorPolicyExecutionSpace<FunctorType,
163  void>::execution_space;
164  using policy = RangePolicy<execution_space>;
165 
166  policy execution_policy = policy(0, work_count);
167  ::Kokkos::parallel_for(str, execution_policy, functor);
168 }
169 
170 template <class FunctorType>
171 inline void parallel_for(const size_t work_count, const FunctorType& functor) {
172  ::Kokkos::parallel_for("", work_count, functor);
173 }
174 
175 } // namespace Kokkos
176 
177 #include <Kokkos_Parallel_Reduce.hpp>
178 //----------------------------------------------------------------------------
179 //----------------------------------------------------------------------------
180 
181 namespace Kokkos {
182 
221 // const value_type& input) const
331 // i/ }
348 template <class ExecutionPolicy, class FunctorType,
349  class Enable =
350  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>>
351 inline void parallel_scan(const std::string& str, const ExecutionPolicy& policy,
352  const FunctorType& functor) {
353  uint64_t kpID = 0;
355  const auto& response =
356  Kokkos::Tools::Impl::begin_parallel_scan(policy, functor, str, kpID);
357  const auto& inner_policy = response.policy;
358 
359  auto closure =
360  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
361  Impl::ParallelScan<FunctorType, ExecutionPolicy>>(functor,
362  inner_policy);
363 
364  closure.execute();
365 
366  Kokkos::Tools::Impl::end_parallel_scan(inner_policy, functor, str, kpID);
367 }
368 
369 template <class ExecutionPolicy, class FunctorType>
370 inline void parallel_scan(
371  const ExecutionPolicy& policy, const FunctorType& functor,
372  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>* = nullptr) {
373  ::Kokkos::parallel_scan("", policy, functor);
374 }
375 
376 template <class FunctorType>
377 inline void parallel_scan(const std::string& str, const size_t work_count,
378  const FunctorType& functor) {
379  using execution_space =
380  typename Kokkos::Impl::FunctorPolicyExecutionSpace<FunctorType,
381  void>::execution_space;
382 
384 
385  policy execution_policy(0, work_count);
386  parallel_scan(str, execution_policy, functor);
387 }
388 
389 template <class FunctorType>
390 inline void parallel_scan(const size_t work_count, const FunctorType& functor) {
391  ::Kokkos::parallel_scan("", work_count, functor);
392 }
393 
394 template <class ExecutionPolicy, class FunctorType, class ReturnType,
395  class Enable =
396  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>>
397 inline void parallel_scan(const std::string& str, const ExecutionPolicy& policy,
398  const FunctorType& functor,
399  ReturnType& return_value) {
400  uint64_t kpID = 0;
401  ExecutionPolicy inner_policy = policy;
402  Kokkos::Tools::Impl::begin_parallel_scan(inner_policy, functor, str, kpID);
403 
404  if constexpr (Kokkos::is_view<ReturnType>::value) {
405  auto closure =
406  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
407  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy,
408  typename ReturnType::value_type>>(
409  functor, inner_policy, return_value);
410  closure.execute();
411  } else {
412  Kokkos::View<ReturnType, Kokkos::HostSpace> view(&return_value);
413  auto closure =
414  Kokkos::Impl::construct_with_shared_allocation_tracking_disabled<
415  Impl::ParallelScanWithTotal<FunctorType, ExecutionPolicy,
416  ReturnType>>(functor, inner_policy,
417  view);
418  closure.execute();
419  }
420 
421  Kokkos::Tools::Impl::end_parallel_scan(inner_policy, functor, str, kpID);
422 
423  if (!Kokkos::is_view<ReturnType>::value)
424  policy.space().fence(
425  "Kokkos::parallel_scan: fence due to result being a value, not a view");
426 }
427 
428 template <class ExecutionPolicy, class FunctorType, class ReturnType>
429 inline void parallel_scan(
430  const ExecutionPolicy& policy, const FunctorType& functor,
431  ReturnType& return_value,
432  std::enable_if_t<is_execution_policy<ExecutionPolicy>::value>* = nullptr) {
433  ::Kokkos::parallel_scan("", policy, functor, return_value);
434 }
435 
436 template <class FunctorType, class ReturnType>
437 inline void parallel_scan(const std::string& str, const size_t work_count,
438  const FunctorType& functor,
439  ReturnType& return_value) {
440  using execution_space =
441  typename Kokkos::Impl::FunctorPolicyExecutionSpace<FunctorType,
442  void>::execution_space;
443 
445 
446  policy execution_policy(0, work_count);
447  parallel_scan(str, execution_policy, functor, return_value);
448 }
449 
450 template <class FunctorType, class ReturnType>
451 inline void parallel_scan(const size_t work_count, const FunctorType& functor,
452  ReturnType& return_value) {
453  ::Kokkos::parallel_scan("", work_count, functor, return_value);
454 }
455 
456 } // namespace Kokkos
457 
458 //----------------------------------------------------------------------------
459 //----------------------------------------------------------------------------
460 
461 namespace Kokkos {
462 namespace Impl {
463 
464 template <class FunctorType,
465  bool HasTeamShmemSize =
466  has_member_team_shmem_size<FunctorType>::value,
467  bool HasShmemSize = has_member_shmem_size<FunctorType>::value>
468 struct FunctorTeamShmemSize {
469  KOKKOS_INLINE_FUNCTION static size_t value(const FunctorType&, int) {
470  return 0;
471  }
472 };
473 
474 template <class FunctorType>
475 struct FunctorTeamShmemSize<FunctorType, true, false> {
476  static inline size_t value(const FunctorType& f, int team_size) {
477  return f.team_shmem_size(team_size);
478  }
479 };
480 
481 template <class FunctorType>
482 struct FunctorTeamShmemSize<FunctorType, false, true> {
483  static inline size_t value(const FunctorType& f, int team_size) {
484  return f.shmem_size(team_size);
485  }
486 };
487 template <class FunctorType>
488 struct FunctorTeamShmemSize<FunctorType, true, true> {
489  static inline size_t value(const FunctorType& /*f*/, int /*team_size*/) {
490  Kokkos::abort(
491  "Functor with both team_shmem_size and shmem_size defined is "
492  "not allowed");
493  return 0;
494  }
495 };
496 
497 } // namespace Impl
498 } // namespace Kokkos
499 
500 //----------------------------------------------------------------------------
501 //----------------------------------------------------------------------------
502 
503 #endif /* KOKKOS_PARALLEL_HPP */
ReturnType
Given a Functor and Execution Policy query an execution space.
Execution policy for work over a range of an integral type.