OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Main.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Main.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.9.2.2 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Main program for OPAL
10 //
11 // ------------------------------------------------------------------------
12 //
13 // $Date: 2004/11/12 20:10:10 $
14 // $Author: adelmann $
15 //
16 // ------------------------------------------------------------------------
17 
18 #include "opal.h"
19 
22 
23 #include "H5hut.h"
24 
27 #include "OpalParser/OpalParser.h"
28 #include "Parser/FileStream.h"
29 #include "Parser/TerminalStream.h"
30 #include "Utilities/Timer.h"
31 #include "Fields/Fieldmap.h"
32 #include "FixedAlgebra/FTps.h"
33 
34 #include "BasicActions/Option.h"
35 #include "Utilities/Options.h"
36 #include "Utilities/Options.h"
39 #include "Utilities/Util.h"
40 
41 #include "OPALconfig.h"
42 
43 #ifdef ENABLE_AMR
44 #include <AMReX_ParallelDescriptor.H>
45 #endif
46 /*
47  Includes related to the optimizer
48 */
49 #include "boost/smart_ptr.hpp"
50 
51 #include "Pilot/Pilot.h"
52 #include "Util/CmdArguments.h"
53 #include "Util/OptPilotException.h"
54 
58 
60 
61 #include "Comm/CommSplitter.h"
65 
67 #include "Expression/FromFile.h"
68 #include "Expression/SumErrSq.h"
70 #include "Expression/RadialPeak.h"
73 
74 #include <gsl/gsl_errno.h>
75 
76 #include <boost/filesystem.hpp>
77 #include <boost/algorithm/string/predicate.hpp>
78 
79 #include <cstring>
80 #include <set>
81 #include <algorithm>
82 
83 namespace {
84  void errorHandlerGSL(const char *reason,
85  const char *file,
86  int line,
87  int gsl_errno) {
88  throw OpalException(file, reason);
89  }
90 }
91 
92 
93 bool checkInitAmrFlag(int argc, char* argv[]) {
94  std::string noamr = "noInitAMR";
95  bool initAMR = true;
96  for (int i = 0; i < argc; ++i) {
97  std::string sargv = std::string(argv[i]);
98  if ( sargv.find(noamr) != std::string::npos ) {
99  initAMR = false;
100  break;
101  }
102  }
103  return initAMR;
104 }
105 
106 
107 int main(int argc, char *argv[]) {
108  Ippl *ippl = new Ippl(argc, argv);
109  gmsg = new Inform("OPAL");
110 
111  namespace fs = boost::filesystem;
112 
113 #ifdef ENABLE_AMR
114  bool initAMR = checkInitAmrFlag(argc, argv);
115  if ( initAMR ) {
116  // false: build no parmparse, we use the OPAL parser instead.
117  amrex::Initialize(argc, argv, false, Ippl::getComm());
118  }
119 #endif
120 
121  OPALTimer::Timer simtimer;
122 
123  std::string dateStr(simtimer.date());
124  std::string timeStr(simtimer.time());
125 
126  H5SetVerbosityLevel(1); //65535);
127 
128  gsl_set_error_handler(&errorHandlerGSL);
129 
130  static IpplTimings::TimerRef mainTimer = IpplTimings::getTimer("mainTimer");
131  IpplTimings::startTimer(mainTimer);
132 
133  Inform hmsg("");
134  std::string mySpace(" ");
135 
136  if(Ippl::myNode() == 0) remove("errormsg.txt");
137 
138  hmsg << mySpace << " ____ _____ ___ " << endl;
139  hmsg << mySpace << " / __ \\| __ \\ /\\ | | " << endl;
140  hmsg << mySpace << " | | | | |__) / \\ | |" << endl;
141  hmsg << mySpace << " | | | | ___/ /\\ \\ | |" << endl ;
142  hmsg << mySpace << " | |__| | | / ____ \\| |____" << endl;
143  hmsg << mySpace << " \\____/|_| /_/ \\_\\______|" << endl;
144 
145 
146  std::string gitRevision = "git rev. " + Util::getGitRevision();
147  std::string copyRight = "(c) PSI, http://amas.web.psi.ch";
148  *gmsg << endl
149  << "This is OPAL (Object Oriented Parallel Accelerator Library) Version " << OPAL_PROJECT_VERSION << "\n"
150  << std::setw(37 + gitRevision.length() / 2) << std::right << gitRevision << "\n\n" << endl
151  << std::setw(37 + copyRight.length() / 2) << std::right << copyRight << "\n\n" << endl
152  << "The optimiser (former opt-Pilot) is integrated " << endl
153  << endl;
154 
155 #ifdef OPAL_DKS
156  *gmsg << "OPAL compiled with DKS (Dynamic Kernel Scheduler) Version "
157  << DKS_VERSION;
159  *gmsg << " GPU present" << endl << endl;
160  else
161  *gmsg << " GPU not present" << endl << endl;
162 #endif
163 
164  *gmsg << "Please send cookies, goodies or other motivations (wine and beer ... ) \nto the OPAL developers " << PACKAGE_BUGREPORT << "\n" << endl;
165  *gmsg << "Time: " << timeStr << " date: " << dateStr << "\n" << endl;
166 
167 
168  /*
169  Make a directory data for some of the output
170  */
171  if(Ippl::myNode() == 0) {
172  if (!fs::exists("data")) {
173  boost::system::error_code error_code;
174  if (!fs::create_directory("data", error_code)) {
175  std::cerr << error_code.message() << std::endl;
176  // use error code to prevent create_directory from throwing an exception
177  }
178  }
179  }
180  Ippl::Comm->barrier();
181  if (!fs::is_directory("data")) {
182  std::cerr << "unable to create directory; aborting" << std::endl;
183  abort();
184  }
185 
186  const OpalParser parser;
187 
188  // DTA
189  std::cout.precision(16);
190  std::cout.setf(std::ios::scientific, std::ios::floatfield);
191  std::cerr.precision(16);
192  std::cerr.setf(std::ios::scientific, std::ios::floatfield);
193  // /DTA
194 
195  // Set global truncation orders.
199 
201  opal->storeArguments(argc, argv);
202  try {
204 
205  // Read startup file.
207 
208  char *startup = getenv("HOME");
209  boost::filesystem::path p = strncat(startup, "/init.opal", 20);
210  if (startup != NULL && is_regular_file(p)) {
211 
212  FileStream::setEcho(false);
213  FileStream *is;
214 
215  try {
216  is = new FileStream(startup);
217  } catch(...) {
218  is = 0;
219  ERRORMSG("Could not open startup file \"" << startup << "\".\n"
220  << "Note: this is not mandatory for an OPAL simulation!\n");
221  }
222 
223  if(is) {
224  *gmsg << "Reading startup file \"" << startup << "\"." << endl;
225  parser.run(is);
226  *gmsg << "Finished reading startup file." << endl;
227  }
229  } else {
230  *gmsg << "Couldn't find startup file \"" << startup << "\".\n"
231  << "Note: this is not mandatory for an OPAL simulation!\n" << endl;
232  }
233 
234  if(argc <= 1) {
235  // Run commands from standard input
236  parser.run(new TerminalStream("OPAL"));
237  } else {
238  int arg = -1;
239  std::string fname;
240  std::string restartFileName;
241  // // will write dumping date into a new h5 file
242  for(int ii = 1; ii < argc; ++ ii) {
243  std::string argStr = std::string(argv[ii]);
244  // The sequence of the two arguments is free
245  if (argStr == std::string("--input")) {
246  ++ ii;
247  arg = ii;
248  INFOMSG(argv[ii] << endl);
249  continue;
250  } else if (argStr == std::string("-restart") ||
251  argStr == std::string("--restart")) {
252  opal->setRestartRun();
253  opal->setRestartStep(atoi(argv[++ ii]));
254  opal->setRestartFileName(argv[1]);
255  continue;
256  } else if (argStr == std::string("-restartfn") ||
257  argStr == std::string("--restartfn")) {
258  restartFileName = std::string(argv[++ ii]);
259  continue;
260  } else if (argStr == std::string("-version") ||
261  argStr == std::string("--version")) {
262  INFOMSG("OPAL Version " << OPAL_PROJECT_VERSION << ", git rev. " << Util::getGitRevision() << endl);
264  std::string options = (IpplInfo::compileOptions() +
265  std::string(" ") +
266  std::string(OPAL_COMPILE_OPTIONS) +
267  std::string(" "));
268  std::set<std::string> uniqOptions;
269  while (options.length() > 0) {
270  size_t n = options.find_first_of(' ');
271  while (n == 0) {
272  options = options.substr(n + 1);
273  n = options.find_first_of(' ');
274  }
275 
276  uniqOptions.insert(options.substr(0, n));
277  options = options.substr(n + 1);
278  }
279  for (auto it: uniqOptions) {
280  options += it + " ";
281  }
282 
283  std::string header("Compile-time options: ");
284  while (options.length() > 58) {
285  std::string line = options.substr(0, 58);
286  size_t n = line.find_last_of(' ');
287  INFOMSG(header << line.substr(0, n) << "\n");
288 
289  header = std::string(22, ' ');
290  options = options.substr(n + 1);
291  }
292  INFOMSG(header << options << endl);
293  exit(0);
294  } else if ( argStr.find("noInitAMR") != std::string::npos) {
295  // do nothing here
296  } else if (argStr == std::string("-help") ||
297  argStr == std::string("--help")) {
298  IpplInfo::printHelp(argv);
299  INFOMSG(" --version : Print a brief version summary.\n");
300  INFOMSG(" --input <fname> : Specifies the input file <fname>.\n");
301  INFOMSG(" --restart <n> : Performes a restart from step <n>.\n");
302  INFOMSG(" --restartfn <fname> : Uses the file <fname> to restart from.\n");
303  INFOMSG(" --help : Display this command-line summary.\n");
304  INFOMSG(endl);
305  exit(0);
306  } else {
307  if (arg == -1 &&
308  (ii == 1 || ii + 1 == argc) &&
309  argv[ii][0] != '-') {
310  arg = ii;
311  continue;
312  } else {
313  INFOMSG("Unknown argument \"" << argStr << "\"" << endl);
314  IpplInfo::printHelp(argv);
315  INFOMSG(" --version : Print a brief version summary.\n");
316  INFOMSG(" --input <fname> : Specifies the input file <fname>.\n");
317  INFOMSG(" --restart <n> : Performes a restart from step <n>.\n");
318  INFOMSG(" --restartfn <fname> : Uses the file <fname> to restart from.\n");
319  INFOMSG(" --help : Display this command-line summary.\n");
320  INFOMSG(endl);
321  exit(1);
322  }
323  }
324  }
325 
326  if (arg == -1) {
327  INFOMSG("No input file provided!" << endl);
328  exit(1);
329  }
330 
331  fname = std::string(argv[arg]);
332  if (!fs::exists(fname)) {
333  INFOMSG("Input file \"" << fname << "\" doesn't exist!" << endl);
334  exit(1);
335  }
336 
337  opal->storeInputFn(fname);
338 
339  if (opal->inRestartRun()) {
340  if (restartFileName == "")
341  restartFileName = opal->getInputBasename() + std::string(".h5");
342  if (!fs::exists(restartFileName)) {
343  INFOMSG("Restart file \"" << restartFileName << "\" doesn't exist!" << endl);
344  exit(1);
345  }
346  opal->setRestartFileName(restartFileName);
347  }
348 
349  FileStream *is;
350 
351  try {
352  is = new FileStream(fname);
353  } catch(...) {
354  is = 0;
355  *gmsg << "Input file \"" << fname << "\" not found." << endl;
356  }
357 
358  if(is) {
359  *gmsg << "* Reading input stream \"" << fname << "\"." << endl;
360  parser.run(is);
361  *gmsg << "* End of input stream \"" << fname << "\"." << endl;
362  }
363  }
364 
365  if(Ippl::myNode() == 0) {
366  std::ifstream errormsg("errormsg.txt");
367  if(errormsg.good()) {
368  char buffer[256];
369  std::string closure(" *\n");
370  ERRORMSG("\n"
371  << "* **********************************************************************************\n"
372  << "* ************** W A R N I N G / E R R O R * * M E S S A G E S *********************\n"
373  << "* **********************************************************************************"
374  << endl);
375  errormsg.getline(buffer, 256);
376  while(errormsg.good()) {
377  ERRORMSG("* ");
378  if(errormsg.gcount() == 1) {
379  ERRORMSG(closure);
380  } else if ((size_t)errormsg.gcount() <= closure.size()) {
381  ERRORMSG(buffer << closure.substr(errormsg.gcount() - 1));
382  } else {
383  ERRORMSG(buffer << endl);
384  }
385  errormsg.getline(buffer, 256);
386  }
387  ERRORMSG("* " << closure
388  << "* **********************************************************************************\n"
389  << "* **********************************************************************************"
390  << endl);
391  }
392  errormsg.close();
393  }
394 
395  } catch(EarlyLeaveException& ex) {
396  // do nothing here
397  } catch(OpalException &ex) {
398  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
399  errorMsg << "\n*** User error detected by function \""
400  << ex.where() << "\"\n";
401  // stat->printWhere(errorMsg, true);
402  std::string what = ex.what();
403  size_t pos = what.find_first_of('\n');
404  do {
405  errorMsg << " " << what.substr(0, pos) << endl;
406  what = what.substr(pos + 1, std::string::npos);
407  pos = what.find_first_of('\n');
408  } while (pos != std::string::npos);
409  errorMsg << " " << what << endl;
410 
411  MPI_Abort(MPI_COMM_WORLD, -100);
412  } catch(ClassicException &ex) {
413  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
414  errorMsg << "\n*** User error detected by function \""
415  << ex.where() << "\"\n";
416  // stat->printWhere(errorMsg, true);
417  std::string what = ex.what();
418  size_t pos = what.find_first_of('\n');
419  do {
420  errorMsg << " " << what.substr(0, pos) << endl;
421  what = what.substr(pos + 1, std::string::npos);
422  pos = what.find_first_of('\n');
423  } while (pos != std::string::npos);
424  errorMsg << " " << what << endl;
425 
426  MPI_Abort(MPI_COMM_WORLD, -100);
427  } catch(SDDSParserException &ex) {
428  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
429 
430  std::stringstream msg;
431  errorMsg << "\n*** Error detected by function \""
432  << ex.where() << "\"\n";
433  std::string what = ex.what();
434  size_t pos = what.find_first_of('\n');
435  do {
436  errorMsg << " " << what.substr(0, pos) << endl;
437  what = what.substr(pos + 1, std::string::npos);
438  pos = what.find_first_of('\n');
439  } while (pos != std::string::npos);
440  errorMsg << " " << what << endl;
441 
442  MPI_Abort(MPI_COMM_WORLD, -100);
443  } catch(IpplException &ex) {
444  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
445 
446  std::stringstream msg;
447  errorMsg << "\n*** Error detected by function \""
448  << ex.where() << "\"\n";
449  std::string what = ex.what();
450  size_t pos = what.find_first_of('\n');
451  do {
452  errorMsg << " " << what.substr(0, pos) << endl;
453  what = what.substr(pos + 1, std::string::npos);
454  pos = what.find_first_of('\n');
455  } while (pos != std::string::npos);
456  errorMsg << " " << what << endl;
457 
458  MPI_Abort(MPI_COMM_WORLD, -100);
459  } catch(std::bad_alloc &ex) {
460  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
461  errorMsg << "\n*** Error:\n";
462  errorMsg << " Sorry, virtual memory exhausted.\n"
463  << ex.what()
464  << endl;
465 
466  MPI_Abort(MPI_COMM_WORLD, -100);
467  } catch(assertion &ex) {
468  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
469  errorMsg << "\n*** Runtime-error ******************\n";
470  std::string what = ex.what();
471  size_t pos = what.find_first_of('\n');
472  do {
473  errorMsg << " " << what.substr(0, pos) << endl;
474  what = what.substr(pos + 1, std::string::npos);
475  pos = what.find_first_of('\n');
476  } while (pos != std::string::npos);
477  errorMsg << " " << what << endl;
478 
479  errorMsg << "\n************************************\n" << endl;
480  throw std::runtime_error("in Parser");
481  } catch(std::exception &ex) {
482  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
483  errorMsg << "\n"
484  << "*** Error:\n"
485  << " Internal OPAL error: \n";
486  std::string what = ex.what();
487  size_t pos = what.find_first_of('\n');
488  do {
489  errorMsg << " " << what.substr(0, pos) << endl;
490  what = what.substr(pos + 1, std::string::npos);
491  pos = what.find_first_of('\n');
492  } while (pos != std::string::npos);
493  errorMsg << " " << what << endl;
494 
495  MPI_Abort(MPI_COMM_WORLD, -100);
496  } catch(...) {
497  Inform errorMsg("Error", std::cerr, INFORM_ALL_NODES);
498  errorMsg << "\n*** Error:\n"
499  << " Unexpected exception caught.\n" << endl;
500 
501  MPI_Abort(MPI_COMM_WORLD, -100);
502  }
503 
504 
505  IpplTimings::stopTimer(mainTimer);
506 
508 
509  IpplTimings::print(std::string("timing.dat"),
510  OpalData::getInstance()->getProblemCharacteristicValues());
511 
512  Ippl::Comm->barrier();
515  delete gmsg;
516 
517 #ifdef ENABLE_AMR
518  if ( initAMR ) {
519  amrex::Finalize(true);
520  }
521 #endif
522 
523  delete ippl;
524  delete Ippl::Info;
525  delete Ippl::Warn;
526  delete Ippl::Error;
527  delete Ippl::Debug;
528 
529  return 0;
530 }
static void deleteInstance()
Definition: OpalData.cpp:219
The global OPAL structure.
Definition: OpalData.h:54
IpplInfo Ippl
Definition: IpplInfo.h:410
Ippl * ippl
Definition: Main.cpp:20
A stream of input tokens.
static void clearDictionary()
Definition: Fieldmap.cpp:271
#define INFORM_ALL_NODES
Definition: Inform.h:38
void setRestartRun(const bool &value=true)
set OPAL in restart mode
Definition: OpalData.cpp:340
The base class for all OPAL exceptions.
Definition: OpalException.h:28
bool inRestartRun()
true if we do a restart run
Definition: OpalData.cpp:336
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
void storeInputFn(const std::string &fn)
store opals input filename
Definition: OpalData.cpp:700
Inform * gmsg
Definition: Main.cpp:21
static bool DKSEnabled
Definition: IpplInfo.h:285
static Inform * Warn
Definition: IpplInfo.h:88
void barrier(void)
bool echo
Echo flag.
Definition: Options.cpp:7
static int myNode()
Definition: IpplInfo.cpp:794
The default parser for OPAL-9.
Definition: OpalParser.h:44
FRONT * fs
Definition: hypervolume.cpp:59
virtual const char * where() const
const char * what()
Definition: PAssert.h:66
The abstract base class for all exceptions in CLASSIC.
std::string date() const
Return date.
Definition: Timer.cpp:35
virtual const std::string & where() const
Definition: IpplException.h:19
static OpalData * getInstance()
Definition: OpalData.cpp:209
static Inform * Debug
Definition: IpplInfo.h:90
static void printVersion(bool=false)
Definition: IpplInfo.cpp:839
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187
#define INFOMSG(msg)
Definition: IpplInfo.h:397
#define OPAL_PROJECT_VERSION
Definition: OPALconfig.h:5
virtual const std::string & what() const
Return the message string for the exception.
static MPI_Comm getComm()
Definition: IpplInfo.h:178
arg(a))
void configure()
Configure all commands.
Definition: Configure.cpp:303
#define OPAL_COMPILE_OPTIONS
Definition: OPALconfig.h:11
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:601
static void printHelp(char **argv)
Definition: IpplInfo.cpp:850
static void setEcho(bool flag)
Set echo flag.
Definition: FileStream.cpp:47
A stream of input tokens.
Definition: FileStream.h:32
static Inform * Error
Definition: IpplInfo.h:89
static const char * compileOptions()
Definition: IpplInfo.cpp:950
std::string time() const
Return time.
Definition: Timer.cpp:42
#define DKS_VERSION
Definition: OPALconfig.h:17
static Inform * Info
Definition: IpplInfo.h:87
int main(int argc, char *argv[])
Definition: Main.cpp:107
#define PACKAGE_BUGREPORT
Definition: OPALconfig.h:14
static void setGlobalTruncOrder(int order)
Set the global truncation order.
Definition: FTps.hpp:419
void storeArguments(int argc, char *argv[])
Definition: OpalData.cpp:830
void setRestartFileName(std::string s)
store opals restart h5 format filename
Definition: OpalData.cpp:359
std::string getGitRevision()
Definition: Util.cpp:15
virtual const char * what() const
Definition: IpplException.h:15
virtual const char * what() const
static void print()
Definition: IpplTimings.h:207
Timing::TimerRef TimerRef
Definition: IpplTimings.h:176
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:717
Definition: Inform.h:41
static Communicate * Comm
Definition: IpplInfo.h:93
bool checkInitAmrFlag(int argc, char *argv[])
Definition: Main.cpp:93
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void setRestartStep(int s)
store the location where to restart
Definition: OpalData.cpp:345
virtual const std::string & where() const
Return the name of the method or function which detected the exception.