Replies: 7 comments 18 replies
-
Hi, Sebastian and I are doing a similar thing but in reverse. We parser Fortran namelist and generate a yaml representation in memory. Then we access input data from C++ using |
Beta Was this translation helpful? Give feedback.
-
So your proposal is to interpret Fortran namelists as a dialect of .ini/TOML? Sounds good and should be easy to write a parser. I have a few additional comments: In Step 1.1 make sure to add a version, the current format being version 1 or so. This way you might not even need to deprecate the old format. (Keep in mind that there are published setups on Zenodo. I'm not saying one needs to support these until t -> inf, but one also doesn't need to break them if there's no good reason.) One other thing to think about early is what the internal data structure for the configuration should be. Using a generic hash map as offered by yaml-cpp / toml parsers is a design failure imho. Besides being inefficient (which is not a big deal for configuration though), the user has to convert the entry in the hash map to the proper data type always when he uses it. Moreover, there are no guarantees that the configuration data is proper and the values need to be checked everytime. Think of horrible spaghetti code like this: double cfl = conf["cfl"].get_as<double>();
if (isnan(cfl)) ...; // error
if (cfl < 0) ...; // error What I found a super useful idea is to implement a schema. (I think I got inspired by the following Python package: https://pypi.org/project/schema/) In tandem, I do the following. Define a configuration struct, e.g. struct Config {
double cfl;
std::array<double, 3> ref_normal;
std::optional<std::string> output;
}; Then I define a Schema for this struct, e.g. TableSchema<Config> schema;
schema.add_value("cfl", &Config::cfl)
.validator([](auto&& x) { return x > 0 && !isnan(x); })
.help("CFL tuning parameter");
schema.add_array("ref_normal", &Config::ref_normal).of_values();
schema.add_value("output", &Config::output)
.converter(path_converter)
.validator(PathExists()); You then parse a toml (or potentially namelist) file with toml::table rawCfg;
try {
rawCfg = toml::parse_file(program.get(configPar));
} catch (toml::parse_error const& err) {
...
}
Conf cfg;
try {
cfg = schema.translate(rawCfg);
} catch (std::runtime_error const& e) { ...} and when I want to use a configuration parameter I can just write: cfg.cfl i.e. no checking and very efficient. |
Beta Was this translation helpful? Give feedback.
-
You could have a Schema for each configuration file. You then need some code to fill the entries of one configuration struct with values of the other -- but you need such functionality anyhow if you have multiple configuration formats. |
Beta Was this translation helpful? Give feedback.
-
Hi, |
Beta Was this translation helpful? Give feedback.
-
Hi... Time to drag out this old thread again. By now, we've done the plan in reverse (after #829 and following), I'd guess:
In short, we'd need a new format in the end. In the long run, at least. We are now also able to go more tree-like (e.g. have a node And just to put forward the idea again: I'd love to just have something like a |
Beta Was this translation helpful? Give feedback.
-
Instead of having a separate compatibility script I'd rather leave support for parsing parameters.par in SeisSol along with a deprecation notice for the following reasons:
Moreover, please add a mandatory version number to the YAML format! |
Beta Was this translation helpful? Give feedback.
-
This compability script kind of exists and already is kind of in use ;-) |
Beta Was this translation helpful? Give feedback.
-
The Fortran namelist based configuration file is the bane of our existence.
I propose the following (really stupid/brilliant) plan:
Step 1
Step 2
Step 3
After Step 1 we get a lot of benefits (we can easily add new configuration options to the new format and access it from C++) whilst we keep some backward compatibility.
After Step 2 we are able to access the entire configuration structures from C++ code (and also from Fortran code).
After Step 3 we can finally be happy.
There should be some time (maybe half a year) between step 1 and step 2 so that users have time to adjust to the new format. Maybe we can add a quick script that converts to a new format automatically, e.g. using something like https://github.com/marshallward/f90nml.
What do you think?
Beta Was this translation helpful? Give feedback.
All reactions