Sierra Toolkit  Version of the Day
Env.cpp
1 
10 #include <pwd.h>
11 #include <unistd.h>
12 
13 #include <ostream>
14 #include <fstream>
15 #include <sstream>
16 #include <string>
17 #include <cstring>
18 #include <cstdlib>
19 #include <stdexcept>
20 #include <numeric>
21 #include <iomanip>
22 #include <algorithm>
23 #include <locale>
24 #include <map>
25 
26 #include <stk_util/util/Null_Streambuf.hpp>
27 #include <stk_util/parallel/mpi_filebuf.hpp>
28 
29 #include <stk_util/diag/Timer.hpp>
30 #include <stk_util/diag/Writer.hpp>
31 #include <stk_util/diag/WriterRegistry.hpp>
32 #include <stk_util/diag/Env.hpp>
33 #include <stk_util/diag/Platform.hpp>
34 #include <stk_util/diag/Signal.hpp>
36 #include <stk_util/parallel/ExceptionReport.hpp>
37 #include <stk_util/parallel/MPI.hpp>
39 #include <stk_util/environment/ProductRegistry.hpp>
40 #include <stk_util/diag/StringUtil.hpp>
43 #include <stk_util/diag/PreParse.hpp>
44 
46 #include <stk_util/environment/ProgramOptions.hpp>
48 #include <stk_util/parallel/BroadcastArg.hpp>
49 #include <stk_util/parallel/ParallelReduce.hpp>
50 #include <stk_util/util/Bootstrap.hpp>
51 #include <stk_util/util/IndentStreambuf.hpp>
52 
53 namespace sierra {
54 namespace Env {
55 
56 namespace {
57 
58 void bootstrap()
59 {
60  // Add my command line options to the option descriptions.
61  boost::program_options::options_description desc("Runtime environment", 120);
62  desc.add_options()
63  ("help,h", "Display command line options")
64  ("directory,d", boost::program_options::value<std::string>()->default_value("./"), "Set working directory")
65  ("output-log,o", boost::program_options::value<std::string>()->default_value(""), "Output log file path, one of : 'cout', 'cerr', or a file path")
66  ("logfile,l", boost::program_options::value<std::string>()->default_value(""), "Output log file path, one of : 'cout', 'cerr', or a file path")
67  ("pout", boost::program_options::value<std::string>()->implicit_value("-"), "Per-processor log file path")
68  ("dout", boost::program_options::value<std::string>()->implicit_value("out"), "Diagnostic output stream one of: 'cout', 'cerr', 'out' or a file path")
69 // ("timer", boost::program_options::value<std::string>(), "Wall and CPU time options") // , &Diag::Timer::theTimerParser())
70  ("version", "Display version information")
71  ("jamsub", boost::program_options::value<std::string>(), "Display user subroutine build command")
72  ("runtest", boost::program_options::value<std::string>()->implicit_value("pid"), "Record process host and pid to this file")
73  ("developer-mode", "Activate developer specific features")
74  ("architecture", boost::program_options::value<std::string>(), "Specifies the architecture running the sierra application");
75 
77 }
78 
79 stk_classic::Bootstrap x(&bootstrap);
80 
81 struct EnvData
82 {
83  typedef std::map<ExecType, ExecInfo> ExecMap;
84 
85  static EnvData &instance() {
86  static EnvData s_env;
87 
88  return s_env;
89  }
90 
91  EnvData()
92  : m_productName("not specified"),
94  m_nullBuf(),
95  m_outputNull(&m_nullBuf),
96  m_outputP0(&std::cout),
97  m_output(),
98  m_startTime((double) ::time(NULL)),
99  m_executablePath(),
100  m_shutdownRequested(false),
101  m_inputFileRequired(true),
102  m_checkSubCycle(false),
103  m_worldComm(MPI_COMM_NULL),
104  m_parallelComm(MPI_COMM_NULL),
105  m_parallelSize(-1),
106  m_parallelRank(-1),
107  m_emptyString(),
108  m_onString(PARAM_ON),
109  m_inputFile("")
110  {
111  m_execMap[EXEC_TYPE_LAG].m_master = -1;
112  m_execMap[EXEC_TYPE_LAG].m_groupComm = MPI_COMM_NULL;
113  m_execMap[EXEC_TYPE_LAG].m_interComm = MPI_COMM_NULL;
114  m_execMap[EXEC_TYPE_FLUID].m_master = -1;
115  m_execMap[EXEC_TYPE_FLUID].m_groupComm = MPI_COMM_NULL;
116  m_execMap[EXEC_TYPE_FLUID].m_interComm = MPI_COMM_NULL;
117  stk_classic::register_log_ostream(std::cout, "cout");
118  stk_classic::register_log_ostream(std::cerr, "cerr");
119 
124 
125  static_cast<stk_classic::indent_streambuf *>(sierra::dwout().rdbuf())->redirect(sierra::dout().rdbuf());
126  }
127 
128  ~EnvData()
129  {
130  static_cast<stk_classic::indent_streambuf *>(sierra::dwout().rdbuf())->redirect(std::cout.rdbuf());
131 
136 
139  }
140 
141  std::string m_productName;
142 
143  boost::program_options::variables_map & m_vm;
144 
145  null_streambuf m_nullBuf;
146  std::ostream m_outputNull;
147  std::ostream * m_outputP0;
148  std::ostringstream m_output;
149 
150  double m_startTime;
151  std::string m_executablePath;
152 
153  bool m_shutdownRequested;
154  bool m_inputFileRequired;
155  bool m_checkSubCycle;
156 
157  MPI_Comm m_worldComm;
158 
159  MPI_Comm m_parallelComm;
160  int m_parallelSize;
161  int m_parallelRank;
162 
163  ExecMap m_execMap;
164 
165  const std::string m_emptyString;
166  const std::string m_onString;
167 
168  std::string m_inputFile;
169 };
170 
171 } // namespace <unnamed>
172 
173 const std::string &
175 {
176  return EnvData::instance().m_productName;
177 }
178 
179 
180 const std::string &
182 {
183  return EnvData::instance().m_executablePath;
184 }
185 
186 
187 const std::string &
189 {
190  static std::string executable_date;
191 
192  if (executable_date.empty())
193  executable_date = ProductRegistry::instance().getProductAttribute(EnvData::instance().m_productName, ProductRegistry::BUILD_TIME);
194 
195  return executable_date;
196 }
197 
198 
199 const std::string &
201 {
202  static std::string startup_date;
203 
204  if (startup_date.empty())
205  startup_date = format_time(EnvData::instance().m_startTime).c_str();
206 
207  return startup_date;
208 }
209 
210 
211 double
213 {
214  return EnvData::instance().m_startTime;
215 }
216 
217 
218 bool
220 {
221  return !get_param("developer-mode").empty();
222 }
223 
224 
225 void setInputFileName(std::string name) {
226  EnvData::instance().m_inputFile = name;
227 }
228 
229 std::string getInputFileName() {
230  return EnvData::instance().m_inputFile;
231 }
232 
233 void set_input_file_required(bool value)
234 {
235  EnvData::instance().m_inputFileRequired = value;
236 }
237 
238 void set_check_subcycle(bool value)
239 {
240  EnvData::instance().m_checkSubCycle = value;
241 }
242 
243 
244 const std::string &
246 {
247  return get_param("architecture");
248 }
249 
250 
251 const std::string
253  char cwd[PATH_MAX];
254  std::string directory = get_param("directory");
255  if (directory[0] != '/' && getcwd(cwd, PATH_MAX) != NULL) {
256  directory = cwd;
257  directory += '/';
258  }
259  return directory;
260 }
261 
262 
263 std::ostream &
265 {
266  return EnvData::instance().m_output;
267 }
268 
269 
270 std::ostream &
272 {
273  return *EnvData::instance().m_outputP0;
274 }
275 
276 
277 std::ostream &
279  return EnvData::instance().m_outputNull;
280 }
281 
282 
283 const char *
285 {
286  static const char *s_sectionSeparator = "+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----";
287 
288  return s_sectionSeparator;
289 }
290 
291 
292 const char *
294 {
295  static const char *s_subsectionSeparator = "---------------------------------------------------";
296 
297  return s_subsectionSeparator;
298 }
299 
300 
301 std::string
303  const std::string & title)
304 {
305  static size_t s_sectionSeparatorLength = std::strlen(section_separator());
306 
307  std::ostringstream strout;
308 
309  strout << std::left << std::setw(s_sectionSeparatorLength - 20) << title << std::right << std::setw(20) << format_time(Env::wall_now());
310  return strout.str();
311 }
312 
313 
315  return EnvData::instance().m_parallelSize;
316 }
317 
319  return EnvData::instance().m_parallelRank;
320 }
321 
322 MPI_Comm
324 {
325  return EnvData::instance().m_parallelComm;
326 }
327 
328 MPI_Comm
330 {
331  return EnvData::instance().m_worldComm;
332 }
333 
335  return EnvData::instance().m_execMap[EXEC_TYPE_LAG].m_master;
336 }
337 
339  return EnvData::instance().m_execMap[EXEC_TYPE_FLUID].m_master;
340 }
341 
342 int peer_group() {
343  return EnvData::instance().m_execMap[EXEC_TYPE_PEER].m_master;
344 }
345 
346 std::string
347 get_program_path(const char *program)
348 {
349  // If we already have the full path, just return it
350  if (program[0] == '/')
351  return program;
352 
353  char full_path[PATH_MAX];
354  if (strchr(program, '/') != NULL) {
355  realpath(program, full_path);
356  return full_path;
357  }
358 
359  char *PATH = getenv("PATH");
360  while (PATH && *PATH) {
361  // Get the character past the end of the next directory in PATH, i.e.
362  // either the '/' or the '\0'
363  char *end = strchr(PATH, ':');
364  if (!end) {
365  end = PATH+strlen(PATH);
366  }
367 
368  // Set current = directory + '/' + program
369  strncpy(full_path, PATH, end-PATH);
370  full_path[end-PATH] = '/';
371  strcpy(&full_path[end-PATH+1], program);
372 
373  // Check whether possible exists
374  if (access(full_path, X_OK) == 0)
375  return full_path;
376 
377  // Advance to the next directory
378  PATH = *end ? end+1 : end;
379  }
380 
381  // Not found; this shouldn't happen, but maybe the executable got deleted
382  // after it was invoked before we got here -- or we have some crazy
383  // parallel machine where the executable is inaccessible on the compute
384  // nodes despite it somehow having been loaded. No big deal, just return
385  // the non-absolute path.
386  return program;
387 }
388 
389 void parse_options(MPI_Comm comm, int *argc, char ***argv);
390 void startup_multi_exec(MPI_Comm world_comm, ExecType my_executable_type, const std::vector<int> *peer_sizes);
391 
392 
393 
394 bool StartupSierra(int * argc,
395  char *** argv,
396  const char * product_name,
397  const char * build_time,
398  ExecType mpi_key,
399  const std::vector<int> *peer_sizes) {
400  bool returnValue = false;
401 
403 
404  EnvData &env_data = EnvData::instance();
405 
406  env_data.m_executablePath = get_program_path(*argv[0]);
407  env_data.m_productName = product_name;
408 
409  ProductRegistry::instance().setProductName(product_name);
410 
411  ProductRegistry::AttributeMap &product_attributes = ProductRegistry::instance().getProductAttributeMap(product_name);
412  product_attributes[ProductRegistry::BUILD_TIME] = build_time;
413  product_attributes[ProductRegistry::EXECUTABLE] = env_data.m_executablePath;
414 
415  // Add Utility runtime library to the product registry
416  sierra::register_product();
417 
418  // Add mpih to the product registry
419  sierra::mpih::register_product();
420 
421  // Add operating system information to the product registry.
422  ProductRegistry::AttributeMap &attr_map = ProductRegistry::instance().addProduct(osname().c_str());
423  attr_map[ProductRegistry::VERSION] = osversion().c_str();
424 
425  // Process the broadcast command line arguments
426  namespace opt = boost::program_options;
427 
428  opt::variables_map &vm = stk_classic::get_variables_map();
429  opt::options_description &od = stk_classic::get_options_description();
430  {
431  boost::program_options::options_description desc("Diagnostic writers", 120);
432 
433  for (Diag::WriterRegistry::iterator it = Diag::getWriterRegistry().begin(); it != Diag::getWriterRegistry().end(); ++it) {
434  std::ostringstream str;
435  str << "Diagnostic writer " << (*it).first << std::endl;
436  (*it).second.second->describe(str);
437  desc.add_options()((*it).first.c_str(), boost::program_options::value<std::string>(), str.str().c_str());
438  }
439 
440  std::ostringstream str;
441  str << "Wall and CPU time options" << std::endl;
442  Diag::theTimerParser().describe(str);
443  desc.add_options()("timer", boost::program_options::value<std::string>(), str.str().c_str());
444 
445  od.add(desc);
446  }
447 
448  for (int i = 0; i < *argc; ++i) {
449  const std::string s((*argv)[i]);
450  if (s == "-h" || s == "-help" || s == "--help") {
451  std::cout << std::endl
452  << "Sierra Usage: sierra " << lower(product_name) << " [sierra-options...] -O \"[" << lower(product_name) << "-options...]\"" << std::endl << std::endl
453 // << "Usage: (MPI run) " << env_data.m_executablePath << " [options...]" << std::endl
454  << "For example:" << std::endl
455  << "" << std::endl
456  << " sierra " << lower(product_name) << " -i input_deck.i -o sierra.log" << std::endl
457  << " This creates the normal output file sierra.log" << std::endl
458  << "" << std::endl
459  << " sierra " << lower(product_name) << " -i input_deck.i -o sierra.log -O \"--pout=pp.log\"" << std::endl
460  << " The per-processor output is written to pp.log.n.r for each rank, r, of n processors." << std::endl
461  << "" << std::endl
462  << " sierra " << lower(product_name) << " -i input_deck.i -o sierra.log -O \"--fmwkout=field,parameters\"" << std::endl
463  << " Enable the framework field and parameter diagnostics" << std::endl
464  << "" << std::endl
465  << " sierra " << lower(product_name) << " -i input_deck.i -o sierra.log -O \"--timer=all\"" << std::endl
466  << " Enable the all timers" << std::endl
467  << std::endl
468  << " For additional information see:" << std::endl
469  << " http://sierra-dev.sandia.gov/stk/group__stk__util__output__log__detail.html#stk_util_output_log_howto_use_in_sierra_app" << std::endl << std::endl
470  << product_name << " options are:" << std::endl
471  << stk_classic::get_options_description() << std::endl;
472  std::exit(0);
473  }
474  }
475 
476  for (int i = 0; i < *argc; ++i) {
477  const std::string s((*argv)[i]);
478  if (s == "-jamsub" || s == "--jamsub") {
479  const char *t = (*argv)[i + 1];
480  const char **symbol = sierra::Plugin::Registry::getsym<const char **>(t);
481  if (symbol) {
482  std::cout << *symbol << std::endl;
483  std::exit(0);
484  }
485  else
486  std::exit(1);
487  }
488  }
489 
490  try {
492 
493  // Communicator has not been set, initialize MPI if not already initialized
494  int mpi_init_val = 0 ;
495  if ( MPI_SUCCESS != MPI_Initialized( &mpi_init_val ) ) {
496  throw RuntimeError() << "MPI_Initialized failed";
497  }
498 
499  // Default startup communicator
500  MPI_Comm startup_mpi_comm = MPI_COMM_WORLD;
501 
502  // If we are initializing the comm, see if there are differing
503  // executables running. If there are, find our partition and the
504  // leads of the other partitions.
505  if ( mpi_init_val == 0 ) {
506  if ( MPI_SUCCESS != MPI_Init( argc , argv ) ) {
507  throw RuntimeError() << "MPI_Init failed";
508  }
509 
510  returnValue = true ;
511 
512  if (mpi_key != EXEC_TYPE_WORLD) startup_multi_exec(startup_mpi_comm, mpi_key, peer_sizes);
513  }
514 
515  // Ready to reset the environment from NULL, we are the Lagrangian application at this point.
516  MPI_Comm new_comm = mpi_key != EXEC_TYPE_WORLD ? env_data.m_execMap[mpi_key].m_groupComm : MPI_COMM_WORLD;
517  reset(new_comm);
518  }
519  catch (const std::exception &x) {
520  std::cerr << "SIERRA execution failed during mpi initialization with the following exception:" << std::endl
521  << x.what() << std::endl;
522  MPI_Abort(env_data.m_parallelComm , MPI_ERR_OTHER);
523  }
524  catch (...) {
525  std::cerr << "SIERRA execution failed during mpi initialization with unknown exception:" << std::endl;
526 
527  MPI_Abort(env_data.m_parallelComm, MPI_ERR_OTHER);
528  }
529 
530  parse_options(env_data.m_parallelComm, argc, argv);
531 
532  {
533  std::ostringstream output_description;
534 
535  // On processor 0:
536  // [outfile=path] [poutfile=path.n.r] [doutfile=path.n.r] out>{-|cout|cerr|outfile}+pout pout>{null|poutfile} dout>{out|doutfile}
537 
538  // On processor 1..n:
539  // [poutfile=path.n.r] [doutfile=path.n.r] out>pout pout>{null|poutfile} dout>{out|doutfile}
540 
541  std::string out_path1 = vm["output-log"].as<std::string>();
542  std::string out_path2 = vm["logfile"].as<std::string>();
543 
544 
545 
546  std::string originalFileName = Env::get_param("input-deck");
547  std::string modifiedFileName = originalFileName;
548 
549  if(originalFileName == "") {
550  //
551  // If no input file specified, error out (unless just running the --version or --help option)
552  //
553  if ( get_param("version").empty() && get_param("help").empty() ) {
554  if (env_data.m_inputFileRequired) {
555  throw RuntimeError() << "No input file specified. An input file must be specified with the '-i' option";
556  } else {
557  std::cerr << "WARNING: No input file specified. An input file should be specified with the '-i' option!" << std::endl;
558  }
559  }
560  } else if ( env_data.m_checkSubCycle ) {
561  // Alter input-deck if subcycle present
562  bool debugSubCycleSplit = false;
563  std::string subCycleRegexp("^\\s*subcycle\\s+blocks\\s*=");
564  bool subCycleSet = CaseInSensitiveRegexInFile(subCycleRegexp, originalFileName, debugSubCycleSplit);
565  std::string coarseRegionRegexp("^\\s*begin\\s+presto\\s+region\\s+\\w+_AutoCoarseRegion\\>");
566  bool coarseRegionMade = CaseInSensitiveRegexInFile( coarseRegionRegexp, originalFileName, debugSubCycleSplit);
567  std::string fineRegionRegexp("^\\s*begin\\s+presto\\s+region\\s+\\w+_AutoFineRegion\\>");
568  bool fineRegionMade = CaseInSensitiveRegexInFile( fineRegionRegexp, originalFileName, debugSubCycleSplit);
569  if ( subCycleSet ) {
570  if ( !coarseRegionMade && !fineRegionMade ) {
571  modifiedFileName = CreateSubCycleInputFile( originalFileName );
572  } else {
573  if(Env::parallel_rank() == 0) {
574  std::cout<<"Input File: " << originalFileName << " Appears to have already been converted for subcycling. ";
575  std::cout<<"Skipping input conversion " << std::endl;
576  }
577  }
578  }
579  }
580 
581  setInputFileName(modifiedFileName);
582 
583 
584  std::string trueOut;
585  if(out_path2 != "") {
586  trueOut = out_path2;
587  } else if(out_path1 != "") {
588  //
589  // Old syntax compatibility, access the old output-file executable option if the logfile is not defined
590  //
591  trueOut = out_path1;
592  } else {
593  //
594  // If log file name is unspecified, default it to (Base Input File Name).log
595  // Use the following logic:
596  // If the input file has an extension, replace the last ".extension" with ".log"
597  // If the input file has no extension, append ".log" to the input file name
598  // If the input file contains the word '.aprepro', assume aprepro was used to convert and strip out the aprepro
599  // If the input file contains any directory movement (like ../) strip them out so log file is written to current director
600  //
601 
602  int dotPos = originalFileName.rfind(".");
603 
604  if(dotPos == -1) { //No extension
605  trueOut = originalFileName + ".log";
606  } else { //Extension found
607  trueOut = originalFileName.substr(0, dotPos) + ".log";
608  }
609  //
610  // If the output path contains a ".aprepro" tag get rid of it
611  //
612  int apreproPos = trueOut.rfind(".aprepro");
613  if(apreproPos != -1) {
614  trueOut.erase(apreproPos, 8);
615  }
616  //
617  // If the output path contains a "aaa/input.i" pull off the initial directory redirects so that the log file is written int the current directory
618  //
619  int lastSlashPos = trueOut.rfind("/");
620 
621  if(lastSlashPos != -1) {
622  trueOut.erase(0,lastSlashPos+1);
623  }
624 
625 
626  }
627 
628  std::string out_path = trueOut;
629 
630  if (out_path == "-")
631  out_path = "cout";
632 
633  std::string out_ostream;
634 
635  if (!stk_classic::get_log_ostream(out_path))
636  if (out_path.size() && out_path[0] != '/')
637  out_path = working_directory() + out_path;
638 
639  if (parallel_rank() == 0) {
640  if (!stk_classic::get_log_ostream(out_path)) {
641  output_description << "outfile=\"" << out_path << "\"";
642  out_ostream = "outfile";
643  }
644  else {
645  out_ostream = out_path;
646  }
647  }
648  else
649  out_ostream = "null";
650 
651  std::string pout_ostream = "null";
652  if (vm.count("pout")) {
653  std::string pout_path = vm["pout"].as<std::string>();
654  if (pout_path == "-") {
655  std::ostringstream s;
656 
657  if (stk_classic::get_log_ostream(out_path))
658  s << working_directory() << "sierra.log." << parallel_size() << "." << parallel_rank();
659  else
660  s << out_path << "." << parallel_size() << "." << parallel_rank();
661  pout_path = s.str();
662  }
663  else if (pout_path.find("/") == std::string::npos && !stk_classic::get_log_ostream(pout_path)) {
664  std::ostringstream s;
665 
666  s << working_directory() << pout_path << "." << parallel_size() << "." << parallel_rank();
667  pout_path = s.str();
668  }
669 
670  if (!stk_classic::get_log_ostream(pout_path)) {
671  output_description << " poutfile=\"" << pout_path << "\"";
672  pout_ostream = "poutfile";
673  }
674  else
675  pout_ostream = pout_path;
676  }
677 
678 
679  std::string dout_ostream;
680  if (vm.count("dout")) {
681  std::string dout_path = vm["dout"].as<std::string>();
682  if (!dout_path.empty() && stk_classic::is_registered_ostream(dout_path))
683  dout_ostream = dout_path;
684  else {
685  std::ostringstream s;
686  if (dout_path.size() && dout_path[0] != '/')
687  s << working_directory() << dout_path << "." << parallel_size() << "." << parallel_rank();
688  else
689  s << dout_path << parallel_size() << "." << parallel_rank();;
690  dout_path = s.str();
691  output_description << " doutfile=\"" << dout_path << "\"";
692  dout_ostream = "doutfile";
693  }
694  }
695  else
696  dout_ostream = "out";
697 
698  if (parallel_rank() == 0)
699  output_description << " out>" << out_ostream << "+pout";
700  else
701  output_description << " out>pout";
702 
703  output_description << " pout>" << pout_ostream << " dout>" << dout_ostream;
704 
705 
706  stk_classic::bind_output_streams(output_description.str());
707  }
708 
709  env_data.m_outputP0 = &sierra::out();
710 
711 #ifdef SIERRA_EXPORT_CONTROL_EAR99
712  // If you are using an EAR99 export controlled version of Sierra,
713  // any attempt to modify or bypass this section of code is a
714  // violation of U.S. Export Control Regulations and subject to
715  // criminal prosecution.
716  if (parallel_size() > SIERRA_EXPORT_CONTROL_EAR99) {
717  if (parallel_rank() == 0) {
718  std::cerr << "ERROR: You are running an EAR99 export controlled version of\n";
719  std::cerr << " Sierra. For this export control level, a maximum of\n";
720  std::cerr << " "<<SIERRA_EXPORT_CONTROL_EAR99<<" processors is permitted\n";
721  }
722  MPI_Abort(env_data.m_parallelComm, MPI_ERR_OTHER);
723  }
724 #endif
725 
726  try {
727  // Create pid file if runtest command line option specified
728  if ( !get_param("runtest").empty() ) {
729 
730  mpi_filebuf mpi_buf;
731 
732  mpi_buf.open(env_data.m_parallelComm, 0, std::ios::out, get_param("runtest").c_str());
733 
734  if ( ! mpi_buf.is_open() )
735  throw RuntimeError() << "failed to open pid file " << get_param("runtest");
736 
737  std::ostream s( &mpi_buf );
738  s << parallel_rank() << ":" << hostname() << domainname() << ":" << pid() << ":" << pgrp() << std::endl;
739  }
740 
741  // Enable the timers
742  if (!get_param("timer").empty()) {
743  Diag::TimerParser parser;
744 
745  Diag::sierraTimerSet().setEnabledTimerMask(parser.parse(get_param("timer").c_str()));
746  }
747 
748  // Enable parallel exception handling, waited until now because it needs the Env output streams
750  }
751  catch (const std::exception &x) {
752  std::cerr << "SIERRA execution failed during diagnostic and timer initialization with the following exception:" << std::endl
753  << x.what() << std::endl;
754  abort();
755  }
756  catch (...) {
757  std::cerr << "SIERRA execution failed during diagnostic and timer initialization with unknown exception:" << std::endl;
758  abort();
759  }
760 
761 // Setup the hangup, segmentation violation, illegal instruction, bus error and
762 // terminate signal handlers.
763  if (get_param("nosignal").empty())
765 
766 
767  return returnValue;
768 }
769 
770 
771 
772 
773 void
774 Startup::startup(
775  int * argc,
776  char *** argv,
777  const char * product_name,
778  const char * build_time,
779  ExecType mpi_key,
780  const std::vector<int> *peer_sizes) {
781  m_mpiInitFlag = StartupSierra(argc, argv, product_name, build_time, mpi_key, peer_sizes);
782 }
783 
784 
786  int * argc,
787  char *** argv,
788  const char * product_name,
789  const char * build_date_time,
790  ExecType mpi_key,
791  const std::vector<int> *peer_sizes)
792  : m_mpiInitFlag(false)
793 {
794  startup(argc, argv, product_name, build_date_time, mpi_key, peer_sizes);
795 }
796 
797 
798 void ShutDownSierra(bool mpiInitFlag) {
799  if (get_param("nosignal").empty())
801 
802  mpih::Delete_Handles();
803 
804  EnvData &env_data = EnvData::instance();
805  mpih::Keyval_delete(env_data.m_parallelComm);
806 
807  reset(MPI_COMM_NULL);
808 
809  if (mpiInitFlag)
810  MPI_Finalize();
811 }
812 
813 
814 
816  ShutDownSierra(m_mpiInitFlag);
817 }
818 
819 
820 void parse_options(MPI_Comm comm,
821  int * argc,
822  char *** argv)
823 {
824  try {
825  char ** argv2 = new char *[*argc];
826  for (int i = 0; i < *argc; ++i) {
827  if (std::strlen((*argv)[i]) > 2 && (*argv)[i][0] == '-' && (*argv)[i][1] != '-') {
828  argv2[i] = new char[std::strlen((*argv)[i]) + 2];
829  argv2[i][0] = '-';
830  std::strcpy(&argv2[i][1], (*argv)[i]);
831  }
832  else {
833  argv2[i] = new char[std::strlen((*argv)[i]) + 1];
834  std::strcpy(argv2[i], (*argv)[i]);
835  }
836  }
837 
838  // Broadcast argc and argv to all processors.
839  stk_classic::BroadcastArg b_arg(comm, *argc, argv2);
840 
841  for (int i = 0; i < *argc; ++i)
842  delete[] argv2[i];
843  delete[] argv2;
844 
845  namespace opt = boost::program_options;
846  opt::variables_map &vm = stk_classic::get_variables_map();
847  opt::options_description &od = stk_classic::get_options_description();
848  opt::store(opt::parse_command_line(b_arg.m_argc, b_arg.m_argv, od, opt::command_line_style::unix_style), vm);
849  opt::notify(vm);
850 
851  for (Diag::WriterRegistry::iterator it = Diag::getWriterRegistry().begin(); it != Diag::getWriterRegistry().end(); ++it)
852  if (vm.count((*it).first.c_str()))
853  (*it).second.second->parse(vm[(*it).first.c_str()].as<std::string>().c_str());
854 
855 
856  // Must have a working directory
857  const std::string &working_dir = get_param("directory");
858  if ( working_dir.empty() || working_dir == PARAM_ON )
859  throw RuntimeError() << "working directory must be specified";
860  if (working_dir[working_dir.length() - 1] != '/')
861  const_cast<std::string &>(working_dir) += '/';
862 
863  }
864  catch (const std::exception &x) {
865  std::cerr << "SIERRA execution failed during command line processing with the following exception:" << std::endl
866  << x.what() << std::endl;
867  MPI_Abort(comm, MPI_ERR_OTHER);
868  }
869  catch (...) {
870  std::cerr << "SIERRA execution failed during command line processing with unknown exception:" << std::endl;
871 
872  MPI_Abort(comm, MPI_ERR_OTHER);
873  }
874 }
875 
876 void
877 startup_multi_exec(MPI_Comm world_comm,
878  ExecType my_executable_type,
879  const std::vector<int> *peer_sizes) // can be NULL.
880 {
881  EnvData &env_data = EnvData::instance();
882 
883  // MPI interface construction
884  int world_size = -1 ;
885  int world_rank = -1 ;
886 
887  if ( MPI_Comm_size(world_comm, &world_size) != MPI_SUCCESS)
888  throw RuntimeError() << "MPI_Comm_size failed";
889 
890  if ( MPI_Comm_rank(world_comm, &world_rank) != MPI_SUCCESS || -1 == world_rank )
891  throw RuntimeError() << "MPI_Comm_rank failed";
892 
893  if (my_executable_type == EXEC_TYPE_FLUID || my_executable_type == EXEC_TYPE_LAG) {
894  // This is specific for gemini. Gemini performs three broadcasts, one for the
895  // EXEC_TYPE_FLUID and one for the EXEC_TYPE_LAG. Also note that the ranks of processors must
896  // be ordered such that all gemini processors come first. Gemini mandates that it;s master is
897  // processor 0 and use ranks through its size.
898  int lag_master = 0;
899  int lag_rank_size = -1;
900  int fluid_master = 0;
901 
902  if (world_rank == 0) {
903  typedef std::map<ExecType, std::vector<int> > ExecTypeRanks;
904 
905  ExecTypeRanks exec_type_ranks;
906 
907  exec_type_ranks[my_executable_type].push_back(0);
908 
909  for (int i = 1; i < world_size; ++i) {
910  MPI_Status status;
911  int proc_stat[2]; // rank, ExecType
912  if (MPI_Recv(proc_stat, 2, MPI_INTEGER, i, MPI_ANY_TAG, world_comm, &status) != MPI_SUCCESS)
913  throw RuntimeError() << "MPI_Recv failed";
914 
915  exec_type_ranks[(ExecType) proc_stat[1]].push_back(proc_stat[0]);
916  }
917 
918  std::vector<int> &fluid_ranks = exec_type_ranks[EXEC_TYPE_FLUID];
919  if (fluid_ranks.size())
920  fluid_master = fluid_ranks.front();
921 
922  if (MPI_Bcast(&fluid_master, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
923  throw RuntimeError() << "MPI_Bcast failed";
924 
925  std::vector<int> &lag_ranks = exec_type_ranks[EXEC_TYPE_LAG];
926  if (lag_ranks.size())
927  lag_master = lag_ranks.front();
928 
929  if (MPI_Bcast(&lag_master, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
930  throw RuntimeError() << "MPI_Bcast failed";
931 
932  lag_rank_size = lag_ranks.size();
933  if (MPI_Bcast(&lag_rank_size, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
934  throw RuntimeError() << "MPI_Bcast failed";
935  }
936  else {
937  int proc_stat[2];
938  proc_stat[0] = world_rank;
939  proc_stat[1] = my_executable_type;
940 
941  if (MPI_Send(proc_stat, 2, MPI_INTEGER, 0, 0, world_comm) != MPI_SUCCESS)
942  throw RuntimeError() << "MPI_Send failed";
943 
944  if (MPI_Bcast(&fluid_master, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
945  throw RuntimeError() << "MPI_Bcast failed";
946 
947  if (MPI_Bcast(&lag_master, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
948  throw RuntimeError() << "MPI_Bcast failed";
949 
950  if (MPI_Bcast(&lag_rank_size, 1, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
951  throw RuntimeError() << "MPI_Bcast failed";
952  }
953 
954  MPI_Comm lag_comm = world_comm;
955  MPI_Comm fluid_comm = MPI_COMM_NULL;
956  const int fluid_rank_size = world_size - lag_rank_size;
957  if (fluid_rank_size) {
958 
959  MPI_Group world_group;
960  MPI_Group lag_group;
961  MPI_Group fluid_group;
962 
963  if (MPI_Comm_group(world_comm, &world_group) != MPI_SUCCESS)
964  throw RuntimeError() << "MPI_Comm_group failed";
965 
966  std::vector<int> lag_ranks;
967  for (int i = 0; i < lag_rank_size; ++i)
968  lag_ranks.push_back(lag_master + i);
969 
970  if (MPI_Group_incl(world_group, lag_ranks.size(), &lag_ranks[0], &lag_group) != MPI_SUCCESS)
971  throw RuntimeError() << "MPI_Group_incl failed";
972  if (MPI_Comm_create(world_comm, lag_group, &lag_comm) != MPI_SUCCESS)
973  throw RuntimeError() << "MPI_Comm_create failed";
974 
975  std::vector<int> fluid_ranks;
976  for (int i = 0; i < fluid_rank_size; ++i)
977  fluid_ranks.push_back(fluid_master + i);
978 
979  if (MPI_Group_incl(world_group, fluid_ranks.size(), &fluid_ranks[0], &fluid_group) != MPI_SUCCESS)
980  throw RuntimeError() << "MPI_Group_incl failed";
981  if (MPI_Comm_create(world_comm, fluid_group, &fluid_comm) != MPI_SUCCESS)
982  throw RuntimeError() << "MPI_Comm_create failed";
983  }
984 
985  env_data.m_worldComm = world_comm;
986  env_data.m_execMap[EXEC_TYPE_LAG].m_master = lag_master;
987  env_data.m_execMap[EXEC_TYPE_LAG].m_groupComm = lag_comm;
988  env_data.m_execMap[EXEC_TYPE_FLUID].m_master = fluid_master;
989  env_data.m_execMap[EXEC_TYPE_FLUID].m_groupComm = fluid_comm;
990  }
991  else if (my_executable_type == EXEC_TYPE_PEER) {
992  // This executable will run on 2 or more communicators.
993 
994  // NOTE: Only 2 communicators is currently supported...
995 
996  // If peer_sizes is NULL, then split world_comm into two equal
997  // size communicators (peer(1) is larger if world_comm size is
998  // odd)
999  // If peer_sizes is not NULL, then split world_comm into
1000  // peer_sizes.size() sub communicators with peer(i) of size
1001  // peer_sizes(i).
1002 
1003  // Sync 'peer_sizes' across all processors if non-null
1004  // For now, we limit the number of peer applications to 2.
1005 
1006  if (peer_sizes != NULL && peer_sizes->size() > 2) {
1007  throw RuntimeError() << "The total number of peer application processor sizes specfied is "
1008  << peer_sizes->size()
1009  << ", but the current limit is 2.";
1010  }
1011 
1012  // Peer sizes is only set correctly on processor 0 since it was passed in by the
1013  // main routine prior to MPI_Init being called. Broadcast the values to all processors.
1014  int peers[2];
1015  if (world_rank == 0) {
1016  if (peer_sizes != NULL) {
1017  peers[0] = (*peer_sizes)[0];
1018  peers[1] = (*peer_sizes)[1];
1019  } else {
1020  peers[0] = world_size / 2;
1021  peers[1] = world_size - world_size/2;
1022  }
1023  }
1024  if (MPI_Bcast(peers, 2, MPI_INTEGER, 0, world_comm) != MPI_SUCCESS)
1025  throw RuntimeError() << "MPI_Broadcast -- peers failed";
1026 
1027  // Check that the number of processes specified is equal to the
1028  // total number of processes
1029  int peer_proc_count = peers[0] + peers[1];
1030  if (peer_proc_count != world_size) {
1031  throw RuntimeError() << "The total number of peer processors specfied is " << peer_proc_count
1032  << " which is not equal to the total number of processors (" << world_size << ").";
1033  }
1034 
1035  int my_peer_group = MPI_UNDEFINED;
1036  int sum = 0;
1037  for (size_t i=0; i < 2; i++) {
1038  sum += peers[i];
1039  if (world_rank < sum) {
1040  my_peer_group = i;
1041  break;
1042  }
1043  }
1044 
1045  MPI_Comm peer_comm;
1046  if (MPI_Comm_split(world_comm, my_peer_group, world_rank, &peer_comm) != MPI_SUCCESS) {
1047  throw RuntimeError() << "MPI_Comm_split failed";
1048  }
1049  env_data.m_worldComm = world_comm;
1050  env_data.m_execMap[EXEC_TYPE_PEER].m_groupComm = peer_comm;
1051  env_data.m_execMap[EXEC_TYPE_PEER].m_master = my_peer_group; // Overloading meaning to peer group.
1052  }
1053 }
1054 
1055 bool
1056 is_comm_valid()
1057 {
1058  EnvData &env_data = EnvData::instance();
1059  if (env_data.m_parallelComm == MPI_COMM_NULL) {
1060  return false;
1061  } else {
1062  return true;
1063  }
1064 }
1065 
1066 void
1068  MPI_Comm new_comm)
1069 {
1070  EnvData &env_data = EnvData::instance();
1071 
1072  // Destroy old comm
1073  if (env_data.m_parallelComm != MPI_COMM_NULL) {
1074 
1075  if (new_comm != MPI_COMM_NULL) {
1076  mpih::Sub_Communicator(env_data.m_parallelComm, new_comm);
1077  }
1078 
1079  env_data.m_parallelComm = MPI_COMM_NULL ;
1080  env_data.m_parallelSize = -1;
1081  env_data.m_parallelRank = -1 ;
1082  }
1083 
1084  setMpiCommunicator(new_comm);
1085 }
1086 
1087 void setMpiCommunicator(MPI_Comm communicator)
1088 {
1089  EnvData &env_data = EnvData::instance();
1090  if(communicator != MPI_COMM_NULL)
1091  {
1092  env_data.m_parallelComm = communicator;
1093 
1094  if(MPI_Comm_size(env_data.m_parallelComm, &env_data.m_parallelSize) != MPI_SUCCESS
1095  || MPI_Comm_rank(env_data.m_parallelComm, &env_data.m_parallelRank) != MPI_SUCCESS
1096  || env_data.m_parallelSize == -1
1097  || env_data.m_parallelRank == -1)
1098  {
1099  throw RuntimeError() << "reset given bad MPI communicator";
1100  }
1101  }
1102 }
1103 
1104 void
1106 {
1107  EnvData &env_data = EnvData::instance();
1108 
1110 
1111  stk_classic::all_write_string(Env::parallel_comm(), *env_data.m_outputP0, env_data.m_output.str());
1112  env_data.m_output.str("");
1113 }
1114 
1115 
1116 void
1117 request_shutdown(bool shutdown)
1118 {
1119  EnvData::instance().m_shutdownRequested = shutdown;
1120 }
1121 
1122 
1123 bool
1124 is_shutdown_requested()
1125 {
1126  int shutdown_requested_in = EnvData::instance().m_shutdownRequested || Env::HUP_received();
1127  int shutdown_requested;
1128 
1129  MPI_Allreduce(&shutdown_requested_in, &shutdown_requested, 1, MPI_INT, MPI_SUM, Env::parallel_comm());
1130 
1131  return shutdown_requested != 0;
1132 }
1133 
1134 
1135 void abort() {
1136  EnvData &env_data = EnvData::instance();
1137 
1138  // Cannot be sure of parallel synchronization status; therefore, no communications can
1139  // occur. Grab and dump all pending output buffers to 'std::cerr'.
1140  std::cerr << std::endl
1141  << "*** SIERRA ABORT on P" << EnvData::instance().m_parallelRank << " ***"
1142  << std::endl
1143  << "*** check " << get_param("output-log")
1144  << " file for more information ***"
1145  << std::endl ;
1146 
1147  if (!env_data.m_output.str().empty()) {
1148  std::cerr << "Buffer contents of deferred output stream on processor " << parallel_rank()
1149  << std::endl ;
1150  std::cerr << env_data.m_output.str();
1151  }
1152 
1153  std::cerr.flush();
1154  std::cout.flush();
1155 
1156  ::sleep(1); // Give the other processors a chance at
1157  // catching up, seems to help hanging problems.
1158  MPI_Abort(env_data.m_parallelComm, MPI_ERR_OTHER); // First try to die
1159  std::exit( EXIT_FAILURE ); // Second try to die
1160 }
1161 
1162 
1163 const std::string &
1165  const char * const option)
1166 {
1167  if (EnvData::instance().m_vm.count(option)) {
1168  if (EnvData::instance().m_vm[option].as<std::string>().empty())
1169  return EnvData::instance().m_onString;
1170  else
1171  return EnvData::instance().m_vm[option].as<std::string>();
1172  }
1173  else
1174  return EnvData::instance().m_emptyString;
1175 }
1176 
1177 
1178 void
1180  const char * option,
1181  const std::string & value) {
1182 
1183 
1184  namespace opt = boost::program_options;
1185 
1186  opt::variables_map &vm = stk_classic::get_variables_map();
1187  opt::options_description &od = stk_classic::get_options_description();
1188 
1189  int argc = 1;
1190  char *s = std::strcpy(new char[std::strlen(option) + 1], option);
1191 
1192  opt::store(opt::parse_command_line(argc, &s, od), vm);
1193  opt::notify(vm);
1194 
1195  delete [] s;
1196 }
1197 
1198 } // namespace Env
1199 } // namespace sierra
std::ostream & dout()
Diagnostic output stream.
Definition: OutputLog.cpp:674
std::ostream & output()
Function output returns the processor output log stream. This stream is connected via an mpi_filebuf ...
Definition: Env.cpp:264
std::string title(const std::string &s)
Function title returns a first letter of each word capitalized of the string.
Definition: StringUtil.cpp:107
std::ostream & dwout()
Diagnostic writer stream.
Definition: OutputLog.cpp:690
const std::string & startup_date()
Function startup_date returns the startup date of this application execution.
Definition: Env.cpp:200
std::string osversion()
Function osversion returns the hardware type of the host running the application. ...
Definition: Platform.cpp:541
Definition: Env.cpp:53
void set_param(const char *option, const std::string &value)
Member function set_param assigns the value to the parameter option.
Definition: Env.cpp:1179
void set_check_subcycle(bool value)
Function set_check_subcycle sets whether to check input file for subcycling. The default behavior cor...
Definition: Env.cpp:238
Class BroadcastArg creates a copy of argc and argv after broadcasting them from processor 0...
Class TimerParser implements the bit mask parser for the timer&#39;s bit masks.
Definition: Timer.hpp:790
Generic application using entire communicator (MPI_COMM_WORLD)
Definition: Env.hpp:63
~Startup()
Destroys a Startup instance. IT closes all logging output streams and will finalize MPI only if the S...
Definition: Env.cpp:815
double wall_now()
Member function wall_now returns the epoch as a double precision value in seconds to "millisecond" ac...
Definition: Platform.cpp:261
std::ostream & outputP0()
Function outputP0 returns the processor output log stream on processor 0 and the null log stream on a...
Definition: Env.cpp:271
Split communicator application; non-Gemini.
Definition: Env.hpp:66
const std::string working_directory()
Function working_directory returns the current working directory of this application execution...
Definition: Env.cpp:252
std::ostream & pout()
Per-processor output stream (See RuntimeDeferredx)
Definition: OutputLog.cpp:666
const std::string & executable_file()
Function executable_file returns the path of this executable file. information.
Definition: Env.cpp:181
int pid()
Function pid returns the process id of the process running the application.
Definition: Platform.cpp:557
bool shutdown_requested()
Function shutdown_requested returns true if an application shutdown has requested via the request_shu...
std::ostream & outputNull()
Function outputNull returns the null output stream. All data is simply discarded by the buffer associ...
Definition: Env.cpp:278
const std::string & architecture()
Function architecture returns the platform executing this product. This is obtained during startup by...
Definition: Env.cpp:245
std::ostream & out()
Normal output stream.
Definition: OutputLog.cpp:658
void abort()
Function abort aborts the execution of the sierra application.
Definition: Env.cpp:1135
String lower(const String &s)
Function lower returns a lower case version of the string.
Definition: StringUtil.hpp:281
void startup_preparallel_platform()
Function startup_preparallel_platform ...
Definition: Platform.cpp:255
static const std::string PARAM_ON
Option value when command line option specified without a parameter.
Definition: Env.hpp:45
std::string section_title(const std::string &title)
Function section_title returns a section title. The title has date and time concatenated and right ju...
Definition: Env.cpp:302
int parallel_rank()
function parallel_rank returns the rank of this processor in the current mpi communicator.
Definition: Env.cpp:318
ExecType
Enumeration ExecutableType defines the known types of coordinated executables that operate with a sie...
Definition: Env.hpp:62
double start_time()
Function start_time returns the start time of this application execution.
Definition: Env.cpp:212
ExTemp1< std::runtime_error > RuntimeError
Defined in <stdexcept>
Definition: Exception.hpp:775
boost::program_options::options_description & get_options_description()
Function get_options_description is a singleton used to store the command line option descriptions fo...
Class basic_indent_streambuf implements a output streambuf that performs indentation, blank line removal and outline bracing, sending the result character stream to another output stream buffer.
MPI_Comm parallel_world_comm()
Function parallel_world_comm returns the MPI_COMM_WORLD communicator used by the sierra environment i...
Definition: Env.cpp:329
bool HUP_received()
Function request_shutdown sets the shutdown requested flag so that future calls to shutdown_requested...
Definition: Signal.cpp:278
const char * subsection_separator()
Function subsection_separator returns a c-style string to be used as a output subsection separator...
Definition: Env.cpp:293
static void bootstrap()
Member function bootstrap runs through the stored bootstrap function pointers and executes each funct...
Definition: Bootstrap.cpp:21
void bind_output_streams(const std::string &output_description)
Function bind_output_streams parses the output_description and opens and registers the log streams an...
Definition: OutputLog.cpp:644
bool StartupSierra(int *argc, char ***argv, const char *product_name, const char *build_time, ExecType mpi_key, const std::vector< int > *peer_sizes)
Initialize MPI related operations for sierra, outputs banner, etc. returns 1 if MPI was initialized...
Definition: Env.cpp:394
std::string format_time(double t, const char *format)
Function format_time encodes the time using the format specified. The format is described in stdftime...
Definition: StringUtil.cpp:173
void deactivate_signals()
Function deactivate_signals disables the signal handlers.
Definition: Signal.cpp:250
bool is_registered_ostream(const std::string &name)
Function is_registered_ostream returns true if an output stream of the specified name is registered...
Definition: OutputLog.cpp:356
int peer_group()
Function peer_group returns the peer group rank for an application of type EXEC_TYPE_PEER.
Definition: Env.cpp:342
void register_stl_parallel_exceptions()
Member function register_stl_parallel_exceptions registers the stl exceptions with the parallel excep...
Definition: Exception.cpp:156
_setw setw(int width)
Function setw sets the width for the next field as a manipulator.
Definition: WriterManip.hpp:44
Mask parse(const char *mask_string) const
Member function parse parses the mask string and generates the corresponding bit mask.
Definition: Timer.cpp:1151
void all_write_string(ParallelMachine arg_comm, std::ostream &arg_root_os, const std::string &arg_msg)
Write string from any or all processors to the ostream on the root processor.
std::string domainname()
Function domainname returns the domainname of the domain running the application. ...
Definition: Platform.cpp:463
int parallel_lag_master()
Function parallel_lag_master returns the global rank of the Sierra lagrangian application.
Definition: Env.cpp:334
WriterRegistry & getWriterRegistry()
Function getWriterRegistry returns a reference to the diagnostic writer registry. ...
Gemini Euler application.
Definition: Env.hpp:64
std::ostream & tout()
Regression test textual output stream.
Definition: OutputLog.cpp:682
MPI_Comm parallel_comm()
Function parallel_comm returns the current MPI communicator used by the sierra environment.
Definition: Env.cpp:323
int parallel_fluid_master()
Function parallel_lag_master returns the global rank of the Gemini Euler application.
Definition: Env.cpp:338
const std::string & executable_date()
Function executable_date returns the build date of the executable file as a string in the form Mmm dd...
Definition: Env.cpp:188
Class Bootstrap serves as a bootstrapping mechanism for products in the sierra toolkit and elsewhere...
Definition: Bootstrap.hpp:35
bool developer_mode()
Function developer_mode returns true if the –developer option was specified on the application comma...
Definition: Env.cpp:219
void reset(MPI_Comm new_comm)
Function reset determines new parallel_size and parallel_rank. Flushes, closes, and reopens log files...
Definition: Env.cpp:1067
boost::program_options::variables_map & get_variables_map()
Function get_variabel_map is a singleton used to store the variables parsed from the line option desc...
const std::string & get_param(const char *const option)
Function query_env_param searches the command line options for the specified option. If not found, a const reference to an empty string is returned.
Definition: Env.cpp:1164
int parallel_size()
function parallel_size returns the number of processors in the current mpi communicator.
Definition: Env.cpp:314
void activate_signals()
Function activate_signals enables the signal handlers.
Definition: Signal.cpp:243
Sierra Lagrangian application.
Definition: Env.hpp:65
void set_input_file_required(bool value)
Function set_input_file_required sets whether lack of an input file specification will automatically ...
Definition: Env.cpp:233
Startup(int *argc, char ***argv, const char *product_name, const char *build_date_time, ExecType mpi_key=EXEC_TYPE_WORLD, const std::vector< int > *peer_sizes=NULL)
Creates a new Startup instance.
Definition: Env.cpp:785
int pgrp()
Function pgrp returns the process group id of the process running the application.
Definition: Platform.cpp:564
std::ostream * get_log_ostream(const std::string &name)
Function get_log_file_ostream return the output stream of the log file with the specified name from t...
Definition: OutputLog.cpp:263
std::string osname()
Function osname returns the operating system nameof the host running the application.
Definition: Platform.cpp:525
void report_deferred_messages(ParallelMachine comm)
Function report_deferred_messages aggregates and reports the message on the root processor.
void unregister_ostream(std::ostream &os)
Function unregister_ostream unregisters an output stream.
Definition: OutputLog.cpp:300
std::string hostname()
Function hostname returns the hostname of the host running the application.
Definition: Platform.cpp:454
void output_flush()
Function output_flush flushes all output on all currently open synchronous outptu files which were op...
Definition: Env.cpp:1105
void unregister_log_ostream(std::ostream &os)
Function register_log_ostream takes an existing std::ostream and makes it available for output redire...
Definition: OutputLog.cpp:228
const char * section_separator()
Function output_open opens an output file on processor zero for synchronous data output from all proc...
Definition: Env.cpp:284
const std::string & product_name()
Function product_name returns the product&#39;s name. This name is used to query the product registry for...
Definition: Env.cpp:174
void register_log_ostream(std::ostream &os, const std::string &name)
Function register_log_ostream takes an existing std::ostream and makes it available for output redire...
Definition: OutputLog.cpp:205
void register_ostream(std::ostream &os, const std::string &name)
Function register_ostream registers an output stream with the output stream registry. The registration process creates an intermediate tee streambuf.
Definition: OutputLog.cpp:275