Interface Documentation
Version: invalid
execution.hh
Go to the documentation of this file.
1 /*
2  @@@@@@@@ @@ @@@@@@ @@@@@@@@ @@
3  /@@///// /@@ @@////@@ @@////// /@@
4  /@@ /@@ @@@@@ @@ // /@@ /@@
5  /@@@@@@@ /@@ @@///@@/@@ /@@@@@@@@@/@@
6  /@@//// /@@/@@@@@@@/@@ ////////@@/@@
7  /@@ /@@/@@//// //@@ @@ /@@/@@
8  /@@ @@@//@@@@@@ //@@@@@@ @@@@@@@@ /@@
9  // /// ////// ////// //////// //
10 
11  Copyright (c) 2016, Triad National Security, LLC
12  All rights reserved.
13  */
14 #pragma once
15 
18 #if !defined(__FLECSI_PRIVATE__)
19 #define __FLECSI_PRIVATE__
20 #endif
21 
22 #include <boost/optional.hpp>
23 #include <boost/optional/optional_io.hpp>
24 #include <boost/program_options.hpp>
25 #include <boost/smart_ptr/make_shared.hpp>
26 
27 #include "flecsi/exec/backend.hh"
28 #include "flecsi/exec/fold.hh"
29 #include "flecsi/exec/launch.hh"
31 #include "flecsi/flog.hh"
32 #include "flecsi/run/backend.hh"
33 
34 /*----------------------------------------------------------------------------*
35  Basic runtime interface
36  *----------------------------------------------------------------------------*/
37 
38 namespace flecsi {
39 
54 inline int
55 initialize(int argc, char ** argv, bool dependent = true) {
56  return run::context::instance().initialize(argc, argv, dependent);
57 }
58 
68 inline int
69 start(const std::function<int()> & action) {
70  return run::context::instance().start(action);
71 }
72 
79 inline void
81  run::context::instance().finalize();
82 }
83 
84 enum option_attribute : size_t {
85  option_default,
86  option_implicit,
87  option_zero,
88  option_multi
89 }; // enum
90 
91 /*
92  Auxilliary type for program options.
93  */
94 
95 using any = boost::any;
96 
103 template<typename ValueType>
104 ValueType
105 option_value(any const & v) {
106  return boost::any_cast<boost::optional<ValueType>>(v).value();
107 }
108 
116 template<typename ValueType>
118 
120  : public std::pair<option_attribute, boost::optional<ValueType>> {
121 
122  initializer_value(option_attribute key) : initializer_value::pair(key, {}) {
123  flog_assert(key == option_zero || key == option_multi,
124  "invalid constructor for initializer_value: "
125  << (key == option_default ? "option_default" : "option_implicit")
126  << " must take a value");
127  }
128  initializer_value(option_attribute key, ValueType value)
129  : initializer_value::pair(key, value) {
130  flog_assert(key == option_default || key == option_implicit,
131  "invalid constructor for initializer_value: "
132  << (key == option_zero ? "option_zero" : "option_multi")
133  << " does not take a value");
134  }
135  };
136 
172  program_option(const char * section,
173  const char * flag,
174  const char * help,
175  std::initializer_list<initializer_value> values = {},
176  std::function<bool(const any &)> const & check = default_check) {
177 
178  auto semantic_ = boost::program_options::value(&value_);
179 
180  bool zero{false}, implicit{false};
181  for(auto const & v : values) {
182  if(v.first == option_default) {
183  semantic_->default_value(v.second);
184  }
185  else if(v.first == option_implicit) {
186  semantic_->implicit_value(v.second);
187  implicit = true;
188  }
189  else if(v.first == option_zero) {
190  semantic_->zero_tokens();
191  zero = true;
192  }
193  else if(v.first == option_multi) {
194  semantic_->multitoken();
195  }
196  else {
197  flog_fatal("invalid value type");
198  } // if
199  } // for
200 
201  if(zero) {
202  flog_assert(implicit, "option_zero specified without option_implicit");
203  } // if
204 
205  auto option =
206  boost::make_shared<boost::program_options::option_description>(
207  flag, semantic_, help);
208 
209  run::context::instance()
210  .descriptions_map()
211  .try_emplace(section, section)
212  .first->second.add(option);
213 
214  std::string sflag(flag);
215  sflag = sflag.substr(0, sflag.find(','));
216 
217  run::context::instance().option_checks().try_emplace(sflag, false, check);
218  } // program_option
219 
232  program_option(const char * name,
233  const char * help,
234  size_t count,
235  std::function<bool(const any &)> const & check = default_check) {
236  auto semantic_ = boost::program_options::value(&value_);
237  semantic_->required();
238 
239  auto option =
240  boost::make_shared<boost::program_options::option_description>(
241  name, semantic_, help);
242 
243  auto & c = run::context::instance();
244  c.positional_description().add(name, count);
245  c.positional_help().try_emplace(name, help);
246  c.hidden_options().add(option);
247  c.option_checks().try_emplace(name, true, check);
248  } // program_options
249 
250  ValueType value() const {
251  return value_.value();
252  }
253 
254  operator ValueType() const {
255  return value();
256  }
257 
258  bool has_value() const {
259  return value_.has_value();
260  }
261 
262 private:
263  static bool default_check(const boost::any &) {
264  return true;
265  }
266 
267  boost::optional<ValueType> value_{};
268 
269 }; // struct program_option
270 
275 inline std::string const &
277  return run::context::instance().program();
278 }
279 
284 inline size_t
286  return run::context::instance().process();
287 }
288 
293 inline size_t
295  return run::context::instance().processes();
296 }
297 
302 inline size_t
304  return run::context::instance().threads_per_process();
305 }
306 
315 inline size_t
317  return run::context::instance().threads();
318 }
319 
325 inline size_t
326 color() {
327  return run::context::instance().color();
328 }
329 
335 inline size_t
337  return run::context::instance().colors();
338 }
339 
350 template<auto & TASK,
351  const exec::launch_domain & LAUNCH_DOMAIN,
352  class REDUCTION_OPERATION,
353  size_t ATTRIBUTES,
354  typename... ARGS>
355 decltype(auto) reduce(ARGS &&... args);
356 
377 template<auto & TASK,
378  const exec::launch_domain & LAUNCH_DOMAIN = index,
379  size_t ATTRIBUTES = flecsi::loc | flecsi::leaf,
380  typename... ARGS>
381 decltype(auto)
382 execute(ARGS &&... args) {
383  return reduce<TASK, LAUNCH_DOMAIN, void, ATTRIBUTES>(
384  std::forward<ARGS>(args)...);
385 } // execute
386 
406 template<auto & TASK,
407  const exec::launch_domain & LAUNCH_DOMAIN = flecsi::index,
408  size_t ATTRIBUTES = flecsi::loc | flecsi::leaf,
409  typename... ARGS>
410 int
411 test(ARGS &&... args) {
412  return reduce<TASK, LAUNCH_DOMAIN, exec::fold::sum<int>, ATTRIBUTES>(
413  std::forward<ARGS>(args)...)
414  .get();
415 } // test
416 
417 } // namespace flecsi
int test(ARGS &&... args)
Definition: execution.hh:411
size_t threads_per_process()
Definition: execution.hh:303
program_option(const char *name, const char *help, size_t count, std::function< bool(const any &)> const &check=default_check)
Definition: execution.hh:232
ValueType option_value(any const &v)
Definition: execution.hh:105
std::string const & program()
Definition: execution.hh:276
decltype(auto) execute(ARGS &&... args)
Definition: execution.hh:382
decltype(auto) reduce(ARGS &&... args)
Definition: policy.hh:90
#define flog_assert(test, message)
Definition: flog.hh:411
int start(const std::function< int()> &action)
Definition: execution.hh:69
Definition: execution.hh:117
program_option(const char *section, const char *flag, const char *help, std::initializer_list< initializer_value > values={}, std::function< bool(const any &)> const &check=default_check)
Definition: execution.hh:172
#define flog_fatal(message)
Definition: flog.hh:358
size_t processes()
Definition: execution.hh:294
int initialize(int argc, char **argv, bool dependent=true)
Definition: execution.hh:55
size_t process()
Definition: execution.hh:285
void finalize()
Definition: execution.hh:80
A launch domain with a static identity but a runtime size.
Definition: launch.hh:62
size_t color()
Definition: execution.hh:326
size_t colors()
Definition: execution.hh:336
Definition: execution.hh:119
size_t threads()
Definition: execution.hh:316
Definition: control.hh:31