Substitute struct SimParams through class

This commit is contained in:
Max Lübke 2021-02-02 13:42:10 +01:00
parent e8bdc8ec50
commit 007d4b0375
12 changed files with 413 additions and 307 deletions

View File

@ -24,16 +24,19 @@ static uint64_t get_md5(int key_size, void *key) {
return retval; return retval;
} }
DHT_Wrapper::DHT_Wrapper(t_simparams *params, MPI_Comm dht_comm, DHT_Wrapper::DHT_Wrapper(SimParams &params, MPI_Comm dht_comm,
int buckets_per_process, int data_size, int key_size) { int buckets_per_process, int data_size, int key_size) {
dht_object = dht_object =
DHT_create(dht_comm, buckets_per_process, data_size, key_size, &get_md5); DHT_create(dht_comm, buckets_per_process, data_size, key_size, &get_md5);
fuzzing_buffer = (double *)malloc(key_size); fuzzing_buffer = (double *)malloc(key_size);
this->dt_differ = params->dt_differ; t_simparams tmp = params.getNumParams();
this->dht_log = params->dht_log;
this->dht_signif_vector = params->dht_signif_vector; this->dt_differ = tmp.dt_differ;
this->dht_prop_type_vector = params->dht_prop_type_vector; this->dht_log = tmp.dht_log;
this->dht_signif_vector = params.getDHTSignifVector();
this->dht_prop_type_vector = params.getDHTPropTypeVector();
} }
DHT_Wrapper::~DHT_Wrapper() { DHT_Wrapper::~DHT_Wrapper() {

View File

@ -18,7 +18,7 @@ extern "C" {
namespace poet { namespace poet {
class DHT_Wrapper { class DHT_Wrapper {
public: public:
DHT_Wrapper(t_simparams *params, MPI_Comm dht_comm, int buckets_per_process, DHT_Wrapper(SimParams &params, MPI_Comm dht_comm, int buckets_per_process,
int data_size, int key_size); int data_size, int key_size);
~DHT_Wrapper(); ~DHT_Wrapper();

View File

@ -10,7 +10,6 @@
// BSD-licenced #include "dht_wrapper.h" #include "global_buffer.h" // BSD-licenced #include "dht_wrapper.h" #include "global_buffer.h"
#include <ChemSim.h> #include <ChemSim.h>
#include <Grid.h> #include <Grid.h>
#include <Parser.h>
#include <RRuntime.h> #include <RRuntime.h>
#include <SimParams.h> #include <SimParams.h>
#include <TransportSim.h> #include <TransportSim.h>
@ -89,7 +88,6 @@ int main(int argc, char *argv[]) {
// int dht_significant_digits; // int dht_significant_digits;
// cout << "CPP: Start Init (MPI)" << endl; // cout << "CPP: Start Init (MPI)" << endl;
t_simparams params;
int world_size, world_rank; int world_size, world_rank;
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
@ -190,8 +188,8 @@ int main(int argc, char *argv[]) {
"source('parallel_r_library.R');"; "source('parallel_r_library.R');";
R.parseEvalQ(r_load_dependencies); R.parseEvalQ(r_load_dependencies);
Parser parser(argv, world_rank, world_size); SimParams parser(world_rank, world_size);
int pret = parser.parseCmdl(); int pret = parser.parseFromCmdl(argv, R);
if (pret == PARSER_ERROR) { if (pret == PARSER_ERROR) {
MPI_Finalize(); MPI_Finalize();
@ -201,8 +199,8 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
parser.parseR(R); // parser.parseR(R);
params = parser.getParams(); // params = parser.getParams();
// if (params.world_rank == 0) { // if (params.world_rank == 0) {
// cout << "CPP: Complete results storage is " << (params.store_result ? // cout << "CPP: Complete results storage is " << (params.store_result ?
@ -233,6 +231,7 @@ int main(int argc, char *argv[]) {
// "source(filesim)"); // eval the init string, ignoring any returns // "source(filesim)"); // eval the init string, ignoring any returns
// only rank 0 initializes goes through the whole initialization // only rank 0 initializes goes through the whole initialization
bool dt_differ;
if (world_rank == 0) { if (world_rank == 0) {
// cmdl(2) >> params.out_dir; // <- second positional argument // cmdl(2) >> params.out_dir; // <- second positional argument
// R["fileout"] = // R["fileout"] =
@ -248,13 +247,17 @@ int main(int argc, char *argv[]) {
std::string master_init_code = "mysetup <- master_init(setup=setup)"; std::string master_init_code = "mysetup <- master_init(setup=setup)";
R.parseEval(master_init_code); R.parseEval(master_init_code);
params.dt_differ = R.parseEval("mysetup$dt_differ"); dt_differ = R.parseEval("mysetup$dt_differ");
MPI_Bcast(&(params.dt_differ), 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); MPI_Bcast(&dt_differ, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
} else { // workers will only read the setup DataFrame defined by input file } else { // workers will only read the setup DataFrame defined by input file
R.parseEval("mysetup <- setup"); R.parseEval("mysetup <- setup");
MPI_Bcast(&(params.dt_differ), 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); MPI_Bcast(&dt_differ, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
} }
parser.setDtDiffer(dt_differ);
t_simparams params = parser.getNumParams();
if (world_rank == 0) { if (world_rank == 0) {
cout << "CPP: R init done on process with rank " << params.world_rank cout << "CPP: R init done on process with rank " << params.world_rank
<< endl; << endl;
@ -267,6 +270,8 @@ int main(int argc, char *argv[]) {
Grid grid(R); Grid grid(R);
// params.grid = &grid; // params.grid = &grid;
grid.init(); grid.init();
parser.initVectorParams(R, grid.getCols());
/* Retrieve state_C from R context for MPI buffer generation */ /* Retrieve state_C from R context for MPI buffer generation */
// Rcpp::DataFrame state_C = R.parseEval("mysetup$state_C"); // Rcpp::DataFrame state_C = R.parseEval("mysetup$state_C");
@ -296,78 +301,79 @@ int main(int argc, char *argv[]) {
// params.R = &R; // params.R = &R;
if (params.dht_enabled) { // if (params.dht_enabled) {
// cout << "\nCreating DHT\n"; // // cout << "\nCreating DHT\n";
// determine size of dht entries // // determine size of dht entries
// int dht_data_size = grid.getCols() * sizeof(double); // // int dht_data_size = grid.getCols() * sizeof(double);
// int dht_key_size = // // int dht_key_size =
// grid.getCols() * sizeof(double) + (params.dt_differ * // // grid.getCols() * sizeof(double) + (params.dt_differ *
// sizeof(double)); // // sizeof(double));
// // // determine bucket count for preset memory usage // // // // determine bucket count for preset memory usage
// // // bucket size is key + value + 1 byte for status // // // // bucket size is key + value + 1 byte for status
// int dht_buckets_per_process = // // int dht_buckets_per_process =
// params.dht_size_per_process / (1 + dht_data_size + dht_key_size); // // params.dht_size_per_process / (1 + dht_data_size + dht_key_size);
// MDL : following code moved here from worker.cpp // // MDL : following code moved here from worker.cpp
/*Load significance vector from R setup file (or set default)*/ // /*Load significance vector from R setup file (or set default)*/
bool signif_vector_exists = R.parseEval("exists('signif_vector')"); // bool signif_vector_exists = R.parseEval("exists('signif_vector')");
if (signif_vector_exists) { // if (signif_vector_exists) {
params.dht_signif_vector = as<std::vector<int>>(R["signif_vector"]); // params.dht_signif_vector = as<std::vector<int>>(R["signif_vector"]);
} else { // } else {
params.dht_signif_vector.assign(grid.getCols(), params.dht_significant_digits); // params.dht_signif_vector.assign(grid.getCols(),
} // params.dht_significant_digits);
// }
/*Load property type vector from R setup file (or set default)*/ // /*Load property type vector from R setup file (or set default)*/
bool prop_type_vector_exists = R.parseEval("exists('prop_type')"); // bool prop_type_vector_exists = R.parseEval("exists('prop_type')");
if (prop_type_vector_exists) { // if (prop_type_vector_exists) {
params.dht_prop_type_vector = as<std::vector<string>>(R["prop_type"]); // params.dht_prop_type_vector = as<std::vector<string>>(R["prop_type"]);
} else { // } else {
params.dht_prop_type_vector.assign(grid.getCols(), "act"); // params.dht_prop_type_vector.assign(grid.getCols(), "act");
} // }
if (params.world_rank == 0) { // if (params.world_rank == 0) {
// // print only on master, values are equal on all workes // // // print only on master, values are equal on all workes
// cout << "CPP: dht_data_size: " << dht_data_size << "\n"; // // cout << "CPP: dht_data_size: " << dht_data_size << "\n";
// cout << "CPP: dht_key_size: " << dht_key_size << "\n"; // // cout << "CPP: dht_key_size: " << dht_key_size << "\n";
// cout << "CPP: dht_buckets_per_process: " << dht_buckets_per_process // // cout << "CPP: dht_buckets_per_process: " << dht_buckets_per_process
// << endl; // // << endl;
// MDL: new output on signif_vector and prop_type // // MDL: new output on signif_vector and prop_type
if (signif_vector_exists) { // if (signif_vector_exists) {
cout << "CPP: using problem-specific rounding digits: " << endl; // cout << "CPP: using problem-specific rounding digits: " << endl;
R.parseEval( // R.parseEval(
"print(data.frame(prop=prop, type=prop_type, " // "print(data.frame(prop=prop, type=prop_type, "
"digits=signif_vector))"); // "digits=signif_vector))");
} else { // } else {
cout << "CPP: using DHT default rounding digits = " // cout << "CPP: using DHT default rounding digits = "
<< params.dht_significant_digits << endl; // << params.dht_significant_digits << endl;
} // }
// MDL: pass to R the DHT stuff. These variables exist // // MDL: pass to R the DHT stuff. These variables exist
// only if dht_enabled is true // // only if dht_enabled is true
R["dht_final_signif"] = params.dht_signif_vector; // R["dht_final_signif"] = params.dht_signif_vector;
R["dht_final_proptype"] = params.dht_prop_type_vector; // R["dht_final_proptype"] = params.dht_prop_type_vector;
} // }
// if (params.dht_strategy == 0) { // // if (params.dht_strategy == 0) {
// if (params.world_rank != 0) { // // if (params.world_rank != 0) {
// dht_object = DHT_create(dht_comm, dht_buckets_per_process, // // dht_object = DHT_create(dht_comm, dht_buckets_per_process,
// dht_data_size, dht_key_size, get_md5); // // dht_data_size, dht_key_size, get_md5);
// // storing for access from worker and callback functions // // // storing for access from worker and callback functions
// fuzzing_buffer = (double *)malloc(dht_key_size); // // fuzzing_buffer = (double *)malloc(dht_key_size);
// } // // }
// } else { // // } else {
// dht_object = DHT_create(MPI_COMM_WORLD, dht_buckets_per_process, // // dht_object = DHT_create(MPI_COMM_WORLD, dht_buckets_per_process,
// dht_data_size, dht_key_size, get_md5); // // dht_data_size, dht_key_size, get_md5);
// } // // }
// if (params.world_rank == 0) { // // if (params.world_rank == 0) {
// cout << "CPP: DHT successfully created!" << endl; // // cout << "CPP: DHT successfully created!" << endl;
// } // // }
}
// }
// MDL: store all parameters // MDL: store all parameters
if (params.world_rank == 0) { if (params.world_rank == 0) {
cout << "CPP: Calling R Function to store calling parameters" << endl; cout << "CPP: Calling R Function to store calling parameters" << endl;
@ -377,7 +383,7 @@ int main(int argc, char *argv[]) {
MPI_Barrier(MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);
if (params.world_rank == 0) { /* This is executed by the master */ if (params.world_rank == 0) { /* This is executed by the master */
ChemMaster master(&params, R, grid); ChemMaster master(parser, R, grid);
TransportSim trans(R); TransportSim trans(R);
Rcpp::NumericVector master_send; Rcpp::NumericVector master_send;
@ -572,14 +578,14 @@ int main(int argc, char *argv[]) {
R.parseEval(r_vis_code); R.parseEval(r_vis_code);
cout << "CPP: Done! Results are stored as R objects into <" cout << "CPP: Done! Results are stored as R objects into <"
<< params.out_dir << "/timings.rds>" << endl; << parser.getOutDir() << "/timings.rds>" << endl;
/*exporting results and profiling data*/ /*exporting results and profiling data*/
// std::string r_vis_code; // std::string r_vis_code;
// r_vis_code = "saveRDS(profiling, file=paste0(fileout,'/timings.rds'));"; // r_vis_code = "saveRDS(profiling, file=paste0(fileout,'/timings.rds'));";
// R.parseEval(r_vis_code); // R.parseEval(r_vis_code);
} else { /*This is executed by the workers*/ } else { /*This is executed by the workers*/
ChemWorker worker(&params, R, grid, dht_comm); ChemWorker worker(parser, R, grid, dht_comm);
// worker.prepareSimulation(dht_comm); // worker.prepareSimulation(dht_comm);
worker.loop(); worker.loop();
} }

View File

@ -8,13 +8,14 @@ using namespace poet;
using namespace std; using namespace std;
using namespace Rcpp; using namespace Rcpp;
#define TAG_WORK 42 ChemMaster::ChemMaster(SimParams &params, RRuntime &R_, Grid &grid_)
ChemMaster::ChemMaster(t_simparams *params, RRuntime &R_, Grid &grid_)
: ChemSim(params, R_, grid_) { : ChemSim(params, R_, grid_) {
this->wp_size = params->wp_size; t_simparams tmp = params.getNumParams();
this->out_dir = params->out_dir;
this->dht_enabled = params->dht_enabled; this->wp_size = tmp.wp_size;
this->dht_enabled = tmp.dht_enabled;
this->out_dir = params.getOutDir();
workerlist = (worker_struct *)calloc(world_size - 1, sizeof(worker_struct)); workerlist = (worker_struct *)calloc(world_size - 1, sizeof(worker_struct));
send_buffer = (double *)calloc((wp_size * (grid.getCols())) + BUFFER_OFFSET, send_buffer = (double *)calloc((wp_size * (grid.getCols())) + BUFFER_OFFSET,

View File

@ -7,12 +7,13 @@
using namespace Rcpp; using namespace Rcpp;
using namespace poet; using namespace poet;
ChemSim::ChemSim(t_simparams *params, RRuntime &R_, Grid &grid_) ChemSim::ChemSim(SimParams &params, RRuntime &R_, Grid &grid_)
: R(R_), grid(grid_) { : R(R_), grid(grid_) {
this->world_rank = params->world_rank; t_simparams tmp = params.getNumParams();
this->world_size = params->world_size; this->world_rank = tmp.world_rank;
this->wp_size = params->wp_size; this->world_size = tmp.world_size;
this->out_dir = params->out_dir; this->wp_size = tmp.wp_size;
this->out_dir = params.getOutDir();
} }
void ChemSim::run() { void ChemSim::run() {

View File

@ -3,8 +3,8 @@
#include <DHT_Wrapper.h> #include <DHT_Wrapper.h>
#include <RRuntime.h> #include <RRuntime.h>
#include <SimParams.h>
#include <mpi.h> #include <mpi.h>
#include <SimParams.h>
#include <vector> #include <vector>
@ -23,7 +23,7 @@
namespace poet { namespace poet {
class ChemSim { class ChemSim {
public: public:
ChemSim(t_simparams *params, RRuntime &R_, Grid &grid_); ChemSim(SimParams &params, RRuntime &R_, Grid &grid_);
virtual void run(); virtual void run();
virtual void end(); virtual void end();
@ -59,7 +59,7 @@ class ChemSim {
class ChemMaster : public ChemSim { class ChemMaster : public ChemSim {
public: public:
ChemMaster(t_simparams *params, RRuntime &R_, Grid &grid_); ChemMaster(SimParams &params, RRuntime &R_, Grid &grid_);
~ChemMaster(); ~ChemMaster();
void run() override; void run() override;
@ -91,7 +91,7 @@ class ChemMaster : public ChemSim {
class ChemWorker : public ChemSim { class ChemWorker : public ChemSim {
public: public:
ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_, ChemWorker(SimParams &params, RRuntime &R_, Grid &grid_,
MPI_Comm dht_comm); MPI_Comm dht_comm);
~ChemWorker(); ~ChemWorker();
@ -110,7 +110,6 @@ class ChemWorker : public ChemSim {
std::string dht_file; std::string dht_file;
unsigned int dht_size_per_process; unsigned int dht_size_per_process;
std::vector<bool> dht_flags; std::vector<bool> dht_flags;
t_simparams *params;
double *mpi_buffer_results; double *mpi_buffer_results;

View File

@ -9,14 +9,17 @@ using namespace poet;
using namespace std; using namespace std;
using namespace Rcpp; using namespace Rcpp;
ChemWorker::ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_, ChemWorker::ChemWorker(SimParams &params, RRuntime &R_, Grid &grid_,
MPI_Comm dht_comm) MPI_Comm dht_comm)
: params(params_), ChemSim(params_, R_, grid_) { : ChemSim(params, R_, grid_) {
this->dt_differ = params->dt_differ; t_simparams tmp = params.getNumParams();
this->dht_enabled = params->dht_enabled;
this->dht_size_per_process = params->dht_size_per_process; this->dt_differ = tmp.dt_differ;
this->dht_file = params->dht_file; this->dht_enabled = tmp.dht_enabled;
this->dht_snaps = params->dht_snaps; this->dht_size_per_process = tmp.dht_size_per_process;
this->dht_snaps = tmp.dht_snaps;
this->dht_file = params.getDHTFile();
mpi_buffer = (double *)calloc((wp_size * (grid.getCols())) + BUFFER_OFFSET, mpi_buffer = (double *)calloc((wp_size * (grid.getCols())) + BUFFER_OFFSET,
sizeof(double)); sizeof(double));
@ -49,9 +52,9 @@ ChemWorker::ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_,
if (!dht_file.empty()) readFile(); if (!dht_file.empty()) readFile();
// set size // set size
dht_flags.resize(params->wp_size, true); dht_flags.resize(wp_size, true);
// assign all elements to true (default) // assign all elements to true (default)
dht_flags.assign(params->wp_size, true); dht_flags.assign(wp_size, true);
timing[0] = 0.0; timing[0] = 0.0;
timing[1] = 0.0; timing[1] = 0.0;
@ -178,9 +181,9 @@ void ChemWorker::doWork(MPI_Status &probe_status) {
// R.parseEvalQ("print(head(work_package_full))"); // R.parseEvalQ("print(head(work_package_full))");
// R.parseEvalQ("print( c(length(dht_flags), nrow(work_package_full)) )"); // R.parseEvalQ("print( c(length(dht_flags), nrow(work_package_full)) )");
grid.importWP(mpi_buffer, params->wp_size); grid.importWP(mpi_buffer, wp_size);
if (params->dht_enabled) { if (dht_enabled) {
R.parseEvalQ("work_package <- work_package_full[dht_flags,]"); R.parseEvalQ("work_package <- work_package_full[dht_flags,]");
} else { } else {
R.parseEvalQ("work_package <- work_package_full"); R.parseEvalQ("work_package <- work_package_full");

View File

@ -1,4 +1,4 @@
add_library(POET_Util RRuntime.cpp Parser.cpp) add_library(POET_Util RRuntime.cpp SimParams.cpp)
target_include_directories(POET_Util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${R_INCLUDE_DIRS}) target_include_directories(POET_Util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${R_INCLUDE_DIRS})
target_link_libraries(POET_Util ${R_LIBRARIES}) target_link_libraries(POET_Util ${R_LIBRARIES})
target_compile_definitions(POET_Util PUBLIC STRICT_R_HEADERS) target_compile_definitions(POET_Util PUBLIC STRICT_R_HEADERS)

View File

@ -1,144 +0,0 @@
#include "Parser.h"
#include <Rcpp.h>
#include <iostream>
using namespace poet;
using namespace std;
using namespace Rcpp;
Parser::Parser(char *argv[], int world_rank_, int world_size_)
: cmdl(argv), world_rank(world_rank_), world_size(world_size_) {
this->simparams.world_rank = world_rank_;
this->simparams.world_size = world_size;
}
int Parser::parseCmdl() {
// if user asked for help
if (cmdl[{"help", "h"}]) {
if (world_rank == 0) {
cout << "Todo" << endl
<< "See README.md for further information." << endl;
}
return PARSER_HELP;
}
// if positional arguments are missing
else if (!cmdl(2)) {
if (world_rank == 0) {
cerr << "ERROR. Kin needs 2 positional arguments: " << endl
<< "1) the R script defining your simulation and" << endl
<< "2) the directory prefix where to save results and profiling"
<< endl;
}
return PARSER_ERROR;
}
std::list<std::string> optionsError = checkOptions(cmdl);
if (!optionsError.empty()) {
if (world_rank == 0) {
cerr << "Unrecognized option(s):\n" << endl;
for (auto option : optionsError) {
cerr << option << endl;
}
cerr << "\nMake sure to use available options. Exiting!" << endl;
}
return PARSER_ERROR;
}
/*Parse DHT arguments*/
simparams.dht_enabled = cmdl["dht"];
// cout << "CPP: DHT is " << ( dht_enabled ? "ON" : "OFF" ) << '\n';
if (simparams.dht_enabled) {
cmdl("dht-strategy", 0) >> simparams.dht_strategy;
// cout << "CPP: DHT strategy is " << dht_strategy << endl;
cmdl("dht-signif", 5) >> simparams.dht_significant_digits;
// cout << "CPP: DHT significant digits = " << dht_significant_digits <<
// endl;
simparams.dht_log = !(cmdl["dht-nolog"]);
// cout << "CPP: DHT logarithm before rounding: " << ( dht_logarithm ? "ON"
// : "OFF" ) << endl;
cmdl("dht-size", DHT_SIZE_PER_PROCESS) >> simparams.dht_size_per_process;
// cout << "CPP: DHT size per process (Byte) = " << dht_size_per_process <<
// endl;
cmdl("dht-snaps", 0) >> simparams.dht_snaps;
cmdl("dht-file") >> simparams.dht_file;
}
/*Parse work package size*/
cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size;
/*Parse output options*/
simparams.store_result = !cmdl["ignore-result"];
if (world_rank == 0) {
cout << "CPP: Complete results storage is "
<< (simparams.store_result ? "ON" : "OFF") << endl;
cout << "CPP: Work Package Size: " << simparams.wp_size << endl;
cout << "CPP: DHT is " << (simparams.dht_enabled ? "ON" : "OFF") << '\n';
if (simparams.dht_enabled) {
cout << "CPP: DHT strategy is " << simparams.dht_strategy << endl;
cout << "CPP: DHT key default digits (ignored if 'signif_vector' is "
"defined) = "
<< simparams.dht_significant_digits << endl;
cout << "CPP: DHT logarithm before rounding: "
<< (simparams.dht_log ? "ON" : "OFF") << endl;
cout << "CPP: DHT size per process (Byte) = "
<< simparams.dht_size_per_process << endl;
cout << "CPP: DHT save snapshots is " << simparams.dht_snaps << endl;
cout << "CPP: DHT load file is " << simparams.dht_file << endl;
}
}
cmdl(1) >> simparams.filesim;
cmdl(2) >> simparams.out_dir;
return PARSER_OK;
}
void Parser::parseR(RRuntime &R) {
// if local_rank == 0 then master else worker
R["local_rank"] = simparams.world_rank;
// assign a char* (string) to 'filesim'
R["filesim"] = wrap(simparams.filesim);
// assign a char* (string) to 'fileout'
R["fileout"] = wrap(simparams.out_dir);
// pass the boolean "store_result" to the R process
R["store_result"] = simparams.store_result;
// worker count
R["n_procs"] = simparams.world_size - 1;
// work package size
R["work_package_size"] = simparams.wp_size;
// dht enabled?
R["dht_enabled"] = simparams.dht_enabled;
// log before rounding?
R["dht_log"] = simparams.dht_log;
// eval the init string, ignoring any returns
R.parseEvalQ("source(filesim)");
}
t_simparams Parser::getParams() { return this->simparams; }
std::list<std::string> Parser::checkOptions(argh::parser cmdl) {
std::list<std::string> retList;
// std::set<std::string> flist = flagList();
// std::set<std::string> plist = paramList();
for (auto &flag : cmdl.flags()) {
if (!(flaglist.find(flag) != flaglist.end())) retList.push_back(flag);
}
for (auto &param : cmdl.params()) {
if (!(paramlist.find(param.first) != paramlist.end()))
retList.push_back(param.first);
}
return retList;
}

View File

@ -1,42 +0,0 @@
#ifndef PARSER_H
#define PARSER_H
#include <RRuntime.h>
#include <string>
#include "SimParams.h"
#include "argh.h"
#define PARSER_OK 0
#define PARSER_ERROR 1
#define PARSER_HELP 2
#define DHT_SIZE_PER_PROCESS 1073741824
#define WORK_PACKAGE_SIZE_DEFAULT 5
namespace poet {
class Parser {
public:
Parser(char *argv[], int world_rank, int world_size);
int parseCmdl();
void parseR(RRuntime &R);
t_simparams getParams();
private:
std::list<std::string> checkOptions(argh::parser cmdl);
std::set<std::string> flaglist{"ignore-result", "dht", "dht-nolog"};
std::set<std::string> paramlist{"work-package-size", "dht-signif",
"dht-strategy", "dht-size",
"dht-snaps", "dht-file"};
argh::parser cmdl;
t_simparams simparams;
int world_rank;
int world_size;
};
} // namespace poet
#endif // PARSER_H

238
src/util/SimParams.cpp Normal file
View File

@ -0,0 +1,238 @@
#include "SimParams.h"
#include <Rcpp.h>
#include <iostream>
using namespace poet;
using namespace std;
using namespace Rcpp;
SimParams::SimParams(int world_rank_, int world_size_)
: world_rank(world_rank_), world_size(world_size_) {
this->simparams.world_rank = world_rank_;
this->simparams.world_size = world_size;
}
int SimParams::parseFromCmdl(char *argv[], RRuntime &R) {
// initialize argh object
argh::parser cmdl(argv);
// if user asked for help
if (cmdl[{"help", "h"}]) {
if (world_rank == 0) {
cout << "Todo" << endl
<< "See README.md for further information." << endl;
}
return PARSER_HELP;
}
// if positional arguments are missing
else if (!cmdl(2)) {
if (world_rank == 0) {
cerr << "ERROR. Kin needs 2 positional arguments: " << endl
<< "1) the R script defining your simulation and" << endl
<< "2) the directory prefix where to save results and profiling"
<< endl;
}
return PARSER_ERROR;
}
std::list<std::string> optionsError = checkOptions(cmdl);
if (!optionsError.empty()) {
if (world_rank == 0) {
cerr << "Unrecognized option(s):\n" << endl;
for (auto option : optionsError) {
cerr << option << endl;
}
cerr << "\nMake sure to use available options. Exiting!" << endl;
}
return PARSER_ERROR;
}
/*Parse DHT arguments*/
simparams.dht_enabled = cmdl["dht"];
// cout << "CPP: DHT is " << ( dht_enabled ? "ON" : "OFF" ) << '\n';
if (simparams.dht_enabled) {
cmdl("dht-strategy", 0) >> simparams.dht_strategy;
// cout << "CPP: DHT strategy is " << dht_strategy << endl;
cmdl("dht-signif", 5) >> simparams.dht_significant_digits;
// cout << "CPP: DHT significant digits = " << dht_significant_digits <<
// endl;
simparams.dht_log = !(cmdl["dht-nolog"]);
// cout << "CPP: DHT logarithm before rounding: " << ( dht_logarithm ? "ON"
// : "OFF" ) << endl;
cmdl("dht-size", DHT_SIZE_PER_PROCESS) >> simparams.dht_size_per_process;
// cout << "CPP: DHT size per process (Byte) = " << dht_size_per_process <<
// endl;
cmdl("dht-snaps", 0) >> simparams.dht_snaps;
cmdl("dht-file") >> dht_file;
}
/*Parse work package size*/
cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size;
/*Parse output options*/
simparams.store_result = !cmdl["ignore-result"];
if (world_rank == 0) {
cout << "CPP: Complete results storage is "
<< (simparams.store_result ? "ON" : "OFF") << endl;
cout << "CPP: Work Package Size: " << simparams.wp_size << endl;
cout << "CPP: DHT is " << (simparams.dht_enabled ? "ON" : "OFF") << '\n';
if (simparams.dht_enabled) {
cout << "CPP: DHT strategy is " << simparams.dht_strategy << endl;
cout << "CPP: DHT key default digits (ignored if 'signif_vector' is "
"defined) = "
<< simparams.dht_significant_digits << endl;
cout << "CPP: DHT logarithm before rounding: "
<< (simparams.dht_log ? "ON" : "OFF") << endl;
cout << "CPP: DHT size per process (Byte) = "
<< simparams.dht_size_per_process << endl;
cout << "CPP: DHT save snapshots is " << simparams.dht_snaps << endl;
cout << "CPP: DHT load file is " << dht_file << endl;
}
}
cmdl(1) >> filesim;
cmdl(2) >> out_dir;
/* distribute information to R runtime */
// if local_rank == 0 then master else worker
R["local_rank"] = simparams.world_rank;
// assign a char* (string) to 'filesim'
R["filesim"] = wrap(filesim);
// assign a char* (string) to 'fileout'
R["fileout"] = wrap(out_dir);
// pass the boolean "store_result" to the R process
R["store_result"] = simparams.store_result;
// worker count
R["n_procs"] = simparams.world_size - 1;
// work package size
R["work_package_size"] = simparams.wp_size;
// dht enabled?
R["dht_enabled"] = simparams.dht_enabled;
// log before rounding?
R["dht_log"] = simparams.dht_log;
// eval the init string, ignoring any returns
R.parseEvalQ("source(filesim)");
return PARSER_OK;
}
void SimParams::initVectorParams(RRuntime &R, int col_count) {
if (simparams.dht_enabled) {
// cout << "\nCreating DHT\n";
// determine size of dht entries
// int dht_data_size = grid.getCols() * sizeof(double);
// int dht_key_size =
// grid.getCols() * sizeof(double) + (params.dt_differ *
// sizeof(double));
// // // determine bucket count for preset memory usage
// // // bucket size is key + value + 1 byte for status
// int dht_buckets_per_process =
// params.dht_size_per_process / (1 + dht_data_size + dht_key_size);
// MDL : following code moved here from worker.cpp
/*Load significance vector from R setup file (or set default)*/
bool signif_vector_exists = R.parseEval("exists('signif_vector')");
if (signif_vector_exists) {
dht_signif_vector = as<std::vector<int>>(R["signif_vector"]);
} else {
dht_signif_vector.assign(col_count, simparams.dht_significant_digits);
}
/*Load property type vector from R setup file (or set default)*/
bool prop_type_vector_exists = R.parseEval("exists('prop_type')");
if (prop_type_vector_exists) {
dht_prop_type_vector = as<std::vector<string>>(R["prop_type"]);
} else {
dht_prop_type_vector.assign(col_count, "act");
}
if (simparams.world_rank == 0) {
// // print only on master, values are equal on all workes
// cout << "CPP: dht_data_size: " << dht_data_size << "\n";
// cout << "CPP: dht_key_size: " << dht_key_size << "\n";
// cout << "CPP: dht_buckets_per_process: " << dht_buckets_per_process
// << endl;
// MDL: new output on signif_vector and prop_type
if (signif_vector_exists) {
cout << "CPP: using problem-specific rounding digits: " << endl;
R.parseEval(
"print(data.frame(prop=prop, type=prop_type, "
"digits=signif_vector))");
} else {
cout << "CPP: using DHT default rounding digits = "
<< simparams.dht_significant_digits << endl;
}
// MDL: pass to R the DHT stuff. These variables exist
// only if dht_enabled is true
R["dht_final_signif"] = dht_signif_vector;
R["dht_final_proptype"] = dht_prop_type_vector;
}
}
}
// void SimParams::parseR(RRuntime &R) {
// // if local_rank == 0 then master else worker
// R["local_rank"] = simparams.world_rank;
// // assign a char* (string) to 'filesim'
// R["filesim"] = wrap(simparams.filesim);
// // assign a char* (string) to 'fileout'
// R["fileout"] = wrap(simparams.out_dir);
// // pass the boolean "store_result" to the R process
// R["store_result"] = simparams.store_result;
// // worker count
// R["n_procs"] = simparams.world_size - 1;
// // work package size
// R["work_package_size"] = simparams.wp_size;
// // dht enabled?
// R["dht_enabled"] = simparams.dht_enabled;
// // log before rounding?
// R["dht_log"] = simparams.dht_log;
// // eval the init string, ignoring any returns
// R.parseEvalQ("source(filesim)");
// }
void SimParams::setDtDiffer(bool dt_differ) { simparams.dt_differ = dt_differ; }
t_simparams SimParams::getNumParams() { return this->simparams; }
std::vector<int> SimParams::getDHTSignifVector() {
return this->dht_signif_vector;
}
std::vector<std::string> SimParams::getDHTPropTypeVector() {
return this->dht_prop_type_vector;
}
std::string SimParams::getDHTFile() { return this->dht_file; }
std::string SimParams::getFilesim() { return this->filesim; }
std::string SimParams::getOutDir() { return this->out_dir; }
std::list<std::string> SimParams::checkOptions(argh::parser cmdl) {
std::list<std::string> retList;
// std::set<std::string> flist = flagList();
// std::set<std::string> plist = paramList();
for (auto &flag : cmdl.flags()) {
if (!(flaglist.find(flag) != flaglist.end())) retList.push_back(flag);
}
for (auto &param : cmdl.params()) {
if (!(paramlist.find(param.first) != paramlist.end()))
retList.push_back(param.first);
}
return retList;
}

View File

@ -1,8 +1,18 @@
#ifndef SIMPARAMS_H #ifndef PARSER_H
#define SIMPARAMS_H #define PARSER_H
#include "RRuntime.h"
#include <string> #include <string>
#include <vector>
#include "argh.h"
#define PARSER_OK 0
#define PARSER_ERROR 1
#define PARSER_HELP 2
#define DHT_SIZE_PER_PROCESS 1073741824
#define WORK_PACKAGE_SIZE_DEFAULT 5
typedef struct { typedef struct {
int world_size; int world_size;
@ -15,19 +25,50 @@ typedef struct {
int dht_strategy; int dht_strategy;
unsigned int dht_size_per_process; unsigned int dht_size_per_process;
int dht_significant_digits; int dht_significant_digits;
unsigned int wp_size;
bool store_result;
} t_simparams;
namespace poet {
class SimParams {
public:
SimParams(int world_rank, int world_size);
int parseFromCmdl(char *argv[], RRuntime &R);
// void parseR(RRuntime &R);
void initVectorParams(RRuntime &R, int col_count);
void setDtDiffer(bool dt_differ);
t_simparams getNumParams();
std::vector<int> getDHTSignifVector();
std::vector<std::string> getDHTPropTypeVector();
std::string getDHTFile();
std::string getFilesim();
std::string getOutDir();
private:
std::list<std::string> checkOptions(argh::parser cmdl);
std::set<std::string> flaglist{"ignore-result", "dht", "dht-nolog"};
std::set<std::string> paramlist{"work-package-size", "dht-signif",
"dht-strategy", "dht-size",
"dht-snaps", "dht-file"};
t_simparams simparams;
int world_rank;
int world_size;
std::vector<int> dht_signif_vector; std::vector<int> dht_signif_vector;
std::vector<std::string> dht_prop_type_vector; std::vector<std::string> dht_prop_type_vector;
std::string dht_file; std::string dht_file;
unsigned int wp_size;
std::string filesim; std::string filesim;
std::string out_dir; std::string out_dir;
};
bool store_result; } // namespace poet
#endif // PARSER_H
// void* R;
// void* grid;
} t_simparams;
#endif // SIMPARAMS_H