Stride Reference Manual  1.0
unipar/unipar.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <functional>
5 #include <type_traits>
6 
7 #include "utils.h"
8 
9 namespace unipar {
10 namespace internal {
11 
12 template<typename Impl, typename... Types>
14 
15 template<typename Impl, typename Type, typename... Rest>
16 struct ResourceManager<Impl, Type, Rest...> {
17  using RestType = typename Impl::template RMType<Impl, Rest...>;
18  using FuncType = std::function<Type()>;
19 
20  ResourceManager() = default;
21 
22  ResourceManager(const RestType& rest) : m_rest(rest) {}
23 
25  : m_rest(rm.m_rest) {
26  using ThisRMType = typename Impl::template RMType<Impl, Type, Rest...>;
27  ((ThisRMType*) this)->setFunc(rm.m_func);
28  }
29 
30  ResourceManager<Impl, Type, Rest...>& operator=(const ResourceManager<Impl, Type, Rest...>& other) {
31  using ThisRMType = typename Impl::template RMType<Impl, Type, Rest...>;
32  m_rest = other.m_rest;
33  ((ThisRMType*) this)->setFunc(other.m_func);
34  return *this;
35  }
36 
37  void setFunc(const FuncType& f) {
38  m_func = f;
39  }
40 
42  return m_rest;
43  }
44 
45  const RestType& rest() const {
46  return m_rest;
47  }
48 
49  // The function call is essential and should be provided by
50  // all classes inheriting this class!
51 
52 protected:
55 };
56 
57 template<typename Impl>
58 struct ResourceManager<Impl> {
59  // End of the recursion
60  template<typename F, typename... Args>
61  typename std::result_of<F(Args...)>::type call(const F& func, Args&& ... args) {
62  return func(std::forward<Args>(args)...);
63  }
64 };
65 
66 
67 template<typename Impl, typename... Types>
69 public:
70  using RMType = typename Impl::template RMType<Impl, Types...>;
71 
72  // Constructors .......................................
73 
74  ParallelWrapper(const Impl& impl) : m_impl(impl) {}
75 
76  // Prefer the one without an argument.
77  ParallelWrapper(int nthreads) : m_impl(nthreads) { m_impl.init(m_resource_manager); }
78 
79  ParallelWrapper() : m_impl() { m_impl.init(m_resource_manager); }
80 
81  // Kinda private, however friend'ing is rather hard with variadic templates
82  template<typename PrevResMan>
83  ParallelWrapper(Impl& impl, PrevResMan& prev_rm)
84  : m_impl(impl), m_resource_manager(prev_rm) {
85  m_impl.init(m_resource_manager);
86  }
87 
88 
89  // Actual parallel constructions ......................
90 
91  template<typename IndexF, typename IndexL, typename Func>
92  void for_(IndexF first, IndexL last, const Func& f) {
93  for_(first, last, typename unipar::utils::largest<IndexF, IndexL>::type(1), f);
94  }
95 
96  template<typename IndexF, typename IndexL, typename IndexS, typename Func>
97  void for_(IndexF first, IndexL last, IndexS step, const Func& f) {
98  m_impl.parallelFor(first, last, step, f, m_resource_manager);
99  }
100 
101 
102  // Resource management ................................
103 
104  template<typename T>
105  ParallelWrapper<Impl, T, Types...> withFunc(const std::function<T()>& f) {
106  auto p = ParallelWrapper<Impl, T, Types...>(m_impl, m_resource_manager);
107  p.resources().setFunc(f);
108  return p;
109  }
110 
111  // for Lambda's
112  template<typename T, typename Func>
113  ParallelWrapper<Impl, T, Types...> withFunc(const Func& f) {
114  return withFunc(std::function<T()>(f));
115  }
116 
117  template<typename T, typename... Args>
118  ParallelWrapper<Impl, T, Types...> with(Args... args) {
119  return withFunc<T>(std::function<T()>([=]() {
120  return T(args...);
121  }));
122  }
123 
125  return m_resource_manager;
126  }
127 
128 
129  // Proxying to the implementation .....................
130 
131  // Also see the constructors above
132 
133  Impl& impl() { return m_impl; }
134 
135  const Impl& impl() const { return m_impl; }
136 
137  // This number should be seen as a hint and not a hard limit.
138  int getNumThreads() const { return m_impl.getNumThreads(); }
139 
140  void setNumThreads(int nthreads) { m_impl.setNumThreads(nthreads); }
141 
142 protected:
143  Impl m_impl;
145 };
146 
147 }
148 }
149 
ParallelWrapper< Impl, T, Types... > with(Args...args)
void for_(IndexF first, IndexL last, const Func &f)
Definition: unipar/unipar.h:92
ResourceManager< Impl, Type, Rest... > & operator=(const ResourceManager< Impl, Type, Rest... > &other)
Definition: unipar/unipar.h:30
std::result_of< F(Args...)>::type call(const F &func, Args &&...args)
Definition: unipar/unipar.h:61
ResourceManager(const ResourceManager< Impl, Type, Rest... > &rm)
Definition: unipar/unipar.h:24
ParallelWrapper(Impl &impl, PrevResMan &prev_rm)
Definition: unipar/unipar.h:83
typename Impl::template RMType< Impl, Types... > RMType
Definition: unipar/unipar.h:70
ParallelWrapper< Impl, T, Types... > withFunc(const std::function< T()> &f)
Unified Parallelisation.
Definition: dummy.h:7
void for_(IndexF first, IndexL last, IndexS step, const Func &f)
Definition: unipar/unipar.h:97
typename Impl::template RMType< Impl, Rest... > RestType
Definition: unipar/unipar.h:17
ParallelWrapper< Impl, T, Types... > withFunc(const Func &f)
is_cond<(sizeof(T1) > sizeof(T2)), T1, T2 >::type type