27#include "boost/variant.hpp"
28#include "boost/smart_ptr.hpp"
29#include "boost/algorithm/string.hpp"
41 std::map<std::string, std::string> uvars)
48 namespace fs = std::filesystem;
52 if(getenv(
"SIMTMPDIR") == nullptr) {
53 std::cout <<
"Environment variable SIMTMPDIR not defined!"
55 simTmpDir_ = getenv(
"PWD");
59 simulationName_ =
name;
63 std::vector<std::string> dict;
64 for(
auto parameter : params) {
65 std::ostringstream tmp;
67 tmp << parameter.first <<
"=" << parameter.second;
68 dvarNames_.insert(parameter.first);
69 dict.push_back(tmp.str());
71 std::ostringstream value;
73 value << parameter.second;
74 userVariables_.insert(
75 std::pair<std::string, std::string>(parameter.first, value.str()));
85 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
87 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
89 unsigned num_coworkers_worker_ = 0;
90 num_coworkers_worker_ = args->getArg<
size_t>(
"num-coworkers");
92 unsigned group_start = 0;
94 unsigned worker_group = ((my_rank % world_size) - 2) / num_coworkers_worker_;
96 unsigned leader_ = group_start + 2 + worker_group * num_coworkers_worker_;
97 leader_ = leader_ % world_size;
103 std::ostringstream tmp;
106 tmp << simTmpDir_ <<
"/" << hash <<
"_" << leader_;
108 simulationDirName_ = tmp.str();
110 std::string tmplDir = args->getArg<std::string>(
"templates");
111 if (tmplDir.empty()) {
112 if(getenv(
"TEMPLATES") ==
nullptr) {
114 "Environment variable TEMPLATES not defined!");
116 tmplDir = getenv(
"TEMPLATES");
118 std::string tmplFile = tmplDir +
"/" + simulationName_ +
".tmpl";
120 std::string dataFile = simulationName_ +
".data";
122 if (!fs::exists(tmplFile))
124 "The template file '" + tmplFile +
"' doesn't exit");
126 for (
const auto& uvar : userVariables_) {
127 uvars[uvar.first] = uvar.second;
142 struct stat fileInfo;
144 if(stat(infile.c_str(), &fileInfo) == 0) {
145 std::cout <<
"-> Simulation input file (" << infile
146 <<
") already exist from previous run.." << std::endl;
155 namespace fs = std::filesystem;
157 for (
auto &p: fs::directory_iterator(path)) {
158 fs::path source = p.path();
160 target +=source.filename();
163 fs::create_symlink(source, target);
164 }
catch (fs::filesystem_error &e) {
165 std::cerr << e.what() <<
"\n"
166 <<
"in OpalSimulation::createSymlink()" << std::endl;
174 std::string restartfile = args->
getArg<std::string>(
"restartfile",
"",
false);
176 if (restartfile.empty())
return;
178 namespace fs = std::filesystem;
179 if ( !fs::exists(restartfile) ) {
180 std::cerr <<
"H5 file '" + restartfile +
"' doesn't exist." <<
"\n"
181 <<
"in OpalSimulation::copyH5_m()" << std::endl;
187 fs::path srcfile(restartfile);
189 fs::copy_file(srcfile, targetfile);
190 }
catch (fs::filesystem_error &ex) {
191 std::cerr << ex.what() <<
"\n"
192 <<
"in OpalSimulation::copyH5_m()" << std::endl;
198 namespace fs = std::filesystem;
201 std::string restartfile = args->
getArg<std::string>(
"restartfile",
"",
false);
204 std::ostringstream tmp;
214 if (getenv(
"FIELDMAPS") ==
nullptr) {
216 "Environment variable FIELDMAPS not defined!");
228 if (!fs::exists(dataDir)) {
230 "Directory '" + dataDir +
"' doesn't exist");
233 if (!restartfile.empty() &&
241 namespace fs = std::filesystem;
244 MPI_Comm_rank(
comm_, &rank);
245 if (rank != 0)
return;
254 fs::perms::owner_all |
255 fs::perms::group_read |
256 fs::perms::group_exec |
257 fs::perms::others_read |
258 fs::perms::others_exec);
260 }
catch (fs::filesystem_error &e) {
261 std::cerr << e.what() <<
"\n"
262 <<
"in OpalSimulation::setupSimulation" << std::endl;
269 fs::create_directory(dataDir);
270 fs::permissions(dataDir,
271 fs::perms::owner_all |
272 fs::perms::group_read |
273 fs::perms::group_exec |
274 fs::perms::others_read |
275 fs::perms::others_exec);
277 }
catch (fs::filesystem_error &e) {
278 std::cerr << e.what() <<
"\n"
279 <<
"in OpalSimulation::setupSimulation" << std::endl;
285 gs_->writeInputFile(infile);
287 std::string fieldmapPath = getenv(
"FIELDMAPS");
290 if (getenv(
"DISTRIBUTIONS") !=
nullptr) {
291 std::string distPath = getenv(
"DISTRIBUTIONS");
305 MPI_Comm_rank(MPI_COMM_WORLD, &world_pid);
307 std::ostringstream fname;
308 fname <<
"sim.out." << world_pid;
309 std::ofstream file(fname.str().c_str());
311 std::ofstream err(fname.str().c_str());
314 std::cout.rdbuf(file.rdbuf());
315 std::cerr.rdbuf(err.rdbuf());
326 namespace fs = std::filesystem;
335 pwd_ = fs::current_path().native();
340 std::cout <<
"Cannot chdir to "
342 std::cout <<
"Continuing 1, disregarding this simulation.."
348 std::ostringstream inputFileName;
350 char *inputfile =
new char[inputFileName.str().size()+1] ;
351 strcpy(inputfile, inputFileName.str().c_str());
355 int restartStep= args->
getArg<
int>(
"restartstep",
356 std::numeric_limits<int>::min(),
false);
357 std::string restartfile = args->
getArg<std::string>(
"restartfile",
"",
false);
360 if ( restartStep > -2 && restartfile.empty() ) {
362 "Restart specified but no restart H5 file available.");
365 char exe_name[] =
"opal";
366 char nocomm[] =
"--nocomminit";
367 char info[] =
"--info";
369 char warn[] =
"--warn";
371 char *
arg[] = { exe_name, inputfile, nocomm, info, info0, warn, warn0 };
377 std::cout.setstate(std::ios::failbit);
394 std::cerr <<
"Opal exception during simulation run: \n"
395 << ex->
where() <<
"\n"
396 << ex->
what() << std::endl;
397 std::cerr <<
"Continuing, disregarding this simulation.."
407 std::cerr <<
"Classic exception during simulation run: \n"
408 << ex->
where() <<
"\n"
409 << ex->
what() << std::endl;
410 std::cerr <<
"Continuing, disregarding this simulation.."
412 }
catch(std::exception &ex) {
416 std::cerr <<
"Exception occured during simulation run: \n"
417 << ex.
what() << std::endl
418 <<
"Continuing, disregarding this simulation.." << std::endl;
423 std::cerr <<
"Unknown exception occured during simulation run.\n"
424 <<
"Continuing, disregarding this simulation.." << std::endl;
431 err = chdir(
pwd_.c_str());
433 std::cerr <<
"Cannot chdir to "
434 <<
pwd_ << std::endl;
440 std::map<std::string, std::vector<double> > ret;
443 for (
const std::string &var : statVariables) {
448 std::cout <<
"failed to read data: " << e.what() <<
" in " << e.where() << std::endl;
452 std::vector<double> values;
453 values.reserve(column.size());
455 for (
const auto& val: column) {
458 ret.insert(std::make_pair(var, values));
473 std::cout <<
"Cannot chdir to "
475 std::cout <<
"Continuing, with cleanup.."
482 struct stat fileInfo;
485 if(stat(fn.c_str(), &fileInfo) != 0) {
488 Expressions::Named_t::iterator namedIt;
491 if (namedIt->first ==
"dummy")
continue;
501 objective->
evaluate(variable_dictionary);
503 std::vector<double> values;
504 values.push_back(boost::get<0>(result));
505 bool is_valid = boost::get<1>(result);
509 std::pair<std::string, reqVarInfo_t>(namedIt->first, tmps));
523 constraint->
evaluate(variable_dictionary);
525 std::vector<double> values;
526 values.push_back(boost::get<0>(result));
527 bool is_valid = boost::get<1>(result);
530 std::string constr_str = constraint->
toString();
531 std::vector<std::string> split;
532 boost::split(split, constr_str, boost::is_any_of(
"<>!="),
533 boost::token_compress_on);
534 std::string lhs_constr_str = split[0];
535 std::string rhs_constr_str = split[1];
536 boost::trim_left_if(rhs_constr_str, boost::is_any_of(
"="));
539 const std::unique_ptr<Expressions::Expr_t> lhs(
541 const std::unique_ptr<Expressions::Expr_t> rhs(
547 values.push_back(boost::get<0>(lhs_res));
548 values.push_back(boost::get<0>(rhs_res));
552 std::pair<std::string, reqVarInfo_t>(namedIt->first, tmps));
556 std::cout <<
"Evaluation of objective or constraint " << namedIt->first <<
" threw an exception ('" << e.what() <<
"' in " << e.where() <<
")!" << std::endl;
559 std::cout <<
"Evaluation of objective or constraint " << namedIt->first <<
" threw an exception ('" << e.what() <<
"' in " << e.where() <<
")!" << std::endl;
561 }
catch(std::exception &e) {
562 std::cout <<
"Evaluation of objective or constraint " << namedIt->first <<
" threw an exception ('" << e.what() <<
"')!" << std::endl;
565 std::cout <<
"Evaluation of objective or constraint " << namedIt->first <<
" threw an exception!" << std::endl;
571 err = chdir(
pwd_.c_str());
573 std::cout <<
"Cannot chdir to "
579 const std::string& filename,
582 std::set<std::string> req_vars = expression->
getReqVars();
585 for (
auto req_it = req_vars.begin(); req_it!=req_vars.end();) {
591 double value = std::stod((*it).second);
592 dictionary.insert(std::pair<std::string, double>(*req_it, value));
593 req_it = req_vars.erase(req_it);
596 if(req_vars.empty())
return;
599 const std::unique_ptr<SDDSReader> sddsr(
new SDDSReader(filename));
602 for(std::string req_var : req_vars) {
603 if(dictionary.count(req_var) != 0)
continue;
606 sddsr->getValue(-1 , req_var, value);
607 dictionary.insert(std::pair<std::string, double>(req_var, value));
614 std::vector<double> tmp_values;
615 tmp_values.push_back(0.0);
618 std::pair<std::string, reqVarInfo_t>(namedObjective.first, tmps));
623 namespace fs = std::filesystem;
626 MPI_Comm_rank(
comm_, &my_rank);
631 }
catch(fs::filesystem_error &ex) {
632 std::cout <<
"Can't remove directory '" <<
simulationDirName_ <<
"', (" << ex.what() <<
")" << std::endl;
639 namespace fs = std::filesystem;
641 if ( keep.empty() ) {
648 MPI_Comm_rank(
comm_, &my_rank);
654 fs::directory_iterator it{p};
655 while (it != fs::directory_iterator{}) {
656 std::string extension =
Util::toUpper(it->path().extension().string());
659 extension.erase(0, 1);
661 auto result = std::find(keep.begin(), keep.end(), extension);
663 if ( result == keep.end() && ! fs::is_directory(it->path())) {
664 fs::remove(it->path());
670 fs::directory_iterator it{p};
671 while (it != fs::directory_iterator{}) {
672 if (fs::is_directory(it->path()) && fs::is_empty(it->path())) {
673 fs::remove(it->path());
678 }
catch(fs::filesystem_error &ex) {
680 <<
"', (" << ex.what() <<
")" << std::endl;
int run_opal(char *[], std::string inputfile, int restartStep, int infoLevel, int warnLevel, MPI_Comm comm)
struct reqVarInfo reqVarInfo_t
namedVariableCollection_t Param_t
std::shared_ptr< CmdArguments > CmdArguments_t
std::map< std::string, client::function::type > functionDictionary_t
std::map< std::string, double > variableDictionary_t
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
Expression Expr_t
type of an expression
boost::tuple< double, bool > Result_t
int seed
The current random seed.
std::string toUpper(const std::string &str)
std::vector< variant_t > columnData_t
The global OPAL structure.
static OpalData * getInstance()
The abstract base class for all exceptions in CLASSIC.
std::string pwd_
holds current directory (for restoring)
void invalidBunch()
mark a solution as invalid
virtual ~OpalSimulation()
std::map< std::string, std::vector< double > > getData(const std::vector< std::string > &statVariables)
void getVariableDictionary(variableDictionary_t &dictionary, const std::string &filename, const Expressions::Expr_t *const expression)
get variables for expression evaluation from SDDS file. Can throw SDDSParserException
reqVarContainer_t requestedVars_
holds solutions returned to the optimizer
void setupSimulation()
create directories, input files, fieldmaps...
void copyH5_m()
copy H5 file
void redirectOutToFile()
redirect stdout and stderr to file
std::unique_ptr< GenerateOpalSimulation > gs_
object to generate simulation input files
Expressions::Named_t objectives_
std::streambuf * strm_err_
stream buffer to redirect stderr
std::string simulationDirName_
full path of simulation directory (where simulation will be run)
Expressions::Named_t constraints_
std::map< std::string, std::string > userVariables_
variable dictionary holding requested optimizer values
std::string simTmpDir_
temporary directory for simulation data (environment var SIMTMPDIR)
std::streambuf * strm_buffer_
stream buffer to redirect output
void createSymlink_m(const std::string &path)
create symbolic links
std::string simulationName_
identification of the simulation (corresponding to output filename)
bool hasResultsAvailable()
check if we already have simulated the current set of design vars
void setupFSStructure()
create directories, input files, symlinks...
void collectResults()
Parse SDDS stat file and build up requested variable dictionary.
void restoreOut()
restore stdout and stderr to default
int id_m
job id (SAMPLE command)
OpalSimulation(Expressions::Named_t objectives, Expressions::Named_t constraints, Param_t params, std::string name, MPI_Comm comm, CmdArguments_t args, std::map< std::string, std::string > uvars)
The base class for all OPAL exceptions.
virtual const std::string & what() const
Return the message string for the exception.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.
std::string toString() const
functionDictionary_t getRegFuncs() const
Expressions::Result_t evaluate(variableDictionary_t vars)
evaluate an expression given a value dictionary of free variables
std::set< std::string > getReqVars() const
Simulation(CmdArguments_t args)
T getArg(const std::string name, bool isFatal=false)
static std::string generate(std::vector< std::string > arguments, size_t world_pid=0)
ast::columnData_t getColumnData(const std::string &columnName)
ast::datatype getColumnType(const std::string &col_name)
T getBoostVariantValue(const ast::variant_t &val, int datatype) const
Convert value from boost variant (only numeric types) to a value of type T.