Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
readparameters.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include "readparameters.h"
24
25using namespace std;
26namespace PO = boost::program_options;
27
28// Initialize static member of class ReadParameters
30
31PO::options_description* Readparameters::descriptions = NULL;
32PO::variables_map* Readparameters::variables = NULL;
33
37
40
41map<string, string> Readparameters::options;
42map<string, bool> Readparameters::isOptionParsed;
43map<string, vector<string>> Readparameters::vectorOptions;
45
51Readparameters::Readparameters(int cmdargc, char* cmdargv[]) {
52 argc = cmdargc;
53 argv = cmdargv;
54 int rank;
55 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
56
57 if (rank == MASTER_RANK) {
58 descriptions = new PO::options_description("Usage: main [options (options given on the command line override "
59 "options given everywhere else)], where options are:",
60 160);
61 variables = new PO::variables_map;
63
64 // Read options from command line, first time for help message parsing, second time in parse() below.
65 PO::store(PO::command_line_parser(argc, argv).options(*descriptions).allow_unregistered().run(), *variables);
66 PO::notify(*variables);
67
68 helpRequested = (variables->count("help") > 0);
69 }
70 MPI_Bcast(&helpRequested, sizeof(bool), MPI_BYTE, 0, MPI_COMM_WORLD);
71}
72
74 if(descriptions != nullptr) {
75 delete descriptions;
76 delete variables;
77 descriptions = NULL;
78 variables = NULL;
79 }
80}
81
89void Readparameters::addComposing(const string& name, const string& desc) {
90 int rank;
91 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
92 if (rank == MASTER_RANK) {
93 isVectorOptionParsed[name] = false;
94 descriptions->add_options()(name.c_str(), PO::value<vector<string>>(&(vectorOptions[name]))->composing(),
95 desc.c_str());
96 }
97}
98
103 if (helpRequested) {
104 int rank;
105 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
106 if (rank == MASTER_RANK) {
107 cout << *descriptions << endl;
108 }
109 MPI_Finalize();
110 exit(0);
111 }
112}
113
120 int rank;
121 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
122 if (rank == MASTER_RANK) {
123 if (variables->count("version")) {
124 printVersion();
125 return true;
126 }
127 return false;
128 }
129 return true;
130}
131
132
137 return getVersion();
138}
139
144 return getConfig(run_config_file_name.c_str());
145}
146
147
157bool Readparameters::parse(const bool needsRunConfig, const bool allowUnknown) {
158
159 int rank;
160 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
161
162 if (rank == MASTER_RANK) {
163 // Read options from command line:
164 PO::store(PO::parse_command_line(argc, argv, *descriptions), *variables);
165 PO::notify(*variables);
166 // Read options from environment variables:
167 PO::store(PO::parse_environment(*descriptions, "MAIN_"), *variables);
168 PO::notify(*variables);
169 // Read options from run config file:
170 if (run_config_file_name.size() > 0) {
171 ifstream run_config_file(run_config_file_name.c_str(), fstream::in);
172 if (run_config_file.good()) {
173 PO::store(PO::parse_config_file(run_config_file, *descriptions, allowUnknown), *variables);
174 PO::notify(*variables);
175 run_config_file.close();
176 } else {
177 cerr << __FILE__ << ":" << __LINE__ << "Couldn't open or read run config file " + run_config_file_name
178 << endl;
179 MPI_Abort(MPI_COMM_WORLD, 1);
180 }
181 }
182 // Read options from user config file:
183 if (user_config_file_name.size() > 0) {
184 ifstream user_config_file(user_config_file_name.c_str(), fstream::in);
185 if (user_config_file.good()) {
186 PO::store(PO::parse_config_file(user_config_file, *descriptions, allowUnknown), *variables);
187 PO::notify(*variables);
188 user_config_file.close();
189 } else {
190 cerr << __FILE__ << ":" << __LINE__ << "Couldn't open or read user config file " + user_config_file_name
191 << endl;
192 MPI_Abort(MPI_COMM_WORLD, 1);
193 }
194 }
195 // Read options from global config file:
196 if (global_config_file_name.size() > 0) {
197 ifstream global_config_file(global_config_file_name.c_str(), fstream::in);
198 if (global_config_file.good()) {
199 PO::store(PO::parse_config_file(global_config_file, *descriptions, allowUnknown), *variables);
200 PO::notify(*variables);
201 global_config_file.close();
202 } else {
203 cerr << __FILE__ << ":" << __LINE__ << "Couldn't open or read global config file " + global_config_file_name
204 << endl;
205 MPI_Abort(MPI_COMM_WORLD, 1);
206 }
207 }
208 }
209
210 // Check if the user has specified --version
211 bool hasVersionOption = versionMessage();
212 MPI_Bcast(&hasVersionOption, sizeof(bool), MPI_BYTE, 0, MPI_COMM_WORLD);
213 if (hasVersionOption) {
214 MPI_Finalize();
215 exit(0);
216 }
217
218 // Require that there is a run config file.
219 // There are so many options so it is unlikely that one would like to define
220 // all on the command line, or only in global/user run files.
221 bool hasRunConfigFile = (run_config_file_name.size() > 0);
222 MPI_Bcast(&hasRunConfigFile, sizeof(bool), MPI_BYTE, 0, MPI_COMM_WORLD);
223 if (needsRunConfig && !hasRunConfigFile && !helpRequested) {
224 if (rank == MASTER_RANK) {
225 cout << "Run config file required. Use --help to list all options" << endl;
226 }
227 MPI_Finalize();
228 exit(0);
229 }
230
231 int nOptionsToBroadcast;
232 int vectorSize;
233 const int maxStringLength = 1024;
234 char value[maxStringLength];
235 char name[maxStringLength];
236 value[maxStringLength - 1] = '\0';
237 name[maxStringLength - 1] = '\0';
238
239 /*
240 loop through options and broadcast all options from root rank to the others
241 Separate bcasts not optimal from performance point of view, but parse is
242 normally just called a few times so it should not matter.
243 */
244
245 // count number of options not parsed/broadcasted previously
246 if (rank == MASTER_RANK) {
247 nOptionsToBroadcast = 0;
248 for (map<string, bool>::iterator ip = isOptionParsed.begin(); ip != isOptionParsed.end(); ++ip) {
249 if (!ip->second)
250 nOptionsToBroadcast++;
251 }
252 }
253
254 MPI_Bcast(&nOptionsToBroadcast, 1, MPI_INT, 0, MPI_COMM_WORLD);
255 if (rank == MASTER_RANK) {
256 // iterate through map and bcast cstrings of key/value pairs not parsed before
257 for (map<string, string>::iterator p = options.begin(); p != options.end(); ++p) {
258
259 if (!isOptionParsed[p->first]) {
260 strncpy(name, p->first.c_str(), maxStringLength - 1);
261 strncpy(value, p->second.c_str(), maxStringLength - 1);
262 MPI_Bcast(name, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
263 MPI_Bcast(value, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
264 isOptionParsed[p->first] = true;
265 }
266 }
267 } else {
268 // receive new options
269 for (int p = 0; p < nOptionsToBroadcast; p++) {
270 MPI_Bcast(name, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
271 MPI_Bcast(value, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
272 string sName(name);
273 string sValue(value);
274 options[sName] = sValue;
275 }
276 }
277
278 /*
279 loop through vector options and broadcast all vector options from root rank
280 to the others. Separate bcasts not optimal from performance point of view,
281 but parse is normally just called a few times so it should not matter.
282 */
283
284 // count number of vector options not parsed/broarcasted previously
285 if (rank == MASTER_RANK) {
286 nOptionsToBroadcast = 0;
287 for (map<string, bool>::iterator ip = isVectorOptionParsed.begin(); ip != isVectorOptionParsed.end(); ++ip) {
288 if (!ip->second)
289 nOptionsToBroadcast++;
290 }
291 }
292
293 // root broadcasts its new vector values
294 MPI_Bcast(&nOptionsToBroadcast, 1, MPI_INT, 0, MPI_COMM_WORLD);
295 if (rank == MASTER_RANK) {
296 // iterate through map and bcast cstrings of key/value pairs not parsed before
297 for (map<string, vector<string>>::iterator p = vectorOptions.begin(); p != vectorOptions.end(); ++p) {
298 if (!isVectorOptionParsed[p->first]) {
299 strncpy(name, p->first.c_str(), maxStringLength - 1);
300 MPI_Bcast(name, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
301 vectorSize = vectorOptions[p->first].size();
302 MPI_Bcast(&vectorSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
303 for (vector<string>::iterator v = vectorOptions[p->first].begin(); v != vectorOptions[p->first].end();
304 ++v) {
305 strncpy(value, v->c_str(), maxStringLength - 1);
306 MPI_Bcast(value, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
307 }
308 isVectorOptionParsed[p->first] = true;
309 }
310 }
311 } else {
312 // others receive new options
313 for (int p = 0; p < nOptionsToBroadcast; p++) {
314 MPI_Bcast(name, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
315 string sName(name);
316 MPI_Bcast(&vectorSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
317 for (int i = 0; i < vectorSize; i++) {
318 MPI_Bcast(value, maxStringLength, MPI_CHAR, 0, MPI_COMM_WORLD);
319 string sValue(value);
320 vectorOptions[sName].push_back(sValue);
321 }
322 }
323 }
324
325 return true;
326}
327
328// add names of input files
330 int rank;
331 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
332 if (rank == MASTER_RANK) {
333 descriptions->add_options()("help", "print this help message");
334 descriptions->add_options()("version", "print version information");
335
336 // Parameters which set the names of the configuration file(s):
337 descriptions->add_options()(
338 "global_config", PO::value<string>(&global_config_file_name)->default_value(""),
339 "read options from the global configuration file arg (relative to the current working directory). Options "
340 "given in this file are overridden by options given in the user's and run's configuration files and by "
341 "options given in environment variables (prefixed with MAIN_) and the command line")(
342 "user_config", PO::value<string>(&user_config_file_name)->default_value(""),
343 "read options from the user's configuration file arg (relative to the current working directory). Options "
344 "given in this file override options given in the global configuration file. Options given in this file "
345 "are "
346 "overridden by options given in the run's configuration file and by options given in environment "
347 "variables "
348 "(prefixed with MAIN_) and the command line")("run_config",
349 PO::value<string>(&run_config_file_name)->default_value(""),
350 "read options from the run's configuration file arg "
351 "(relative to the current working directory). Options "
352 "given in this file override options given in the user's "
353 "and global configuration files. Options given in "
354 "this override options given in the user's and global "
355 "configuration files. Options given in this file are "
356 "overridden by options given in environment variables "
357 "(prefixed with MAIN_) and the command line");
358 }
359}
for i
Definition Dispersion.m:24
static bool versionMessage()
static void addDefaultParameters()
static boost::program_options::variables_map * variables
static std::map< std::string, std::vector< std::string > > vectorOptions
static void addComposing(const std::string &name, const std::string &desc)
static std::string user_config_file_name
static std::map< std::string, bool > isVectorOptionParsed
static boost::program_options::options_description * descriptions
static char ** argv
static std::map< std::string, std::string > options
static std::string configInfo()
static bool helpRequested
static std::string global_config_file_name
static std::string run_config_file_name
static void helpMessage()
static std::string versionInfo()
static bool parse(const bool needsRunConfig=true, const bool allowUnknown=true)
static std::map< std::string, bool > isOptionParsed
Readparameters(int cmdargc, char *cmdargv[])
#define MASTER_RANK
Definition common.h:67
bool printVersion()
std::string getConfig(const char *filename)
std::string getVersion()