Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Traits.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
20 #ifndef GALOIS_TRAITS_H
21 #define GALOIS_TRAITS_H
22 
23 #include <tuple>
24 #include <type_traits>
25 
26 #include "galois/config.h"
28 
29 namespace galois {
30 
31 // Trait classifications
32 
33 template <typename T>
35  typedef T type;
36 };
37 
38 template <typename T>
40  typedef T type;
42  trait_has_value(const type& v) : value(v) {}
43  trait_has_value(type&& v) : value(std::move(v)) {}
44  T getValue() const { return value; }
45 };
46 
47 template <typename T, T V>
49  typedef T type;
50  static const type value = V;
51  T getValue() const { return V; }
52 };
53 
58 template <template <typename...> class TT, typename... Args>
59 auto make_trait_with_args(Args... args) -> TT<Args...> {
60  return TT<Args...>(args...);
61 }
62 
68 template <typename Base, typename Derived>
69 constexpr bool at_least_base_of =
70  std::is_base_of<Base, Derived>::value || std::is_same<Base, Derived>::value;
71 
77 template <typename T, typename Tuple, size_t Int, size_t... Ints>
78 constexpr size_t find_trait(std::index_sequence<Int, Ints...> /*seq*/) {
79  if constexpr (at_least_base_of<
80  T, typename std::tuple_element<Int, Tuple>::type>) {
81  return Int;
82  } else {
83  return find_trait<T, Tuple>(std::index_sequence<Ints...>{});
84  }
85 }
86 
87 template <typename T, typename Tuple>
88 constexpr size_t find_trait() {
89  constexpr std::make_index_sequence<std::tuple_size<Tuple>::value> seq{};
90  return find_trait<T, Tuple>(seq);
91 }
92 
96 template <typename T, typename... Ts>
97 constexpr bool has_trait(std::tuple<Ts...>* /*tpl*/) {
98  return (... || at_least_base_of<T, Ts>);
99 }
100 
101 template <typename T, typename Tuple>
102 constexpr bool has_trait() {
103  return has_trait<T>(static_cast<Tuple*>(nullptr));
104 }
105 
111 template <typename T, typename Tuple>
112 constexpr auto get_trait_value(Tuple tpl) {
113  constexpr size_t match(find_trait<T, Tuple>());
114  return std::get<match>(tpl);
115 }
116 
120 template <typename T, typename Tuple>
122  using type = typename std::tuple_element<find_trait<T, Tuple>(), Tuple>::type;
123 };
124 
125 // Fallback to enable_if tricks over if constexpr to play more nicely with
126 // unused parameter warnings.
127 
128 template <typename S, typename T, typename D>
129 constexpr auto get_default_trait_value(
130  S /*source*/, T /*tag*/, D /*def*/,
131  typename std::enable_if<has_trait<T, S>()>::type* = nullptr) {
132  return std::make_tuple();
133 }
134 
135 template <typename S, typename T, typename D>
136 constexpr auto get_default_trait_value(
137  S GALOIS_UNUSED(source), T GALOIS_UNUSED(tags), D defaults,
138  typename std::enable_if<!has_trait<T, S>()>::type* = nullptr) {
139  return std::make_tuple(defaults);
140 }
141 
146 template <typename S, typename T, typename D>
147 constexpr auto
148 get_default_trait_values(std::index_sequence<> GALOIS_UNUSED(seq),
149  S GALOIS_UNUSED(source), T GALOIS_UNUSED(tags),
150  D GALOIS_UNUSED(defaults)) {
151  return std::make_tuple();
152 }
153 
154 template <size_t... Ints, typename S, typename T, typename D>
155 constexpr auto
156 get_default_trait_values(std::index_sequence<Ints...> GALOIS_UNUSED(seq),
157  S source, T tags, D defaults) {
158  return std::tuple_cat(get_default_trait_value(source, std::get<Ints>(tags),
159  std::get<Ints>(defaults))...);
160 }
161 
162 template <typename S, typename T, typename D>
163 constexpr auto get_default_trait_values(S source, T tags, D defaults) {
164  constexpr std::make_index_sequence<std::tuple_size<T>::value> seq{};
165  return get_default_trait_values(seq, source, tags, defaults);
166 }
167 
168 template <typename T>
169 constexpr auto has_function_traits(int)
170  -> decltype(std::declval<typename T::function_traits>(), bool()) {
171  return true;
172 }
173 
174 template <typename>
175 constexpr auto has_function_traits(...) -> bool {
176  return false;
177 }
178 
179 template <typename T, typename Enable = void>
181  typedef std::tuple<> type;
182 };
183 
184 template <typename T>
186  T, typename std::enable_if<has_function_traits<T>(0)>::type> {
187  typedef typename T::function_traits type;
188 };
189 
190 // Traits
191 
196 struct loopname_tag {};
197 struct loopname : public trait_has_value<const char*>, loopname_tag {
198  loopname(const char* p = "ANON_LOOP") : trait_has_value<const char*>(p) {}
199 };
200 
205 struct steal_tag {};
206 struct steal : public trait_has_type<bool>, steal_tag {};
207 
211 struct wl_tag {};
212 template <typename T, typename... Args>
213 struct s_wl : public trait_has_type<T>, wl_tag {
214  std::tuple<Args...> args;
215  s_wl(Args&&... a) : args(std::forward<Args>(a)...) {}
216 };
217 
218 template <typename T, typename... Args>
219 s_wl<T, Args...> wl(Args&&... args) {
220  return s_wl<T, Args...>(std::forward<Args>(args)...);
221 }
222 
223 //
230 
234 struct no_pushes_tag {};
235 struct no_pushes : public trait_has_type<bool>, no_pushes_tag {};
236 
242 
246 struct no_stats_tag {};
247 struct no_stats : public trait_has_type<bool>, no_stats_tag {};
248 
253 struct more_stats_tag {};
254 struct more_stats : public trait_has_type<bool>, more_stats_tag {};
255 
260 struct no_conflicts : public trait_has_type<bool>, no_conflicts_tag {};
261 
270 struct fixed_neighborhood : public trait_has_type<bool>,
272 
278 
284 template <typename T>
287  neighborhood_visitor(const T& t = T{}) : trait_has_value<T>(t) {}
288  neighborhood_visitor(T&& t) : trait_has_value<T>(std::move(t)) {}
289 };
290 
302 template <typename T>
304  static_assert(std::is_same<typename std::result_of<T()>::type, bool>::value,
305  "signature must be bool()");
306  det_parallel_break(const T& t = T()) : trait_has_value<T>(t) {}
307  det_parallel_break(T&& t) : trait_has_value<T>(std::move(t)) {}
308 };
309 
317 struct det_id_tag {};
318 template <typename T>
319 struct det_id : public trait_has_value<T>, det_id_tag {
320  det_id(const T& t = T()) : trait_has_value<T>(t) {}
321  det_id(T&& t) : trait_has_value<T>(std::move(t)) {}
322 };
323 
329 struct local_state_tag {};
330 template <typename T>
332 
333 // TODO: separate to libdist
335 struct op_tag {};
336 
338  enum { MIN = 1, MAX = 4096 };
339 };
340 
354 template <unsigned SZ = 32>
355 struct chunk_size : public trait_has_value<unsigned>, chunk_size_tag {
356 private:
357  constexpr static unsigned clamp(unsigned int v) {
358  return std::min(std::max(v, unsigned{chunk_size_tag::MIN}),
359  unsigned{chunk_size_tag::MAX});
360  }
361 
362 public:
363  constexpr static unsigned value = clamp(SZ);
364 
365  chunk_size(unsigned cs = SZ) : trait_has_value(clamp(cs)) {}
366 };
367 
369 
370 namespace internal {
371 
372 template <typename Tup>
373 struct NeedStats {
374  constexpr static const bool value =
375  !has_trait<no_stats_tag, Tup>() && has_trait<loopname_tag, Tup>();
376 };
377 
378 template <typename Tup>
379 std::enable_if_t<has_trait<loopname_tag, Tup>(), const char*>
380 getLoopName(const Tup& t) {
381  return get_trait_value<loopname_tag>(t).value;
382 }
383 
384 template <typename Tup>
385 std::enable_if_t<!has_trait<loopname_tag, Tup>(), const char*>
386 getLoopName(const Tup&) {
387  return "ANON_LOOP";
388 }
389 } // namespace internal
390 
391 } // namespace galois
392 
393 #endif
Definition: Traits.h:247
Definition: Traits.h:235
Definition: Traits.h:338
neighborhood_visitor(T &&t)
Definition: Traits.h:288
Definition: Traits.h:338
Indicate whetherlink do_all()} loops should perform work-stealing.
Definition: Traits.h:205
det_id(const T &t=T())
Definition: Traits.h:320
loopname(const char *p="ANON_LOOP")
Definition: Traits.h:198
Definition: Traits.h:277
Indicates the operator may request the access to a per-iteration allocator.
Definition: Traits.h:240
T type
Definition: Traits.h:35
Definition: Traits.h:197
Definition: Traits.h:241
det_id(T &&t)
Definition: Traits.h:321
Definition: Traits.h:180
Definition: Traits.h:34
worklists::PerSocketChunkFIFO< chunk_size<>::value > defaultWL
Definition: Traits.h:368
constexpr size_t find_trait(std::index_sequence< Int, Ints...>)
Returns index of first matching trait in Tuple.
Definition: Traits.h:78
Indicates the operator has a function that optimizes the generation of unique ids for active elements...
Definition: Traits.h:317
Definition: Traits.h:229
Definition: Traits.h:303
Returns the type associated with the given trait in a tuple.
Definition: Traits.h:121
Specify chunk size for do_all_coupled &amp; do_all_choice at compile time or at runtime.
Definition: Traits.h:355
For distributed Galois.
Definition: Traits.h:335
Indicates that the operator uses the intent to read flag.
Definition: Traits.h:276
Definition: Traits.h:254
trait_has_value(type &&v)
Definition: Traits.h:43
Indicates worklist to use.
Definition: Traits.h:211
T getValue() const
Definition: Traits.h:44
Definition: Traits.h:260
Indicate name to appear in statistics.
Definition: Traits.h:196
typename std::tuple_element< find_trait< T, Tuple >(), Tuple >::type type
Definition: Traits.h:122
Indicates that the neighborhood set does not change through out i.e.
Definition: Traits.h:269
T getValue() const
Definition: Traits.h:51
type value
Definition: Traits.h:41
Indicates the operator has a function that visits the neighborhood of the operator without modifying ...
Definition: Traits.h:283
s_wl< T, Args...> wl(Args &&...args)
Definition: Traits.h:219
const Ty max(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:40
Definition: Traits.h:337
Definition: Traits.h:206
static constexpr unsigned value
Definition: Traits.h:363
constexpr bool at_least_base_of
True if Derived is derived from Base or is Base itself.
Definition: Traits.h:69
chunk_size(unsigned cs=SZ)
Definition: Traits.h:365
std::tuple type
Definition: Traits.h:181
det_parallel_break(const T &t=T())
Definition: Traits.h:306
Definition: Traits.h:331
const Ty min(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:70
auto make_trait_with_args(Args...args) -> TT< Args...>
Utility function to simplify creating traits that take unnamed functions (i.e., lambdas).
Definition: Traits.h:59
neighborhood_visitor(const T &t=T{})
Definition: Traits.h:287
trait_has_value(const type &v)
Definition: Traits.h:42
Definition: Traits.h:285
s_wl(Args &&...a)
Definition: Traits.h:215
Definition: Traits.h:39
static const type value
Definition: Traits.h:50
Definition: Traits.h:270
Indicates the operator does not generate new work and push it on the worklist.
Definition: Traits.h:234
Indicates the operator doesn&#39;t need abort support.
Definition: Traits.h:259
Definition: Traits.h:48
Definition: Traits.h:319
det_parallel_break(T &&t)
Definition: Traits.h:307
Indicates the operator doesn&#39;t need its execution stats recorded.
Definition: Traits.h:246
std::tuple< Args...> args
Definition: Traits.h:214
T type
Definition: Traits.h:40
constexpr auto get_trait_value(Tuple tpl)
Returns the value associated with the given trait T in a tuple.
Definition: Traits.h:112
Indicates the operator has a function that allows a galois::for_each loop to be exited deterministica...
Definition: Traits.h:301
Definition: Traits.h:213
constexpr bool has_trait(std::tuple< Ts...> *)
Returns true if the tuple type contains the given trait T.
Definition: Traits.h:97
constexpr auto has_function_traits(int) -> decltype(std::declval< typename T::function_traits >(), bool())
Definition: Traits.h:169
constexpr auto get_default_trait_values(std::index_sequence<> GALOIS_UNUSED(seq), S GALOIS_UNUSED(source), T GALOIS_UNUSED(tags), D GALOIS_UNUSED(defaults))
Returns a tuple that has an element from defaults[i] for every type from tags[i] missing in source...
Definition: Traits.h:148
internal::ChunkMaster< T, ConExtLinkedQueue, true, false, ChunkSize, Concurrent > PerSocketChunkFIFO
Distributed chunked FIFO.
Definition: Chunk.h:296
constexpr auto get_default_trait_value(S, T, D, typename std::enable_if< has_trait< T, S >()>::type *=nullptr)
Definition: Traits.h:129
T type
Definition: Traits.h:49
Indicates the operator has a type that encapsulates state that is passed between the suspension and r...
Definition: Traits.h:329
Indicates the operator may request the parallel loop to be suspended and a given function run in seri...
Definition: Traits.h:228
Indicates the operator needs detailed stats Must provide loopname to enable this flag.
Definition: Traits.h:253