From 007d4b0375fba555a1af2e2910a23a794561176d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20L=C3=BCbke?= Date: Tue, 2 Feb 2021 13:42:10 +0100 Subject: [PATCH] Substitute struct SimParams through class --- src/DHT/DHT_Wrapper.cpp | 13 ++- src/DHT/DHT_Wrapper.h | 2 +- src/kin.cpp | 154 +++++++++++++------------ src/model/ChemMaster.cpp | 13 ++- src/model/ChemSim.cpp | 11 +- src/model/ChemSim.h | 9 +- src/model/ChemWorker.cpp | 25 ++-- src/util/CMakeLists.txt | 2 +- src/util/Parser.cpp | 144 ----------------------- src/util/Parser.h | 42 ------- src/util/SimParams.cpp | 238 +++++++++++++++++++++++++++++++++++++++ src/util/SimParams.h | 67 ++++++++--- 12 files changed, 413 insertions(+), 307 deletions(-) delete mode 100644 src/util/Parser.cpp delete mode 100644 src/util/Parser.h create mode 100644 src/util/SimParams.cpp diff --git a/src/DHT/DHT_Wrapper.cpp b/src/DHT/DHT_Wrapper.cpp index b112e53b5..a4cc1cb66 100644 --- a/src/DHT/DHT_Wrapper.cpp +++ b/src/DHT/DHT_Wrapper.cpp @@ -24,16 +24,19 @@ static uint64_t get_md5(int key_size, void *key) { return retval; } -DHT_Wrapper::DHT_Wrapper(t_simparams *params, MPI_Comm dht_comm, +DHT_Wrapper::DHT_Wrapper(SimParams ¶ms, MPI_Comm dht_comm, int buckets_per_process, int data_size, int key_size) { dht_object = DHT_create(dht_comm, buckets_per_process, data_size, key_size, &get_md5); fuzzing_buffer = (double *)malloc(key_size); - this->dt_differ = params->dt_differ; - this->dht_log = params->dht_log; - this->dht_signif_vector = params->dht_signif_vector; - this->dht_prop_type_vector = params->dht_prop_type_vector; + t_simparams tmp = params.getNumParams(); + + this->dt_differ = tmp.dt_differ; + this->dht_log = tmp.dht_log; + + this->dht_signif_vector = params.getDHTSignifVector(); + this->dht_prop_type_vector = params.getDHTPropTypeVector(); } DHT_Wrapper::~DHT_Wrapper() { diff --git a/src/DHT/DHT_Wrapper.h b/src/DHT/DHT_Wrapper.h index fa836cdf5..affc8b695 100644 --- a/src/DHT/DHT_Wrapper.h +++ b/src/DHT/DHT_Wrapper.h @@ -18,7 +18,7 @@ extern "C" { namespace poet { class DHT_Wrapper { public: - DHT_Wrapper(t_simparams *params, MPI_Comm dht_comm, int buckets_per_process, + DHT_Wrapper(SimParams ¶ms, MPI_Comm dht_comm, int buckets_per_process, int data_size, int key_size); ~DHT_Wrapper(); diff --git a/src/kin.cpp b/src/kin.cpp index fcd1e0fb7..367b01f60 100644 --- a/src/kin.cpp +++ b/src/kin.cpp @@ -10,7 +10,6 @@ // BSD-licenced #include "dht_wrapper.h" #include "global_buffer.h" #include #include -#include #include #include #include @@ -89,7 +88,6 @@ int main(int argc, char *argv[]) { // int dht_significant_digits; // cout << "CPP: Start Init (MPI)" << endl; - t_simparams params; int world_size, world_rank; MPI_Init(&argc, &argv); @@ -190,8 +188,8 @@ int main(int argc, char *argv[]) { "source('parallel_r_library.R');"; R.parseEvalQ(r_load_dependencies); - Parser parser(argv, world_rank, world_size); - int pret = parser.parseCmdl(); + SimParams parser(world_rank, world_size); + int pret = parser.parseFromCmdl(argv, R); if (pret == PARSER_ERROR) { MPI_Finalize(); @@ -201,8 +199,8 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } - parser.parseR(R); - params = parser.getParams(); + // parser.parseR(R); + // params = parser.getParams(); // if (params.world_rank == 0) { // 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 // only rank 0 initializes goes through the whole initialization + bool dt_differ; if (world_rank == 0) { // cmdl(2) >> params.out_dir; // <- second positional argument // R["fileout"] = @@ -248,13 +247,17 @@ int main(int argc, char *argv[]) { std::string master_init_code = "mysetup <- master_init(setup=setup)"; R.parseEval(master_init_code); - params.dt_differ = R.parseEval("mysetup$dt_differ"); - MPI_Bcast(&(params.dt_differ), 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); + dt_differ = R.parseEval("mysetup$dt_differ"); + MPI_Bcast(&dt_differ, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); } else { // workers will only read the setup DataFrame defined by input file 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) { cout << "CPP: R init done on process with rank " << params.world_rank << endl; @@ -267,6 +270,8 @@ int main(int argc, char *argv[]) { Grid grid(R); // params.grid = &grid; grid.init(); + + parser.initVectorParams(R, grid.getCols()); /* Retrieve state_C from R context for MPI buffer generation */ // Rcpp::DataFrame state_C = R.parseEval("mysetup$state_C"); @@ -296,78 +301,79 @@ int main(int argc, char *argv[]) { // params.R = &R; - if (params.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)); + // if (params.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); + // // // // 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) { - params.dht_signif_vector = as>(R["signif_vector"]); - } else { - params.dht_signif_vector.assign(grid.getCols(), params.dht_significant_digits); - } + // // 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) { + // params.dht_signif_vector = as>(R["signif_vector"]); + // } else { + // params.dht_signif_vector.assign(grid.getCols(), + // params.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) { - params.dht_prop_type_vector = as>(R["prop_type"]); - } else { - params.dht_prop_type_vector.assign(grid.getCols(), "act"); - } + // /*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) { + // params.dht_prop_type_vector = as>(R["prop_type"]); + // } else { + // params.dht_prop_type_vector.assign(grid.getCols(), "act"); + // } - if (params.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; + // if (params.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 = " - << params.dht_significant_digits << 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 = " + // << params.dht_significant_digits << endl; + // } - // MDL: pass to R the DHT stuff. These variables exist - // only if dht_enabled is true - R["dht_final_signif"] = params.dht_signif_vector; - R["dht_final_proptype"] = params.dht_prop_type_vector; - } + // // MDL: pass to R the DHT stuff. These variables exist + // // only if dht_enabled is true + // R["dht_final_signif"] = params.dht_signif_vector; + // R["dht_final_proptype"] = params.dht_prop_type_vector; + // } - // if (params.dht_strategy == 0) { - // if (params.world_rank != 0) { - // dht_object = DHT_create(dht_comm, dht_buckets_per_process, - // dht_data_size, dht_key_size, get_md5); + // // if (params.dht_strategy == 0) { + // // if (params.world_rank != 0) { + // // dht_object = DHT_create(dht_comm, dht_buckets_per_process, + // // dht_data_size, dht_key_size, get_md5); - // // storing for access from worker and callback functions - // fuzzing_buffer = (double *)malloc(dht_key_size); - // } - // } else { - // dht_object = DHT_create(MPI_COMM_WORLD, dht_buckets_per_process, - // dht_data_size, dht_key_size, get_md5); - // } + // // // storing for access from worker and callback functions + // // fuzzing_buffer = (double *)malloc(dht_key_size); + // // } + // // } else { + // // dht_object = DHT_create(MPI_COMM_WORLD, dht_buckets_per_process, + // // dht_data_size, dht_key_size, get_md5); + // // } - // if (params.world_rank == 0) { - // cout << "CPP: DHT successfully created!" << endl; - // } - } + // // if (params.world_rank == 0) { + // // cout << "CPP: DHT successfully created!" << endl; + // // } + // } // MDL: store all parameters if (params.world_rank == 0) { 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); if (params.world_rank == 0) { /* This is executed by the master */ - ChemMaster master(¶ms, R, grid); + ChemMaster master(parser, R, grid); TransportSim trans(R); Rcpp::NumericVector master_send; @@ -572,14 +578,14 @@ int main(int argc, char *argv[]) { R.parseEval(r_vis_code); 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*/ // std::string r_vis_code; // r_vis_code = "saveRDS(profiling, file=paste0(fileout,'/timings.rds'));"; // R.parseEval(r_vis_code); } else { /*This is executed by the workers*/ - ChemWorker worker(¶ms, R, grid, dht_comm); + ChemWorker worker(parser, R, grid, dht_comm); // worker.prepareSimulation(dht_comm); worker.loop(); } diff --git a/src/model/ChemMaster.cpp b/src/model/ChemMaster.cpp index f662572a0..64f1305c3 100644 --- a/src/model/ChemMaster.cpp +++ b/src/model/ChemMaster.cpp @@ -8,13 +8,14 @@ using namespace poet; using namespace std; using namespace Rcpp; -#define TAG_WORK 42 - -ChemMaster::ChemMaster(t_simparams *params, RRuntime &R_, Grid &grid_) +ChemMaster::ChemMaster(SimParams ¶ms, RRuntime &R_, Grid &grid_) : ChemSim(params, R_, grid_) { - this->wp_size = params->wp_size; - this->out_dir = params->out_dir; - this->dht_enabled = params->dht_enabled; + t_simparams tmp = params.getNumParams(); + + 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)); send_buffer = (double *)calloc((wp_size * (grid.getCols())) + BUFFER_OFFSET, diff --git a/src/model/ChemSim.cpp b/src/model/ChemSim.cpp index d6459512c..7be1a7406 100644 --- a/src/model/ChemSim.cpp +++ b/src/model/ChemSim.cpp @@ -7,12 +7,13 @@ using namespace Rcpp; using namespace poet; -ChemSim::ChemSim(t_simparams *params, RRuntime &R_, Grid &grid_) +ChemSim::ChemSim(SimParams ¶ms, RRuntime &R_, Grid &grid_) : R(R_), grid(grid_) { - this->world_rank = params->world_rank; - this->world_size = params->world_size; - this->wp_size = params->wp_size; - this->out_dir = params->out_dir; + t_simparams tmp = params.getNumParams(); + this->world_rank = tmp.world_rank; + this->world_size = tmp.world_size; + this->wp_size = tmp.wp_size; + this->out_dir = params.getOutDir(); } void ChemSim::run() { diff --git a/src/model/ChemSim.h b/src/model/ChemSim.h index 3765c3bc2..790f80982 100644 --- a/src/model/ChemSim.h +++ b/src/model/ChemSim.h @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include @@ -23,7 +23,7 @@ namespace poet { class ChemSim { public: - ChemSim(t_simparams *params, RRuntime &R_, Grid &grid_); + ChemSim(SimParams ¶ms, RRuntime &R_, Grid &grid_); virtual void run(); virtual void end(); @@ -59,7 +59,7 @@ class ChemSim { class ChemMaster : public ChemSim { public: - ChemMaster(t_simparams *params, RRuntime &R_, Grid &grid_); + ChemMaster(SimParams ¶ms, RRuntime &R_, Grid &grid_); ~ChemMaster(); void run() override; @@ -91,7 +91,7 @@ class ChemMaster : public ChemSim { class ChemWorker : public ChemSim { public: - ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_, + ChemWorker(SimParams ¶ms, RRuntime &R_, Grid &grid_, MPI_Comm dht_comm); ~ChemWorker(); @@ -110,7 +110,6 @@ class ChemWorker : public ChemSim { std::string dht_file; unsigned int dht_size_per_process; std::vector dht_flags; - t_simparams *params; double *mpi_buffer_results; diff --git a/src/model/ChemWorker.cpp b/src/model/ChemWorker.cpp index 1f62371a1..c81ea450f 100644 --- a/src/model/ChemWorker.cpp +++ b/src/model/ChemWorker.cpp @@ -9,14 +9,17 @@ using namespace poet; using namespace std; using namespace Rcpp; -ChemWorker::ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_, +ChemWorker::ChemWorker(SimParams ¶ms, RRuntime &R_, Grid &grid_, MPI_Comm dht_comm) - : params(params_), ChemSim(params_, R_, grid_) { - this->dt_differ = params->dt_differ; - this->dht_enabled = params->dht_enabled; - this->dht_size_per_process = params->dht_size_per_process; - this->dht_file = params->dht_file; - this->dht_snaps = params->dht_snaps; + : ChemSim(params, R_, grid_) { + t_simparams tmp = params.getNumParams(); + + this->dt_differ = tmp.dt_differ; + this->dht_enabled = tmp.dht_enabled; + 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, sizeof(double)); @@ -49,9 +52,9 @@ ChemWorker::ChemWorker(t_simparams *params_, RRuntime &R_, Grid &grid_, if (!dht_file.empty()) readFile(); // set size - dht_flags.resize(params->wp_size, true); + dht_flags.resize(wp_size, true); // assign all elements to true (default) - dht_flags.assign(params->wp_size, true); + dht_flags.assign(wp_size, true); timing[0] = 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( 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,]"); } else { R.parseEvalQ("work_package <- work_package_full"); diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 9c1446c2c..fb6b282f5 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -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_link_libraries(POET_Util ${R_LIBRARIES}) target_compile_definitions(POET_Util PUBLIC STRICT_R_HEADERS) \ No newline at end of file diff --git a/src/util/Parser.cpp b/src/util/Parser.cpp deleted file mode 100644 index b04692868..000000000 --- a/src/util/Parser.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "Parser.h" - -#include - -#include - -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 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 Parser::checkOptions(argh::parser cmdl) { - std::list retList; - // std::set flist = flagList(); - // std::set plist = paramList(); - - for (auto &flag : cmdl.flags()) { - if (!(flaglist.find(flag) != flaglist.end())) retList.push_back(flag); - } - - for (auto ¶m : cmdl.params()) { - if (!(paramlist.find(param.first) != paramlist.end())) - retList.push_back(param.first); - } - - return retList; -} diff --git a/src/util/Parser.h b/src/util/Parser.h deleted file mode 100644 index 0b9440a0b..000000000 --- a/src/util/Parser.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef PARSER_H -#define PARSER_H - -#include - -#include - -#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 checkOptions(argh::parser cmdl); - std::set flaglist{"ignore-result", "dht", "dht-nolog"}; - std::set 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 \ No newline at end of file diff --git a/src/util/SimParams.cpp b/src/util/SimParams.cpp new file mode 100644 index 000000000..d165bf887 --- /dev/null +++ b/src/util/SimParams.cpp @@ -0,0 +1,238 @@ +#include "SimParams.h" + +#include + +#include + +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 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>(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>(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 SimParams::getDHTSignifVector() { + return this->dht_signif_vector; +} +std::vector 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 SimParams::checkOptions(argh::parser cmdl) { + std::list retList; + // std::set flist = flagList(); + // std::set plist = paramList(); + + for (auto &flag : cmdl.flags()) { + if (!(flaglist.find(flag) != flaglist.end())) retList.push_back(flag); + } + + for (auto ¶m : cmdl.params()) { + if (!(paramlist.find(param.first) != paramlist.end())) + retList.push_back(param.first); + } + + return retList; +} diff --git a/src/util/SimParams.h b/src/util/SimParams.h index 9c7a26168..17813f08a 100644 --- a/src/util/SimParams.h +++ b/src/util/SimParams.h @@ -1,8 +1,18 @@ -#ifndef SIMPARAMS_H -#define SIMPARAMS_H +#ifndef PARSER_H +#define PARSER_H + +#include "RRuntime.h" #include -#include + +#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 { int world_size; @@ -15,19 +25,50 @@ typedef struct { int dht_strategy; unsigned int dht_size_per_process; 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 getDHTSignifVector(); + std::vector getDHTPropTypeVector(); + std::string getDHTFile(); + + std::string getFilesim(); + std::string getOutDir(); + + private: + std::list checkOptions(argh::parser cmdl); + std::set flaglist{"ignore-result", "dht", "dht-nolog"}; + std::set 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 dht_signif_vector; std::vector dht_prop_type_vector; std::string dht_file; - unsigned int wp_size; - std::string filesim; std::string out_dir; - - bool store_result; - - // void* R; - // void* grid; -} t_simparams; - -#endif // SIMPARAMS_H +}; +} // namespace poet +#endif // PARSER_H \ No newline at end of file