xref: /petsc/src/sys/objects/init.c (revision 63f3c55c12ae2f190c391f6df6c540efe018a44a)
1 /*
2 
3    This file defines part of the initialization of PETSc
4 
5   This file uses regular malloc and free because it cannot known
6   what malloc is being used until it has already processed the input.
7 */
8 
9 #include <petscsys.h>        /*I  "petscsys.h"   I*/
10 #include <petsc/private/petscimpl.h>
11 #include <petscvalgrind.h>
12 #include <petscviewer.h>
13 #if defined(PETSC_USE_LOG)
14 PETSC_INTERN PetscErrorCode PetscLogInitialize(void);
15 #endif
16 
17 #if defined(PETSC_HAVE_SYS_SYSINFO_H)
18 #include <sys/sysinfo.h>
19 #endif
20 #if defined(PETSC_HAVE_UNISTD_H)
21 #include <unistd.h>
22 #endif
23 #if defined(PETSC_HAVE_CUDA)
24 #include <cuda_runtime.h>
25 PETSC_EXTERN PetscErrorCode PetscCUBLASInitializeHandle(void);
26 PETSC_EXTERN PetscErrorCode PetscCUSOLVERDnInitializeHandle(void);
27 #endif
28 
29 #if defined(PETSC_HAVE_VIENNACL)
30 PETSC_EXTERN PetscErrorCode PetscViennaCLInit();
31 #endif
32 
33 /* ------------------------Nasty global variables -------------------------------*/
34 /*
35      Indicates if PETSc started up MPI, or it was
36    already started before PETSc was initialized.
37 */
38 PetscBool   PetscBeganMPI         = PETSC_FALSE;
39 PetscBool   PetscInitializeCalled = PETSC_FALSE;
40 PetscBool   PetscFinalizeCalled   = PETSC_FALSE;
41 PetscBool   PetscCUDAInitialized  = PETSC_FALSE;
42 
43 PetscMPIInt PetscGlobalRank       = -1;
44 PetscMPIInt PetscGlobalSize       = -1;
45 
46 #if defined(PETSC_HAVE_COMPLEX)
47 #if defined(PETSC_COMPLEX_INSTANTIATE)
48 template <> class std::complex<double>; /* instantiate complex template class */
49 #endif
50 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
51 MPI_Datatype MPIU_C_DOUBLE_COMPLEX;
52 MPI_Datatype MPIU_C_COMPLEX;
53 #endif
54 
55 /*MC
56    PETSC_i - the imaginary number i
57 
58    Synopsis:
59    #include <petscsys.h>
60    PetscComplex PETSC_i;
61 
62    Level: beginner
63 
64    Note:
65    Complex numbers are automatically available if PETSc located a working complex implementation
66 
67 .seealso: PetscRealPart(), PetscImaginaryPart(), PetscRealPartComplex(), PetscImaginaryPartComplex()
68 M*/
69 PetscComplex PETSC_i;
70 #endif
71 #if defined(PETSC_USE_REAL___FLOAT128)
72 MPI_Datatype MPIU___FLOAT128 = 0;
73 #if defined(PETSC_HAVE_COMPLEX)
74 MPI_Datatype MPIU___COMPLEX128 = 0;
75 #endif
76 #elif defined(PETSC_USE_REAL___FP16)
77 MPI_Datatype MPIU___FP16 = 0;
78 #endif
79 MPI_Datatype MPIU_2SCALAR = 0;
80 #if defined(PETSC_USE_64BIT_INDICES)
81 MPI_Datatype MPIU_2INT = 0;
82 #endif
83 MPI_Datatype MPIU_BOOL;
84 MPI_Datatype MPIU_ENUM;
85 MPI_Datatype MPIU_FORTRANADDR;
86 MPI_Datatype MPIU_SIZE_T;
87 
88 /*
89        Function that is called to display all error messages
90 */
91 PetscErrorCode (*PetscErrorPrintf)(const char [],...)          = PetscErrorPrintfDefault;
92 PetscErrorCode (*PetscHelpPrintf)(MPI_Comm,const char [],...)  = PetscHelpPrintfDefault;
93 PetscErrorCode (*PetscVFPrintf)(FILE*,const char[],va_list)    = PetscVFPrintfDefault;
94 /*
95   This is needed to turn on/off GPU synchronization
96 */
97 PetscBool PetscViennaCLSynchronize = PETSC_FALSE;
98 PetscBool PetscCUDASynchronize = PETSC_FALSE;
99 
100 /* ------------------------------------------------------------------------------*/
101 /*
102    Optional file where all PETSc output from various prints is saved
103 */
104 PETSC_INTERN FILE *petsc_history;
105 FILE *petsc_history = NULL;
106 
107 PetscErrorCode  PetscOpenHistoryFile(const char filename[],FILE **fd)
108 {
109   PetscErrorCode ierr;
110   PetscMPIInt    rank,size;
111   char           pfile[PETSC_MAX_PATH_LEN],pname[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN],date[64];
112   char           version[256];
113 
114   PetscFunctionBegin;
115   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
116   if (!rank) {
117     char        arch[10];
118     int         err;
119 
120     ierr = PetscGetArchType(arch,10);CHKERRQ(ierr);
121     ierr = PetscGetDate(date,64);CHKERRQ(ierr);
122     ierr = PetscGetVersion(version,256);CHKERRQ(ierr);
123     ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
124     if (filename) {
125       ierr = PetscFixFilename(filename,fname);CHKERRQ(ierr);
126     } else {
127       ierr = PetscGetHomeDirectory(pfile,240);CHKERRQ(ierr);
128       ierr = PetscStrcat(pfile,"/.petschistory");CHKERRQ(ierr);
129       ierr = PetscFixFilename(pfile,fname);CHKERRQ(ierr);
130     }
131 
132     *fd = fopen(fname,"a");
133     if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file: %s",fname);
134 
135     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr);
136     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s %s\n",version,date);CHKERRQ(ierr);
137     ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
138     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s on a %s, %d proc. with options:\n",pname,arch,size);CHKERRQ(ierr);
139     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr);
140 
141     err = fflush(*fd);
142     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
143   }
144   PetscFunctionReturn(0);
145 }
146 
147 PETSC_INTERN PetscErrorCode PetscCloseHistoryFile(FILE **fd)
148 {
149   PetscErrorCode ierr;
150   PetscMPIInt    rank;
151   char           date[64];
152   int            err;
153 
154   PetscFunctionBegin;
155   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
156   if (!rank) {
157     ierr = PetscGetDate(date,64);CHKERRQ(ierr);
158     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr);
159     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"Finished at %s\n",date);CHKERRQ(ierr);
160     ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr);
161     err  = fflush(*fd);
162     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
163     err = fclose(*fd);
164     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
165   }
166   PetscFunctionReturn(0);
167 }
168 
169 /* ------------------------------------------------------------------------------*/
170 
171 /*
172    This is ugly and probably belongs somewhere else, but I want to
173   be able to put a true MPI abort error handler with command line args.
174 
175     This is so MPI errors in the debugger will leave all the stack
176   frames. The default MP_Abort() cleans up and exits thus providing no useful information
177   in the debugger hence we call abort() instead of MPI_Abort().
178 */
179 
180 void Petsc_MPI_AbortOnError(MPI_Comm *comm,PetscMPIInt *flag,...)
181 {
182   PetscFunctionBegin;
183   (*PetscErrorPrintf)("MPI error %d\n",*flag);
184   abort();
185 }
186 
187 void Petsc_MPI_DebuggerOnError(MPI_Comm *comm,PetscMPIInt *flag,...)
188 {
189   PetscErrorCode ierr;
190 
191   PetscFunctionBegin;
192   (*PetscErrorPrintf)("MPI error %d\n",*flag);
193   ierr = PetscAttachDebugger();
194   if (ierr) MPI_Abort(*comm,*flag); /* hopeless so get out */
195 }
196 
197 #if defined(PETSC_HAVE_CUDA)
198 /*@C
199      PetscCUDAInitialize - Initializes the CUDA device and cuBLAS on the device
200 
201      Logically collective
202 
203   Input Parameter:
204   comm - the MPI communicator that will utilize the CUDA devices
205 
206   Options Database:
207 +  -cuda_initialize <default yes,no> - do the initialization in PetscInitialize(). If -cuda_initialize no is used then the default initialization is done automatically
208                                when the first CUDA call is made unless you call PetscCUDAInitialize() before any CUDA operations are performed
209 .  -cuda_view - view information about the CUDA devices
210 .  -cuda_synchronize - wait at the end of asynchronize CUDA calls so that their time gets credited to the current event; default with -log_view
211 -  -cuda_set_device <gpu> - integer number of the device
212 
213   Level: beginner
214 
215   Notes:
216    Initializing cuBLAS takes about 1/2 second there it is done by default in PetscInitialize() before logging begins
217 
218 @*/
219 PetscErrorCode PetscCUDAInitialize(MPI_Comm comm)
220 {
221   PetscErrorCode        ierr;
222   PetscInt              deviceOpt = 0;
223   PetscBool             cuda_view_flag = PETSC_FALSE,flg;
224   struct cudaDeviceProp prop;
225   int                   devCount,device,devicecnt;
226   cudaError_t           err = cudaSuccess;
227   PetscMPIInt           rank,size;
228 
229   PetscFunctionBegin;
230   /*
231      If collecting logging information, by default, wait for GPU to complete its operations
232      before returning to the CPU in order to get accurate timings of each event
233   */
234   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&PetscCUDASynchronize);CHKERRQ(ierr);
235   if (!PetscCUDASynchronize) {
236     ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&PetscCUDASynchronize);CHKERRQ(ierr);
237   }
238 
239   ierr = PetscOptionsBegin(comm,NULL,"CUDA options","Sys");CHKERRQ(ierr);
240   ierr = PetscOptionsInt("-cuda_set_device","Set all MPI ranks to use the specified CUDA device",NULL,deviceOpt,&deviceOpt,&flg);CHKERRQ(ierr);
241   device = (int)deviceOpt;
242   ierr = PetscOptionsBool("-cuda_synchronize","Wait for the GPU to complete operations before returning to the CPU",NULL,PetscCUDASynchronize,&PetscCUDASynchronize,NULL);CHKERRQ(ierr);
243   ierr = PetscOptionsDeprecated("-cuda_show_devices","-cuda_view","3.12",NULL);CHKERRQ(ierr);
244   ierr = PetscOptionsName("-cuda_view","Display CUDA device information and assignments",NULL,&cuda_view_flag);CHKERRQ(ierr);
245   ierr = PetscOptionsEnd();CHKERRQ(ierr);
246   if (!PetscCUDAInitialized) {
247     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
248 
249     if (size>1 && !flg) {
250       /* check to see if we force multiple ranks to hit the same GPU */
251       /* we're not using the same GPU on multiple MPI threads. So try to allocated different   GPUs to different processes */
252 
253       /* First get the device count */
254       err   = cudaGetDeviceCount(&devCount);
255       if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err));
256 
257       /* next determine the rank and then set the device via a mod */
258       ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
259       device = rank % devCount;
260     }
261     err = cudaSetDevice(device);
262     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDevice %s",cudaGetErrorString(err));
263 
264     /* set the device flags so that it can map host memory */
265     err = cudaSetDeviceFlags(cudaDeviceMapHost);
266     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDeviceFlags %s",cudaGetErrorString(err));
267 
268     ierr = PetscCUBLASInitializeHandle();CHKERRQ(ierr);
269     ierr = PetscCUSOLVERDnInitializeHandle();CHKERRQ(ierr);
270     PetscCUDAInitialized = PETSC_TRUE;
271   }
272   if (cuda_view_flag) {
273     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
274     err  = cudaGetDeviceCount(&devCount);
275     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err));
276     for (devicecnt = 0; devicecnt < devCount; ++devicecnt) {
277       err = cudaGetDeviceProperties(&prop,devicecnt);
278       if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceProperties %s",cudaGetErrorString(err));
279       ierr = PetscPrintf(comm, "CUDA device %d: %s\n", devicecnt, prop.name);CHKERRQ(ierr);
280     }
281     ierr = PetscSynchronizedPrintf(comm,"[%d] Using CUDA device %d.\n",rank,device);CHKERRQ(ierr);
282     ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr);
283   }
284   PetscFunctionReturn(0);
285 }
286 #endif
287 
288 /*@C
289    PetscEnd - Calls PetscFinalize() and then ends the program. This is useful if one
290      wishes a clean exit somewhere deep in the program.
291 
292    Collective on PETSC_COMM_WORLD
293 
294    Options Database Keys are the same as for PetscFinalize()
295 
296    Level: advanced
297 
298    Note:
299    See PetscInitialize() for more general runtime options.
300 
301 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscFinalize()
302 @*/
303 PetscErrorCode  PetscEnd(void)
304 {
305   PetscFunctionBegin;
306   PetscFinalize();
307   exit(0);
308   return 0;
309 }
310 
311 PetscBool PetscOptionsPublish = PETSC_FALSE;
312 PETSC_INTERN PetscErrorCode PetscSetUseHBWMalloc_Private(void);
313 PETSC_INTERN PetscBool      petscsetmallocvisited;
314 static       char           emacsmachinename[256];
315 
316 PetscErrorCode (*PetscExternalVersionFunction)(MPI_Comm) = 0;
317 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm)    = 0;
318 
319 /*@C
320    PetscSetHelpVersionFunctions - Sets functions that print help and version information
321    before the PETSc help and version information is printed. Must call BEFORE PetscInitialize().
322    This routine enables a "higher-level" package that uses PETSc to print its messages first.
323 
324    Input Parameter:
325 +  help - the help function (may be NULL)
326 -  version - the version function (may be NULL)
327 
328    Level: developer
329 
330 @*/
331 PetscErrorCode  PetscSetHelpVersionFunctions(PetscErrorCode (*help)(MPI_Comm),PetscErrorCode (*version)(MPI_Comm))
332 {
333   PetscFunctionBegin;
334   PetscExternalHelpFunction    = help;
335   PetscExternalVersionFunction = version;
336   PetscFunctionReturn(0);
337 }
338 
339 #if defined(PETSC_USE_LOG)
340 PETSC_INTERN PetscBool   PetscObjectsLog;
341 #endif
342 
343 PETSC_INTERN PetscErrorCode  PetscOptionsCheckInitial_Private(void)
344 {
345   char              string[64],mname[PETSC_MAX_PATH_LEN],*f;
346   MPI_Comm          comm = PETSC_COMM_WORLD;
347   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flag;
348   PetscErrorCode    ierr;
349   PetscReal         si;
350   PetscInt          intensity;
351   int               i;
352   PetscMPIInt       rank;
353   char              version[256],helpoptions[256];
354 #if defined(PETSC_USE_LOG)
355   PetscViewerFormat format;
356   PetscBool         flg4 = PETSC_FALSE;
357 #endif
358 #if defined(PETSC_HAVE_CUDA)
359   PetscBool         initCuda = PETSC_TRUE;
360 #endif
361 
362   PetscFunctionBegin;
363   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
364 
365 #if !defined(PETSC_HAVE_THREADSAFETY)
366   if (!(PETSC_RUNNING_ON_VALGRIND)) {
367     /*
368       Setup the memory management; support for tracing malloc() usage
369     */
370     PetscBool         mdebug = PETSC_FALSE, eachcall = PETSC_FALSE, initializenan = PETSC_FALSE, mlog = PETSC_FALSE;
371 
372 #if defined(PETSC_USE_DEBUG)
373     mdebug        = PETSC_TRUE;
374     initializenan = PETSC_TRUE;
375     ierr   = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr);
376 #else
377     /* don't warn about unused option */
378     ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr);
379     flg1 = PETSC_FALSE;
380 #endif
381     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_debug",&flg2,&flg3);CHKERRQ(ierr);
382     if (flg1 || flg2) {
383       mdebug        = PETSC_TRUE;
384       eachcall      = PETSC_TRUE;
385       initializenan = PETSC_TRUE;
386     } else if (flg3 && !flg2) {
387       mdebug        = PETSC_FALSE;
388       eachcall      = PETSC_FALSE;
389       initializenan = PETSC_FALSE;
390     }
391 
392     ierr = PetscOptionsHasName(NULL,NULL,"-malloc_view",&mlog);CHKERRQ(ierr);
393     if (mlog) {
394       mdebug = PETSC_TRUE;
395     }
396     /* the next line is deprecated */
397     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc",&mdebug,NULL);CHKERRQ(ierr);
398     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&mdebug,NULL);CHKERRQ(ierr);
399     ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&mdebug,NULL);CHKERRQ(ierr);
400     if (mdebug) {
401       ierr = PetscMallocSetDebug(eachcall,initializenan);CHKERRQ(ierr);
402     }
403     if (mlog) {
404       PetscReal logthreshold = 0;
405       ierr = PetscOptionsGetReal(NULL,NULL,"-malloc_view_threshold",&logthreshold,NULL);CHKERRQ(ierr);
406       ierr = PetscMallocViewSet(logthreshold);CHKERRQ(ierr);
407     }
408   }
409 
410   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr);
411   if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);}
412   flg1 = PETSC_FALSE;
413   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr);
414   /* ignore this option if malloc is already set */
415   if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);}
416 
417   flg1 = PETSC_FALSE;
418   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr);
419   if (!flg1) {
420     flg1 = PETSC_FALSE;
421     ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr);
422   }
423   if (flg1) {
424     ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr);
425   }
426 #endif
427 
428 #if defined(PETSC_USE_LOG)
429   ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr);
430 #endif
431 
432   /*
433       Set the display variable for graphics
434   */
435   ierr = PetscSetDisplay();CHKERRQ(ierr);
436 
437   /*
438       Print the PETSc version information
439   */
440   ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr);
441   ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr);
442   ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr);
443   if (flg1 || flg2 || flg3) {
444 
445     /*
446        Print "higher-level" package version message
447     */
448     if (PetscExternalVersionFunction) {
449       ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr);
450     }
451 
452     ierr = PetscGetVersion(version,256);CHKERRQ(ierr);
453     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
454     ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr);
455     ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr);
456     ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr);
457     ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr);
458     ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr);
459     ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr);
460     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
461   }
462 
463   /*
464        Print "higher-level" package help message
465   */
466   if (flg3) {
467     if (PetscExternalHelpFunction) {
468       ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr);
469     }
470   }
471 
472   ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr);
473   if (flg1) {
474     ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr);
475     if (flg2) {
476       ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr);
477       ierr = PetscFreeMPIResources();CHKERRQ(ierr);
478       ierr = MPI_Finalize();CHKERRQ(ierr);
479       exit(0);
480     }
481   }
482 
483   /*
484       Setup the error handling
485   */
486   flg1 = PETSC_FALSE;
487   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr);
488   if (flg1) {
489     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr);
490     ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
491   }
492   flg1 = PETSC_FALSE;
493   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr);
494   if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,0);CHKERRQ(ierr);}
495   flg1 = PETSC_FALSE;
496   ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr);
497   if (flg1) {
498     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr);
499   }
500   flg1 = PETSC_FALSE;
501   ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
502   if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);}
503   flg1 = PETSC_FALSE;
504   ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,&flag);CHKERRQ(ierr);
505   if (flag) {ierr = PetscSetFPTrap((PetscFPTrap)flg1);CHKERRQ(ierr);}
506   ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr);
507   if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);}
508 
509   /*
510       Setup debugger information
511   */
512   ierr = PetscSetDefaultDebugger();CHKERRQ(ierr);
513   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr);
514   if (flg1) {
515     MPI_Errhandler err_handler;
516 
517     ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
518     ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr);
519     ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
520     ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,0);CHKERRQ(ierr);
521   }
522   ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr);
523   if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); }
524   ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr);
525   ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr);
526   if (flg1 || flg2) {
527     PetscMPIInt    size;
528     PetscInt       lsize,*nodes;
529     MPI_Errhandler err_handler;
530     /*
531        we have to make sure that all processors have opened
532        connections to all other processors, otherwise once the
533        debugger has stated it is likely to receive a SIGUSR1
534        and kill the program.
535     */
536     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
537     if (size > 2) {
538       PetscMPIInt dummy = 0;
539       MPI_Status  status;
540       for (i=0; i<size; i++) {
541         if (rank != i) {
542           ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr);
543         }
544       }
545       for (i=0; i<size; i++) {
546         if (rank != i) {
547           ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr);
548         }
549       }
550     }
551     /* check if this processor node should be in debugger */
552     ierr  = PetscMalloc1(size,&nodes);CHKERRQ(ierr);
553     lsize = size;
554     ierr  = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr);
555     if (flag) {
556       for (i=0; i<lsize; i++) {
557         if (nodes[i] == rank) { flag = PETSC_FALSE; break; }
558       }
559     }
560     if (!flag) {
561       ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
562       ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
563       if (flg1) {
564         ierr = PetscAttachDebugger();CHKERRQ(ierr);
565       } else {
566         ierr = PetscStopForDebugger();CHKERRQ(ierr);
567       }
568       ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr);
569       ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
570     }
571     ierr = PetscFree(nodes);CHKERRQ(ierr);
572   }
573 
574   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr);
575   if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);}
576 
577   /*
578         Setup profiling and logging
579   */
580 #if defined(PETSC_USE_INFO)
581   {
582     char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0;
583     ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr);
584     if (flg1 && logname[0]) {
585       ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr);
586     } else if (flg1) {
587       ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr);
588     }
589   }
590 #endif
591 #if defined(PETSC_USE_LOG)
592   mname[0] = 0;
593   ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
594   if (flg1) {
595     if (mname[0]) {
596       ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr);
597     } else {
598       ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr);
599     }
600   }
601 
602   ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr);
603 
604 #if defined(PETSC_HAVE_MPE)
605   flg1 = PETSC_FALSE;
606   ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr);
607   if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);}
608 #endif
609   flg1 = PETSC_FALSE;
610   flg3 = PETSC_FALSE;
611   ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr);
612   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
613   if (flg1)                      { ierr = PetscLogAllBegin();CHKERRQ(ierr); }
614   else if (flg3)                 { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);}
615 
616   ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr);
617   if (flg1) {
618     char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN];
619     FILE *file;
620     if (mname[0]) {
621       PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank);
622       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
623       file = fopen(fname,"w");
624       if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname);
625     } else file = PETSC_STDOUT;
626     ierr = PetscLogTraceBegin(file);CHKERRQ(ierr);
627   }
628 
629   ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr);
630   if (flg4) {
631     if (format == PETSC_VIEWER_ASCII_XML) {
632       ierr = PetscLogNestedBegin();CHKERRQ(ierr);
633     } else {
634       ierr = PetscLogDefaultBegin();CHKERRQ(ierr);
635     }
636   }
637   if (flg4 && format == PETSC_VIEWER_ASCII_XML) {
638     PetscReal threshold = PetscRealConstant(0.01);
639     ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr);
640     if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);}
641   }
642 #endif
643 
644   ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr);
645 
646 #if defined(PETSC_HAVE_CUDA)
647   ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr);
648   ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr);
649   ierr = PetscOptionsEnd();CHKERRQ(ierr);
650   if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);}
651 #endif
652 
653   /*
654        Print basic help message
655   */
656   ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr);
657   if (flg1) {
658     ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr);
659     ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr);
660     ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr);
661     ierr = (*PetscHelpPrintf)(comm,"       only when run in the debugger\n");CHKERRQ(ierr);
662     ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
663     ierr = (*PetscHelpPrintf)(comm,"       start the debugger in new xterm\n");CHKERRQ(ierr);
664     ierr = (*PetscHelpPrintf)(comm,"       unless noxterm is given\n");CHKERRQ(ierr);
665     ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
666     ierr = (*PetscHelpPrintf)(comm,"       start all processes in the debugger\n");CHKERRQ(ierr);
667     ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr);
668     ierr = (*PetscHelpPrintf)(comm,"    emacs jumps to error file\n");CHKERRQ(ierr);
669     ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr);
670     ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr);
671     ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr);
672     ierr = (*PetscHelpPrintf)(comm,"                      waits the delay for you to attach\n");CHKERRQ(ierr);
673     ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr);
674     ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr);
675     ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr);
676     ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr);
677     ierr = (*PetscHelpPrintf)(comm,"           note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr);
678     ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr);
679     ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr);
680     ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr);
681     ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr);
682     ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr);
683     ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr);
684     ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr);
685     ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr);
686     ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr);
687     ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr);
688     ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr);
689     ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr);
690     ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr);
691 #if defined(PETSC_USE_LOG)
692     ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr);
693     ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr);
694     ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr);
695 #if defined(PETSC_HAVE_MPE)
696     ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr);
697 #endif
698     ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr);
699 #endif
700     ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr);
701     ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr);
702     ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr);
703     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
704   }
705 
706 #if defined(PETSC_HAVE_POPEN)
707   {
708   char machine[128];
709   ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr);
710   if (flg1) {
711     ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr);
712   }
713   }
714 #endif
715 
716   ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr);
717   if (flg1) {
718     ierr = PetscSleep(si);CHKERRQ(ierr);
719   }
720 
721   ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
722   if (flg1) {
723     ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr);
724     if (f) {
725       ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr);
726     }
727   }
728 
729 #if defined(PETSC_HAVE_VIENNACL)
730   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
731   if (!flg3) {
732     ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr);
733   }
734   ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr);
735   PetscViennaCLSynchronize = flg3;
736   ierr = PetscViennaCLInit();CHKERRQ(ierr);
737 #endif
738 
739   /*
740      Creates the logging data structures; this is enabled even if logging is not turned on
741      This is the last thing we do before returning to the user code to prevent having the
742      logging numbers contaminated by any startup time associated with MPI and the GPUs
743   */
744 #if defined(PETSC_USE_LOG)
745   ierr = PetscLogInitialize();CHKERRQ(ierr);
746 #endif
747 
748   PetscFunctionReturn(0);
749 }
750