From 164406ff25708a97e2dc4a1e87e46ac747fb408f Mon Sep 17 00:00:00 2001 From: Max Luebke Date: Thu, 10 Aug 2023 14:15:26 +0200 Subject: [PATCH] feat: enable interpolation without DHT lookup --- app/poet.cpp | 30 +- ext/phreeqcrm | 2 +- include/poet/ChemistryModule.hpp | 9 +- include/poet/DHT_Types.hpp | 8 - include/poet/DHT_Wrapper.hpp | 25 +- include/poet/DataStructures.hpp | 16 + include/poet/Interpolation.hpp | 14 +- include/poet/enums.hpp | 10 + src/ChemistryModule/ChemistryModule.cpp | 15 +- src/ChemistryModule/MasterFunctions.cpp | 23 +- src/ChemistryModule/SurrogateModels/DHT.c | 6 +- .../SurrogateModels/DHT_Wrapper.cpp | 90 ++--- .../SurrogateModels/InterpolationModule.cpp | 46 ++- .../SurrogateModels/ProximityHashTable.cpp | 28 +- src/ChemistryModule/WorkerFunctions.cpp | 240 +++--------- src/SimParams.cpp | 345 ++++++++++-------- 16 files changed, 393 insertions(+), 514 deletions(-) delete mode 100644 include/poet/DHT_Types.hpp create mode 100644 include/poet/enums.hpp diff --git a/app/poet.cpp b/app/poet.cpp index 67cf3c6fd..51dc51fd9 100644 --- a/app/poet.cpp +++ b/app/poet.cpp @@ -224,21 +224,21 @@ inline double RunMasterLoop(SimParams ¶ms, RInside &R, R.parseEvalQ("profiling$dht_get_time <- dht_get_time"); R["dht_fill_time"] = Rcpp::wrap(chem.GetWorkerDHTFillTimings()); R.parseEvalQ("profiling$dht_fill_time <- dht_fill_time"); - if (params.getChemParams().use_interp) { - R["interp_w"] = Rcpp::wrap(chem.GetWorkerInterpolationWriteTimings()); - R.parseEvalQ("profiling$interp_write <- interp_w"); - R["interp_r"] = Rcpp::wrap(chem.GetWorkerInterpolationReadTimings()); - R.parseEvalQ("profiling$interp_read <- interp_r"); - R["interp_g"] = Rcpp::wrap(chem.GetWorkerInterpolationGatherTimings()); - R.parseEvalQ("profiling$interp_gather <- interp_g"); - R["interp_fc"] = - Rcpp::wrap(chem.GetWorkerInterpolationFunctionCallTimings()); - R.parseEvalQ("profiling$interp_function_calls <- interp_fc"); - R["interp_calls"] = Rcpp::wrap(chem.GetWorkerInterpolationCalls()); - R.parseEvalQ("profiling$interp_calls <- interp_calls"); - R["interp_cached"] = Rcpp::wrap(chem.GetWorkerPHTCacheHits()); - R.parseEvalQ("profiling$interp_cached <- interp_cached"); - } + } + if (params.getChemParams().use_interp) { + R["interp_w"] = Rcpp::wrap(chem.GetWorkerInterpolationWriteTimings()); + R.parseEvalQ("profiling$interp_write <- interp_w"); + R["interp_r"] = Rcpp::wrap(chem.GetWorkerInterpolationReadTimings()); + R.parseEvalQ("profiling$interp_read <- interp_r"); + R["interp_g"] = Rcpp::wrap(chem.GetWorkerInterpolationGatherTimings()); + R.parseEvalQ("profiling$interp_gather <- interp_g"); + R["interp_fc"] = + Rcpp::wrap(chem.GetWorkerInterpolationFunctionCallTimings()); + R.parseEvalQ("profiling$interp_function_calls <- interp_fc"); + R["interp_calls"] = Rcpp::wrap(chem.GetWorkerInterpolationCalls()); + R.parseEvalQ("profiling$interp_calls <- interp_calls"); + R["interp_cached"] = Rcpp::wrap(chem.GetWorkerPHTCacheHits()); + R.parseEvalQ("profiling$interp_cached <- interp_cached"); } chem.MasterLoopBreak(); diff --git a/ext/phreeqcrm b/ext/phreeqcrm index 89f713b27..6ed14c353 160000 --- a/ext/phreeqcrm +++ b/ext/phreeqcrm @@ -1 +1 @@ -Subproject commit 89f713b273cd5340b2e8169523da04c2d7ad89c9 +Subproject commit 6ed14c35322a245e3a9776ef262c0ac0eba3b301 diff --git a/include/poet/ChemistryModule.hpp b/include/poet/ChemistryModule.hpp index 16dc1f5f9..f5930184d 100644 --- a/include/poet/ChemistryModule.hpp +++ b/include/poet/ChemistryModule.hpp @@ -1,15 +1,15 @@ -// Time-stamp: "Last modified 2023-08-01 13:13:18 mluebke" +// Time-stamp: "Last modified 2023-08-08 13:15:49 mluebke" #ifndef CHEMISTRYMODULE_H_ #define CHEMISTRYMODULE_H_ #include "DHT_Wrapper.hpp" +#include "DataStructures.hpp" #include "Field.hpp" #include "Interpolation.hpp" #include "IrmResult.h" #include "PhreeqcRM.h" #include "SimParams.hpp" -#include "DataStructures.hpp" #include #include @@ -322,9 +322,8 @@ protected: void WorkerPerfToMaster(int type, const struct worker_s &timings); void WorkerMetricsToMaster(int type); - IRM_RESULT WorkerRunWorkPackage(std::vector &vecWP, - std::vector &vecMapping, - double dSimTime, double dTimestep); + IRM_RESULT WorkerRunWorkPackage(WorkPackage &work_package, double dSimTime, + double dTimestep); std::vector CalculateWPSizesVector(uint32_t n_cells, uint32_t wp_size) const; diff --git a/include/poet/DHT_Types.hpp b/include/poet/DHT_Types.hpp deleted file mode 100644 index 15eb9913e..000000000 --- a/include/poet/DHT_Types.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DHT_TYPES_H_ -#define DHT_TYPES_H_ - -namespace poet { -enum DHT_PROP_TYPES { DHT_TYPE_DEFAULT, DHT_TYPE_CHARGE, DHT_TYPE_TOTAL }; -} - -#endif // DHT_TYPES_H_ diff --git a/include/poet/DHT_Wrapper.hpp b/include/poet/DHT_Wrapper.hpp index f2ed226ab..a066d3ccd 100644 --- a/include/poet/DHT_Wrapper.hpp +++ b/include/poet/DHT_Wrapper.hpp @@ -1,4 +1,4 @@ -// Time-stamp: "Last modified 2023-08-01 13:48:34 mluebke" +// Time-stamp: "Last modified 2023-08-08 18:01:12 mluebke" /* ** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of @@ -25,7 +25,7 @@ #include "DataStructures.hpp" #include "LookupKey.hpp" -#include "poet/DHT_Types.hpp" +#include "enums.hpp" #include "poet/HashFunctions.hpp" #include "poet/LookupKey.hpp" #include "poet/Rounding.hpp" @@ -57,12 +57,9 @@ using DHT_Location = std::pair; class DHT_Wrapper { public: using DHT_ResultObject = struct DHTResobj { - uint32_t length; std::vector keys; - std::vector> results; - std::vector old_values; - std::vector needPhreeqc; std::vector locations; + std::vector filledDHT; }; static constexpr std::int32_t DHT_KEY_INPUT_CUSTOM = @@ -119,9 +116,7 @@ public: * @param[in,out] work_package Pointer to current work package * @param dt Current timestep of simulation */ - auto checkDHT(int length, double dt, const std::vector &work_package, - std::vector &curr_mapping) - -> const DHT_ResultObject &; + auto checkDHT(WorkPackage &work_package) -> const DHT_ResultObject &; /** * @brief Write simulated values into DHT @@ -139,7 +134,7 @@ public: * outputs of the PHREEQC simulation * @param dt Current timestep of simulation */ - void fillDHT(int length, const std::vector &work_package); + void fillDHT(const WorkPackage &work_package); void resultsToWP(std::vector &work_package); @@ -214,6 +209,14 @@ public: std::uint32_t getOutputCount() const { return this->data_count; } + inline void prepareKeys(const std::vector> &input_values, + double dt) { + dht_results.keys.resize(input_values.size()); + for (std::size_t i = 0; i < input_values.size(); i++) { + dht_results.keys[i] = fuzzForDHT(input_values[i], dt); + } + } + private: uint32_t key_count; uint32_t data_count; @@ -221,7 +224,7 @@ private: DHT *dht_object; MPI_Comm communicator; - LookupKey fuzzForDHT(int var_count, void *key, double dt); + LookupKey fuzzForDHT(const std::vector &cell, double dt); std::vector outputToInputAndRates(const std::vector &old_results, diff --git a/include/poet/DataStructures.hpp b/include/poet/DataStructures.hpp index ec323d6fe..c2ab99d77 100644 --- a/include/poet/DataStructures.hpp +++ b/include/poet/DataStructures.hpp @@ -1,13 +1,29 @@ #ifndef DATASTRUCTURES_H_ #define DATASTRUCTURES_H_ +#include "enums.hpp" + #include +#include #include #include #include namespace poet { +struct WorkPackage { + std::size_t size; + std::vector> input; + std::vector> output; + std::vector mapping; + + WorkPackage(size_t _size) : size(_size) { + input.resize(size); + output.resize(size); + mapping.resize(size, CHEM_PQC); + } +}; + template class NamedVector { public: void insert(std::pair to_insert) { diff --git a/include/poet/Interpolation.hpp b/include/poet/Interpolation.hpp index c80cdc97b..5f85872ca 100644 --- a/include/poet/Interpolation.hpp +++ b/include/poet/Interpolation.hpp @@ -1,4 +1,4 @@ -// Time-stamp: "Last modified 2023-08-01 18:10:48 mluebke" +// Time-stamp: "Last modified 2023-08-09 12:52:37 mluebke" #ifndef INTERPOLATION_H_ #define INTERPOLATION_H_ @@ -65,10 +65,9 @@ public: void writeLocationToPHT(LookupKey key, DHT_Location location); const PHT_Result &query(const LookupKey &key, - const std::vector &signif, - std::uint32_t min_entries_needed, - std::uint32_t input_count, - std::uint32_t output_count); + const std::uint32_t min_entries_needed, + const std::uint32_t input_count, + const std::uint32_t output_count); std::uint64_t getLocations(const LookupKey &key); @@ -185,10 +184,9 @@ public: auto getMinEntriesNeeded() { return this->min_entries_needed; } - void writePairs(const DHT_Wrapper::DHT_ResultObject &in); + void writePairs(); - void tryInterpolation(DHT_Wrapper::DHT_ResultObject &dht_results, - std::vector &curr_mapping); + void tryInterpolation(WorkPackage &work_package); void resultsToWP(std::vector &work_package) const; diff --git a/include/poet/enums.hpp b/include/poet/enums.hpp new file mode 100644 index 000000000..11c3c1281 --- /dev/null +++ b/include/poet/enums.hpp @@ -0,0 +1,10 @@ +#ifndef ENUMS_H_ +#define ENUMS_H_ + +namespace poet { +enum DHT_PROP_TYPES { DHT_TYPE_DEFAULT, DHT_TYPE_CHARGE, DHT_TYPE_TOTAL }; + +enum CHEMISTRY_OUT_SOURCE { CHEM_PQC, CHEM_DHT, CHEM_INTERP }; +} // namespace poet + +#endif // ENUMS_H_ diff --git a/src/ChemistryModule/ChemistryModule.cpp b/src/ChemistryModule/ChemistryModule.cpp index acbd7af7d..6f194e8bc 100644 --- a/src/ChemistryModule/ChemistryModule.cpp +++ b/src/ChemistryModule/ChemistryModule.cpp @@ -293,16 +293,23 @@ void poet::ChemistryModule::initializeField(const Field &trans_field) { this->n_cells = trans_field.GetRequestedVecSize(); chem_field = Field(n_cells); - std::vector phreeqc_init; - this->getDumpedField(phreeqc_init); + std::vector> phreeqc_dump(this->nxyz); + this->getDumpedField(phreeqc_dump); if (is_sequential) { - std::vector init_vec{phreeqc_init}; - this->unshuffleField(phreeqc_init, n_cells, prop_count, 1, init_vec); + std::vector init_vec; + for (std::size_t i = 0; i < n_cells; i++) { + init_vec.insert(init_vec.end(), phreeqc_dump[i].begin(), + phreeqc_dump[i].end()); + } + + const auto tmp_buffer{init_vec}; + this->unshuffleField(tmp_buffer, n_cells, prop_count, 1, init_vec); chem_field.InitFromVec(init_vec, prop_names); return; } + std::vector &phreeqc_init = phreeqc_dump[0]; std::vector> initial_values; for (const auto &vec : trans_field.As2DVector()) { diff --git a/src/ChemistryModule/MasterFunctions.cpp b/src/ChemistryModule/MasterFunctions.cpp index b40341dbd..77bfa6023 100644 --- a/src/ChemistryModule/MasterFunctions.cpp +++ b/src/ChemistryModule/MasterFunctions.cpp @@ -90,8 +90,8 @@ std::vector poet::ChemistryModule::GetWorkerDHTEvictions() const { MPI_Get_count(&probe, MPI_UINT32_T, &count); std::vector ret(count); - MPI_Recv(ret.data(), count, MPI_UINT32_T, probe.MPI_SOURCE, WORKER_DHT_EVICTIONS, - this->group_comm, NULL); + MPI_Recv(ret.data(), count, MPI_UINT32_T, probe.MPI_SOURCE, + WORKER_DHT_EVICTIONS, this->group_comm, NULL); return ret; } @@ -322,9 +322,24 @@ void poet::ChemistryModule::RunCells() { void poet::ChemistryModule::MasterRunSequential() { std::vector shuffled_field = shuffleField(chem_field.AsVector(), n_cells, prop_count, 1); - this->setDumpedField(shuffled_field); + + std::vector> input; + for (std::size_t i = 0; i < n_cells; i++) { + input.push_back( + std::vector(shuffled_field.begin() + (i * prop_count), + shuffled_field.begin() + ((i + 1) * prop_count))); + } + + this->setDumpedField(input); PhreeqcRM::RunCells(); - this->getDumpedField(shuffled_field); + this->getDumpedField(input); + + shuffled_field.clear(); + for (std::size_t i = 0; i < n_cells; i++) { + shuffled_field.insert(shuffled_field.end(), input[i].begin(), + input[i].end()); + } + std::vector out_vec{shuffled_field}; unshuffleField(shuffled_field, n_cells, prop_count, 1, out_vec); chem_field.SetFromVector(out_vec); diff --git a/src/ChemistryModule/SurrogateModels/DHT.c b/src/ChemistryModule/SurrogateModels/DHT.c index 5275cb02c..0a7261049 100644 --- a/src/ChemistryModule/SurrogateModels/DHT.c +++ b/src/ChemistryModule/SurrogateModels/DHT.c @@ -1,4 +1,4 @@ -/// Time-stamp: "Last modified 2023-06-28 15:58:19 mluebke" +/// Time-stamp: "Last modified 2023-08-10 11:50:46 mluebke" /* ** Copyright (C) 2017-2021 Max Luebke (University of Potsdam) ** @@ -35,8 +35,8 @@ static void determine_dest(uint64_t hash, int comm_size, /** how many bytes do we need for one index? */ int index_size = sizeof(double) - (index_count - 1); for (int i = 0; i < index_count; i++) { - tmp_index = 0; - memcpy(&tmp_index, (char *)&hash + i, index_size); + tmp_index = (hash >> (i * 8)) & ((1ULL << (index_size * 8)) - 1); + /* memcpy(&tmp_index, (char *)&hash + i, index_size); */ index[i] = (uint64_t)(tmp_index % table_size); } *dest_rank = (unsigned int)(hash % comm_size); diff --git a/src/ChemistryModule/SurrogateModels/DHT_Wrapper.cpp b/src/ChemistryModule/SurrogateModels/DHT_Wrapper.cpp index 86df22d49..bc3e8cfd5 100644 --- a/src/ChemistryModule/SurrogateModels/DHT_Wrapper.cpp +++ b/src/ChemistryModule/SurrogateModels/DHT_Wrapper.cpp @@ -1,4 +1,4 @@ -// Time-stamp: "Last modified 2023-08-01 13:41:57 mluebke" +// Time-stamp: "Last modified 2023-08-09 14:05:01 mluebke" /* ** Copyright (C) 2018-2021 Alexander Lindemann, Max Luebke (University of @@ -21,11 +21,11 @@ */ #include "poet/DHT_Wrapper.hpp" -#include "poet/DHT_Types.hpp" #include "poet/HashFunctions.hpp" #include "poet/Interpolation.hpp" #include "poet/LookupKey.hpp" #include "poet/Rounding.hpp" +#include "poet/enums.hpp" #include #include @@ -83,97 +83,68 @@ DHT_Wrapper::~DHT_Wrapper() { // free DHT DHT_free(dht_object, NULL, NULL); } -auto DHT_Wrapper::checkDHT(int length, double dt, - const std::vector &work_package, - std::vector &curr_mapping) +auto DHT_Wrapper::checkDHT(WorkPackage &work_package) -> const DHT_ResultObject & { - dht_results.length = length; - dht_results.keys.resize(length); - dht_results.results.resize(length); - dht_results.needPhreeqc.resize(length); + const auto length = work_package.size; std::vector bucket_writer(this->data_count + input_key_elements.size()); - std::vector new_mapping; // loop over every grid cell contained in work package for (int i = 0; i < length; i++) { // point to current grid cell - void *key = (void *)&(work_package[i * this->data_count]); - auto &data = dht_results.results[i]; auto &key_vector = dht_results.keys[i]; - // data.resize(this->data_count); - key_vector = fuzzForDHT(this->key_count, key, dt); - // overwrite input with data from DHT, IF value is found in DHT int res = DHT_read(this->dht_object, key_vector.data(), bucket_writer.data()); switch (res) { case DHT_SUCCESS: - dht_results.results[i] = inputAndRatesToOutput(bucket_writer); - dht_results.needPhreeqc[i] = false; + work_package.output[i] = inputAndRatesToOutput(bucket_writer); + work_package.mapping[i] = CHEM_DHT; this->dht_hits++; break; case DHT_READ_MISS: - dht_results.needPhreeqc[i] = true; - new_mapping.push_back(curr_mapping[i]); - dht_results.results[i] = std::vector{ - &work_package[i * this->data_count], - &work_package[i * this->data_count] + this->data_count}; - - // HACK: apply normalization to total H and O in results field of DHT - // dht_results.results[i][0] -= base_totals[0]; - // dht_results.results[i][1] -= base_totals[1]; break; } } - curr_mapping = std::move(new_mapping); - dht_results.old_values = work_package; - return dht_results; } -void DHT_Wrapper::fillDHT(int length, const std::vector &work_package) { +void DHT_Wrapper::fillDHT(const WorkPackage &work_package) { + + const auto length = work_package.size; // loop over every grid cell contained in work package dht_results.locations.resize(length); + dht_results.filledDHT = std::vector(length, false); for (int i = 0; i < length; i++) { // If true grid cell was simulated, needs to be inserted into dht - if (dht_results.needPhreeqc[i]) { + if (work_package.mapping[i] == CHEM_PQC) { // check if calcite or dolomite is absent and present, resp.n and vice // versa in input/output. If this is the case -> Do not write to DHT! // HACK: hardcoded, should be fixed! - if ((dht_results.old_values[i * this->data_count + 7] == 0) != - (work_package[i * this->data_count + 7] == 0)) { - dht_results.needPhreeqc[i] = false; + if ((work_package.input[i][7] == 0) != (work_package.output[i][7] == 0)) { continue; } - if ((dht_results.old_values[i * this->data_count + 9] == 0) != - (work_package[i * this->data_count + 9] == 0)) { - dht_results.needPhreeqc[i] = false; + if ((work_package.input[i][9] == 0) != (work_package.output[i][9] == 0)) { continue; } uint32_t proc, index; - const auto &key = dht_results.keys[i]; - const auto curr_old_data = std::vector( - dht_results.old_values.begin() + (i * this->data_count), - dht_results.old_values.begin() + ((i + 1) * this->data_count)); - const auto curr_new_data = std::vector( - work_package.begin() + (i * this->data_count), - work_package.begin() + ((i + 1) * this->data_count)); - const auto data = outputToInputAndRates(curr_old_data, curr_new_data); + auto &key = dht_results.keys[i]; + const auto data = + outputToInputAndRates(work_package.input[i], work_package.output[i]); // void *data = (void *)&(work_package[i * this->data_count]); // fuzz data (round, logarithm etc.) // insert simulated data with fuzzed key into DHT - int res = DHT_write(this->dht_object, (void *)(key.data()), + int res = DHT_write(this->dht_object, key.data(), const_cast(data.data()), &proc, &index); dht_results.locations[i] = {proc, index}; @@ -182,6 +153,8 @@ void DHT_Wrapper::fillDHT(int length, const std::vector &work_package) { if ((res != DHT_SUCCESS) && (res == DHT_WRITE_SUCCESS_WITH_EVICTION)) { dht_evictions++; } + + dht_results.filledDHT[i] = true; } } } @@ -218,14 +191,14 @@ DHT_Wrapper::inputAndRatesToOutput(const std::vector &dht_data) { return output; } -void DHT_Wrapper::resultsToWP(std::vector &work_package) { - for (int i = 0; i < dht_results.length; i++) { - if (!dht_results.needPhreeqc[i]) { - std::copy(dht_results.results[i].begin(), dht_results.results[i].end(), - work_package.begin() + (data_count * i)); - } - } -} +// void DHT_Wrapper::resultsToWP(std::vector &work_package) { +// for (int i = 0; i < dht_results.length; i++) { +// if (!dht_results.needPhreeqc[i]) { +// std::copy(dht_results.results[i].begin(), dht_results.results[i].end(), +// work_package.begin() + (data_count * i)); +// } +// } +// } int DHT_Wrapper::tableToFile(const char *filename) { int res = DHT_to_file(dht_object, filename); @@ -255,11 +228,10 @@ void DHT_Wrapper::printStatistics() { } } -LookupKey DHT_Wrapper::fuzzForDHT(int var_count, void *key, double dt) { +LookupKey DHT_Wrapper::fuzzForDHT(const std::vector &cell, double dt) { const auto c_zero_val = std::pow(10, AQUEOUS_EXP); - const Lookup_Keyelement dummy = {.0}; - LookupKey vecFuzz(var_count + 1, dummy); + LookupKey vecFuzz(this->key_count + 1, {.0}); DHT_Rounder rounder; int totals_i = 0; @@ -269,7 +241,7 @@ LookupKey DHT_Wrapper::fuzzForDHT(int var_count, void *key, double dt) { if (input_key_elements[i] == DHT_KEY_INPUT_CUSTOM) { continue; } - double curr_key = ((double *)key)[input_key_elements[i]]; + double curr_key = cell[input_key_elements[i]]; if (curr_key != 0) { if (curr_key < c_zero_val && this->dht_prop_type_vector[i] == DHT_TYPE_DEFAULT) { @@ -284,7 +256,7 @@ LookupKey DHT_Wrapper::fuzzForDHT(int var_count, void *key, double dt) { } } // add timestep to the end of the key as double value - vecFuzz[var_count].fp_element = dt; + vecFuzz[this->key_count].fp_element = dt; return vecFuzz; } diff --git a/src/ChemistryModule/SurrogateModels/InterpolationModule.cpp b/src/ChemistryModule/SurrogateModels/InterpolationModule.cpp index e5c36fa0c..0321e6d8a 100644 --- a/src/ChemistryModule/SurrogateModels/InterpolationModule.cpp +++ b/src/ChemistryModule/SurrogateModels/InterpolationModule.cpp @@ -1,4 +1,4 @@ -// Time-stamp: "Last modified 2023-08-01 23:18:45 mluebke" +// Time-stamp: "Last modified 2023-08-09 13:41:53 mluebke" #include "poet/DHT_Wrapper.hpp" #include "poet/HashFunctions.hpp" @@ -48,31 +48,32 @@ void InterpolationModule::initPHT(std::uint32_t key_count, key_size, data_size, entries_per_bucket, size_per_process, communicator); } -void InterpolationModule::writePairs(const DHT_Wrapper::DHT_ResultObject &in) { - for (int i = 0; i < in.length; i++) { - if (in.needPhreeqc[i]) { +void InterpolationModule::writePairs() { + const auto in = this->dht_instance.getDHTResults(); + for (int i = 0; i < in.filledDHT.size(); i++) { + if (in.filledDHT[i]) { const auto coarse_key = roundKey(in.keys[i]); pht->writeLocationToPHT(coarse_key, in.locations[i]); } } } -void InterpolationModule::tryInterpolation( - DHT_Wrapper::DHT_ResultObject &dht_results, - std::vector &curr_mapping) { - interp_result.status.resize(dht_results.length, NOT_NEEDED); - interp_result.results.resize(dht_results.length, {}); +void InterpolationModule::tryInterpolation(WorkPackage &work_package) { + interp_result.status.resize(work_package.size, NOT_NEEDED); - for (int i = 0; i < dht_results.length; i++) { - if (!dht_results.needPhreeqc[i]) { + const auto dht_results = this->dht_instance.getDHTResults(); + + for (int i = 0; i < work_package.size; i++) { + if (work_package.mapping[i] != CHEM_PQC) { interp_result.status[i] = NOT_NEEDED; continue; } + const auto rounded_key = roundKey(dht_results.keys[i]); + auto pht_result = - pht->query(roundKey(dht_results.keys[i]), this->key_signifs.getValues(), - this->min_entries_needed, dht_instance.getInputCount(), - dht_instance.getOutputCount()); + pht->query(rounded_key, this->min_entries_needed, + dht_instance.getInputCount(), dht_instance.getOutputCount()); int pht_i = 0; @@ -85,9 +86,9 @@ void InterpolationModule::tryInterpolation( auto out_it = pht_result.out_values.begin() + pht_i; bool same_sig_calcite = (pht_result.in_values[pht_i][7] == 0) == - (dht_results.results[i][7] == 0); + (work_package.input[i][7] == 0); bool same_sig_dolomite = (pht_result.in_values[pht_i][8] == 0) == - (dht_results.results[i][9] == 0); + (work_package.input[i][9] == 0); if (!same_sig_calcite || !same_sig_dolomite) { pht_result.size -= 1; pht_result.in_values.erase(in_it); @@ -104,7 +105,7 @@ void InterpolationModule::tryInterpolation( } #ifdef POET_PHT_ADD - this->pht->incrementReadCounter(roundKey(dht_results.keys[i])); + this->pht->incrementReadCounter(roundKey(roundedKey)); #endif double start_fc = MPI_Wtime(); @@ -115,11 +116,11 @@ void InterpolationModule::tryInterpolation( // } // mean_water /= pht_result.size; - interp_result.results[i] = - f_interpolate(dht_instance.getKeyElements(), dht_results.results[i], + work_package.output[i] = + f_interpolate(dht_instance.getKeyElements(), work_package.input[i], pht_result.in_values, pht_result.out_values); - if (interp_result.results[i][7] < 0 || interp_result.results[i][9] < 0) { + if (work_package.output[i][7] < 0 || work_package.output[i][9] < 0) { interp_result.status[i] = INSUFFICIENT_DATA; continue; } @@ -129,10 +130,7 @@ void InterpolationModule::tryInterpolation( this->interpolations++; - curr_mapping.erase(std::remove(curr_mapping.begin(), curr_mapping.end(), i), - curr_mapping.end()); - - dht_results.needPhreeqc[i] = false; + work_package.mapping[i] = CHEM_INTERP; interp_result.status[i] = RES_OK; } } diff --git a/src/ChemistryModule/SurrogateModels/ProximityHashTable.cpp b/src/ChemistryModule/SurrogateModels/ProximityHashTable.cpp index e0f014755..285ed21d3 100644 --- a/src/ChemistryModule/SurrogateModels/ProximityHashTable.cpp +++ b/src/ChemistryModule/SurrogateModels/ProximityHashTable.cpp @@ -1,4 +1,4 @@ -// Time-stamp: "Last modified 2023-08-01 17:11:42 mluebke" +// Time-stamp: "Last modified 2023-08-09 13:32:11 mluebke" #include "poet/DHT_Wrapper.hpp" #include "poet/HashFunctions.hpp" @@ -106,9 +106,8 @@ void ProximityHashTable::writeLocationToPHT(LookupKey key, } const ProximityHashTable::PHT_Result &ProximityHashTable::query( - const LookupKey &key, const std::vector &signif, - std::uint32_t min_entries_needed, std::uint32_t input_count, - std::uint32_t output_count) { + const LookupKey &key, const std::uint32_t min_entries_needed, + const std::uint32_t input_count, const std::uint32_t output_count) { double start_r = MPI_Wtime(); const auto cache_ret = localCache[key]; @@ -158,27 +157,6 @@ const ProximityHashTable::PHT_Result &ProximityHashTable::query( buffer += input_count; lookup_results.out_values.push_back( std::vector(buffer, buffer + output_count)); - - // if (!similarityCheck(check_key, key, signif)) { - // // TODO: original stored location in PHT was overwritten in DHT. - // Need to - // // handle this! - // lookup_results.size--; - // if (lookup_results.size < min_entries_needed) { - // lookup_results.size = 0; - // break; - // } - // continue; - // } - - // auto input = convertKeysFromDHT(buffer_start, dht_key_count); - // // remove timestep from the key - // input.pop_back(); - // lookup_results.in_keys.push_back(input); - - // auto *data = reinterpret_cast(buffer + dht_key_count); - // lookup_results.out_values.push_back( - // std::vector(data, data + dht_data_count)); } if (lookup_results.size != 0) { diff --git a/src/ChemistryModule/WorkerFunctions.cpp b/src/ChemistryModule/WorkerFunctions.cpp index a87b07a86..eb9df84a2 100644 --- a/src/ChemistryModule/WorkerFunctions.cpp +++ b/src/ChemistryModule/WorkerFunctions.cpp @@ -1,10 +1,10 @@ -// Time-stamp: "Last modified 2023-08-01 17:22:20 mluebke" +// Time-stamp: "Last modified 2023-08-10 12:14:24 mluebke" -#include "IrmResult.h" #include "poet/ChemistryModule.hpp" #include "poet/DHT_Wrapper.hpp" #include "poet/Interpolation.hpp" +#include #include #include #include @@ -19,146 +19,6 @@ #include namespace poet { - -//std::vector -//inverseDistanceWeighting(const std::vector &to_calc, -// const std::vector &from, -// const std::vector> &input, -// const std::vector> &output) { -// std::vector results = from; -// -// const std::uint32_t buffer_size = input.size() + 1; -// double buffer[buffer_size]; -// double from_rescaled; -// -// const std::uint32_t data_set_n = input.size(); -// double rescaled[to_calc.size()][data_set_n + 1]; -// double weights[data_set_n]; -// -// // rescaling over all key elements -// for (int key_comp_i = 0; key_comp_i < to_calc.size(); key_comp_i++) { -// const auto output_comp_i = to_calc[key_comp_i]; -// -// // rescale input between 0 and 1 -// for (int point_i = 0; point_i < data_set_n; point_i++) { -// rescaled[key_comp_i][point_i] = input[point_i][key_comp_i]; -// } -// -// rescaled[key_comp_i][data_set_n] = from[output_comp_i]; -// -// const double min = *std::min_element(rescaled[key_comp_i], -// rescaled[key_comp_i] + data_set_n + 1); -// const double max = *std::max_element(rescaled[key_comp_i], -// rescaled[key_comp_i] + data_set_n + 1); -// -// for (int point_i = 0; point_i < data_set_n; point_i++) { -// rescaled[key_comp_i][point_i] = -// ((max - min) != 0 -// ? (rescaled[key_comp_i][point_i] - min) / (max - min) -// : 0); -// } -// rescaled[key_comp_i][data_set_n] = -// ((max - min) != 0 ? (from[output_comp_i] - min) / (max - min) : 0); -// } -// -// // calculate distances for each data set -// double inv_sum = 0; -// for (int point_i = 0; point_i < data_set_n; point_i++) { -// double distance = 0; -// for (int key_comp_i = 0; key_comp_i < to_calc.size(); key_comp_i++) { -// distance += std::pow( -// rescaled[key_comp_i][point_i] - rescaled[key_comp_i][data_set_n], 2); -// } -// weights[point_i] = 1 / std::sqrt(distance); -// assert(!std::isnan(weights[point_i])); -// inv_sum += weights[point_i]; -// } -// -// assert(!std::isnan(inv_sum)); -// -// // actual interpolation -// // bool has_h = false; -// // bool has_o = false; -// -// for (int key_comp_i = 0; key_comp_i < to_calc.size(); key_comp_i++) { -// const auto output_comp_i = to_calc[key_comp_i]; -// double key_delta = 0; -// -// // if (interp_i == 0) { -// // has_h = true; -// // } -// -// // if (interp_i == 1) { -// // has_o = true; -// // } -// -// for (int j = 0; j < data_set_n; j++) { -// key_delta += weights[j] * input[j][key_comp_i]; -// } -// -// key_delta /= inv_sum; -// -// results[output_comp_i] = from[output_comp_i] + key_delta; -// } -// -// // if (!has_h) { -// // double new_val = 0; -// // for (int j = 0; j < data_set_n; j++) { -// // new_val += weights[j] * output[j][0]; -// // } -// // results[0] = new_val / inv_sum; -// // } -// -// // if (!has_h) { -// // double new_val = 0; -// // for (int j = 0; j < data_set_n; j++) { -// // new_val += weights[j] * output[j][1]; -// // } -// // results[1] = new_val / inv_sum; -// // } -// -// // for (std::uint32_t i = 0; i < to_calc.size(); i++) { -// // const std::uint32_t interp_i = to_calc[i]; -// -// // // rescale input between 0 and 1 -// // for (int j = 0; j < input.size(); j++) { -// // buffer[j] = input[j].at(i); -// // } -// -// // buffer[buffer_size - 1] = from[interp_i]; -// -// // const double min = *std::min_element(buffer, buffer + buffer_size); -// // const double max = *std::max_element(buffer, buffer + buffer_size); -// -// // for (int j = 0; j < input.size(); j++) { -// // buffer[j] = ((max - min) != 0 ? (buffer[j] - min) / (max - min) : 1); -// // } -// // from_rescaled = -// // ((max - min) != 0 ? (from[interp_i] - min) / (max - min) : 0); -// -// // double inv_sum = 0; -// -// // // calculate distances for each point -// // for (int i = 0; i < input.size(); i++) { -// // const double distance = std::pow(buffer[i] - from_rescaled, 2); -// -// // buffer[i] = distance > 0 ? (1 / std::sqrt(distance)) : 0; -// // inv_sum += buffer[i]; -// // } -// // // calculate new values -// // double new_val = 0; -// // for (int i = 0; i < output.size(); i++) { -// // new_val += buffer[i] * output[i][interp_i]; -// // } -// // results[interp_i] = new_val / inv_sum; -// // if (std::isnan(results[interp_i])) { -// // std::cout << "nan with new_val = " << output[0][i] << std::endl; -// // } -// // } -// -// return results; -//} - inline std::string get_string(int root, MPI_Comm communicator) { int count; MPI_Bcast(&count, 1, MPI_INT, root, communicator); @@ -256,8 +116,6 @@ void poet::ChemistryModule::WorkerProcessPkgs(struct worker_s &timings, void poet::ChemistryModule::WorkerDoWork(MPI_Status &probe_status, int double_count, struct worker_s &timings) { - int local_work_package_size = 0; - static int counter = 1; double dht_get_start, dht_get_end; @@ -268,12 +126,11 @@ void poet::ChemistryModule::WorkerDoWork(MPI_Status &probe_status, double dt; double current_sim_time; - const uint32_t n_cells_times_props = this->prop_count * this->wp_size; - std::vector vecCurrWP(n_cells_times_props + BUFFER_OFFSET); int count = double_count; + std::vector mpi_buffer(count); /* receive */ - MPI_Recv(vecCurrWP.data(), count, MPI_DOUBLE, 0, LOOP_WORK, this->group_comm, + MPI_Recv(mpi_buffer.data(), count, MPI_DOUBLE, 0, LOOP_WORK, this->group_comm, MPI_STATUS_IGNORE); /* decrement count of work_package by BUFFER_OFFSET */ @@ -283,72 +140,70 @@ void poet::ChemistryModule::WorkerDoWork(MPI_Status &probe_status, * mpi_buffer */ // work_package_size - local_work_package_size = vecCurrWP[count]; + poet::WorkPackage s_curr_wp(mpi_buffer[count]); // current iteration of simulation - iteration = vecCurrWP[count + 1]; + iteration = mpi_buffer[count + 1]; // current timestep size - dt = vecCurrWP[count + 2]; + dt = mpi_buffer[count + 2]; // current simulation time ('age' of simulation) - current_sim_time = vecCurrWP[count + 3]; + current_sim_time = mpi_buffer[count + 3]; /* 4th double value is currently a placeholder */ // placeholder = mpi_buffer[count+4]; - vecCurrWP.resize(n_cells_times_props); - std::vector vecMappingWP(local_work_package_size); + for (std::size_t wp_i = 0; wp_i < s_curr_wp.size; wp_i++) { + s_curr_wp.input[wp_i] = + std::vector(mpi_buffer.begin() + this->prop_count * wp_i, + mpi_buffer.begin() + this->prop_count * (wp_i + 1)); + } - { - std::uint32_t i = 0; - std::generate(vecMappingWP.begin(), vecMappingWP.end(), - [&] { return i++; }); + // std::cout << this->comm_rank << ":" << counter++ << std::endl; + if (dht_enabled || interp_enabled) { + dht->prepareKeys(s_curr_wp.input, dt); } if (dht_enabled) { /* check for values in DHT */ dht_get_start = MPI_Wtime(); - dht->checkDHT(local_work_package_size, dt, vecCurrWP, vecMappingWP); + dht->checkDHT(s_curr_wp); dht_get_end = MPI_Wtime(); + timings.dht_get += dht_get_end - dht_get_start; + } - if (interp_enabled) { - interp->tryInterpolation(dht->getDHTResults(), vecMappingWP); - } + if (interp_enabled) { + interp->tryInterpolation(s_curr_wp); } phreeqc_time_start = MPI_Wtime(); - if (WorkerRunWorkPackage(vecCurrWP, vecMappingWP, current_sim_time, dt) != - IRM_OK) { - throw std::runtime_error("Phreeqc threw an error!"); + if (WorkerRunWorkPackage(s_curr_wp, current_sim_time, dt) != IRM_OK) { + std::cerr << "Phreeqc error" << std::endl; }; phreeqc_time_end = MPI_Wtime(); - if (dht_enabled) { - dht->resultsToWP(vecCurrWP); - if (interp_enabled) { - interp->resultsToWP(vecCurrWP); - } + for (std::size_t wp_i = 0; wp_i < s_curr_wp.size; wp_i++) { + std::copy(s_curr_wp.output[wp_i].begin(), s_curr_wp.output[wp_i].end(), + mpi_buffer.begin() + this->prop_count * wp_i); } /* send results to master */ MPI_Request send_req; - MPI_Isend(vecCurrWP.data(), count, MPI_DOUBLE, 0, LOOP_WORK, MPI_COMM_WORLD, + MPI_Isend(mpi_buffer.data(), count, MPI_DOUBLE, 0, LOOP_WORK, MPI_COMM_WORLD, &send_req); - if (dht_enabled) { + if (dht_enabled || interp_enabled) { /* write results to DHT */ dht_fill_start = MPI_Wtime(); - dht->fillDHT(local_work_package_size, vecCurrWP); + dht->fillDHT(s_curr_wp); dht_fill_end = MPI_Wtime(); if (interp_enabled) { - interp->writePairs(dht->getDHTResults()); + interp->writePairs(); } - - timings.dht_get += dht_get_end - dht_get_start; timings.dht_fill += dht_fill_end - dht_fill_start; } @@ -429,36 +284,39 @@ void poet::ChemistryModule::WorkerReadDHTDump( } IRM_RESULT -poet::ChemistryModule::WorkerRunWorkPackage( - std::vector &vecWP, std::vector &vecMapping, - double dSimTime, double dTimestep) { - if ((this->wp_size * this->prop_count) != vecWP.size()) { - return IRM_INVALIDARG; - } - +poet::ChemistryModule::WorkerRunWorkPackage(WorkPackage &work_package, + double dSimTime, double dTimestep) { // check if we actually need to start phreeqc - bool bRunPhreeqc = false; - for (const auto &aMappingNum : vecMapping) { - if (aMappingNum != -1) { - bRunPhreeqc = true; - break; + std::vector pqc_mapping; + + for (std::size_t i = 0; i < work_package.size; i++) { + if (work_package.mapping[i] == CHEM_PQC) { + pqc_mapping.push_back(i); } } - if (!bRunPhreeqc) { + if (pqc_mapping.empty()) { return IRM_OK; } IRM_RESULT result; - this->PhreeqcRM::setPOETMapping(vecMapping); - this->setDumpedField(vecWP); + this->PhreeqcRM::setPOETMapping(pqc_mapping); + this->setDumpedField(work_package.input); this->PhreeqcRM::SetTime(dSimTime); this->PhreeqcRM::SetTimeStep(dTimestep); result = this->PhreeqcRM::RunCells(); - this->getDumpedField(vecWP); + std::vector> output_tmp(work_package.size); + + this->getDumpedField(output_tmp); + + for (std::size_t i = 0; i < work_package.size; i++) { + if (work_package.mapping[i] == CHEM_PQC) { + work_package.output[i] = output_tmp[i]; + } + } return result; } diff --git a/src/SimParams.cpp b/src/SimParams.cpp index 8088609cf..4348917f5 100644 --- a/src/SimParams.cpp +++ b/src/SimParams.cpp @@ -18,15 +18,17 @@ ** Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "poet/enums.hpp" #include #include #include -#include #include #include #include - +#include +#include +#include #include #include #include @@ -37,202 +39,233 @@ using namespace std; using namespace Rcpp; poet::GridParams::s_GridParams(RInside &R) { - auto tmp_n_cells = - Rcpp::as>(R.parseEval("mysetup$grid$n_cells")); - assert(tmp_n_cells.size() < 3); + auto tmp_n_cells = + Rcpp::as>(R.parseEval("mysetup$grid$n_cells")); + assert(tmp_n_cells.size() < 3); - this->dim = tmp_n_cells.size(); + this->dim = tmp_n_cells.size(); - std::copy(tmp_n_cells.begin(), tmp_n_cells.end(), this->n_cells.begin()); + std::copy(tmp_n_cells.begin(), tmp_n_cells.end(), this->n_cells.begin()); - auto tmp_s_cells = - Rcpp::as>(R.parseEval("mysetup$grid$s_cells")); + auto tmp_s_cells = + Rcpp::as>(R.parseEval("mysetup$grid$s_cells")); - assert(tmp_s_cells.size() == this->dim); + assert(tmp_s_cells.size() == this->dim); - std::copy(tmp_s_cells.begin(), tmp_s_cells.end(), this->s_cells.begin()); + std::copy(tmp_s_cells.begin(), tmp_s_cells.end(), this->s_cells.begin()); - this->total_n = - (dim == 1 ? this->n_cells[0] : this->n_cells[0] * this->n_cells[1]); + this->total_n = + (dim == 1 ? this->n_cells[0] : this->n_cells[0] * this->n_cells[1]); - this->type = Rcpp::as(R.parseEval("mysetup$grid$type")); + this->type = Rcpp::as(R.parseEval("mysetup$grid$type")); } poet::DiffusionParams::s_DiffusionParams(RInside &R) { - this->initial_t = - Rcpp::as(R.parseEval("mysetup$diffusion$init")); - this->alpha = - Rcpp::as(R.parseEval("mysetup$diffusion$alpha")); - if (Rcpp::as( - R.parseEval("'vecinj_inner' %in% names(mysetup$diffusion)"))) { - this->vecinj_inner = - Rcpp::as(R.parseEval("mysetup$diffusion$vecinj_inner")); - } - this->vecinj = - Rcpp::as(R.parseEval("mysetup$diffusion$vecinj")); - this->vecinj_index = - Rcpp::as(R.parseEval("mysetup$diffusion$vecinj_index")); + this->initial_t = + Rcpp::as(R.parseEval("mysetup$diffusion$init")); + this->alpha = + Rcpp::as(R.parseEval("mysetup$diffusion$alpha")); + if (Rcpp::as( + R.parseEval("'vecinj_inner' %in% names(mysetup$diffusion)"))) { + this->vecinj_inner = + Rcpp::as(R.parseEval("mysetup$diffusion$vecinj_inner")); + } + this->vecinj = + Rcpp::as(R.parseEval("mysetup$diffusion$vecinj")); + this->vecinj_index = + Rcpp::as(R.parseEval("mysetup$diffusion$vecinj_index")); } void poet::ChemistryParams::initFromR(RInsidePOET &R) { - this->database_path = - Rcpp::as(R.parseEval("mysetup$chemistry$database")); - this->input_script = - Rcpp::as(R.parseEval("mysetup$chemistry$input_script")); + this->database_path = + Rcpp::as(R.parseEval("mysetup$chemistry$database")); + this->input_script = + Rcpp::as(R.parseEval("mysetup$chemistry$input_script")); - if (R.checkIfExists("dht_species", "mysetup$chemistry")) { - this->dht_signifs = - R.wrapNamedVector("mysetup$chemistry$dht_species"); - } + if (R.checkIfExists("dht_species", "mysetup$chemistry")) { + this->dht_signifs = + R.wrapNamedVector("mysetup$chemistry$dht_species"); + } - if (R.checkIfExists("pht_species", "mysetup$chemistry")) { - this->pht_signifs = - R.wrapNamedVector("mysetup$chemistry$pht_species"); - } + if (R.checkIfExists("pht_species", "mysetup$chemistry")) { + this->pht_signifs = + R.wrapNamedVector("mysetup$chemistry$pht_species"); + } } SimParams::SimParams(int world_rank_, int world_size_) { - this->simparams.world_rank = world_rank_; - this->simparams.world_size = world_size_; + this->simparams.world_rank = world_rank_; + this->simparams.world_size = world_size_; } int SimParams::parseFromCmdl(char *argv[], RInsidePOET &R) { - // initialize argh object - argh::parser cmdl(argv); + // initialize argh object + argh::parser cmdl(argv); - // if user asked for help - if (cmdl[{"help", "h"}]) { - if (simparams.world_rank == 0) { - MSG("Todo"); - MSG("See README.md for further information."); - } - return poet::PARSER_HELP; + // if user asked for help + if (cmdl[{"help", "h"}]) { + if (simparams.world_rank == 0) { + MSG("Todo"); + MSG("See README.md for further information."); } - // if positional arguments are missing - else if (!cmdl(2)) { - if (simparams.world_rank == 0) { - ERRMSG("Kin needs 2 positional arguments: "); - ERRMSG("1) the R script defining your simulation and"); - ERRMSG("2) the directory prefix where to save results and profiling"); - } - return poet::PARSER_ERROR; + return poet::PARSER_HELP; + } + // if positional arguments are missing + else if (!cmdl(2)) { + if (simparams.world_rank == 0) { + ERRMSG("Kin needs 2 positional arguments: "); + ERRMSG("1) the R script defining your simulation and"); + ERRMSG("2) the directory prefix where to save results and profiling"); } + return poet::PARSER_ERROR; + } - // collect all parameters which are not known, print them to stderr and return - // with PARSER_ERROR - std::list optionsError = validateOptions(cmdl); - if (!optionsError.empty()) { - if (simparams.world_rank == 0) { - ERRMSG("Unrecognized option(s):\n"); - for (auto option : optionsError) { - ERRMSG(std::string(option)); - } - ERRMSG("Make sure to use available options. Exiting!"); - } - return poet::PARSER_ERROR; + // collect all parameters which are not known, print them to stderr and return + // with PARSER_ERROR + std::list optionsError = validateOptions(cmdl); + if (!optionsError.empty()) { + if (simparams.world_rank == 0) { + ERRMSG("Unrecognized option(s):\n"); + for (auto option : optionsError) { + ERRMSG(std::string(option)); + } + ERRMSG("Make sure to use available options. Exiting!"); } - - simparams.print_progressbar = cmdl[{"P", "progress"}]; + return poet::PARSER_ERROR; + } - /*Parse DHT arguments*/ - chem_params.use_dht = cmdl["dht"]; - // cout << "CPP: DHT is " << ( dht_enabled ? "ON" : "OFF" ) << '\n'; + simparams.print_progressbar = cmdl[{"P", "progress"}]; + + simparams.print_progressbar = cmdl[{"P", "progress"}]; + + /*Parse DHT arguments*/ + chem_params.use_dht = cmdl["dht"]; + chem_params.use_interp = cmdl["interp"]; + // cout << "CPP: DHT is " << ( dht_enabled ? "ON" : "OFF" ) << '\n'; + + cmdl("dht-size", DHT_SIZE_PER_PROCESS_MB) >> chem_params.dht_size; + // cout << "CPP: DHT size per process (Byte) = " << dht_size_per_process << + // endl; + + cmdl("dht-snaps", 0) >> chem_params.dht_snaps; + + cmdl("dht-file") >> chem_params.dht_file; + /*Parse work package size*/ + cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size; + + cmdl("interp-size", 100) >> chem_params.pht_size; + cmdl("interp-min", 5) >> chem_params.interp_min_entries; + cmdl("interp-bucket-entries", 20) >> chem_params.pht_max_entries; + + /*Parse output options*/ + simparams.store_result = !cmdl["ignore-result"]; + + 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 " << (chem_params.use_dht ? "ON" : "OFF") << '\n'; + + if (chem_params.use_dht || chem_params.use_interp) { + 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) = " << chem_params.dht_size + << endl; + cout << "CPP: DHT save snapshots is " << chem_params.dht_snaps << endl; + cout << "CPP: DHT load file is " << chem_params.dht_file << endl; + } + /*Parse work package size*/ + cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size; + + chem_params.use_interp = cmdl["interp"]; + cmdl("interp-size", 100) >> chem_params.pht_size; + cmdl("interp-min", 5) >> chem_params.interp_min_entries; + cmdl("interp-bucket-entries", 20) >> chem_params.pht_max_entries; + + /*Parse output options*/ + simparams.store_result = !cmdl["ignore-result"]; + + if (simparams.world_rank == 0) { + MSG("Complete results storage is " + BOOL_PRINT(simparams.store_result)); + MSG("Work Package Size: " + std::to_string(simparams.wp_size)); + MSG("DHT is " + BOOL_PRINT(chem_params.use_dht)); if (chem_params.use_dht) { - cmdl("dht-size", DHT_SIZE_PER_PROCESS_MB) >> chem_params.dht_size; - // cout << "CPP: DHT size per process (Byte) = " << dht_size_per_process << - // endl; - - cmdl("dht-snaps", 0) >> chem_params.dht_snaps; - - cmdl("dht-file") >> chem_params.dht_file; - } - /*Parse work package size*/ - cmdl("work-package-size", WORK_PACKAGE_SIZE_DEFAULT) >> simparams.wp_size; - - chem_params.use_interp = cmdl["interp"]; - cmdl("interp-size", 100) >> chem_params.pht_size; - cmdl("interp-min", 5) >> chem_params.interp_min_entries; - cmdl("interp-bucket-entries", 20) >> chem_params.pht_max_entries; - - /*Parse output options*/ - simparams.store_result = !cmdl["ignore-result"]; - - if (simparams.world_rank == 0) { - MSG("Complete results storage is " + BOOL_PRINT(simparams.store_result)); - MSG("Work Package Size: " + std::to_string(simparams.wp_size)); - MSG("DHT is " + BOOL_PRINT(chem_params.use_dht)); - - if (chem_params.use_dht) { - MSG("DHT strategy is " + std::to_string(simparams.dht_strategy)); - // MDL: these should be outdated (?) - // MSG("DHT key default digits (ignored if 'signif_vector' is " - // "defined) = " - // << simparams.dht_significant_digits); - // MSG("DHT logarithm before rounding: " - // << (simparams.dht_log ? "ON" : "OFF")); - MSG("DHT size per process (Byte) = " + std::to_string(chem_params.dht_size)); - MSG("DHT save snapshots is " + BOOL_PRINT(chem_params.dht_snaps)); - MSG("DHT load file is " + chem_params.dht_file); - } - - if (chem_params.use_interp) { - MSG("PHT interpolation enabled: " + BOOL_PRINT(chem_params.use_interp)); - MSG("PHT interp-size = " + std::to_string(chem_params.pht_size)); - MSG("PHT interp-min = " + std::to_string(chem_params.interp_min_entries)); - MSG("PHT interp-bucket-entries = " + std::to_string(chem_params.pht_max_entries)); - } + MSG("DHT strategy is " + std::to_string(simparams.dht_strategy)); + // MDL: these should be outdated (?) + // MSG("DHT key default digits (ignored if 'signif_vector' is " + // "defined) = " + // << simparams.dht_significant_digits); + // MSG("DHT logarithm before rounding: " + // << (simparams.dht_log ? "ON" : "OFF")); + MSG("DHT size per process (Byte) = " + + std::to_string(chem_params.dht_size)); + MSG("DHT save snapshots is " + BOOL_PRINT(chem_params.dht_snaps)); + MSG("DHT load file is " + chem_params.dht_file); } - cmdl(1) >> filesim; - cmdl(2) >> out_dir; + if (chem_params.use_interp) { + MSG("PHT interpolation enabled: " + BOOL_PRINT(chem_params.use_interp)); + MSG("PHT interp-size = " + std::to_string(chem_params.pht_size)); + MSG("PHT interp-min = " + + std::to_string(chem_params.interp_min_entries)); + MSG("PHT interp-bucket-entries = " + + std::to_string(chem_params.pht_max_entries)); + } + } - chem_params.dht_outdir = out_dir; + 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"] = chem_params.use_dht; - // log before rounding? - R["dht_log"] = simparams.dht_log; + chem_params.dht_outdir = out_dir; - // eval the init string, ignoring any returns - R.parseEvalQ("source(filesim)"); - R.parseEvalQ("mysetup <- setup"); + /* 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"] = chem_params.use_dht; + // log before rounding? + R["dht_log"] = simparams.dht_log; - this->chem_params.initFromR(R); + // eval the init string, ignoring any returns + R.parseEvalQ("source(filesim)"); + R.parseEvalQ("mysetup <- setup"); - return poet::PARSER_OK; + this->chem_params.initFromR(R); + + return poet::PARSER_OK; } void SimParams::initVectorParams(RInside &R) {} std::list SimParams::validateOptions(argh::parser cmdl) { - /* store all unknown parameters here */ - std::list retList; + /* store all unknown parameters here */ + std::list retList; - /* loop over all flags and compare to given flaglist*/ - for (auto &flag : cmdl.flags()) { - if (!(flaglist.find(flag) != flaglist.end())) - retList.push_back(flag); - } + /* loop over all flags and compare to given flaglist*/ + for (auto &flag : cmdl.flags()) { + if (!(flaglist.find(flag) != flaglist.end())) + retList.push_back(flag); + } - /* and loop also over params and compare to given paramlist */ - for (auto ¶m : cmdl.params()) { - if (!(paramlist.find(param.first) != paramlist.end())) - retList.push_back(param.first); - } + /* and loop also over params and compare to given paramlist */ + for (auto ¶m : cmdl.params()) { + if (!(paramlist.find(param.first) != paramlist.end())) + retList.push_back(param.first); + } - return retList; + return retList; }