18 #if !defined(__FLECSI_PRIVATE__) 19 #error Do not include this file directly! 25 #include "flecsi/topo/core.hh" 29 #include <boost/optional.hpp> 30 #include <boost/program_options.hpp> 37 #include <unordered_map> 43 inline log::devel_tag context_tag(
"context");
70 using field_info_store_t = data::fields;
79 size_t index_subspace;
107 boost::program_options::positional_options_description &
108 positional_description() {
109 return positional_desc_;
112 std::map<std::string, std::string> & positional_help() {
113 return positional_help_;
116 boost::program_options::options_description & hidden_options() {
117 return hidden_options_;
120 std::map<std::string,
121 std::pair<bool, std::function<bool(boost::any const &)>>> &
123 return option_checks_;
126 std::vector<char *> & argv() {
130 std::string
const &
program() {
134 auto & descriptions_map() {
135 return descriptions_map_;
138 std::vector<std::string>
const & unrecognized_options() {
140 "unitialized program options -> " 141 "invoke flecsi::initialize_program_options");
142 return unrecognized_options_;
149 inline int initialize_generic(
int argc,
char ** argv,
bool dependent) {
151 initialize_dependent_ = dependent;
154 for(
auto i(0); i < argc; ++i) {
155 argv_.push_back(argv[i]);
159 program_ = program_.substr(program_.rfind(
'/') + 1);
161 boost::program_options::options_description master(
"Basic Options");
162 master.add_options()(
"help,h",
"Print this message and exit.");
165 for(
auto & od : descriptions_map_) {
166 if(od.first !=
"FleCSI Options") {
167 master.add(od.second);
171 boost::program_options::options_description flecsi_desc =
172 descriptions_map_.count(
"FleCSI Options")
173 ? descriptions_map_[
"FleCSI Options"]
174 : boost::program_options::options_description(
"FleCSI Options");
176 flecsi_desc.add_options()(
"backend-args",
177 boost::program_options::value(&backend_)->default_value(
""),
178 "Pass arguments to the runtime backend. The single argument is a quoted " 179 "string of backend-specific options.");
180 #if defined(FLECSI_ENABLE_FLOG) 182 flecsi_desc.add_options()
185 boost::program_options::value(&flog_tags_)
186 ->default_value(
"all"),
187 "Enable the specified output tags, e.g., --flog-tags=tag1,tag2." 191 boost::program_options::value(&flog_verbose_)
194 "Enable verbose output. Passing '-1' will strip any additional" 195 " decorations added by flog and will only output the user's message." 199 boost::program_options::value(&flog_output_process_)->default_value(-1),
200 "Restrict output to the specified process id." 206 boost::program_options::options_description all(
"All Options");
208 all.add(flecsi_desc);
209 all.add(hidden_options_);
211 boost::program_options::parsed_options parsed =
212 boost::program_options::command_line_parser(argc, argv)
214 .positional(positional_desc_)
215 .allow_unregistered()
218 auto print_usage = [
this](std::string
program,
222 std::cout <<
"Usage: " << program <<
" ";
224 size_t positional_count = positional_desc_.max_total_count();
225 size_t max_label_chars = std::numeric_limits<size_t>::min();
227 for(
size_t i{0}; i < positional_count; ++i) {
228 std::cout <<
"<" << positional_desc_.name_for_position(i) <<
"> ";
230 const size_t size = positional_desc_.name_for_position(i).size();
231 max_label_chars = size > max_label_chars ? size : max_label_chars;
234 max_label_chars += 2;
236 std::cout << std::endl << std::endl;
238 if(positional_count) {
239 std::cout <<
"Positional Options:" << std::endl;
241 for(
size_t i{0}; i < positional_desc_.max_total_count(); ++i) {
242 auto const & name = positional_desc_.name_for_position(i);
243 auto help = positional_help_.at(name);
244 std::cout <<
" " << name <<
" ";
245 std::cout << std::string(max_label_chars - name.size() - 2,
' ');
247 if(help.size() > 78 - max_label_chars) {
248 std::string first = help.substr(
249 0, help.substr(0, 78 - max_label_chars).find_last_of(
' '));
250 std::cout << first << std::endl;
252 help.substr(first.size() + 1, help.size() - first.size() + 1);
254 while(help.size() > 78 - max_label_chars) {
255 std::string part = help.substr(
256 0, help.substr(0, 78 - max_label_chars).find_last_of(
' '));
257 std::cout << std::string(max_label_chars + 1,
' ') << part
259 help = help.substr(part.size() + 1, help.size() - part.size());
262 std::cout << std::string(max_label_chars + 1,
' ') << help
266 std::cout << help << std::endl;
271 std::cout << std::endl;
274 std::cout << master << std::endl;
275 std::cout <<
flecsi << std::endl;
277 #if defined(FLECSI_ENABLE_FLOG) 281 std::cout <<
"Available FLOG Tags (FleCSI Logging Utility):" 286 std::cout <<
" " << t.first << std::endl;
293 boost::program_options::variables_map vm;
294 boost::program_options::store(parsed, vm);
296 if(vm.count(
"help")) {
297 print_usage(program_, master, flecsi_desc);
301 boost::program_options::notify(vm);
304 for(
auto const & [name, boost_any] : vm) {
305 auto const & ita = option_checks_.find(name);
306 if(ita != option_checks_.end()) {
307 auto const & [positional, check] = ita->second;
309 if(!check(boost_any.value())) {
310 std::string dash = positional ?
"" :
"--";
311 std::cerr << FLOG_COLOR_LTRED <<
"ERROR: " << FLOG_COLOR_RED
312 <<
"invalid argument for '" << dash << name
313 <<
"' option!!!" << FLOG_COLOR_PLAIN << std::endl;
314 print_usage(program_, master, flecsi_desc);
320 catch(boost::program_options::error & e) {
321 std::string error(e.what());
323 auto pos = error.find(
"--");
324 if(pos != std::string::npos) {
325 error.replace(pos, 2,
"");
328 std::cerr << FLOG_COLOR_LTRED <<
"ERROR: " << FLOG_COLOR_RED << error
329 <<
"!!!" << FLOG_COLOR_PLAIN << std::endl
331 print_usage(program_, master, flecsi_desc);
332 return status::command_line_error;
335 unrecognized_options_ = boost::program_options::collect_unrecognized(
336 parsed.options, boost::program_options::include_positional);
338 #if defined(FLECSI_ENABLE_FLOG) 340 flog_tags_, flog_verbose_, flog_output_process_)) {
341 return status::error;
345 #if defined(FLECSI_ENABLE_KOKKOS) 346 if(initialize_dependent_) {
354 return status::success;
357 inline void finalize_generic() {
358 #if defined(FLECSI_ENABLE_FLOG) 362 if(initialize_dependent_) {
363 #if defined(FLECSI_ENABLE_KOKKOS) 369 #ifdef DOXYGEN // these functions are implemented per-backend 374 int initialize(
int argc,
char ** argv,
bool dependent);
393 int start(
const std::function<
int(
int,
char **)> action &);
435 std::size_t
color()
const;
441 std::size_t
colors()
const;
452 void register_init(
void callback()) {
453 init_registry.push_back(callback);
470 return !registered_topology_fields_
471 .insert(std::make_pair(type_key, instance_key))
486 template<
class Topo, std::
size_t Index>
488 constexpr std::size_t NIndex = topo::index_spaces<Topo>;
489 static_assert(Index < NIndex,
"No such index space");
490 topology_field_info_map_.try_emplace(topo::id<Topo>(), NIndex)
491 .first->second[Index]
492 .push_back(&field_info);
502 template<
class Topo, std::
size_t Index = topo::default_space<Topo>>
504 static_assert(Index < topo::index_spaces<Topo>,
"No such index space");
506 static const field_info_store_t empty;
508 auto const & tita = topology_field_info_map_.find(topo::id<Topo>());
509 if(tita == topology_field_info_map_.end())
512 return tita->second[Index];
528 info.index_subspace = index_subspace;
529 info.capacity = capacity;
531 index_subspace_map_.emplace(index_subspace, std::move(info));
544 index_subspace_map_.emplace(info.index_subspace, info);
555 return index_subspace_map_;
567 return tasks_executed_;
575 return tasks_executed_;
583 for(
auto ro : init_registry)
603 std::string program_;
604 std::vector<char *> argv_;
605 std::string backend_;
607 std::string flog_tags_;
609 int64_t flog_output_process_;
611 bool initialize_dependent_ =
true;
614 std::map<std::string, boost::program_options::options_description>
618 boost::program_options::positional_options_description positional_desc_;
619 boost::program_options::options_description hidden_options_;
620 std::map<std::string, std::string> positional_help_;
623 std::map<std::string,
624 std::pair<bool, std::function<bool(boost::any const &)>>>
627 std::vector<std::string> unrecognized_options_;
633 bool initialized_ =
false;
634 size_t process_ = std::numeric_limits<size_t>::max();
635 size_t processes_ = std::numeric_limits<size_t>::max();
636 size_t threads_per_process_ = std::numeric_limits<size_t>::max();
637 size_t threads_ = std::numeric_limits<size_t>::max();
639 int exit_status_ = 0;
645 std::unordered_map<size_t, void *> function_registry_;
651 std::set<std::pair<size_t, size_t>> registered_topology_fields_;
662 std::unordered_map<size_t, std::vector<field_info_store_t>>
663 topology_field_info_map_;
670 std::map<size_t, index_subspace_info_t> index_subspace_map_;
676 size_t tasks_executed_ = 0;
679 std::vector<void (*)()> init_registry;
Definition: field_info.hh:36
std::size_t color() const
Definition: context.hh:78
std::string const & program()
Definition: execution.hh:276
std::map< size_t, index_subspace_info_t > & index_subspace_info()
Definition: context.hh:554
std::size_t threads_per_process() const
void add_field_info(const data::field_info_t &field_info)
Definition: context.hh:487
std::size_t threads() const
#define flog_assert(test, message)
Definition: flog.hh:411
void add_index_subspace(size_t index_subspace, size_t capacity)
Definition: context.hh:526
size_t const & tasks_executed() const
Definition: context.hh:566
int start(const std::function< int()> &action)
Definition: execution.hh:69
void add_index_subspace(const index_subspace_info_t &info)
Definition: context.hh:543
static flog_t & instance()
Definition: state.hh:73
std::size_t colors() const
int initialize(int argc, char **argv, bool dependent=true)
Definition: execution.hh:55
field_info_store_t const & get_field_info_store() const
Definition: context.hh:503
void finalize()
Definition: execution.hh:80
int & exit_status()
Definition: context.hh:448
Definition: context.hh:64
size_t & tasks_executed()
Definition: context.hh:574
std::size_t processes() const
bool topology_fields_registered(size_t type_key, size_t instance_key)
Definition: context.hh:469
Definition: context.hh:63
static std::size_t task_depth()
const std::unordered_map< std::string, size_t > & tag_map()
Definition: state.hh:193
Definition: control.hh:31
std::size_t process() const