Flow123d  release_3.0.0-1264-g45bfb2a
application_base.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file application_base.cc
15  * @brief
16  */
17 
19 #include "system/sys_profiler.hh"
20 #include "system/logger_options.hh"
22 #include "system/file_path.hh"
23 #include "system/system.hh"
24 #include <signal.h>
25 
26 #ifdef FLOW123D_HAVE_PETSC
27 //#include <petsc.h>
28 #include <petscsys.h>
29 #include <petsc/private/petscimpl.h> /* to gain access to the private PetscVFPrintf */
30 #endif
31 
32 #include <string.h> // for strsignal
33 #include <boost/exception/detail/error_info_impl.hpp> // for error_info
34 #include <iostream> // for cout
35 #include <sstream> // for operator<<, endl
36 #include "mpi.h" // for MPI_Comm_size
37 #include "petscerror.h" // for CHKERRQ, Petsc...
38 #include "system/exc_common.hh" // for ExcAssertMsg
39 #include "system/global_defs.h" // for OLD_ASSERT, msg
40 #include "system/logger.hh" // for Logger, operat...
41 #include "system/system.hh" // for SystemInfo
42 
43 
44 
45 
46 /// Function that catches all program signals.
47 /// Note: context variable required by PETSc function PetscPushSignalHandler
48 PetscErrorCode petsc_signal_handler(int signal, FMT_UNUSED void *context)
49 {
50  if (signal == SIGINT) {
51  cout << "SIGINT\n";
52  }
53  if (signal == SIGFPE || // FPE: Floating Point Exception,probably divide by zero
54  signal == SIGILL || // Illegal instruction: Likely due to memory corruption
55  signal == SIGPIPE || // Broken Pipe: Likely while reading or writing to a socket
56  signal == SIGSEGV ) // SEGV: Segmentation Violation, probably memory access out of range
57  {
58  // Signals handled by us.
59  THROW( ExcSignal() << EI_Signal(signal) << EI_SignalName(strsignal(signal)) );
60  } else {
61  return PetscSignalHandlerDefault(signal,(void*)0);
62  }
63  return 0;
64 }
65 
66 void system_signal_handler(int signal) {
67  petsc_signal_handler(signal, nullptr);
68 }
69 
70 
72 : log_filename_(""),
73  signal_handler_off_(false)
74 { }
75 
77 
78 
79 void ApplicationBase::system_init( MPI_Comm comm, const string &log_filename ) {
80  int ierr;
81 
82  sys_info.comm=comm;
83 
84 
85  //Xio::init(); //Initialize XIO library
86 
87  // TODO : otevrit docasne log file jeste pred ctenim vstupu (kvuli zachyceni chyb), po nacteni dokoncit
88  // inicializaci systemu
89 
90  ierr=MPI_Comm_rank(comm, &(sys_info.my_proc));
91  ierr+=MPI_Comm_size(comm, &(sys_info.n_proc));
93  OLD_ASSERT( ierr == MPI_SUCCESS,"MPI not initialized.\n");
94 
95  // determine logfile name or switch it off
96  stringstream log_name;
97 
98  if ( log_filename == "//" ) {
99  // -l option without given name -> turn logging off
100  sys_info.log=NULL;
102  } else {
103  // construct full log name
104  //log_name << log_filename << "." << sys_info.my_proc << ".old.log";
105 
106  //sys_info.log_fname = FilePath(log_name.str(), FilePath::output_file);
107  //sys_info.log=xfopen(sys_info.log_fname.c_str(),"wt");
108 
110  }
111 
114 }
115 
116 
118 
119 #ifdef FLOW123D_HAVE_PETSC
120 PetscErrorCode ApplicationBase::petscvfprintf(FILE *fd, const char format[], va_list Argp) {
121  PetscErrorCode ierr;
122 
123  PetscFunctionBegin;
124  if (fd != stdout && fd != stderr) { /* handle regular files */
125  ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr);
126  } else {
127  const int buf_size = 65000;
128  char buff[65000];
129  size_t length;
130  ierr = PetscVSNPrintf(buff,buf_size,format,&length,Argp);CHKERRQ(ierr);
131 
132  /* now send buff to whatever stream or whatever you want */
133  fwrite(buff, sizeof(char), length, petsc_output_);
134  }
135  PetscFunctionReturn(0);
136 }
137 #endif
138 
139 
140 void ApplicationBase::petsc_initialize(int argc, char ** argv) {
141 #ifdef FLOW123D_HAVE_PETSC
142  if (petsc_redirect_file_ != "") {
143  petsc_output_ = fopen(petsc_redirect_file_.c_str(), "w");
144  if (! petsc_output_)
145  THROW(FilePath::ExcFileOpen() << FilePath::EI_Path(petsc_redirect_file_));
146  PetscVFPrintf = this->petscvfprintf;
147  }
148 
149 
150  PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
151  if (! signal_handler_off_) {
152  // PETSc do not catch SIGINT, but someone on the way does, we try to fix it.
153  signal(SIGINT, system_signal_handler);
154  PetscPushSignalHandler(petsc_signal_handler, nullptr);
155  }
156 
157  int mpi_size;
158  MPI_Comm_size(PETSC_COMM_WORLD, &mpi_size);
159  MessageOut() << "MPI size: " << mpi_size << std::endl;
160 #endif
161 }
162 
163 
164 
166 #ifdef FLOW123D_HAVE_PETSC
167  if ( petsc_initialized )
168  {
169  PetscErrorCode ierr=0;
170 
171  ierr = PetscFinalize(); CHKERRQ(ierr);
172 
173  if (petsc_output_) fclose(petsc_output_);
174 
175  petsc_initialized = false;
176 
177  return ierr;
178  }
179 #endif
180 
181  return 0;
182 }
183 
184 
185 void ApplicationBase::init(int argc, char ** argv) {
186  // parse our own command line arguments, leave others for PETSc
187  this->parse_cmd_line(argc, argv);
189 
190  armadillo_setup(); // set catching armadillo exceptions and reporting stacktrace
191 
192  this->petsc_initialize(argc, argv);
193  petsc_initialized = true;
194 
195  this->system_init(PETSC_COMM_WORLD, log_filename_); // Petsc, open log, read ini file
196 }
197 
198 
200  //if (sys_info.log) xfclose(sys_info.log);
201  petcs_finalize();
202 }
void system_init(MPI_Comm comm, const string &log_filename)
#define MPI_SUCCESS
Definition: mpi.c:17
int my_proc
Definition: system.hh:79
virtual void parse_cmd_line(const int argc, char **argv)=0
void system_signal_handler(int signal)
virtual ~ApplicationBase()
Destructor.
int MPI_Comm
Definition: mpi.h:141
FILE * log
Definition: system.hh:76
#define MessageOut()
Macro defining &#39;message&#39; record of log.
Definition: logger.hh:243
static bool petsc_initialized
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
static FILE * petsc_output_
File handler for redirecting PETSc output.
int verbosity
Definition: system.hh:73
PetscErrorCode petsc_signal_handler(int signal, FMT_UNUSED void *context)
#define OLD_ASSERT(...)
Definition: global_defs.h:131
int setup_mpi(MPI_Comm comm)
Set rank of actual process by MPI communicator.
Global macros to enhance readability and debugging, general constants.
void armadillo_setup()
#define FMT_UNUSED
Definition: posix.h:75
bool signal_handler_off_
Turn off signal handling useful to debug with valgrind.
#define MPI_Comm_size
Definition: mpi.h:235
void init(int argc, char **argv)
void set_log_file(std::string log_file_base)
Initialize instance object in format &#39;log_file_base.process.log&#39;.
#define MPI_Comm_rank
Definition: mpi.h:236
static LoggerOptions & get_instance()
Getter of singleton instance object.
SystemInfo sys_info
Definition: system.cc:41
int n_proc
Definition: system.hh:78
void petsc_initialize(int argc, char **argv)
static Profiler * instance(bool clear=false)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
MPI_Comm comm
Definition: system.hh:81
int pause_after_run
Definition: system.hh:74