RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
MultiPolicy.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_MultiPolicy_HPP
21 #define RAJA_MultiPolicy_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <tuple>
26 
28 
30 #include "RAJA/util/plugins.hpp"
31 
32 #include "RAJA/util/concepts.hpp"
33 #include "RAJA/util/resource.hpp"
34 
35 namespace RAJA
36 {
37 
38 namespace detail
39 {
40 template<size_t index, size_t size, typename Policy, typename... rest>
41 struct policy_invoker;
42 }
43 
44 namespace policy
45 {
46 namespace multi
47 {
48 
54 template<typename Selector, typename... Policies>
56 {
57  Selector _selector;
58 
59 public:
60  MultiPolicy() = delete; // No default construction
61 
62  MultiPolicy(Selector s) : _selector(s), _policies({Policies {}...}) {}
63 
64  MultiPolicy(Selector s, Policies... policies)
65  : _selector(s),
66  _policies({policies...})
67  {}
68 
70  : _selector(p._selector),
72  {}
73 
74  template<typename Iterable, typename Body>
75  int invoke(Iterable&& i, Body&& b)
76  {
77  size_t index = _selector(i);
78  _policies.invoke(index, i, b);
79  return _selector(i);
80  }
81 
82  detail::
83  policy_invoker<sizeof...(Policies) - 1, sizeof...(Policies), Policies...>
85 };
86 
92 template<typename Iterable,
93  typename Body,
94  typename Selector,
95  typename... Policies>
97  Iterable&& iter,
98  Body&& body)
99 {
100  p.invoke(iter, body);
101 }
102 
103 template<typename Res,
104  typename Iterable,
105  typename Body,
106  typename Selector,
107  typename... Policies>
108 RAJA_INLINE resources::EventProxy<Res> forall_impl(
109  Res r,
111  Iterable&& iter,
112  Body&& body)
113 {
114  p.invoke(iter, body);
115  return resources::EventProxy<Res>(r);
116 }
117 
118 } // end namespace multi
119 } // end namespace policy
120 
121 using policy::multi::MultiPolicy;
122 
123 namespace detail
124 {
125 
126 template<camp::idx_t... Indices, typename... Policies, typename Selector>
127 auto make_multi_policy(camp::idx_seq<Indices...>,
128  Selector s,
129  std::tuple<Policies...> policies)
130  -> MultiPolicy<Selector, Policies...>
131 {
132  return MultiPolicy<Selector, Policies...>(s, std::get<Indices>(policies)...);
133 }
134 } // namespace detail
135 
144 template<typename... Policies, typename Selector>
145 RAJA_DEPRECATE("In the next RAJA Release, MultiPolicy will be deprecated.")
146 auto make_multi_policy(Selector s) -> MultiPolicy<Selector, Policies...>
147 {
148  return MultiPolicy<Selector, Policies...>(s, Policies {}...);
149 }
150 
160 template<typename... Policies, typename Selector>
161 RAJA_DEPRECATE("In the next RAJA Release, MultiPolicy will be deprecated.")
162 auto make_multi_policy(std::tuple<Policies...> policies, Selector s)
163  -> MultiPolicy<Selector, Policies...>
164 {
165  return detail::make_multi_policy(camp::make_idx_seq_t<sizeof...(Policies)> {},
166  s, policies);
167 }
168 
169 namespace detail
170 {
171 
172 template<size_t index, size_t size, typename Policy, typename... rest>
173 struct policy_invoker : public policy_invoker<index - 1, size, rest...>
174 {
175  static_assert(index < size, "index must be in the range of possibilities");
177  using NextInvoker = policy_invoker<index - 1, size, rest...>;
178 
179  policy_invoker(Policy p, rest... args) : NextInvoker(args...), _p(p) {}
180 
181  template<typename Iterable, typename LoopBody>
182  void invoke(int offset, Iterable&& iter, LoopBody&& loop_body)
183  {
184  if (offset == size - index - 1)
185  {
186 
187  util::PluginContext context {util::make_context<Policy>(std::string())};
189 
191  auto body = trigger_updates_before(loop_body);
192 
194 
196 
198  RAJA_FORCEINLINE_RECURSIVE
200  forall_impl(r, _p, std::forward<Iterable>(iter), body);
201 
203  }
204  else
205  {
206  NextInvoker::invoke(offset, std::forward<Iterable>(iter),
207  std::forward<LoopBody>(loop_body));
208  }
209  }
210 };
211 
212 template<size_t size, typename Policy, typename... rest>
213 struct policy_invoker<0, size, Policy, rest...>
214 {
216 
217  policy_invoker(Policy p, rest...) : _p(p) {}
218 
219  template<typename Iterable, typename LoopBody>
220  void invoke(int offset, Iterable&& iter, LoopBody&& loop_body)
221  {
222  if (offset == size - 1)
223  {
224 
225  util::PluginContext context {util::make_context<Policy>(std::string())};
227 
229  auto body = trigger_updates_before(loop_body);
230 
232 
234 
235  // std::cout <<"policy_invoker: No index\n";
237  RAJA_FORCEINLINE_RECURSIVE
239  forall_impl(r, _p, std::forward<Iterable>(iter), body);
240 
242  }
243  else
244  {
245  throw std::runtime_error("unknown offset invoked");
246  }
247  }
248 };
249 
250 } // end namespace detail
251 
252 namespace type_traits
253 {
254 
255 template<typename T>
257  : ::RAJA::type_traits::SpecializationOf<RAJA::MultiPolicy,
258  typename std::decay<T>::type>
259 {};
260 } // namespace type_traits
261 
262 } // end namespace RAJA
263 
264 #endif
Header file for basic RAJA policy mechanics.
Definition: MultiPolicy.hpp:56
detail::policy_invoker< sizeof...(Policies) - 1, sizeof...(Policies), Policies... > _policies
Definition: MultiPolicy.hpp:84
MultiPolicy(Selector s)
Definition: MultiPolicy.hpp:62
int invoke(Iterable &&i, Body &&b)
Definition: MultiPolicy.hpp:75
MultiPolicy(const MultiPolicy &p)
Definition: MultiPolicy.hpp:69
MultiPolicy(Selector s, Policies... policies)
Definition: MultiPolicy.hpp:64
Header file for RAJA concept definitions.
#define RAJA_DEPRECATE(Msg)
Macros for marking deprecated features in RAJA.
Definition: macros.hpp:222
Args args
Definition: WorkRunner.hpp:212
auto make_multi_policy(camp::idx_seq< Indices... >, Selector s, std::tuple< Policies... > policies) -> MultiPolicy< Selector, Policies... >
Definition: MultiPolicy.hpp:127
value_type::device_call &[i_loop] iter
Definition: WorkRunner.hpp:216
RAJA_INLINE resources::EventProxy< Res > forall_impl(Res r, MultiPolicy< Selector, Policies... > p, Iterable &&iter, Body &&body)
Definition: MultiPolicy.hpp:108
RAJA_INLINE void forall_impl(MultiPolicy< Selector, Policies... > p, Iterable &&iter, Body &&body)
Definition: MultiPolicy.hpp:96
RAJA_INLINE void callPreLaunchPlugins(const PluginContext &p)
Definition: plugins.hpp:56
RAJA_INLINE void callPostCapturePlugins(const PluginContext &p)
Definition: plugins.hpp:46
RAJA_INLINE auto trigger_updates_before(T &&item) -> typename std::remove_reference< T >::type
Definition: plugins.hpp:29
RAJA_INLINE void callPostLaunchPlugins(const PluginContext &p)
Definition: plugins.hpp:66
RAJA_INLINE void callPreCapturePlugins(const PluginContext &p)
Definition: plugins.hpp:36
Definition: AlignedRangeIndexSetBuilders.cpp:35
Policy
Definition: PolicyBase.hpp:32
auto & body
Definition: launch.hpp:177
auto make_multi_policy(Selector s) -> MultiPolicy< Selector, Policies... >
Definition: MultiPolicy.hpp:146
Definition: ListSegment.hpp:416
Header file for RAJA resource definitions.
Policy _p
Definition: MultiPolicy.hpp:215
policy_invoker(Policy p, rest...)
Definition: MultiPolicy.hpp:217
void invoke(int offset, Iterable &&iter, LoopBody &&loop_body)
Definition: MultiPolicy.hpp:220
Definition: MultiPolicy.hpp:174
policy_invoker(Policy p, rest... args)
Definition: MultiPolicy.hpp:179
void invoke(int offset, Iterable &&iter, LoopBody &&loop_body)
Definition: MultiPolicy.hpp:182
Policy _p
Definition: MultiPolicy.hpp:175
Definition: resource.hpp:48
Definition: MultiPolicy.hpp:259
Definition: PluginContext.hpp:26