Flow123d  3.9.0-960b954f9
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 #ifdef FLOW123D_HAVE_PERMON
33 #include <permonsys.h>
34 #endif
35 
36 #include <string.h> // for strsignal
37 
38 #include <iostream> // for cout
39 #include <sstream> // for operator<<, endl
40 #include "mpi.h" // for MPI_Comm_size
41 #include "petscerror.h" // for CHKERRQ, Petsc...
42 #include "system/exc_common.hh" // for ExcAssertMsg
43 #include "system/asserts.hh" // for ASSERT_PERMANENT, msg
44 #include "system/logger.hh" // for Logger, operat...
45 #include "system/system.hh" // for SystemInfo
46 
47 
48 
49 
50 /// Function that catches all program signals.
51 /// Note: context variable required by PETSc function PetscPushSignalHandler
52 PetscErrorCode petsc_signal_handler(int signal, FMT_UNUSED void *context)
53 {
54  if (signal == SIGINT) {
55  cout << "SIGINT\n";
56  }
57  if (signal == SIGFPE || // FPE: Floating Point Exception,probably divide by zero
58  signal == SIGILL || // Illegal instruction: Likely due to memory corruption
59  signal == SIGPIPE || // Broken Pipe: Likely while reading or writing to a socket
60  signal == SIGSEGV ) // SEGV: Segmentation Violation, probably memory access out of range
61  {
62  // Signals handled by us.
63  THROW( ExcSignal() << EI_Signal(signal) << EI_SignalName(strsignal(signal)) );
64  } else {
65  return PetscSignalHandlerDefault(signal,(void*)0);
66  }
67  return 0;
68 }
69 
70 void system_signal_handler(int signal) {
71  petsc_signal_handler(signal, nullptr);
72 }
73 
74 
76 : log_filename_(""),
77  signal_handler_off_(false)
78 { }
79 
82 
83 
84 void ApplicationBase::system_init( MPI_Comm comm, const string &log_filename ) {
85  int ierr;
86 
87  sys_info.comm=comm;
88 
89 
90  //Xio::init(); //Initialize XIO library
91 
92  // TODO : otevrit docasne log file jeste pred ctenim vstupu (kvuli zachyceni chyb), po nacteni dokoncit
93  // inicializaci systemu
94 
95  ierr=MPI_Comm_rank(comm, &(sys_info.my_proc));
96  ierr+=MPI_Comm_size(comm, &(sys_info.n_proc));
98  ASSERT_PERMANENT( ierr == MPI_SUCCESS ).error("MPI not initialized.\n");
99 
100  // determine logfile name or switch it off
101  stringstream log_name;
102 
103  if ( log_filename == "//" ) {
104  // -l option without given name -> turn logging off
105  sys_info.log=NULL;
107  } else {
108  // construct full log name
109  //log_name << log_filename << "." << sys_info.my_proc << ".old.log";
110 
111  //sys_info.log_fname = FilePath(log_name.str(), FilePath::output_file);
112  //sys_info.log=xfopen(sys_info.log_fname.c_str(),"wt");
113 
115  }
116 
119 }
120 
121 
123 
124 #ifdef FLOW123D_HAVE_PETSC
125 PetscErrorCode ApplicationBase::petscvfprintf(FILE *fd, const char format[], va_list Argp) {
126  PetscErrorCode ierr;
127 
128  PetscFunctionBegin;
129  if (fd != stdout && fd != stderr) { /* handle regular files */
130  ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr);
131  } else {
132  const int buf_size = 65000;
133  char buff[65000];
134  size_t length;
135  ierr = PetscVSNPrintf(buff,buf_size,format,&length,Argp);CHKERRQ(ierr);
136 
137  /* now send buff to whatever stream or whatever you want */
138  fwrite(buff, sizeof(char), length, petsc_output_);
139  }
140  PetscFunctionReturn(0);
141 }
142 #endif
143 
144 
145 void ApplicationBase::petsc_initialize(int argc, char ** argv) {
146 #ifdef FLOW123D_HAVE_PETSC
147  if (petsc_redirect_file_ != "") {
148  petsc_output_ = fopen(petsc_redirect_file_.c_str(), "w");
149  if (! petsc_output_)
150  THROW(FilePath::ExcFileOpen() << FilePath::EI_Path(petsc_redirect_file_));
151  PetscVFPrintf = this->petscvfprintf;
152  }
153 
154 
155  PetscInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
156  if (! signal_handler_off_) {
157  // PETSc do not catch SIGINT, but someone on the way does, we try to fix it.
158  signal(SIGINT, system_signal_handler);
159  PetscPushSignalHandler(petsc_signal_handler, nullptr);
160  }
161 
162  int mpi_size;
163  MPI_Comm_size(PETSC_COMM_WORLD, &mpi_size);
164  MessageOut() << "MPI size: " << mpi_size << std::endl;
165 #endif
166 }
167 
168 
169 
171 #ifdef FLOW123D_HAVE_PETSC
172  if ( petsc_initialized )
173  {
174  PetscErrorCode ierr=0;
175 
176  ierr = PetscFinalize(); CHKERRQ(ierr);
177 
178  if (petsc_output_) fclose(petsc_output_);
179 
180  petsc_initialized = false;
181 
182  return ierr;
183  }
184 #endif
185 
186  return 0;
187 }
188 
189 
190 void ApplicationBase::permon_initialize(int argc, char ** argv) {
191 #ifdef FLOW123D_HAVE_PERMON
192  PermonInitialize(&argc,&argv,PETSC_NULL,PETSC_NULL);
193 #endif
194 }
195 
197 #ifdef FLOW123D_HAVE_PERMON
198  if ( permon_initialized )
199  {
200  PetscErrorCode ierr=0;
201 
202  ierr = PermonFinalize(); CHKERRQ(ierr);
203 
204  permon_initialized = false;
205 
206  return ierr;
207  }
208 #endif
209 
210  return 0;
211 }
212 
213 
214 void ApplicationBase::init(int argc, char ** argv) {
215  // parse our own command line arguments, leave others for PETSc
216  this->parse_cmd_line(argc, argv);
218 
219  armadillo_setup(); // set catching armadillo exceptions and reporting stacktrace
220 
221  this->petsc_initialize(argc, argv);
222  petsc_initialized = true;
223 
224  this->permon_initialize(argc, argv);
225  permon_initialized = true;
226 
227  this->system_init(PETSC_COMM_WORLD, log_filename_); // Petsc, open log, read ini file
228 }
229 
230 
232  //if (sys_info.log) xfclose(sys_info.log);
233  permon_finalize();
234  petcs_finalize();
235 }
format
manipulators::Array< T, Delim > format(T const &deduce, Delim delim=", ")
Definition: logger.hh:325
SystemInfo::verbosity
int verbosity
Definition: system.hh:73
ApplicationBase::permon_finalize
int permon_finalize()
Definition: application_base.cc:196
Profiler::instance
static Profiler * instance(bool clear=false)
Definition: sys_profiler.cc:981
ApplicationBase::permon_initialize
void permon_initialize(int argc, char **argv)
Definition: application_base.cc:190
ApplicationBase::init
void init(int argc, char **argv)
Definition: application_base.cc:214
string.h
file_path.hh
asserts.hh
Definitions of ASSERTS.
SystemInfo::comm
MPI_Comm comm
Definition: system.hh:81
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
system.hh
MPI_Comm_rank
#define MPI_Comm_rank
Definition: mpi.h:236
ApplicationBase::petcs_finalize
int petcs_finalize()
Definition: application_base.cc:170
LoggerOptions::get_instance
static LoggerOptions & get_instance()
Getter of singleton instance object.
Definition: logger_options.cc:31
MPI_Comm_size
#define MPI_Comm_size
Definition: mpi.h:235
armadillo_tools.hh
ApplicationBase::petsc_redirect_file_
string petsc_redirect_file_
Definition: application_base.hh:149
ApplicationBase::log_filename_
string log_filename_
Definition: application_base.hh:145
ApplicationBase::ApplicationBase
ApplicationBase()
Definition: application_base.cc:75
sys_profiler.hh
ASSERT_PERMANENT
#define ASSERT_PERMANENT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:348
armadillo_setup
void armadillo_setup()
Definition: armadillo_tools.cc:66
mpi.h
system_signal_handler
void system_signal_handler(int signal)
Definition: application_base.cc:70
logger.hh
LoggerOptions::set_log_file
void set_log_file(std::string log_file_base)
Initialize instance object in format 'log_file_base.process.log'.
Definition: logger_options.cc:97
exc_common.hh
MPI_Comm
int MPI_Comm
Definition: mpi.h:141
ApplicationBase::petsc_initialized
static bool petsc_initialized
Definition: application_base.hh:86
ApplicationBase::system_init
void system_init(MPI_Comm comm, const string &log_filename)
Definition: application_base.cc:84
ApplicationBase::signal_handler_off_
bool signal_handler_off_
Turn off signal handling useful to debug with valgrind.
Definition: application_base.hh:155
ApplicationBase::parse_cmd_line
virtual void parse_cmd_line(const int argc, char **argv)=0
sys_info
SystemInfo sys_info
Definition: system.cc:41
SystemInfo::pause_after_run
int pause_after_run
Definition: system.hh:74
LoggerOptions::setup_mpi
int setup_mpi(MPI_Comm comm)
Set rank of actual process by MPI communicator.
Definition: logger_options.cc:90
ApplicationBase::permon_initialized
static bool permon_initialized
Definition: application_base.hh:87
ApplicationBase::petsc_initialize
void petsc_initialize(int argc, char **argv)
Definition: application_base.cc:145
application_base.hh
petsc_signal_handler
PetscErrorCode petsc_signal_handler(int signal, FMT_UNUSED void *context)
Definition: application_base.cc:52
MPI_SUCCESS
#define MPI_SUCCESS
Definition: mpi.c:17
ApplicationBase::petsc_output_
static FILE * petsc_output_
File handler for redirecting PETSc output.
Definition: application_base.hh:152
SystemInfo::my_proc
int my_proc
Definition: system.hh:79
logger_options.hh
SystemInfo::n_proc
int n_proc
Definition: system.hh:78
SystemInfo::log
FILE * log
Definition: system.hh:76
ApplicationBase::~ApplicationBase
virtual ~ApplicationBase()
Destructor.
Definition: application_base.cc:231
MessageOut
#define MessageOut()
Macro defining 'message' record of log.
Definition: logger.hh:275
FMT_UNUSED
#define FMT_UNUSED
Definition: posix.h:75