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