42 #include <boost/filesystem.hpp>
74 GENEMUTATIONPROBABILITY,
76 RECOMBINATIONPROBABILITY,
94 "The \"OPTIMIZE\" command initiates optimization.") {
96 (
"INPUT",
"Path to input file");
98 (
"OUTPUT",
"Name used in output file generation");
100 (
"OUTDIR",
"Name of directory used to store generation output files");
102 (
"OBJECTIVES",
"List of objectives to be used");
104 (
"DVARS",
"List of optimization variables to be used");
106 (
"CONSTRAINTS",
"List of constraints to be used");
108 (
"INITIALPOPULATION",
"Size of the initial population");
110 (
"STARTPOPULATION",
"Generation file (JSON format) to be started from (optional)",
"");
112 (
"NUM_MASTERS",
"Number of master nodes");
114 (
"NUM_COWORKERS",
"Number processors per worker");
116 (
"DUMP_DAT",
"Dump old generation data format with frequency (PISA only)");
118 (
"DUMP_FREQ",
"Dump generation data with frequency (PISA only)");
120 (
"DUMP_OFFSPRING",
"Dump offspring (instead of parent population), default: true");
122 (
"NUM_IND_GEN",
"Number of individuals in a generation (PISA only)");
124 (
"MAXGENERATIONS",
"Number of generations to run");
126 (
"EPSILON",
"Tolerance of hypervolume criteria, default 0.001");
128 (
"EXPECTED_HYPERVOL",
"The reference hypervolume, default 0");
130 (
"HYPERVOLREFERENCE",
"The reference point (real array) for the hypervolume, default empty (origin)");
132 (
"CONV_HVOL_PROG",
"Converge if change in hypervolume is smaller, default 0");
134 (
"ONE_PILOT_CONVERGE",
"default false");
136 (
"SOL_SYNCH",
"Solution exchange frequency, default 0");
138 (
"GENE_MUTATION_PROBABILITY",
"Mutation probability of individual gene, default: 0.5");
140 (
"MUTATION_PROBABILITY",
"Mutation probability of genome, default: 0.5");
142 (
"RECOMBINATION_PROBABILITY",
"Probability for genes to recombine, default: 0.5");
144 (
"SIMBIN_CROSSOVER_NU",
"Simulated binary crossover, default: 2.0");
146 (
"INITIAL_OPTIMIZATION",
"Optimize speed of initial generation, default: false");
148 (
"BIRTH_CONTROL",
"Enforce strict population sizes (or flexible to keep workers busy), default: false");
150 (
"SIMTMPDIR",
"Directory where simulations are run");
152 (
"TEMPLATEDIR",
"Directory where templates are stored");
154 (
"FIELDMAPDIR",
"Directory where field maps are stored");
156 (
"DISTDIR",
"Directory where distributions are stored",
"");
158 (
"CROSSOVER",
"Type of cross over (default: Blend)",
"Blend");
160 (
"MUTATION",
"Type of bit mutation (default: IndependentBit)",
"IndependentBit");
162 (
"RESTART_FILE",
"H5 file to restart the OPAL simulations from (optional)",
"");
164 (
"RESTART_STEP",
"Restart from given H5 step (optional)",
181 namespace fs = boost::filesystem;
184 opal->setOptimizerFlag();
203 funcs.insert(std::pair<std::string, client::function::type>
207 funcs.insert(std::pair<std::string, client::function::type>
211 funcs.insert(std::pair<std::string, client::function::type>
212 (
"sddsVariableAt", ff));
215 funcs.insert(std::pair<std::string, client::function::type>
219 funcs.insert(std::pair<std::string, client::function::type>
220 (
"maxNormRadialPeak", ff));
223 funcs.insert(std::pair<std::string, client::function::type>
224 (
"numberOfPeaks", ff));
227 funcs.insert(std::pair<std::string, client::function::type>
228 (
"sumErrSqRadialPeak", ff));
231 funcs.insert(std::pair<std::string, client::function::type>
232 (
"probVariableWithID", ff));
234 std::string fname = inputfile.stem().native();
236 funcs.insert(std::pair<std::string, client::function::type>
237 (
"statVariableAt", ff));
241 std::vector<std::string> arguments(opal->getArguments());
242 std::vector<char*> argv;
243 std::map<unsigned int, std::string> argumentMapper({
244 {INPUT,
"inputfile"},
247 {INITIALPOPULATION,
"initialPopulation"},
248 {STARTPOPULATION,
"start-population"},
249 {NUMMASTERS,
"num-masters"},
250 {NUMCOWORKERS,
"num-coworkers"},
251 {DUMPDAT,
"dump-dat"},
252 {DUMPFREQ,
"dump-freq"},
253 {DUMPOFFSPRING,
"dump-offspring"},
254 {NUMINDGEN,
"num-ind-gen"},
255 {MAXGENERATIONS,
"maxGenerations"},
256 {EPSILON,
"epsilon"},
257 {EXPECTEDHYPERVOL,
"expected-hypervol"},
258 {CONVHVOLPROG,
"conv-hvol-prog"},
259 {ONEPILOTCONVERGE,
"one-pilot-converge"},
260 {SOLSYNCH,
"sol-synch"},
261 {GENEMUTATIONPROBABILITY,
"gene-mutation-probability"},
262 {MUTATIONPROBABILITY,
"mutation-probability"},
263 {RECOMBINATIONPROBABILITY,
"recombination-probability"},
264 {SIMBINCROSSOVERNU,
"simbin-crossover-nu"},
265 {INITIALOPTIMIZATION,
"initial-optimization"},
266 {BIRTHCONTROL,
"birth-control"},
267 {RESTART_FILE,
"restartfile"},
268 {RESTART_STEP,
"restartstep"}
271 auto it = argumentMapper.end();
272 for (
unsigned int i = 0; i <
SIZE; ++ i) {
273 if ((it = argumentMapper.find(i)) != argumentMapper.end()) {
275 if (type ==
"string") {
278 arguments.push_back(argument);
280 }
else if (type ==
"real") {
283 size_t last = val.find_last_not_of(
'0');
284 if (val[last] !=
'.') ++ last;
285 val.erase (last, std::string::npos );
286 std::string argument =
"--" + (*it).second +
"=" + val;
287 arguments.push_back(argument);
289 }
else if (type ==
"logical") {
292 arguments.push_back(argument);
300 "The argument INPUT has to be provided");
304 "The argument INITIALPOPULATION has to be provided");
308 "The argument MAXGENERATIONS has to be provided");
313 "The hypervolume reference point should have the same dimension as the objectives");
318 "No INITIAL_OPTIMIZATION possible when reading initial population from file (STARTPOPULATION)");
323 "No INITIAL_OPTIMIZATION possible with BIRTH_CONTROL");
328 if (dir.is_relative()) {
329 fs::path path = fs::path(std::string(getenv(
"PWD")));
334 if (!fs::exists(dir)) {
335 fs::create_directory(dir);
337 std::string argument =
"--simtmpdir=" + dir.native();
338 arguments.push_back(argument);
343 if (dir.is_relative()) {
344 fs::path path = fs::path(std::string(getenv(
"PWD")));
349 std::string argument =
"--templates=" + dir.native();
350 arguments.push_back(argument);
355 if (dir.is_relative()) {
356 fs::path path = fs::path(std::string(getenv(
"PWD")));
361 setenv(
"FIELDMAPS", dir.c_str(), 1);
366 if (dir.is_relative()) {
367 fs::path path = fs::path(std::string(getenv(
"PWD")));
372 setenv(
"DISTRIBUTIONS", dir.c_str(), 1);
377 for (
size_t i = 0; i < arguments.size(); ++ i) {
378 argv.push_back(const_cast<char*>(arguments[i].c_str()));
379 *gmsg << arguments[i] <<
" ";
383 std::set<std::string> vars;
384 for (
const std::string &
name: dvarsstr) {
386 DVar* dvar =
dynamic_cast<DVar*
>(obj);
387 if (dvar ==
nullptr) {
389 "The design variable " +
name +
" is not known");
396 DVar_t tmp = boost::make_tuple(var, lowerbound, upperbound);
398 auto ret = vars.insert(var);
399 if (ret.second ==
false) {
401 "There is already a design variable with the variable " + var +
" defined");
404 std::set<std::string> objExpressions;
405 for (
const std::string &
name: objectivesstr) {
408 if (objective ==
nullptr) {
410 "The objective " +
name +
" is not known");
416 auto ret = objExpressions.insert(expr);
417 if (ret.second ==
false) {
419 "There is already a objective with the expression " + expr +
" defined");
422 std::set<std::string> constraintExpressions;
423 for (
const std::string &
name: constraintsstr) {
426 if (constraint ==
nullptr) {
428 "The constraint " +
name +
" is not known");
434 auto ret = constraintExpressions.insert(expr);
435 if (ret.second ==
false) {
437 "There is already a constraint with the expression " + expr +
" defined");
443 size_t pos = tmplFile.find_last_of(
"/");
444 if(pos != std::string::npos)
445 tmplFile = tmplFile.substr(pos+1);
446 pos = tmplFile.find(
".");
447 tmplFile = tmplFile.substr(0,pos);
450 std::ifstream infile(tmplFile.c_str());
452 std::map<std::string, short> dvarCheck;
453 for (
auto itr = dvars.begin(); itr != dvars.end(); ++ itr) {
454 dvarCheck.insert(std::make_pair(boost::get<0>(itr->second), 0));
457 while(infile.good()) {
459 std::getline(infile, line,
'\n');
462 for(
auto &check: dvarCheck) {
463 pos = line.find(
"_" + check.first +
"_");
464 if (pos != std::string::npos &&
465 dvarCheck.find(check.first) != dvarCheck.end()) {
466 dvarCheck.at(check.first) = 1;
472 for (
auto itr = dvarCheck.begin(); itr != dvarCheck.end(); ++ itr) {
473 if (itr->second == 0) {
475 "Couldn't find the design variable '" + itr->first +
"' in '" + tmplFile +
"'!");
485 this->
run(args, funcs, dvars, objectives, constraints);
489 MPI_Abort(MPI_COMM_WORLD, -100);
511 std::map<std::string, CrossOver> map;
512 map[
"BLEND"] = CrossOver::Blend;
513 map[
"NAIVEONEPOINT"] = CrossOver::NaiveOnePoint;
514 map[
"NAIVEUNIFORM"] = CrossOver::NaiveUniform;
515 map[
"SIMULATEDBINARY"] = CrossOver::SimulatedBinary;
519 switch ( map[crossover] ) {
520 case CrossOver::Blend:
522 case CrossOver::NaiveOnePoint:
523 co = CrossOver::NaiveOnePoint;
525 case CrossOver::NaiveUniform:
526 co = CrossOver::NaiveUniform;
528 case CrossOver::SimulatedBinary:
529 co = CrossOver::SimulatedBinary;
533 "No cross over '" + crossover +
"' supported.");
542 std::map<std::string, Mutation> map;
543 map[
"INDEPENDENTBIT"] = Mutation::IndependentBit;
544 map[
"ONEBIT"] = Mutation::OneBit;
546 Mutation mut = Mutation::IndependentBit;
548 switch ( map[mutation] ) {
549 case Mutation::IndependentBit:
551 case Mutation::OneBit:
552 mut = Mutation::OneBit;
556 "No mutation '" + mutation +
"' supported.");
573 boost::shared_ptr<Comm_t> comm(
new Comm_t(args, MPI_COMM_WORLD));
574 if (comm->isWorker())
580 switch ( crossover + mutation ) {
581 case CrossOver::Blend + Mutation::IndependentBit:
586 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
588 objectives, constraints,
592 case CrossOver::Blend + Mutation::OneBit:
597 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
599 objectives, constraints,
603 case CrossOver::NaiveOnePoint + Mutation::IndependentBit:
608 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
610 objectives, constraints,
614 case CrossOver::NaiveOnePoint + Mutation::OneBit:
619 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
621 objectives, constraints,
625 case CrossOver::NaiveUniform + Mutation::IndependentBit:
630 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
632 objectives, constraints,
636 case CrossOver::NaiveUniform + Mutation::OneBit:
641 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
643 objectives, constraints,
647 case CrossOver::SimulatedBinary + Mutation::IndependentBit:
652 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
654 objectives, constraints,
658 case CrossOver::SimulatedBinary + Mutation::OneBit:
663 boost::scoped_ptr<pilot_t>
pi(
new pilot_t(args, comm,
665 objectives, constraints,
671 "No such cross over and mutation combination supported.");
674 if (comm->isWorker())
virtual const char * what() const
std::string getExpression() const
std::string getExpression() const
std::pair< std::string, Expressions::Expr_t * > SingleNamed_t
constexpr double e
The value of .
Concrete implementation of an Opal simulation wrapper.
The base class for all OPAL actions.
CrossOver crossoverSelection(std::string crossover)
std::string getVariable() const
The base class for all OPAL exceptions.
boost::shared_ptr< CmdArguments > CmdArguments_t
std::string toUpper(const std::string &str)
Expression to be evaluated in the framework.
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
double getLowerBound() const
Role assignment according to strategy (that might use hardware network information).
Implementing the Variator for the PISA state machine.
bool getBool(const Attribute &attr)
Return logical value.
Attribute makeStringArray(const std::string &name, const std::string &help)
Create a string array attribute.
static OpalData * getInstance()
OptimizeCmd()
Exemplar constructor.
double getUpperBound() const
static void stashInstance()
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Parsing command line arguments.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Mutation mutationSelection(std::string mutation)
boost::tuple< std::string, double, double > DVar_t
type of design variables
void run(const CmdArguments_t &args, const functionDictionary_t &funcs, const DVarContainer_t &dvars, const Expressions::Named_t &objectives, const Expressions::Named_t &constraints)
std::pair< std::string, DVar_t > namedDVar_t
std::map< std::string, DVar_t > DVarContainer_t
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
static OpalData * popInstance()
The base class for all OPAL objects.
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
boost::function< boost::tuple< double, bool >arguments_t)> type
double FromFile(std::string file, const std::vector< double > &referencePoint)
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Modeling social graph (Cartesian neighbors plus additional random link) as underlaying master network...
double getReal(const Attribute &attr)
Return real value.
virtual void execute()
Execute the command.
virtual OptimizeCmd * clone(const std::string &name)
Make clone.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
std::map< std::string, client::function::type > functionDictionary_t
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
The Optimization Pilot (Master): Coordinates requests by optimizer to workers and reports results bac...
Inform & endl(Inform &inf)
std::string getString(const Attribute &attr)
Get string value.