Skip to content

Commit 5fe8699

Browse files
committed
config: Revamp adding options.
Signed-off-by: Matthew Emmett <[email protected]>
1 parent 1a19376 commit 5fe8699

File tree

8 files changed

+150
-186
lines changed

8 files changed

+150
-186
lines changed

examples/advection_diffusion/advection_diffusion_sweeper.hpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,10 @@ namespace pfasst
4747
class AdvectionDiffusionSweeper
4848
: public encap::IMEXSweeper<time>
4949
{
50-
private:
51-
static void init_config_options(po::options_description& opts)
52-
{
53-
opts.add_options()
54-
("spatial_dofs", po::value<size_t>(), "number of spatial degrees of freedom")
55-
;
56-
}
57-
5850
public:
59-
static void enable_config_options(size_t index = -1)
51+
static void init()
6052
{
61-
config::Options::get_instance()
62-
.register_init_function("Advection-Diffusion Sweeper",
63-
std::function<void(po::options_description&)>(init_config_options),
64-
index);
53+
config::add_option<size_t>("Adv/Diff Sweeper", "spatial_dofs", "Number of spatial degrees of freedom");
6554
}
6655

6756
private:
@@ -99,7 +88,7 @@ namespace pfasst
9988

10089
virtual ~AdvectionDiffusionSweeper()
10190
{
102-
CLOG(INFO, "Advec") << "number of f1 evals: " << this->nf1evals;
91+
CLOG(INFO, "User") << "number of f1 evals: " << this->nf1evals;
10392
}
10493
//! @}
10594

@@ -142,7 +131,7 @@ namespace pfasst
142131
auto n = this->get_controller()->get_step();
143132
auto k = this->get_controller()->get_iteration();
144133

145-
CLOG(INFO, "Advec") << "err: " << n << " " << k << " " << max << " (" << qend.size() << "," << predict << ")";
134+
CLOG(INFO, "User") << "err: " << n << " " << k << " " << max << " (" << qend.size() << "," << predict << ")";
146135
this->errors.insert(vtype(ktype(n, k), max));
147136
}
148137

@@ -163,7 +152,7 @@ namespace pfasst
163152

164153
auto n = this->get_controller()->get_step();
165154
auto k = this->get_controller()->get_iteration();
166-
CLOG(INFO, "Advec") << "res: " << n << " " << k << " " << rmax << " (" << residuals.size() << ")";
155+
CLOG(INFO, "User") << "res: " << n << " " << k << " " << rmax << " (" << residuals.size() << ")";
167156

168157
this->residuals[ktype(n, k)] = rmax;
169158
}

examples/advection_diffusion/vanilla_sdc.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,9 @@ namespace pfasst
2727
{
2828
SDC<> sdc;
2929

30-
const size_t nsteps = config::get_value<size_t>("num_steps", 4);
31-
const double dt = config::get_value<double>("delta_step", 0.01);
32-
const size_t nnodes = config::get_value<size_t>("num_nodes", 3);
33-
const size_t ndofs = config::get_value<size_t>("spatial_dofs", 64);
34-
const size_t niters = config::get_value<size_t>("num_iter", 4);
35-
const quadrature::QuadratureType quad_type = \
30+
auto const nnodes = config::get_value<size_t>("num_nodes", 3);
31+
auto const ndofs = config::get_value<size_t>("spatial_dofs", 64);
32+
auto const quad_type = \
3633
config::get_value<quadrature::QuadratureType>("nodes_type", quadrature::QuadratureType::GaussLegendre);
3734

3835
auto quad = quadrature::quadrature_factory(nnodes, quad_type);
@@ -44,7 +41,8 @@ namespace pfasst
4441
sweeper->set_residual_tolerances(abs_residual_tol, 0.0);
4542

4643
sdc.add_level(sweeper);
47-
sdc.set_duration(0.0, nsteps*dt, dt, niters);
44+
sdc.set_duration(0.0, 4*0.01, 0.01, 4);
45+
sdc.set_options();
4846
sdc.setup();
4947

5048
auto q0 = sweeper->get_start_state();
@@ -64,10 +62,8 @@ namespace pfasst
6462
#ifndef PFASST_UNIT_TESTING
6563
int main(int argc, char** argv)
6664
{
67-
pfasst::examples::advection_diffusion::AdvectionDiffusionSweeper<>::enable_config_options();
65+
pfasst::examples::advection_diffusion::AdvectionDiffusionSweeper<>::init();
6866
pfasst::init(argc, argv);
69-
pfasst::log::add_custom_logger("Advec");
70-
7167
pfasst::examples::advection_diffusion::run_vanilla_sdc(0.0);
7268
}
7369
#endif

include/pfasst.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ namespace pfasst
1111
{
1212
inline static void init(int argc, char** argv)
1313
{
14-
SDC<>::enable_config_options(0);
15-
Quadrature::enable_config_options(0);
16-
config::init_config();
14+
config::init();
1715
log::start_log(argc, argv);
1816
config::read_commandline(argc, argv);
1917
}

include/pfasst/config.hpp

Lines changed: 89 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -15,176 +15,141 @@ using namespace std;
1515
#include <boost/program_options.hpp>
1616
namespace po = boost::program_options;
1717

18+
#include "logging.hpp"
19+
1820
namespace pfasst
1921
{
22+
2023
namespace config
2124
{
2225
/**
2326
* @note This is using the Singleton Pattern.
24-
* pfasst::Options::get_instance() is thread-safe with C++11.
27+
* pfasst::options::get_instance() is thread-safe with C++11.
2528
*/
26-
class Options
29+
class options
2730
{
2831
public:
2932
//! Maximum width of a line in the help output
3033
static const size_t LINE_WIDTH = 100;
3134

3235
private:
3336
po::options_description all_options;
34-
vector<string> group_names;
3537
map<string, po::options_description> option_groups;
36-
map<string, function<void(po::options_description&)>> init_functions;
37-
po::variables_map vars_map;
38+
39+
po::variables_map variables_map;
3840
vector<string> unrecognized_args;
3941
bool initialized = false;
4042

4143
private:
42-
//! ctor is private to make it a singleton
43-
Options()
44-
{}
45-
Options(const Options&) = delete;
46-
void operator=(const Options&) = delete;
44+
options() {}
45+
options(const options&) = delete;
46+
void operator=(const options&) = delete;
4747

4848
public:
49-
static Options& get_instance()
49+
static options& get_instance()
5050
{
51-
static Options instance;
51+
static options instance;
5252
return instance;
5353
}
5454

5555
po::variables_map& get_variables_map()
56-
{ return this->vars_map; }
56+
{
57+
return this->variables_map;
58+
}
5759

5860
po::options_description& get_all_options()
59-
{ return this->all_options; }
61+
{
62+
return this->all_options;
63+
}
6064

6165
vector<string>& get_unrecognized_args()
62-
{ return this->unrecognized_args; }
63-
64-
/**
65-
* @throws invalid_argument if there is already an init function or options group with the
66-
* given name registered
67-
*/
68-
void register_init_function(const string& name,
69-
const function<void(po::options_description&)>& fnc,
70-
int index = -1)
7166
{
72-
assert(fnc);
73-
if (!this->option_groups.count(name) && !this->init_functions.count(name)) {
74-
this->option_groups.emplace(make_pair<string,
75-
po::options_description>(string(name),
76-
po::options_description(name,
77-
LINE_WIDTH)));
78-
this->init_functions[name] = fnc;
79-
if (index == -1) {
80-
this->group_names.push_back(name);
81-
} else {
82-
this->group_names.insert(this->group_names.begin() + index, name);
83-
}
84-
} else {
85-
throw invalid_argument("There is already an init function named '" + name + "' registered.");
86-
}
67+
return this->unrecognized_args;
68+
}
69+
70+
void add_option(string group, string option, string help)
71+
{
72+
this->option_groups.emplace(make_pair<string,
73+
po::options_description>(string(group),
74+
po::options_description(string(group), LINE_WIDTH)));
75+
this->option_groups[group].add_options()
76+
(option.c_str(), help.c_str());
77+
}
78+
79+
template<typename T>
80+
void add_option(string group, string option, string help)
81+
{
82+
this->option_groups.emplace(make_pair<string,
83+
po::options_description>(string(group),
84+
po::options_description(string(group), LINE_WIDTH)));
85+
this->option_groups[group].add_options()
86+
(option.c_str(), po::value<T>(), help.c_str());
8787
}
8888

8989
void init()
9090
{
9191
if (!this->initialized) {
92-
for(string name : this->group_names) {
93-
auto fnc = this->init_functions[name];
94-
// calling init function
95-
fnc(this->option_groups[name]);
96-
this->all_options.add(this->option_groups[name]);
92+
for (auto const & kv : this->option_groups) {
93+
this->all_options.add(kv.second);
9794
}
98-
this->initialized = true;
9995
}
96+
this->initialized = true;
10097
}
101-
};
10298

99+
};
103100

104101
template<typename T>
105102
inline static T get_value(const string& name, const T& default_val)
106103
{
107-
return Options::get_instance().get_variables_map().count(name)
108-
? Options::get_instance().get_variables_map()[name].as<T>() : default_val;
104+
return options::get_instance().get_variables_map().count(name)
105+
? options::get_instance().get_variables_map()[name].as<T>() : default_val;
109106
}
110107

111-
112108
template<typename T>
113109
inline static T get_value(const string& name)
114110
{
115-
return Options::get_instance().get_variables_map()[name].as<T>();
116-
}
117-
118-
119-
inline static bool no_params_given()
120-
{
121-
return Options::get_instance().get_variables_map().empty();
122-
}
123-
124-
125-
inline static string pretty_print()
126-
{
127-
stringstream s;
128-
s << "Logging Options:" << endl
129-
<< " -v [ --verbose ] activates maximum verbosity" << endl
130-
<< " --v=arg activates verbosity upto verbose level 2" << endl
131-
<< " (valid range: 0-9)" << endl
132-
<< " -vmodule=arg actives verbose logging for specific module" << endl
133-
<< " (see [1] for details)" << endl;
134-
s << Options::get_instance().get_all_options() << endl;
135-
s << "[1]: https://github.com/easylogging/easyloggingpp#vmodule";
136-
return s.str();
111+
return options::get_instance().get_variables_map()[name].as<T>();
137112
}
138113

139-
140114
/**
141115
* @returns empty string if params are set and `if_no_params` is `true`
142116
*/
143117
inline static string print_help(bool if_no_params = false)
144118
{
145-
if (!if_no_params || (if_no_params && no_params_given())) {
146-
return pretty_print();
119+
bool no_params_given = options::get_instance().get_variables_map().empty();
120+
121+
if (!if_no_params || (if_no_params && no_params_given)) {
122+
stringstream s;
123+
s << options::get_instance().get_all_options() << endl;
124+
s << "Logging options:" << endl
125+
<< " -v [ --verbose ] activates maximum verbosity" << endl
126+
<< " --v=arg activates verbosity upto verbose level 2" << endl
127+
<< " (valid range: 0-9)" << endl
128+
<< " -vmodule=arg actives verbose logging for specific module" << endl
129+
<< " (see [1] for details)" << endl;
130+
s << "[1]: https://github.com/easylogging/easyloggingpp#vmodule" << endl;
131+
return s.str();
147132
} else {
148133
return string();
149134
}
150135
}
151136

152-
153-
inline static void init_global_options(po::options_description& opts)
154-
{
155-
opts.add_options()
156-
("help,h", "display this help message");
157-
}
158-
159-
160-
inline static void init_config()
161-
{
162-
Options::get_instance()
163-
.register_init_function("Global Options",
164-
function<void(po::options_description&)>(init_global_options),
165-
0);
166-
167-
Options::get_instance().init();
168-
}
169-
170-
171137
inline static void read_commandline(int argc, char* argv[], bool exit_on_help = true)
172138
{
173139
po::parsed_options parsed = po::command_line_parser(argc, argv)
174-
.options(Options::get_instance().get_all_options())
140+
.options(options::get_instance().get_all_options())
175141
.allow_unregistered().run();
176-
Options::get_instance().get_unrecognized_args() = po::collect_unrecognized(parsed.options,
142+
options::get_instance().get_unrecognized_args() = po::collect_unrecognized(parsed.options,
177143
po::exclude_positional);
178-
po::store(parsed, Options::get_instance().get_variables_map());
179-
po::notify(Options::get_instance().get_variables_map());
144+
po::store(parsed, options::get_instance().get_variables_map());
145+
po::notify(options::get_instance().get_variables_map());
180146

181-
if (Options::get_instance().get_variables_map().count("help")) {
147+
if (options::get_instance().get_variables_map().count("help")) {
182148
cout << print_help() << endl;
183149
if (exit_on_help) exit(0);
184150
}
185151
}
186152

187-
188153
/**
189154
* @throws invalid_argument if the given file could not be opened
190155
*/
@@ -194,13 +159,36 @@ namespace pfasst
194159
if (!ifs) {
195160
throw invalid_argument("Config file '" + file_name + "' not found.");
196161
} else {
197-
po::store(po::parse_config_file(ifs, Options::get_instance().get_all_options()),
198-
Options::get_instance().get_variables_map());
199-
po::notify(Options::get_instance().get_variables_map());
162+
po::store(po::parse_config_file(ifs, options::get_instance().get_all_options()),
163+
options::get_instance().get_variables_map());
164+
po::notify(options::get_instance().get_variables_map());
200165
}
201166
}
202167

168+
static void add_option(string group, string name, string help)
169+
{
170+
options::get_instance().add_option(group, name, help);
171+
}
172+
173+
template<typename T>
174+
static void add_option(string group, string name, string help)
175+
{
176+
options::get_instance().add_option<T>(group, name, help);
177+
}
178+
179+
inline static void init()
180+
{
181+
add_option("Global", "help,h", "display this help message");
182+
183+
add_option<double>("Duration", "dt", "time step size");
184+
add_option<double>("Duration", "tend", "final time of simulation");
185+
add_option<size_t>("Duration", "num_iters", "number of iterations");
186+
187+
options::get_instance().init();
188+
}
189+
203190
} // ::pfasst::config
191+
204192
} // ::pfasst
205193

206194
#endif // _PFASST__CONFIG_HPP_

0 commit comments

Comments
 (0)