diff --git a/README.md b/README.md index 42354c51b..07fe96f1e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +

+ pestpplogo image +

# PEST++ ## Tools for non-intrusive and scalable parameter estimation and uncertainty quantification diff --git a/benchmarks/basic_tests.py b/benchmarks/basic_tests.py index 886df9a8a..56113891d 100644 --- a/benchmarks/basic_tests.py +++ b/benchmarks/basic_tests.py @@ -953,6 +953,51 @@ def mf6_v5_glm_test(): assert oe.shape[0] == pst.pestpp_options["glm_num_reals"],"{0},{1}".\ format(oe.shape[0],pst.pestpp_options["glm_num_reals"]) + +def cmdline_test(): + model_d = "mf6_freyberg" + local=True + if "linux" in platform.platform().lower() and "10par" in model_d: + #print("travis_prep") + #prep_for_travis(model_d) + local=False + + t_d = os.path.join(model_d,"template") + pst_name = "freyberg6_run_glm.pst" + pst = pyemu.Pst(os.path.join(t_d,"freyberg6_run_glm.pst")) + pst.pestpp_options["debug_parse_only"] = True + pst_name = "CmdLine_test.pst" #camel case on purpose for linux testing + pst.write(os.path.join(t_d,pst_name)) + pyemu.os_utils.run("{0} {1}".format(exe_path,pst_name),cwd=t_d) + pyemu.os_utils.run("{0} {1} /h :4004".format(exe_path,pst_name),cwd=t_d) + pyemu.os_utils.run("{0} {1} /r /h :4004".format(exe_path.replace("-ies","-glm"),pst_name),cwd=t_d) + pyemu.os_utils.run("{0} {1} /r ".format(exe_path.replace("-ies","-glm"),pst_name),cwd=t_d) + + try: + pyemu.os_utils.run("{0} {1} \\h :4004".format(exe_path,pst_name),cwd=t_d) + + except: + pass + else: + raise Exception("should have failed") + + try: + pyemu.os_utils.run("{0} {1} :4004".format(exe_path,pst_name),cwd=t_d) + + except: + pass + else: + raise Exception("should have failed") + + try: + pyemu.os_utils.run("{0} {1} /h 4004".format(exe_path,pst_name),cwd=t_d) + + except: + pass + else: + raise Exception("should have failed") + + if __name__ == "__main__": #glm_long_name_test() @@ -973,3 +1018,4 @@ def mf6_v5_glm_test(): #mf6_v5_sen_test() #mf6_v5_opt_stack_test() #mf6_v5_glm_test() + #cmdline_test() diff --git a/documentation/pestpp5.0.0.docx b/documentation/pestpp5.0.0.docx deleted file mode 100644 index 20d1e1427..000000000 Binary files a/documentation/pestpp5.0.0.docx and /dev/null differ diff --git a/documentation/pestpp5.0.3.docx b/documentation/pestpp5.0.3.docx new file mode 100644 index 000000000..48f0e014a Binary files /dev/null and b/documentation/pestpp5.0.3.docx differ diff --git a/documentation/pestpplogo.png b/documentation/pestpplogo.png new file mode 100644 index 000000000..5a5a476a9 Binary files /dev/null and b/documentation/pestpplogo.png differ diff --git a/src/libs/common/config_os.h b/src/libs/common/config_os.h index 033912770..412117f9f 100644 --- a/src/libs/common/config_os.h +++ b/src/libs/common/config_os.h @@ -2,7 +2,7 @@ #define CONFIG_OS_H_ -#define PESTPP_VERSION "5.0.0"; +#define PESTPP_VERSION "5.0.3"; #if defined(_WIN32) || defined(_WIN64) #define OS_WIN diff --git a/src/libs/common/utilities.cpp b/src/libs/common/utilities.cpp index 9886f5dd9..fc76e60ad 100644 --- a/src/libs/common/utilities.cpp +++ b/src/libs/common/utilities.cpp @@ -624,7 +624,7 @@ void thread_exceptions::rethrow() } catch (const std::exception& e) { - ss << e.what() << ", "; + ss << e.what() << " "; } } throw runtime_error(ss.str()); @@ -1428,7 +1428,159 @@ string get_time_string_short() } -} // end of namespace pest_utils +CmdLine::CmdLine(int argc, char* argv[]) : + ctl_file_name(""), panther_host_name(""), panther_port(""), + runmanagertype(RunManagerType::SERIAL),org_cmdline_str(""), + restart(false),jac_restart(false) +{ + for (int i = 0; i < argc; ++i) + { + org_cmdline_str.append(" "); + org_cmdline_str.append(argv[i]); + } + cout << "...processing command line: '" << org_cmdline_str << "'" << endl; + vector org_cmdline_vec(argc); + copy(argv, argv + argc, org_cmdline_vec.begin()); + vector lower_cmdline_vec = org_cmdline_vec; + for (vector::iterator it = lower_cmdline_vec.begin(); it != lower_cmdline_vec.end(); ++it) + { + transform(it->begin(), it->end(), it->begin(), ::tolower); + } + + if (org_cmdline_vec.size() >= 2) + { + ctl_file_name = org_cmdline_vec[1]; + } + else + { + throw_cmdline_error("too few args, no control file name found"); + } + + //check for shitty restar flags + vector temp, temp_lower; + for (int i = 0; i < lower_cmdline_vec.size(); i++) + { + if (lower_cmdline_vec[i] == "/r") + { + restart = true; + } + else if (lower_cmdline_vec[i] == "/j") + { + if (restart) + throw_cmdline_error("both '/r' and '/j' supplied"); + jac_restart = true; + } + else + { + temp.push_back(org_cmdline_vec[i]); + temp_lower.push_back(lower_cmdline_vec[i]); + } + } + org_cmdline_vec = temp; + lower_cmdline_vec = temp_lower; + + + if ((lower_cmdline_vec.size() == 3) || (lower_cmdline_vec.size() > 4)) + { + throw_cmdline_error("wrong number of args, expecting 2 (serial run mgr) or 4 (parallel run mgr)"); + } + + //serial run mgr...done + if (lower_cmdline_vec.size() == 2) + { + cout << "...using serial run manager" << endl; + return; + } + + //check for various run mgr options + string third_arg = lower_cmdline_vec[2]; + if (third_arg == "/e") + { + cout << "...using external run manager" << endl; + runmanagertype = RunManagerType::EXTERNAL; + } + else if (third_arg == "/g") + { + cout << "...using genie run manager" << endl; + runmanagertype = RunManagerType::GENIE; + } + else if (third_arg == "/h") + { + //assume worker, but check for master later... + runmanagertype = RunManagerType::PANTHER_WORKER; + } + else + { + throw_cmdline_error("unrecognized commandline arg '" + third_arg + "', expecting '/h','/e','/g'"); + } + + if (runmanagertype == RunManagerType::PANTHER_WORKER) + { + string forth_arg = org_cmdline_vec[3]; + if (forth_arg.find(":") == string::npos) + { + throw_cmdline_error("panther master/worker arg '" + forth_arg + "' doesn't have a ':' char"); + } + if (forth_arg[0] == ':') + { + //panther master + runmanagertype = RunManagerType::PANTHER_MASTER; + panther_port = forth_arg.substr(1); + try + { + int test = stoi(panther_port); + } + catch (...) + { + throw_cmdline_error("error casting master port number '" + panther_port + "' to int"); + } + cout << "...using panther run manager in master mode using port " << panther_port << endl; + } + else + { + //panther worker + vector tokens; + tokenize(forth_arg, tokens, ":"); + if (tokens.size() != 2) + throw_cmdline_error("wrong number of colon-delimited tokens in panther worker arg '" + forth_arg); + panther_host_name = tokens[0]; + panther_port = tokens[1]; + try + { + int test = stoi(panther_port); + } + catch (...) + { + throw_cmdline_error("error casting master port number '" + panther_port + "' to int"); + } + cout << "...using panther run manager in worker mode using hostname '" << panther_host_name << "' and port " << panther_port << endl; + } + } + return; + +} + + +void CmdLine::throw_cmdline_error(string message) +{ + cerr << "--------------------------------------------------------" << endl; + cerr << "COMMAND LINE ERROR: " << message << endl; + cerr << "usage:" << endl << endl; + cerr << " serial run manager:" << endl; + cerr << " pestpp-xxx control_file.pst" << endl << endl; + cerr << " PANTHER master:" << endl; + cerr << " pestpp-xxx control_file.pst /H :port" << endl << endl; + cerr << " PANTHER worker:" << endl; + cerr << " pestpp-xxx control_file.pst /H hostname:port " << endl << endl; + + cerr << " additional options can be found in the PEST++ users manual" << endl; + cerr << "--------------------------------------------------------" << endl; + exit(1); +} + +// end of namespace pest_utils +} + diff --git a/src/libs/common/utilities.h b/src/libs/common/utilities.h index ac10721dd..b5f2d6a18 100644 --- a/src/libs/common/utilities.h +++ b/src/libs/common/utilities.h @@ -376,6 +376,22 @@ string get_time_string(); string get_time_string_short(); +class CmdLine { + +public: + enum class RunManagerType { SERIAL, PANTHER_MASTER, PANTHER_WORKER, GENIE, EXTERNAL }; + CmdLine(int argc, char* argv[]); + string ctl_file_name; + string panther_host_name; + string org_cmdline_str; + string panther_port; + bool jac_restart; + bool restart; + RunManagerType runmanagertype; +private: + void throw_cmdline_error(string message); + +}; } // end namespace pest_utils #endif /* UTILITIES_H_ */ diff --git a/src/libs/pestpp_common/Ensemble.cpp b/src/libs/pestpp_common/Ensemble.cpp index f83d911bc..c0cccccf7 100644 --- a/src/libs/pestpp_common/Ensemble.cpp +++ b/src/libs/pestpp_common/Ensemble.cpp @@ -2207,12 +2207,12 @@ void ParameterEnsemble::save_fixed() } } // add the "base" if its not in the real names already - if (find(real_names.begin(), real_names.end(), base_name) == real_names.end()) + if (find(real_names.begin(), real_names.end(), BASE_REAL_NAME) == real_names.end()) { Parameters pars = pest_scenario_ptr->get_ctl_parameters(); for (auto fname : fixed_names) { - pair key(base_name, fname); + pair key(BASE_REAL_NAME, fname); fixed_map[key] = pars[fname]; } } diff --git a/src/libs/pestpp_common/Ensemble.h b/src/libs/pestpp_common/Ensemble.h index ad24dee74..85a5611a5 100644 --- a/src/libs/pestpp_common/Ensemble.h +++ b/src/libs/pestpp_common/Ensemble.h @@ -16,6 +16,7 @@ #include "PerformanceLog.h" +const string BASE_REAL_NAME = "BASE"; class Ensemble { @@ -102,7 +103,6 @@ class Ensemble //ObjectiveFunc *obj_func_ptr; //OutputFileWriter &output_file_writer; //PerformanceLog *performance_log; - string base_name = "BASE"; Eigen::MatrixXd reals; vector var_names; vector real_names; diff --git a/src/libs/pestpp_common/EnsembleMethodUtils.cpp b/src/libs/pestpp_common/EnsembleMethodUtils.cpp index 978d98eb0..46660c38d 100644 --- a/src/libs/pestpp_common/EnsembleMethodUtils.cpp +++ b/src/libs/pestpp_common/EnsembleMethodUtils.cpp @@ -1009,11 +1009,11 @@ void save_base_real_par_rei(Pest& pest_scenario, ParameterEnsemble& pe, Observat { stringstream ss; map vmap = pe.get_real_map(); - if (vmap.find("BASE") != vmap.end()) + if (vmap.find(BASE_REAL_NAME) != vmap.end()) { ParamTransformSeq pts = pest_scenario.get_base_par_tran_seq(); Parameters pars; - pars.update(pe.get_var_names(), eigenvec_2_stlvec(pe.get_real_vector("BASE"))); + pars.update(pe.get_var_names(), eigenvec_2_stlvec(pe.get_real_vector(BASE_REAL_NAME))); if (pe.get_trans_status() == ParameterEnsemble::transStatus::NUM) pts.numeric2ctl_ip(pars); // save parameters to .par file @@ -1025,14 +1025,14 @@ void save_base_real_par_rei(Pest& pest_scenario, ParameterEnsemble& pe, Observat file_manager.close_file("par"); vmap = oe.get_real_map(); - if (vmap.find("BASE") == vmap.end()) + if (vmap.find(BASE_REAL_NAME) == vmap.end()) { //message(2, "unable to find 'BASE' realization in obs ensemble for saving .base.rei file, continuing..."); } else { Observations obs; - obs.update(oe.get_var_names(), eigenvec_2_stlvec(oe.get_real_vector("BASE"))); + obs.update(oe.get_var_names(), eigenvec_2_stlvec(oe.get_real_vector(BASE_REAL_NAME))); ObjectiveFunc obj_func(&(pest_scenario.get_ctl_observations()), &(pest_scenario.get_ctl_observation_info()), &(pest_scenario.get_prior_info())); // save new residuals to .rei file ss.str(""); diff --git a/src/libs/pestpp_common/EnsembleSmoother.cpp b/src/libs/pestpp_common/EnsembleSmoother.cpp index 1a46ef254..618d58f21 100644 --- a/src/libs/pestpp_common/EnsembleSmoother.cpp +++ b/src/libs/pestpp_common/EnsembleSmoother.cpp @@ -198,7 +198,7 @@ void IterEnsembleSmoother::add_bases() //check that 'base' isn't already in ensemble vector rnames = pe.get_real_names(); bool inpar = false; - if (find(rnames.begin(), rnames.end(), base_name) != rnames.end()) + if (find(rnames.begin(), rnames.end(), BASE_REAL_NAME) != rnames.end()) { message(1, "'base' realization already in parameter ensemble, ignoring '++ies_include_base'"); inpar = true; @@ -210,12 +210,12 @@ void IterEnsembleSmoother::add_bases() pe.get_par_transform().active_ctl2numeric_ip(pars); vector drop{ pe.shape().first - 1 }; pe.drop_rows(drop); - pe.append(base_name, pars); + pe.append(BASE_REAL_NAME, pars); } //check that 'base' isn't already in ensemble rnames = oe.get_real_names(); - if (find(rnames.begin(), rnames.end(), base_name) != rnames.end()) + if (find(rnames.begin(), rnames.end(), BASE_REAL_NAME) != rnames.end()) { message(1, "'base' realization already in observation ensemble, ignoring '++ies_include_base'"); } @@ -226,7 +226,7 @@ void IterEnsembleSmoother::add_bases() { vector prnames = pe.get_real_names(); - int idx = find(prnames.begin(), prnames.end(), base_name) - prnames.begin(); + int idx = find(prnames.begin(), prnames.end(), BASE_REAL_NAME) - prnames.begin(); //cout << idx << "," << rnames.size() << endl; string oreal = rnames[idx]; stringstream ss; @@ -237,9 +237,9 @@ void IterEnsembleSmoother::add_bases() vector drop; drop.push_back(oreal); oe.drop_rows(drop); - oe.append(base_name, obs); + oe.append(BASE_REAL_NAME, obs); //rnames.insert(rnames.begin() + idx, string(base_name)); - rnames[idx] = base_name; + rnames[idx] = BASE_REAL_NAME; oe.reorder(rnames, vector()); } else @@ -247,7 +247,7 @@ void IterEnsembleSmoother::add_bases() message(1, "adding 'base' observation values to ensemble"); vector drop{ oe.shape().first - 1 }; oe.drop_rows(drop); - oe.append(base_name, obs); + oe.append(BASE_REAL_NAME, obs); } } } @@ -693,14 +693,14 @@ void IterEnsembleSmoother::initialize_restart() if (missing.size() > 0) { //the special case where the base real is what is missing... - if ((missing.size() == 1) && (missing[0] == "BASE")) + if ((missing.size() == 1) && (missing[0] == BASE_REAL_NAME)) { //check that the base real is in the par en - restart_par_en should be accounted for by now int base_par_idx = -1; vector pe_real_names = pe.get_real_names(), pe_base_real_names = pe_base.get_real_names(); for (int i = 0; i < pe_base.shape().first; i++) { - if (pe_base_real_names[i] == "BASE") + if (pe_base_real_names[i] == BASE_REAL_NAME) { base_par_idx = i; break; @@ -708,11 +708,24 @@ void IterEnsembleSmoother::initialize_restart() } if (base_par_idx != -1) { + ss.str(""); - ss << "WARNING: replacing base obs en realization '" << oe_base_real_names[base_par_idx] << "' with 'base' (noise free) values to match par en 'base' location"; - message(2, ss.str()); + ss << "WARNING: replacing obs+noise obs en realization '" << oe_base_real_names[base_par_idx] << "' with 'base' (noise free) values to match par en 'base' location"; + message(1, ss.str()); Observations obs = pest_scenario.get_ctl_observations(); - oe_base.replace(base_par_idx, obs, "BASE"); + oe_base.replace(base_par_idx, obs, BASE_REAL_NAME); + ss.str(""); + if (pest_scenario.get_pestpp_options().get_ies_save_binary()) + { + ss << file_manager.get_base_filename() << ".obs+noise.jcb"; + oe.to_binary(ss.str()); + } + else + { + ss << file_manager.get_base_filename() << ".obs+noise.csv"; + oe.to_csv(ss.str()); + } + message(1, "re-saved obs+noise observation ensemble (obsval+noise) to ", ss.str()); } else { @@ -941,7 +954,7 @@ void IterEnsembleSmoother::initialize() ParameterEnsemble _pe(&pest_scenario, &rand_gen); _pe.reserve(vector(), pest_scenario.get_ctl_ordered_par_names()); _pe.set_trans_status(ParameterEnsemble::transStatus::CTL); - _pe.append("BASE", pars); + _pe.append(BASE_REAL_NAME, pars); string par_csv = file_manager.get_base_filename() + ".par.csv"; //message(1, "saving parameter values to ", par_csv); //_pe.to_csv(par_csv); @@ -949,7 +962,7 @@ void IterEnsembleSmoother::initialize() pe_base.reorder(vector(), act_par_names); ObservationEnsemble _oe(&pest_scenario, &rand_gen); _oe.reserve(vector(), pest_scenario.get_ctl_ordered_obs_names()); - _oe.append("BASE", pest_scenario.get_ctl_observations()); + _oe.append(BASE_REAL_NAME, pest_scenario.get_ctl_observations()); oe_base = _oe; oe_base.reorder(vector(), act_obs_names); //initialize the phi handler @@ -2436,36 +2449,59 @@ ParameterEnsemble IterEnsembleSmoother::calc_localized_upgrade_threaded(double c message(2, "waiting to join threads"); //for (auto &t : threads) // t.join(); + ss.str(""); + int num_exp = 0; + for (int i = 0; i < num_threads; ++i) { + bool found = false; if (exception_ptrs[i]) { + found = true; + num_exp++; try { rethrow_exception(exception_ptrs[i]); } catch (const std::exception& e) { - ss.str(""); - ss << "thread " << i << "raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //ss.str(""); + ss << " thread " << i << "raised an exception: " << e.what(); + //throw runtime_error(ss.str()); + } + catch (...) + { + //ss.str(""); + ss << " thread " << i << "raised an exception"; + //throw runtime_error(ss.str()); } } threads[i].join(); - if (exception_ptrs[i]) + if ((exception_ptrs[i]) && (!found)) { + num_exp++; try { rethrow_exception(exception_ptrs[i]); } catch (const std::exception& e) { - ss.str(""); - ss << "thread " << i << "raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //ss.str(""); + ss << " thread " << i << "raised an exception: " << e.what(); + //throw runtime_error(ss.str()); + } + catch (...) + { + //ss.str(""); + ss << " thread " << i << "raised an exception: "; + //throw runtime_error(ss.str()); } } } + if (num_exp > 0) + { + throw runtime_error(ss.str()); + } message(2, "threaded localized upgrade calculation done"); } @@ -2990,7 +3026,7 @@ void IterEnsembleSmoother::set_subset_idx(int size) } vector pe_names = pe.get_real_names(); - vector::iterator bidx = find(pe_names.begin(), pe_names.end(), base_name); + vector::iterator bidx = find(pe_names.begin(), pe_names.end(), BASE_REAL_NAME); if (bidx != pe_names.end()) { diff --git a/src/libs/pestpp_common/EnsembleSmoother.h b/src/libs/pestpp_common/EnsembleSmoother.h index e9f7ee27a..9cc7673fd 100644 --- a/src/libs/pestpp_common/EnsembleSmoother.h +++ b/src/libs/pestpp_common/EnsembleSmoother.h @@ -68,6 +68,7 @@ class LocalUpgradeThread class IterEnsembleSmoother { + public: IterEnsembleSmoother(Pest& _pest_scenario, FileManager& _file_manager, OutputFileWriter& _output_file_writer, PerformanceLog* _performance_log, @@ -78,6 +79,7 @@ class IterEnsembleSmoother void finalize(); void throw_ies_error(string message); bool should_terminate(); + private: int verbose_level; @@ -93,7 +95,7 @@ class IterEnsembleSmoother Covariance parcov, obscov; double reg_factor; - string base_name = "BASE"; //this is also defined in Ensemble + bool use_localizer; Localizer localizer; diff --git a/src/libs/run_managers/abstract_base/model_interface.cpp b/src/libs/run_managers/abstract_base/model_interface.cpp index 97c36e09e..537ca644f 100644 --- a/src/libs/run_managers/abstract_base/model_interface.cpp +++ b/src/libs/run_managers/abstract_base/model_interface.cpp @@ -257,6 +257,10 @@ void process_template_file_thread(int tid, vector& tpl_idx, ThreadedTemplat { ttp.work(tid, tpl_idx, pars, pro_pars); } + catch (const std::exception& e) + { + eptr = current_exception(); + } catch (...) { eptr = current_exception(); @@ -272,6 +276,10 @@ void process_instruction_file_thread(int tid, vector& ins_idx, ThreadedInst { tip.work(tid, ins_idx, obs, additional_ins_delims); } + catch (const std::exception& e) + { + eptr = current_exception(); + } catch (...) { eptr = current_exception(); @@ -306,24 +314,37 @@ void ModelInterface::write_input_files(Parameters *pars_ptr) { threads.push_back(thread(process_template_file_thread, i, std::ref(tpl_idx), std::ref(ttp), *pars_ptr, std::ref(pro_pars), std::ref(exception_ptrs[i]))); } - + stringstream ss; + int num_exp = 0; for (int i = 0; i < num_threads; ++i) { + bool found = false; if (exception_ptrs[i]) { + found = true; try { rethrow_exception(exception_ptrs[i]); } catch (const std::exception& e) { - stringstream ss; - ss << "thread processing template file '" << tplfile_vec[i] << "' raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //stringstream ss; + ss << " thread processing template file '" << tplfile_vec[i] << "' raised an exception: " << e.what() << endl; + num_exp++; + //cout << "Error: " << ss.str(); + //throw runtime_error(ss.str()); + } + catch (...) + { + //stringstream ss; + ss << " thread processing template file '" << tplfile_vec[i] << "' raised an exception" << endl; + num_exp++; + //cout << "Error: " << ss.str(); + //throw runtime_error(ss.str()); } } threads[i].join(); - if (exception_ptrs[i]) + if ((exception_ptrs[i]) && (!found)) { try { @@ -331,9 +352,19 @@ void ModelInterface::write_input_files(Parameters *pars_ptr) } catch (const std::exception& e) { - stringstream ss; - ss << "thread processing template file '" << tplfile_vec[i] << "' raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //stringstream ss; + ss << " thread processing template file '" << tplfile_vec[i] << "' raised an exception: " << e.what() << endl; + num_exp++; + //cout << "Error: " << ss.str(); + //throw runtime_error(ss.str()); + } + catch (...) + { + //stringstream ss; + ss << " thread processing template file '" << tplfile_vec[i] << "' raised an exception" << endl; + num_exp++; + //cout << "Error: " << ss.str(); + //throw runtime_error(ss.str()); } } } @@ -365,6 +396,12 @@ void ModelInterface::write_input_files(Parameters *pars_ptr) //update pars to account for possibly truncated par values...important for jco calcs //for (auto pro_pars : pro_par_vec) // pars_ptr->update_without_clear(pro_pars.get_keys(), pro_pars.get_data_vec(pro_pars.get_keys())); + if (num_exp > 0) + { + //cout << "errors processing template files: " << endl << ss.str(); + throw runtime_error(ss.str()); + } + pars_ptr->update_without_clear(pro_pars.get_keys(), pro_pars.get_data_vec(pro_pars.get_keys())); cout << pest_utils::get_time_string() << " done, took " << pest_utils::get_duration_sec(start_time) << " seconds" << endl; } @@ -396,24 +433,37 @@ void ModelInterface::read_output_files(Observations *obs) threads.push_back(thread(process_instruction_file_thread, i, std::ref(ins_idx), std::ref(tip), std::ref(temp_obs), additional_ins_delimiters, std::ref(exception_ptrs[i]))); } - + stringstream ss; + int num_exp = 0; for (int i = 0; i < num_threads; ++i) { + bool found = false; if (exception_ptrs[i]) { + found = true; try { rethrow_exception(exception_ptrs[i]); } catch (const std::exception& e) { - stringstream ss; - ss << "thread processing instruction file '" << insfile_vec[i] << "' raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //stringstream ss; + ss << " thread processing instruction file '" << insfile_vec[i] << "' raised an exception: " << e.what() << endl; + //cout << "Error: " << ss.str() << endl; + //throw runtime_error(ss.str()); + num_exp++; + } + catch (...) + { + //stringstream ss; + ss << " thread processing instruction file '" << insfile_vec[i] << "' raised an exception" << endl; + //cout << "Error: " << ss.str() << endl; + //throw runtime_error(ss.str()); + num_exp++; } } threads[i].join(); - if (exception_ptrs[i]) + if ((exception_ptrs[i]) && (!found)) { try { @@ -421,9 +471,19 @@ void ModelInterface::read_output_files(Observations *obs) } catch (const std::exception& e) { - stringstream ss; - ss << "thread processing instruction file '" << insfile_vec[i] << "' raised an exception: " << e.what(); - throw runtime_error(ss.str()); + //stringstream ss; + ss << " thread processing instruction file '" << insfile_vec[i] << "' raised an exception: " << e.what() << endl; + //cout << "Error: " << ss.str() << endl; + //throw runtime_error(ss.str()); + num_exp++; + } + catch (...) + { + //stringstream ss; + ss << " thread processing instruction file '" << insfile_vec[i] << "' raised an exception" << endl; + //cout << "Error: " << ss.str() << endl; + //throw runtime_error(ss.str()); + num_exp++; } } } @@ -446,6 +506,13 @@ void ModelInterface::read_output_files(Observations *obs) pro_obs = instructionfiles[i].read_output_file(outfile_vec[i]); temp_obs.update_without_clear(pro_obs.get_keys(), pro_obs.get_data_vec(pro_obs.get_keys())); }*/ + + if (num_exp > 0) + { + //cout << "errors processing instruction files: " << endl << ss.str(); + throw runtime_error(ss.str()); + } + unordered_set ins_names, pst_names; vector t, diff; t = obs->get_keys(); @@ -667,8 +734,14 @@ void ModelInterface::run(pest_utils::thread_flag* terminate, pest_utils::thread_ finished->set(true); } + catch (const std::exception& e) + { + cout << "exception raised by run thread: " << e.what() << endl; + shared_execptions->add(current_exception()); + } catch (...) { + cout << "exception raised by run thread" << endl; shared_execptions->add(current_exception()); } return; @@ -769,6 +842,16 @@ Parameters TemplateFile::write_input_file(const string& input_filename, Paramete pro_pars.insert(name, val); } f_in << line << endl; + if (f_in.bad()) + { + throw_tpl_error("ofstream is bad after writing line '" + line + "'", line_num); + } + } + f_tpl.close(); + f_in.close(); + if (f_in.bad()) + { + throw_tpl_error("ofstream is bad after closing file, something is probably corrupt"); } return pro_pars; } @@ -1116,7 +1199,6 @@ Observations InstructionFile::read_output_file(const string& output_filename) pair lhs; while (true) { - if (f_ins.eof()) break; tokens.clear(); @@ -1200,6 +1282,8 @@ Observations InstructionFile::read_output_file(const string& output_filename) //itoken++; } } + f_ins.close(); + f_out.close(); return obs; } diff --git a/src/libs/run_managers/serial/RunManagerSerial.cpp b/src/libs/run_managers/serial/RunManagerSerial.cpp index b6c7396d1..c391ec0ad 100644 --- a/src/libs/run_managers/serial/RunManagerSerial.cpp +++ b/src/libs/run_managers/serial/RunManagerSerial.cpp @@ -92,8 +92,7 @@ void RunManagerSerial::run() { update_run_failed(i_run); failed_runs++; - cerr << endl; - cerr << " " << ex.what() << endl; + cerr << " Error running model: " << ex.what() << endl; cerr << " Aborting model run" << endl << endl; } @@ -101,7 +100,6 @@ void RunManagerSerial::run() { update_run_failed(i_run); failed_runs++; - cerr << endl; cerr << " Error running model" << endl; cerr << " Aborting model run" << endl << endl; } diff --git a/src/my_ubuntu_intel_make.sh b/src/my_ubuntu_intel_make.sh deleted file mode 100755 index 1591075aa..000000000 --- a/src/my_ubuntu_intel_make.sh +++ /dev/null @@ -1 +0,0 @@ -COMPILER=intel STATIC=-static MKLROOT=/home/parallels/intel/mkl/ make -j 5 install \ No newline at end of file diff --git a/src/programs/gsa/main.cpp b/src/programs/gsa/main.cpp index d36412890..81da4fc80 100644 --- a/src/programs/gsa/main.cpp +++ b/src/programs/gsa/main.cpp @@ -62,74 +62,17 @@ int main(int argc, char* argv[]) cout << endl << endl << "version: " << version << endl; cout << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - // build commandline - string commandline = ""; - for(int i=0; i cmd_arg_vec(argc); - copy(argv, argv + argc, cmd_arg_vec.begin()); - for (vector::iterator it = cmd_arg_vec.begin(); it != cmd_arg_vec.end(); ++it) - { - transform(it->begin(), it->end(), it->begin(), ::tolower); - } - - string complete_path; - enum class RunManagerType {SERIAL, PANTHER, GENIE}; - - if (argc >=2) { - complete_path = argv[1]; - } - else { - cerr << "--------------------------------------------------------" << endl; - cerr << "usage:" << endl << endl; - cerr << " serial run manager:" << endl; - cerr << " pestpp-sen control_file.pst" << endl << endl; - cerr << " PANTHER master:" << endl; - cerr << " pestpp-sen control_file.pst /H :port" << endl; - cerr << " PANTHER worker:" << endl; - cerr << " pestpp-sen control_file.pst /H hostname:port " << endl << endl; - cerr << " additional options can be found in the PEST++ manual" << endl; - cerr << "--------------------------------------------------------" << endl; - exit(0); - } - + CmdLine cmdline(argc, argv); FileManager file_manager; - string filename = complete_path; string pathname = "."; - file_manager.initialize_path(get_filename_without_ext(filename), pathname); - - //by default use the serial run manager. This will be changed later if another - //run manger is specified on the command line. - RunManagerType run_manager_type = RunManagerType::SERIAL; - //Check for PANTHER worker - vector::const_iterator it_find, it_find_next; - string next_item; - string socket_str = ""; - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/h"); - next_item.clear(); - if (it_find != cmd_arg_vec.end() && it_find + 1 != cmd_arg_vec.end()) - { - next_item = *(it_find + 1); - strip_ip(next_item); - } - if (it_find != cmd_arg_vec.end() && !next_item.empty() && next_item[0] != ':') + file_manager.initialize_path(get_filename_without_ext(cmdline.ctl_file_name), pathname); + + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_WORKER) { // This is a PANTHER worker, start PEST++ as a PANTHER worker - vector sock_parts; - vector::const_iterator it_find_yamr_ctl; - string file_ext = get_filename_ext(filename); - tokenize(next_item, sock_parts, ":"); try { - if (sock_parts.size() != 2) - { - cerr << "PANTHER worker requires the master be specified as /H hostname:port" << endl << endl; - throw(PestCommandlineError(commandline)); - }ofstream frec("panther_worker.rec"); + ofstream frec("panther_worker.rec"); if (frec.bad()) throw runtime_error("error opening 'panther_worker.rec'"); PANTHERAgent yam_agent(frec); @@ -147,7 +90,7 @@ int main(int argc, char* argv[]) throw(e); } - yam_agent.start(sock_parts[0], sock_parts[1]); + yam_agent.start(cmdline.panther_host_name,cmdline.panther_port); } catch (PestError &perr) { @@ -157,22 +100,18 @@ int main(int argc, char* argv[]) cout << endl << "Work Done..." << endl; exit(0); } - //Check for PANTHER master - else if (it_find != cmd_arg_vec.end()) + + + if (cmdline.runmanagertype == CmdLine::RunManagerType::GENIE) { - // using PANTHER run manager - run_manager_type = RunManagerType::PANTHER; - socket_str = next_item; - } + cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; + exit(1); - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - if (it_find != cmd_arg_vec.end()) + } + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { - cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; - return 1; + cerr << "external run manager ('/e') no longer supported, please use PANTHER instead" << endl; + exit(1); } @@ -181,27 +120,27 @@ int main(int argc, char* argv[]) fout_rec << " by The PEST++ Development Team" << endl << endl; fout_rec << endl << endl << "version: " << version << endl; fout_rec << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - fout_rec << "using control file: \"" << complete_path << "\"" << endl; + fout_rec << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; fout_rec << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; - cout << endl; - cout << "using control file: \"" << complete_path << "\"" << endl; + cout << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; cout << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; // create pest run and process control file to initialize it Pest pest_scenario; pest_scenario.set_defaults(); - try { + try + { pest_scenario.process_ctl_file(file_manager.open_ifile_ext("pst"), file_manager.build_filename("pst"),fout_rec); file_manager.close_file("pst"); //pest_scenario.check_inputs(fout_rec); } catch(PestError e) { - cerr << "Error prococessing control file: " << filename << endl << endl; + cerr << "Error prococessing control file: " << cmdline.ctl_file_name << endl << endl; cerr << e.what() << endl << endl; - fout_rec << "Error prococessing control file: " << filename << endl << endl; + fout_rec << "Error prococessing control file: " << cmdline.ctl_file_name << endl << endl; fout_rec << e.what() << endl; fout_rec.close(); //throw(e); @@ -221,14 +160,11 @@ int main(int argc, char* argv[]) RunManagerAbstract *run_manager_ptr; - if (run_manager_type == RunManagerType::PANTHER) + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_MASTER) { - string port = argv[3]; - strip_ip(port); - strip_ip(port, "front", ":"); const ModelExecInfo &exi = pest_scenario.get_model_exec_info(); run_manager_ptr = new RunManagerPanther ( - file_manager.build_filename("rns"), port, + file_manager.build_filename("rns"), cmdline.panther_port, file_manager.open_ofile_ext("rmr"), pest_scenario.get_pestpp_options().get_max_run_fail(), pest_scenario.get_pestpp_options().get_overdue_reched_fac(), @@ -248,15 +184,19 @@ int main(int argc, char* argv[]) cout << endl; fout_rec << endl; - cout << "using control file: \"" << complete_path << "\"" << endl; - fout_rec << "using control file: \"" << complete_path << "\"" << endl; + cout << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; + fout_rec << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; enum class GSA_RESTART { NONE, RESTART }; GSA_RESTART gsa_restart = GSA_RESTART::NONE; //process restart and reuse jacibian directives - vector::const_iterator it_find_r = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/r"); - if (it_find_r != cmd_arg_vec.end()) + if (cmdline.jac_restart) + { + cerr << "jacobian restart ('/j') not supported in PESTPP-SEN"; + exit(1); + } + if (cmdline.restart) { gsa_restart = GSA_RESTART::RESTART; } diff --git a/src/programs/pest++/pest++.cpp b/src/programs/pest++/pest++.cpp index cafad434e..468700f8c 100644 --- a/src/programs/pest++/pest++.cpp +++ b/src/programs/pest++/pest++.cpp @@ -71,95 +71,30 @@ int main(int argc, char* argv[]) cout << " by The PEST++ Development Team" << endl; cout << endl << endl << "version: " << version << endl; cout << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - // build commandline - string commandline = ""; - for (int i = 0; i < argc; ++i) - { - commandline.append(" "); - commandline.append(argv[i]); - } - - vector cmd_arg_vec(argc); - copy(argv, argv + argc, cmd_arg_vec.begin()); - for (vector::iterator it = cmd_arg_vec.begin(); it != cmd_arg_vec.end(); ++it) - { - transform(it->begin(), it->end(), it->begin(), ::tolower); - } - - string complete_path; - enum class RunManagerType { SERIAL, PANTHER, GENIE, EXTERNAL }; - - if (argc >= 2) { - complete_path = argv[1]; - } - else { - cerr << "--------------------------------------------------------" << endl; - cerr << "usage:" << endl << endl; - cerr << " serial run manager:" << endl; - cerr << " pestpp-glm control_file.pst" << endl << endl; - cerr << " PANTHER master:" << endl; - cerr << " pestpp-glm control_file.pst /H :port" << endl << endl; - cerr << " PANTHER runner:" << endl; - cerr << " pestpp-glm control_file.pst /H hostname:port " << endl << endl; - cerr << " external run manager:" << endl; - cerr << " pestpp-glm control_file.pst /E" << endl << endl; - cerr << " additional options can be found in the PEST++ manual" << endl; - cerr << "--------------------------------------------------------" << endl; - exit(0); - } - + + CmdLine cmdline(argc, argv); + FileManager file_manager; - string filename = complete_path; + string filename = cmdline.ctl_file_name; string pathname = "."; file_manager.initialize_path(get_filename_without_ext(filename), pathname); - //by default use the serial run manager. This will be changed later if another - //run manger is specified on the command line. - RunManagerType run_manager_type = RunManagerType::SERIAL; - - vector::const_iterator it_find, it_find_next; - string next_item; - string socket_str = ""; - //Check for external run manager - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/e"); - if (it_find != cmd_arg_vec.end() ) - { - run_manager_type = RunManagerType::EXTERNAL; - } - //Check for PANTHER Slave - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/h"); - next_item.clear(); - if (it_find != cmd_arg_vec.end() && it_find + 1 != cmd_arg_vec.end()) - { - next_item = *(it_find + 1); - strip_ip(next_item); - } - if (it_find != cmd_arg_vec.end() && !next_item.empty() && next_item[0] != ':') + + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_WORKER) { - // This is a PANTHER Slave, start PEST++ as a PANTHER Slave - vector sock_parts; - vector::const_iterator it_find_PANTHER_ctl; - string file_ext = get_filename_ext(filename); - tokenize(next_item, sock_parts, ":"); try { - if (sock_parts.size() != 2) - { - cerr << "PANTHER agent requires the master be specified as /H hostname:port" << endl << endl; - throw(PestCommandlineError(commandline)); - } ofstream frec("panther_worker.rec"); if (frec.bad()) throw runtime_error("error opening 'panther_worker.rec'"); PANTHERAgent yam_agent(frec); string ctl_file = ""; - try { - + try + { // process traditional PEST control file ctl_file = file_manager.build_filename("pst"); yam_agent.process_ctl_file(ctl_file); - } catch (PestError e) { @@ -168,7 +103,7 @@ int main(int argc, char* argv[]) throw(e); } - yam_agent.start(sock_parts[0], sock_parts[1]); + yam_agent.start(cmdline.panther_host_name,cmdline.panther_port); } catch (PestError &perr) { @@ -179,39 +114,24 @@ int main(int argc, char* argv[]) exit(0); } //Check for PANTHER Master - else if (it_find != cmd_arg_vec.end()) - { - // using PANTHER run manager - run_manager_type = RunManagerType::PANTHER; - socket_str = next_item; - } - - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - if (it_find != cmd_arg_vec.end()) + if (cmdline.runmanagertype == CmdLine::RunManagerType::GENIE) { cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; - return 1; - + exit(1); } - RestartController restart_ctl; - - //process restart and reuse jacobian directives - vector::const_iterator it_find_j = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/j"); - vector::const_iterator it_find_r = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/r"); bool restart_flag = false; bool save_restart_rec_header = true; debug_initialize(file_manager.build_filename("dbg")); - if (it_find_j != cmd_arg_vec.end()) + if (cmdline.jac_restart) { cout << endl << "ERROR: '/j' restart option is deprecated. Please use ++base_jacobian() instead." << endl << endl; //restart_ctl.get_restart_option() = RestartController::RestartOption::REUSE_JACOBIAN; //file_manager.open_default_files(); } - else if (it_find_r != cmd_arg_vec.end()) + else if (cmdline.restart) { ifstream &fin_rst = file_manager.open_ifile_ext("rst"); restart_ctl.process_rst_file(fin_rst); @@ -220,7 +140,7 @@ int main(int argc, char* argv[]) file_manager.open_default_files(true); ofstream &fout_rec_tmp = file_manager.rec_ofstream(); fout_rec_tmp << endl << endl; - if (run_manager_type == RunManagerType::EXTERNAL) + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { save_restart_rec_header = false; } @@ -247,13 +167,13 @@ int main(int argc, char* argv[]) fout_rec << endl; fout_rec << endl << endl << "version: " << version << endl; fout_rec << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - fout_rec << "using control file: \"" << complete_path << "\"" << endl << endl; + fout_rec << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl << endl; fout_rec << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; } cout << endl; - cout << "using control file: \"" << complete_path << "\"" << endl << endl; + cout << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl << endl; cout << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; // create pest run and process control file to initialize it @@ -313,16 +233,13 @@ int main(int argc, char* argv[]) output_file_writer.write_par_iter(0, pest_scenario.get_ctl_parameters()); } RunManagerAbstract *run_manager_ptr; - if (run_manager_type == RunManagerType::PANTHER) + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_MASTER) { // using PANTHER run manager if (pest_scenario.get_control_info().noptmax == 0) { cout << endl << endl << "WARNING: 'noptmax' = 0 but using parallel run mgr. This prob isn't what you want to happen..." << endl << endl; } - string port = socket_str; - strip_ip(port); - strip_ip(port, "front", ":"); const ModelExecInfo &exi = pest_scenario.get_model_exec_info(); //check for condor wrapper string csf = pest_scenario.get_pestpp_options().get_condor_submit_file(); @@ -331,7 +248,7 @@ int main(int argc, char* argv[]) if (!pest_utils::check_exist_in(csf)) throw runtime_error("++condor_submit_file '" + csf + "' not found"); run_manager_ptr = new RunManagerYAMRCondor( - file_manager.build_filename("rns"), port, + file_manager.build_filename("rns"), cmdline.panther_port, file_manager.open_ofile_ext("rmr"), pest_scenario.get_pestpp_options().get_max_run_fail(), pest_scenario.get_pestpp_options().get_overdue_reched_fac(), @@ -342,7 +259,7 @@ int main(int argc, char* argv[]) else { run_manager_ptr = new RunManagerPanther( - file_manager.build_filename("rns"), port, + file_manager.build_filename("rns"), cmdline.panther_port, file_manager.open_ofile_ext("rmr"), pest_scenario.get_pestpp_options().get_max_run_fail(), pest_scenario.get_pestpp_options().get_overdue_reched_fac(), @@ -351,7 +268,7 @@ int main(int argc, char* argv[]) } } - else if (run_manager_type == RunManagerType::EXTERNAL) + else if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { const ModelExecInfo &exi = pest_scenario.get_model_exec_info(); run_manager_ptr = new RunManagerExternal(exi.comline_vec, @@ -377,7 +294,6 @@ int main(int argc, char* argv[]) } const ParamTransformSeq &base_trans_seq = pest_scenario.get_base_par_tran_seq(); - ObjectiveFunc obj_func(&(pest_scenario.get_ctl_observations()), &(pest_scenario.get_ctl_observation_info()), &(pest_scenario.get_prior_info())); Jacobian *base_jacobian_ptr = new Jacobian_1to1(file_manager,output_file_writer); std::mt19937 rand_gen(pest_scenario.get_pestpp_options().get_random_seed()); diff --git a/src/programs/pestpp-ies/pestpp-ies.cpp b/src/programs/pestpp-ies/pestpp-ies.cpp index d4def1c63..b82195ef0 100644 --- a/src/programs/pestpp-ies/pestpp-ies.cpp +++ b/src/programs/pestpp-ies/pestpp-ies.cpp @@ -47,47 +47,12 @@ int main(int argc, char* argv[]) cout << endl << endl << "version: " << version << endl; cout << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - // build commandline - string commandline = ""; - for (int i = 0; i < argc; ++i) - { - commandline.append(" "); - commandline.append(argv[i]); - } - - vector cmd_arg_vec(argc); - copy(argv, argv + argc, cmd_arg_vec.begin()); - for (vector::iterator it = cmd_arg_vec.begin(); it != cmd_arg_vec.end(); ++it) - { - transform(it->begin(), it->end(), it->begin(), ::tolower); - } - - string complete_path; - enum class RunManagerType { SERIAL, PANTHER, GENIE, EXTERNAL }; - - if (argc >= 2) { - complete_path = argv[1]; - } - else { - cerr << "--------------------------------------------------------" << endl; - cerr << "usage:" << endl << endl; - cerr << " serial run manager:" << endl; - cerr << " pestpp-ies control_file.pst" << endl << endl; - cerr << " PANTHER master:" << endl; - cerr << " pestpp-ies control_file.pst /H :port" << endl << endl; - cerr << " PANTHER worker:" << endl; - cerr << " pestpp-ies control_file.pst /H hostname:port " << endl << endl; - - cerr << " additional options can be found in the PEST++ manual" << endl; - cerr << "--------------------------------------------------------" << endl; - exit(0); - } - + CmdLine cmdline(argc, argv); + FileManager file_manager; - string filename = complete_path; string pathname = "."; - file_manager.initialize_path(get_filename_without_ext(filename), pathname); + file_manager.initialize_path(get_filename_without_ext(cmdline.ctl_file_name), pathname); //jwhite - something weird is happening with the machine is busy and an existing //rns file is really large. so let's remove it explicitly and wait a few seconds before continuing... string rns_file = file_manager.build_filename("rns"); @@ -95,39 +60,11 @@ int main(int argc, char* argv[]) //w_sleep(2000); //by default use the serial run manager. This will be changed later if another //run manger is specified on the command line. - RunManagerType run_manager_type = RunManagerType::SERIAL; - - vector::const_iterator it_find, it_find_next; - string next_item; - string socket_str = ""; - //Check for external run manager - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/e"); - if (it_find != cmd_arg_vec.end()) - { - throw runtime_error("External run manager not supported by pestpp-ies"); - } - //Check for PANTHER worker - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/h"); - next_item.clear(); - if (it_find != cmd_arg_vec.end() && it_find + 1 != cmd_arg_vec.end()) - { - next_item = *(it_find + 1); - strip_ip(next_item); - } - if (it_find != cmd_arg_vec.end() && !next_item.empty() && next_item[0] != ':') + + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_WORKER) { - // This is a PANTHER worker, start PEST++ as a PANTHER worker - vector sock_parts; - vector::const_iterator it_find_yamr_ctl; - string file_ext = get_filename_ext(filename); - tokenize(next_item, sock_parts, ":"); try { - if (sock_parts.size() != 2) - { - cerr << "PANTHER worker requires the master be specified as /H hostname:port" << endl << endl; - throw(PestCommandlineError(commandline)); - } ofstream frec("panther_worker.rec"); if (frec.bad()) throw runtime_error("error opening 'panther_worker.rec'"); @@ -151,7 +88,7 @@ int main(int argc, char* argv[]) cerr << "Error processing control file" << endl; throw runtime_error("error processing control file"); } - yam_agent.start(sock_parts[0], sock_parts[1]); + yam_agent.start(cmdline.panther_host_name, cmdline.panther_port); } catch (PestError &perr) { @@ -162,20 +99,16 @@ int main(int argc, char* argv[]) cout << endl << "Work Done..." << endl; exit(0); } - //Check for PANTHER master - else if (it_find != cmd_arg_vec.end()) + + if (cmdline.runmanagertype == CmdLine::RunManagerType::GENIE) { - // using PANTHER run manager - run_manager_type = RunManagerType::PANTHER; - socket_str = next_item; - } + cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; + return 1; - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - if (it_find != cmd_arg_vec.end()) + } + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { - cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; + cerr << "external run manager ('/e') no supported in PESTPP-IES, please use PANTHER instead" << endl; return 1; } @@ -183,17 +116,15 @@ int main(int argc, char* argv[]) RestartController restart_ctl; //process restart and reuse jacobian directives - vector::const_iterator it_find_j = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/j"); - vector::const_iterator it_find_r = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/r"); bool restart_flag = false; bool save_restart_rec_header = true; debug_initialize(file_manager.build_filename("dbg")); - if (it_find_j != cmd_arg_vec.end()) + if (cmdline.jac_restart) { throw runtime_error("/j option not supported by pestpp-ies"); } - else if (it_find_r != cmd_arg_vec.end()) + else if (cmdline.restart) { throw runtime_error("/r option not supported by pestpp-ies"); } @@ -213,12 +144,12 @@ int main(int argc, char* argv[]) fout_rec << endl; fout_rec << endl << endl << "version: " << version << endl; fout_rec << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - fout_rec << "using control file: \"" << complete_path << "\"" << endl; + fout_rec << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; fout_rec << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; } cout << endl; - cout << "using control file: \"" << complete_path << "\"" << endl; + cout << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl; cout << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; // create pest run and process control file to initialize it @@ -232,9 +163,9 @@ int main(int argc, char* argv[]) } catch (PestError e) { - cerr << "Error prococessing control file: " << filename << endl << endl; + cerr << "Error prococessing control file: " << cmdline.ctl_file_name << endl << endl; cerr << e.what() << endl << endl; - fout_rec << "Error prococessing control file: " << filename << endl << endl; + fout_rec << "Error prococessing control file: " << cmdline.ctl_file_name << endl << endl; fout_rec << e.what() << endl << endl; fout_rec.close(); throw(e); @@ -255,8 +186,6 @@ int main(int argc, char* argv[]) output_file_writer.scenario_obs_report(fout_rec); } - - //reset some default args for ies here: PestppOptions *ppo = pest_scenario.get_pestpp_options_ptr(); set pp_args = ppo->get_passed_args(); @@ -276,18 +205,15 @@ int main(int argc, char* argv[]) RunManagerAbstract *run_manager_ptr; - if (run_manager_type == RunManagerType::PANTHER) + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_MASTER) { if (pest_scenario.get_control_info().noptmax == 0) { cout << endl << endl << "WARNING: 'noptmax' = 0 but using parallel run mgr. This prob isn't what you want to happen..." << endl << endl; } - string port = socket_str; - strip_ip(port); - strip_ip(port, "front", ":"); const ModelExecInfo &exi = pest_scenario.get_model_exec_info(); run_manager_ptr = new RunManagerPanther( - rns_file, port, + rns_file, cmdline.panther_port, file_manager.open_ofile_ext("rmr"), pest_scenario.get_pestpp_options().get_max_run_fail(), pest_scenario.get_pestpp_options().get_overdue_reched_fac(), @@ -311,7 +237,6 @@ int main(int argc, char* argv[]) pest_scenario.get_pestpp_options().get_additional_ins_delimiters()); } - const ParamTransformSeq &base_trans_seq = pest_scenario.get_base_par_tran_seq(); ObjectiveFunc obj_func(&(pest_scenario.get_ctl_observations()), &(pest_scenario.get_ctl_observation_info()), &(pest_scenario.get_prior_info())); diff --git a/src/programs/pestpp-opt/pestpp-opt.cpp b/src/programs/pestpp-opt/pestpp-opt.cpp index 1f436d248..a3c888ed2 100644 --- a/src/programs/pestpp-opt/pestpp-opt.cpp +++ b/src/programs/pestpp-opt/pestpp-opt.cpp @@ -49,84 +49,30 @@ int main(int argc, char* argv[]) cout << " by the PEST++ development team" << endl; cout << endl << endl << "version: " << version << endl; cout << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - // build commandline - string commandline = ""; - for (int i = 0; i < argc; ++i) - { - commandline.append(" "); - commandline.append(argv[i]); - } - - vector cmd_arg_vec(argc); - copy(argv, argv + argc, cmd_arg_vec.begin()); - for (vector::iterator it = cmd_arg_vec.begin(); it != cmd_arg_vec.end(); ++it) - { - transform(it->begin(), it->end(), it->begin(), ::tolower); - } - - string complete_path; - enum class RunManagerType { SERIAL, PANTHER, GENIE, EXTERNAL }; - - if (argc >= 2) { - complete_path = argv[1]; - } - else { - cerr << "--------------------------------------------------------" << endl; - cerr << "usage:" << endl << endl; - cerr << " serial run manager:" << endl; - cerr << " pestpp-opt pest_ctl_file.pst" << endl << endl; - cerr << " PANTHER master:" << endl; - cerr << " pestpp-opt control_file.pst /H :port" << endl << endl; - cerr << " PANTHER worker:" << endl; - cerr << " pestpp-opt /H hostname:port " << endl << endl; - cerr << " external run manager:" << endl; - cerr << " pestpp-opt control_file.pst /E" << endl << endl; - cerr << " additional options can be found in the PEST++ manual" << endl; - cerr << "--------------------------------------------------------" << endl; - exit(0); - } - - + + CmdLine cmdline(argc, argv); + FileManager file_manager; - string filename = complete_path; + string filename = cmdline.ctl_file_name; string pathname = "."; file_manager.initialize_path(get_filename_without_ext(filename), pathname); - //by default use the serial run manager. This will be changed later if another - //run manger is specified on the command line. - RunManagerType run_manager_type = RunManagerType::SERIAL; - vector::const_iterator it_find, it_find_next; string next_item; string socket_str = ""; - //Check for external run manager - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/e"); - if (it_find != cmd_arg_vec.end()) - { - run_manager_type = RunManagerType::EXTERNAL; - } - //Check for PANTHER worker - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/h"); - next_item.clear(); - if (it_find != cmd_arg_vec.end() && it_find + 1 != cmd_arg_vec.end()) + + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { - next_item = *(it_find + 1); - strip_ip(next_item); + cerr << "External run manager ('/e') not supported, please use panther instead" << endl; + exit(1); } - if (it_find != cmd_arg_vec.end() && !next_item.empty() && next_item[0] != ':') + + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_WORKER) { - // This is a PANTHER worker, start PEST++ as a PANTHER worker - vector sock_parts; - vector::const_iterator it_find_yamr_ctl; - string file_ext = get_filename_ext(filename); - tokenize(next_item, sock_parts, ":"); + try { - if (sock_parts.size() != 2) - { - cerr << "PANTHER worker requires the master be specified as /H hostname:port" << endl << endl; - throw(PestCommandlineError(commandline)); - } + ofstream frec("panther_worker.rec"); if (frec.bad()) throw runtime_error("error opening 'panther_worker.rec'"); @@ -146,7 +92,7 @@ int main(int argc, char* argv[]) throw(e); } - yam_agent.start(sock_parts[0], sock_parts[1]); + yam_agent.start(cmdline.panther_host_name,cmdline.panther_port); } catch (PestError &perr) { @@ -156,32 +102,25 @@ int main(int argc, char* argv[]) cout << endl << "Work Done..." << endl; exit(0); } - //Check for PANTHER master - else if (it_find != cmd_arg_vec.end()) + + + if (cmdline.runmanagertype == CmdLine::RunManagerType::GENIE) { - - run_manager_type = RunManagerType::PANTHER; - socket_str = next_item; - } + cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; + exit(1); - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - if (it_find != cmd_arg_vec.end()) + } + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { - cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; - return 1; + cerr << "external run manager ('/e') no longer supported, please use PANTHER instead" << endl; + exit(1); } RestartController restart_ctl; - //process restart and reuse jacobian directives - vector::const_iterator it_find_j = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/j"); - vector::const_iterator it_find_r = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/r"); - - debug_initialize(file_manager.build_filename("dbg")); - if ((it_find_j != cmd_arg_vec.end()) || (it_find_r != cmd_arg_vec.end())) + if (cmdline.restart) { cerr << "ERROR: pestpp-opt does not support restart options" << endl < cmd_arg_vec(argc); - copy(argv, argv + argc, cmd_arg_vec.begin()); - for (vector::iterator it = cmd_arg_vec.begin(); it != cmd_arg_vec.end(); ++it) - { - transform(it->begin(), it->end(), it->begin(), ::tolower); - } - - string complete_path; - enum class RunManagerType { SERIAL, PANTHER, GENIE, EXTERNAL }; - - if (argc >= 2) { - complete_path = argv[1]; - } - else { - cerr << "--------------------------------------------------------" << endl; - cerr << "usage:" << endl << endl; - cerr << " serial run manager:" << endl; - cerr << " pestpp-swp control_file.pst" << endl << endl; - cerr << " PANTHER master:" << endl; - cerr << " pestpp-swp control_file.pst /H :port" << endl << endl; - cerr << " PANTHER worker:" << endl; - cerr << " pestpp-swp control_file.pst /H hostname:port " << endl << endl; - cerr << "control file pest++ options:" << endl; - cerr << " ++sweep_parameter_csv_file(pars_file.csv)" << endl; - cerr << " - csv file with each row as a par set" << endl; - cerr << " ++sweep_forgive(true)" << endl; - cerr << " - forgive control file pars missing from csv file" << endl; - cerr << " ++sweep_output_csv_file(output.csv)" << endl; - cerr << " - the csv to save run results to" << endl; - cerr << " ++sweep_chunk(500)" << endl; - cerr << " - number of runs to process in a single batch" << endl << endl; - cerr << " additional options can be found in the PEST++ manual" << endl; - cerr << "--------------------------------------------------------" << endl; - exit(0); - } + + CmdLine cmdline(argc, argv); + + FileManager file_manager; - string filename = complete_path; + string filename = cmdline.ctl_file_name; string pathname = "."; file_manager.initialize_path(get_filename_without_ext(filename), pathname); //jwhite - something weird is happening with the machine is busy and an existing @@ -349,39 +310,24 @@ int main(int argc, char* argv[]) //w_sleep(2000); //by default use the serial run manager. This will be changed later if another //run manger is specified on the command line. - RunManagerType run_manager_type = RunManagerType::SERIAL; - - vector::const_iterator it_find, it_find_next; - string next_item; - string socket_str = ""; - //Check for external run manager - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/e"); - if (it_find != cmd_arg_vec.end()) + + if (cmdline.runmanagertype == CmdLine::RunManagerType::EXTERNAL) { - throw runtime_error("External run manager not supported by sweep"); + cerr << "External run manager ('/e') not supported by sweep, please use panther instead" << endl; + exit(1); } - //Check for PANTHER worker - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/h"); - next_item.clear(); - if (it_find != cmd_arg_vec.end() && it_find + 1 != cmd_arg_vec.end()) + if (cmdline.runmanagertype == CmdLine::RunManagerType::GENIE) { - next_item = *(it_find + 1); - strip_ip(next_item); + cerr << "Genie run manager ('/e') deprecated, please use panther instead" << endl; + exit(1); } - if (it_find != cmd_arg_vec.end() && !next_item.empty() && next_item[0] != ':') + + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_WORKER) { - // This is a PANTHER worker, start PEST++ as a PANTHER worker - vector sock_parts; - vector::const_iterator it_find_yamr_ctl; - string file_ext = get_filename_ext(filename); - tokenize(next_item, sock_parts, ":"); + try { - if (sock_parts.size() != 2) - { - cerr << "PANTHER worker requires the master be specified as /H hostname:port" << endl << endl; - throw(PestCommandlineError(commandline)); - } + ofstream frec("panther_worker.rec"); if (frec.bad()) throw runtime_error("error opening 'panther_worker.rec'"); @@ -401,7 +347,7 @@ int main(int argc, char* argv[]) throw(e); } - yam_agent.start(sock_parts[0], sock_parts[1]); + yam_agent.start(cmdline.panther_host_name,cmdline.panther_port); } catch (PestError &perr) { @@ -411,54 +357,29 @@ int main(int argc, char* argv[]) cout << endl << "Work Done..." << endl; exit(0); } - //Check for PANTHER master - else if (it_find != cmd_arg_vec.end()) - { - // using PANTHER run manager - run_manager_type = RunManagerType::PANTHER; - socket_str = next_item; - } - - it_find = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/g"); - next_item.clear(); - if (it_find != cmd_arg_vec.end()) - { - cerr << "Genie run manager ('/g') no longer supported, please use PANTHER instead" << endl; - return 1; - - } + RestartController restart_ctl; //process restart and reuse jacobian directives - vector::const_iterator it_find_j = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/j"); - vector::const_iterator it_find_r = find(cmd_arg_vec.begin(), cmd_arg_vec.end(), "/r"); + bool restart_flag = false; bool save_restart_rec_header = true; debug_initialize(file_manager.build_filename("dbg")); - if (it_find_j != cmd_arg_vec.end()) + if (cmdline.jac_restart) { throw runtime_error("/j option not supported by sweep"); } - else if (it_find_r != cmd_arg_vec.end()) - { - ifstream &fin_rst = file_manager.open_ifile_ext("rst"); - restart_ctl.process_rst_file(fin_rst); - file_manager.close_file("rst"); - restart_flag = true; - file_manager.open_default_files(true); - ofstream &fout_rec_tmp = file_manager.rec_ofstream(); - fout_rec_tmp << endl << endl; - fout_rec_tmp << "Restarting sweep ....." << endl << endl; - cout << " Restarting sweep ....." << endl << endl; - - } - else + if (cmdline.restart) { - restart_ctl.get_restart_option() = RestartController::RestartOption::NONE; - file_manager.open_default_files(); + throw runtime_error("/r option not supported by sweep"); } + + + restart_ctl.get_restart_option() = RestartController::RestartOption::NONE; + file_manager.open_default_files(); + ofstream &fout_rec = file_manager.rec_ofstream(); PerformanceLog performance_log(file_manager.open_ofile_ext("log")); @@ -470,14 +391,14 @@ int main(int argc, char* argv[]) fout_rec << endl; fout_rec << endl << endl << "version: " << version << endl; fout_rec << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - fout_rec << "using control file: \"" << complete_path << "\"" << endl << endl; + fout_rec << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl << endl; fout_rec << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; } cout << endl; cout << endl << endl << "version: " << version << endl; cout << "binary compiled on " << __DATE__ << " at " << __TIME__ << endl << endl; - cout << "using control file: \"" << complete_path << "\"" << endl << endl; + cout << "using control file: \"" << cmdline.ctl_file_name << "\"" << endl << endl; cout << "in directory: \"" << OperSys::getcwd() << "\"" << endl << endl; // create pest run and process control file to initialize it @@ -535,14 +456,11 @@ int main(int argc, char* argv[]) } RunManagerAbstract *run_manager_ptr; - if (run_manager_type == RunManagerType::PANTHER) + if (cmdline.runmanagertype == CmdLine::RunManagerType::PANTHER_MASTER) { - string port = socket_str; - strip_ip(port); - strip_ip(port, "front", ":"); const ModelExecInfo &exi = pest_scenario.get_model_exec_info(); run_manager_ptr = new RunManagerPanther( - file_manager.build_filename("rns"), port, + file_manager.build_filename("rns"), cmdline.panther_port, file_manager.open_ofile_ext("rmr"), pest_scenario.get_pestpp_options().get_max_run_fail(), pest_scenario.get_pestpp_options().get_overdue_reched_fac(),