GrPPI  0.3.1
Generic and Reusable Parallel Pattern Interface
dynamic_execution.h
Go to the documentation of this file.
1 
21 #ifndef GRPPI_DYN_DYNAMIC_EXECUTION_H
22 #define GRPPI_DYN_DYNAMIC_EXECUTION_H
23 
24 #include "../seq/sequential_execution.h"
25 #include "../native/parallel_execution_native.h"
26 #include "../tbb/parallel_execution_tbb.h"
27 #include "../omp/parallel_execution_omp.h"
28 #include "../ff/parallel_execution_ff.h"
29 
30 #include <memory>
31 
32 namespace grppi{
33 
35 public:
36 
37  dynamic_execution() noexcept :
38  execution_{}
39  {}
40 
41  template <typename E>
42  dynamic_execution(const E & e) : execution_{std::make_unique<execution<E>>(e)} {}
43 
44  bool has_execution() const { return execution_.get() != nullptr; }
45 
60  template <typename ... InputIterators, typename OutputIterator,
61  typename Transformer>
62  void map(std::tuple<InputIterators...> firsts,
63  OutputIterator first_out, std::size_t sequence_size,
64  Transformer && transform_op) const;
65 
79  template <typename InputIterator, typename Identity, typename Combiner>
80  auto reduce(InputIterator first, std::size_t sequence_size,
81  Identity && identity,
82  Combiner && combine_op) const;
83 
98  template <typename ... InputIterators, typename Identity,
99  typename Transformer, typename Combiner>
100  auto map_reduce(std::tuple<InputIterators...> firsts,
101  std::size_t sequence_size,
102  Identity && identity,
103  Transformer && transform_op, Combiner && combine_op) const;
104 
121  template <typename ... InputIterators, typename OutputIterator,
122  typename StencilTransformer, typename Neighbourhood>
123  void stencil(std::tuple<InputIterators...> firsts, OutputIterator first_out,
124  std::size_t sequence_size,
125  StencilTransformer && transform_op,
126  Neighbourhood && neighbour_op) const;
127 
140  template <typename Input, typename Divider, typename Solver, typename Combiner>
141  [[deprecated("Use new interface with predicate argument")]]
142  auto divide_conquer(Input && input,
143  Divider && divide_op,
144  Solver && solve_op,
145  Combiner && combine_op) const;
146 
147 
162  template <typename Input, typename Divider, typename Predicate, typename Solver, typename Combiner>
163  auto divide_conquer(Input && input,
164  Divider && divide_op,
165  Predicate && predicate_op,
166  Solver && solve_op,
167  Combiner && combine_op) const;
168 
169 
177  template <typename Generator, typename ... Transformers>
178  void pipeline(Generator && generate_op,
179  Transformers && ... transform_ops) const;
180 
181 private:
182 
183  class execution_base {
184  public:
185  virtual ~execution_base() {};
186  };
187 
188  template <typename E>
189  class execution : public execution_base {
190  public:
191  execution(const E & e) : ex_{e} {}
192  virtual ~execution() = default;
193  E ex_;
194  };
195 
196 private:
198  std::unique_ptr<execution_base> execution_;
199 
200 };
201 
206 template <>
207 constexpr bool is_supported<dynamic_execution>() { return true; }
208 
213 template <>
214 constexpr bool supports_map<dynamic_execution>() { return true; }
215 
220 template <>
221 constexpr bool supports_reduce<dynamic_execution>() { return true; }
222 
227 template <>
228 constexpr bool supports_map_reduce<dynamic_execution>() { return true; }
229 
234 template <>
235 constexpr bool supports_stencil<dynamic_execution>() { return true; }
236 
241 template <>
242 constexpr bool supports_divide_conquer<dynamic_execution>() { return true; }
243 
248 template <>
249 constexpr bool supports_pipeline<dynamic_execution>() { return true; }
250 
251 
252 
253 #define GRPPI_TRY_PATTERN(E,PATTERN,...)\
254 {\
255  if (supports_##PATTERN<E>()) {\
256  auto * ex = dynamic_cast<execution<E>*>(execution_.get());\
257  if (ex) {\
258  return ex->ex_.PATTERN(__VA_ARGS__);\
259  }\
260  }\
261 }
262 
263 #define GRPPI_PATTERN_NOT_IMPLEMENTED(PATTERN,...)\
264 throw std::runtime_error{"Pattern " #PATTERN " not implemented"};
265 
266 #ifdef GRPPI_OMP
267 #define GRPPI_TRY_PATTERN_OMP(PATTERN,...) \
268 GRPPI_TRY_PATTERN(parallel_execution_omp,PATTERN,__VA_ARGS__)
269 #else
270 #define GRPPI_TRY_PATTERN_OMP(PATTERN,...)
271 #endif
272 
273 #ifdef GRPPI_TBB
274 #define GRPPI_TRY_PATTERN_TBB(PATTERN,...) \
275 GRPPI_TRY_PATTERN(parallel_execution_tbb,PATTERN,__VA_ARGS__)
276 #else
277 #define GRPPI_TRY_PATTERN_TBB(PATTERN,...)
278 #endif
279 
280 #ifdef GRPPI_FF
281 #define GRPPI_TRY_PATTERN_FF(PATTERN,...) \
282 GRPPI_TRY_PATTERN(parallel_execution_ff,PATTERN,__VA_ARGS__)
283 #else
284 #define GRPPI_TRY_PATTERN_FF(PATTERN,...)
285 #endif
286 
287 #define GRPPI_TRY_PATTERN_ALL(...) \
288 GRPPI_TRY_PATTERN(sequential_execution, __VA_ARGS__) \
289 GRPPI_TRY_PATTERN(parallel_execution_native, __VA_ARGS__) \
290 GRPPI_TRY_PATTERN_OMP(__VA_ARGS__) \
291 GRPPI_TRY_PATTERN_TBB(__VA_ARGS__) \
292 GRPPI_TRY_PATTERN_FF(__VA_ARGS__) \
293 GRPPI_PATTERN_NOT_IMPLEMENTED(__VA_ARGS__)\
294 
295 #define GRPPI_TRY_PATTERN_ALL_NOFF(...) \
296 GRPPI_TRY_PATTERN(sequential_execution, __VA_ARGS__) \
297 GRPPI_TRY_PATTERN(parallel_execution_native, __VA_ARGS__) \
298 GRPPI_TRY_PATTERN_OMP(__VA_ARGS__) \
299 GRPPI_TRY_PATTERN_TBB(__VA_ARGS__) \
300 GRPPI_PATTERN_NOT_IMPLEMENTED(__VA_ARGS__)\
301 
302 template <typename ... InputIterators, typename OutputIterator,
303  typename Transformer>
305  std::tuple<InputIterators...> firsts,
306  OutputIterator first_out,
307  std::size_t sequence_size,
308  Transformer && transform_op) const
309 {
310  GRPPI_TRY_PATTERN_ALL(map, firsts, first_out, sequence_size,
311  std::forward<Transformer>(transform_op));
312 }
313 
314 template <typename InputIterator, typename Identity, typename Combiner>
315 auto dynamic_execution::reduce(InputIterator first, std::size_t sequence_size,
316  Identity && identity,
317  Combiner && combine_op) const
318 {
319  GRPPI_TRY_PATTERN_ALL(reduce, first, sequence_size,
320  std::forward<Identity>(identity), std::forward<Combiner>(combine_op));
321 }
322 
323 template <typename ... InputIterators, typename Identity,
324  typename Transformer, typename Combiner>
326  std::tuple<InputIterators...> firsts,
327  std::size_t sequence_size,
328  Identity && identity,
329  Transformer && transform_op,
330  Combiner && combine_op) const
331 {
332  GRPPI_TRY_PATTERN_ALL(map_reduce, firsts, sequence_size,
333  std::forward<Identity>(identity),
334  std::forward<Transformer>(transform_op),
335  std::forward<Combiner>(combine_op));
336 }
337 
338 template <typename ... InputIterators, typename OutputIterator,
339  typename StencilTransformer, typename Neighbourhood>
341  std::tuple<InputIterators...> firsts,
342  OutputIterator first_out,
343  std::size_t sequence_size,
344  StencilTransformer && transform_op,
345  Neighbourhood && neighbour_op) const
346 {
347  GRPPI_TRY_PATTERN_ALL(stencil, firsts, first_out, sequence_size,
348  std::forward<StencilTransformer>(transform_op),
349  std::forward<Neighbourhood>(neighbour_op));
350 }
351 
352 template <typename Input, typename Divider, typename Solver, typename Combiner>
354  Input && input,
355  Divider && divide_op,
356  Solver && solve_op,
357  Combiner && combine_op) const
358 {
359  GRPPI_TRY_PATTERN_ALL_NOFF(divide_conquer, std::forward<Input>(input),
360  std::forward<Divider>(divide_op),
361  std::forward<Solver>(solve_op),
362  std::forward<Combiner>(combine_op));
363 }
364 
365 
366 template <typename Input, typename Divider,typename Predicate, typename Solver, typename Combiner>
368  Input && input,
369  Divider && divide_op,
370  Predicate && predicate_op,
371  Solver && solve_op,
372  Combiner && combine_op) const
373 {
374  GRPPI_TRY_PATTERN_ALL(divide_conquer, std::forward<Input>(input),
375  std::forward<Divider>(divide_op),
376  std::forward<Predicate>(predicate_op),
377  std::forward<Solver>(solve_op),
378  std::forward<Combiner>(combine_op));
379 }
380 
381 template <typename Generator, typename ... Transformers>
383  Generator && generate_op,
384  Transformers && ... transform_ops) const
385 {
386  GRPPI_TRY_PATTERN_ALL(pipeline, std::forward<Generator>(generate_op),
387  std::forward<Transformers>(transform_ops)...);
388 }
389 
390 #undef GRPPI_TRY_PATTERN
391 #undef GRPPI_TRY_PATTERN_OMP
392 #undef GRPPI_TRY_PATTERN_TBB
393 #undef GRPPI_TRY_PATTERN_ALL
394 #undef GRPPI_TRY_PATTERN_ALL_NOFF
395 
396 } // end namespace grppi
397 
398 #endif
Definition: callable_traits.h:26
constexpr bool is_supported< dynamic_execution >()
Determines if an execution policy is supported in the current compilation.
Definition: dynamic_execution.h:207
auto map_reduce(std::tuple< InputIterators... > firsts, std::size_t sequence_size, Identity &&identity, Transformer &&transform_op, Combiner &&combine_op) const
Applies a map/reduce operation to a sequence of data items.
Definition: dynamic_execution.h:325
bool has_execution() const
Definition: dynamic_execution.h:44
auto reduce(InputIterator first, std::size_t sequence_size, Identity &&identity, Combiner &&combine_op) const
Applies a reduction to a sequence of data items.
Definition: dynamic_execution.h:315
constexpr bool supports_pipeline< dynamic_execution >()
Determines if an execution policy supports the pipeline pattern.
Definition: dynamic_execution.h:249
constexpr bool supports_stencil< dynamic_execution >()
Determines if an execution policy supports the stencil pattern.
Definition: dynamic_execution.h:235
constexpr bool supports_map< dynamic_execution >()
Determines if an execution policy supports the map pattern.
Definition: dynamic_execution.h:214
dynamic_execution() noexcept
Definition: dynamic_execution.h:37
#define GRPPI_TRY_PATTERN_ALL_NOFF(...)
Definition: dynamic_execution.h:295
#define GRPPI_TRY_PATTERN_ALL(...)
Definition: dynamic_execution.h:287
constexpr bool supports_reduce< dynamic_execution >()
Determines if an execution policy supports the reduce pattern.
Definition: dynamic_execution.h:221
void stencil(std::tuple< InputIterators... > firsts, OutputIterator first_out, std::size_t sequence_size, StencilTransformer &&transform_op, Neighbourhood &&neighbour_op) const
Applies a stencil to multiple sequences leaving the result in another sequence.
Definition: dynamic_execution.h:340
auto divide_conquer(Input &&input, Divider &&divide_op, Solver &&solve_op, Combiner &&combine_op) const
Invoke Divide/conquer pattern.
Definition: dynamic_execution.h:353
void pipeline(Generator &&generate_op, Transformers &&...transform_ops) const
Invoke Pipeline pattern.
Definition: dynamic_execution.h:382
constexpr bool supports_divide_conquer< dynamic_execution >()
Determines if an execution policy supports the divide/conquer pattern.
Definition: dynamic_execution.h:242
Definition: dynamic_execution.h:34
constexpr bool supports_map_reduce< dynamic_execution >()
Determines if an execution policy supports the map-reduce pattern.
Definition: dynamic_execution.h:228
dynamic_execution(const E &e)
Definition: dynamic_execution.h:42
void map(std::tuple< InputIterators... > firsts, OutputIterator first_out, std::size_t sequence_size, Transformer &&transform_op) const
Applies a trasnformation to multiple sequences leaving the result in another sequence.
Definition: dynamic_execution.h:304