Skip to content
Configuration.cpp 2.11 KiB
Newer Older
#include "Configuration.hpp"

#include <iostream>
#include <stdexcept>

#include "MpiEnvironment.hpp"
#include <boost/format.hpp>
#include <boost/program_options.hpp>

auto Configuration::parseArgs(int argc, char* argv[], const MpiEnvironment& env)
    -> Configuration {
	// parse cmd args
	namespace po = boost::program_options;
	Configuration cfg;
	po::options_description desc{"Allowed options"};
	desc.add_options()("help,h", "produce help message") //
	    ("gridrows,r", po::value<std::size_t>(&cfg.Grid.Rows),
	     "number of rows in the grid") //
	    ("gridcols,c", po::value<std::size_t>(&cfg.Grid.Cols),
	     "number of columns in the grid") //
	    ("generations,g",
	     po::value<std::size_t>(&cfg.Generations)->default_value(1000),
	     "number of generations simulated") //
	    ("inputfile,f", po::value<std::string>(&cfg.InputFilePath)->required(),
	     "path to wireworld file") //
	    ("outputfile,o", po::value<std::string>(&cfg.InputFilePath),
	     "path to output file"); //
	po::positional_options_description poDesc;
	poDesc.add("inputfile", 1);
	po::store(po::command_line_parser(argc, argv)
	              .options(desc)      //
	              .positional(poDesc) //
	              .run(),
	          vm);

	if (vm.count("help") > 0 && env.isMaster()) { std::cout << desc << "\n"; }
	po::notify(vm);

	// if no dimensions given, use MPI_Dims_create
	if (cfg.Grid.Cols < 1 || cfg.Grid.Rows < 1) {
		std::array<int, 2> dims{static_cast<int>(cfg.Grid.Cols),
		                        static_cast<int>(cfg.Grid.Rows)};
		MPI_Dims_create(env.worldSize(), // nnodes
		                2,               // ndims
		                dims.data());    // dims

		cfg.Grid.Cols = dims[0];
		cfg.Grid.Rows = dims[1];
	const auto& totalCellCount = cfg.Grid.Cols * cfg.Grid.Rows;
	const auto& worldSize = env.worldSize();
	if (totalCellCount != worldSize) {
		std::cerr << boost::format("Total number of cells (%d) does not match "
		                           "the MPI World size (%d)") %
		                 totalCellCount % worldSize;
		MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);