xref: /petsc/src/sys/objects/init.c (revision 244bdbcc9eeccc717fe127379b4a3a7b3bf23c72)
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, 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     }
382 
383     ierr = PetscOptionsHasName(NULL,NULL,"-malloc_view",&mlog);CHKERRQ(ierr);
384     if (mlog) {
385       mdebug = PETSC_TRUE;
386     }
387     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc",&mdebug,NULL);CHKERRQ(ierr);
388     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&mdebug,NULL);CHKERRQ(ierr);
389     ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&mdebug,NULL);CHKERRQ(ierr);
390     if (mdebug) {
391       ierr = PetscMallocSetDebug(eachcall,initializenan);CHKERRQ(ierr);
392     }
393     if (mlog) {
394       PetscReal logthreshold = 0;
395       ierr = PetscOptionsGetReal(NULL,NULL,"-malloc_view_threshold",&logthreshold,NULL);CHKERRQ(ierr);
396       ierr = PetscMallocViewSet(logthreshold);CHKERRQ(ierr);
397     }
398   }
399 
400   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr);
401   if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);}
402   flg1 = PETSC_FALSE;
403   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr);
404   /* ignore this option if malloc is already set */
405   if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);}
406 
407   flg1 = PETSC_FALSE;
408   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr);
409   if (!flg1) {
410     flg1 = PETSC_FALSE;
411     ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr);
412   }
413   if (flg1) {
414     ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr);
415   }
416 #endif
417 
418 #if defined(PETSC_USE_LOG)
419   ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr);
420 #endif
421 
422   /*
423       Set the display variable for graphics
424   */
425   ierr = PetscSetDisplay();CHKERRQ(ierr);
426 
427   /*
428       Print the PETSc version information
429   */
430   ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr);
431   ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr);
432   ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr);
433   if (flg1 || flg2 || flg3) {
434 
435     /*
436        Print "higher-level" package version message
437     */
438     if (PetscExternalVersionFunction) {
439       ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr);
440     }
441 
442     ierr = PetscGetVersion(version,256);CHKERRQ(ierr);
443     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
444     ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr);
445     ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr);
446     ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr);
447     ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr);
448     ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr);
449     ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr);
450     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
451   }
452 
453   /*
454        Print "higher-level" package help message
455   */
456   if (flg3) {
457     if (PetscExternalHelpFunction) {
458       ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr);
459     }
460   }
461 
462   ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr);
463   if (flg1) {
464     ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr);
465     if (flg2) {
466       ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr);
467       ierr = PetscFreeMPIResources();CHKERRQ(ierr);
468       ierr = MPI_Finalize();CHKERRQ(ierr);
469       exit(0);
470     }
471   }
472 
473   /*
474       Setup the error handling
475   */
476   flg1 = PETSC_FALSE;
477   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr);
478   if (flg1) {
479     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr);
480     ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
481   }
482   flg1 = PETSC_FALSE;
483   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr);
484   if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,0);CHKERRQ(ierr);}
485   flg1 = PETSC_FALSE;
486   ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr);
487   if (flg1) {
488     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr);
489   }
490   flg1 = PETSC_FALSE;
491   ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
492   if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);}
493   flg1 = PETSC_FALSE;
494   ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,NULL);CHKERRQ(ierr);
495   if (flg1) {ierr = PetscSetFPTrap(PETSC_FP_TRAP_ON);CHKERRQ(ierr);}
496   ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr);
497   if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);}
498 
499   /*
500       Setup debugger information
501   */
502   ierr = PetscSetDefaultDebugger();CHKERRQ(ierr);
503   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr);
504   if (flg1) {
505     MPI_Errhandler err_handler;
506 
507     ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
508     ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr);
509     ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
510     ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,0);CHKERRQ(ierr);
511   }
512   ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr);
513   if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); }
514   ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr);
515   ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr);
516   if (flg1 || flg2) {
517     PetscMPIInt    size;
518     PetscInt       lsize,*nodes;
519     MPI_Errhandler err_handler;
520     /*
521        we have to make sure that all processors have opened
522        connections to all other processors, otherwise once the
523        debugger has stated it is likely to receive a SIGUSR1
524        and kill the program.
525     */
526     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
527     if (size > 2) {
528       PetscMPIInt dummy = 0;
529       MPI_Status  status;
530       for (i=0; i<size; i++) {
531         if (rank != i) {
532           ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr);
533         }
534       }
535       for (i=0; i<size; i++) {
536         if (rank != i) {
537           ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr);
538         }
539       }
540     }
541     /* check if this processor node should be in debugger */
542     ierr  = PetscMalloc1(size,&nodes);CHKERRQ(ierr);
543     lsize = size;
544     ierr  = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr);
545     if (flag) {
546       for (i=0; i<lsize; i++) {
547         if (nodes[i] == rank) { flag = PETSC_FALSE; break; }
548       }
549     }
550     if (!flag) {
551       ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
552       ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
553       if (flg1) {
554         ierr = PetscAttachDebugger();CHKERRQ(ierr);
555       } else {
556         ierr = PetscStopForDebugger();CHKERRQ(ierr);
557       }
558       ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr);
559       ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
560     }
561     ierr = PetscFree(nodes);CHKERRQ(ierr);
562   }
563 
564   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr);
565   if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);}
566 
567   /*
568         Setup profiling and logging
569   */
570 #if defined(PETSC_USE_INFO)
571   {
572     char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0;
573     ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr);
574     if (flg1 && logname[0]) {
575       ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr);
576     } else if (flg1) {
577       ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr);
578     }
579   }
580 #endif
581 #if defined(PETSC_USE_LOG)
582   mname[0] = 0;
583   ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
584   if (flg1) {
585     if (mname[0]) {
586       ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr);
587     } else {
588       ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr);
589     }
590   }
591 
592   ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr);
593 
594 #if defined(PETSC_HAVE_MPE)
595   flg1 = PETSC_FALSE;
596   ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr);
597   if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);}
598 #endif
599   flg1 = PETSC_FALSE;
600   flg3 = PETSC_FALSE;
601   ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr);
602   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
603   if (flg1)                      { ierr = PetscLogAllBegin();CHKERRQ(ierr); }
604   else if (flg3)                 { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);}
605 
606   ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr);
607   if (flg1) {
608     char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN];
609     FILE *file;
610     if (mname[0]) {
611       PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank);
612       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
613       file = fopen(fname,"w");
614       if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname);
615     } else file = PETSC_STDOUT;
616     ierr = PetscLogTraceBegin(file);CHKERRQ(ierr);
617   }
618 
619   ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr);
620   if (flg4) {
621     if (format == PETSC_VIEWER_ASCII_XML) {
622       ierr = PetscLogNestedBegin();CHKERRQ(ierr);
623     } else {
624       ierr = PetscLogDefaultBegin();CHKERRQ(ierr);
625     }
626   }
627   if (flg4 && format == PETSC_VIEWER_ASCII_XML) {
628     PetscReal threshold = PetscRealConstant(0.01);
629     ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr);
630     if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);}
631   }
632 #endif
633 
634   ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr);
635 
636 #if defined(PETSC_HAVE_CUDA)
637   ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr);
638   ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr);
639   ierr = PetscOptionsEnd();CHKERRQ(ierr);
640   if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);}
641 #endif
642 
643   /*
644        Print basic help message
645   */
646   ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr);
647   if (flg1) {
648     ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr);
649     ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr);
650     ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr);
651     ierr = (*PetscHelpPrintf)(comm,"       only when run in the debugger\n");CHKERRQ(ierr);
652     ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
653     ierr = (*PetscHelpPrintf)(comm,"       start the debugger in new xterm\n");CHKERRQ(ierr);
654     ierr = (*PetscHelpPrintf)(comm,"       unless noxterm is given\n");CHKERRQ(ierr);
655     ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
656     ierr = (*PetscHelpPrintf)(comm,"       start all processes in the debugger\n");CHKERRQ(ierr);
657     ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr);
658     ierr = (*PetscHelpPrintf)(comm,"    emacs jumps to error file\n");CHKERRQ(ierr);
659     ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr);
660     ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr);
661     ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr);
662     ierr = (*PetscHelpPrintf)(comm,"                      waits the delay for you to attach\n");CHKERRQ(ierr);
663     ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr);
664     ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr);
665     ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr);
666     ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr);
667     ierr = (*PetscHelpPrintf)(comm,"           note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr);
668     ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr);
669     ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecaited, use -malloc_debug)\n");CHKERRQ(ierr);
670     ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecaited, use -malloc_debug)\n");CHKERRQ(ierr);
671     ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr);
672     ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr);
673     ierr = (*PetscHelpPrintf)(comm," -malloc_debug: enables extended checking for memory corruption\n");CHKERRQ(ierr);
674     ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr);
675     ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr);
676     ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr);
677     ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr);
678     ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr);
679     ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr);
680     ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr);
681 #if defined(PETSC_USE_LOG)
682     ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr);
683     ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr);
684     ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr);
685 #if defined(PETSC_HAVE_MPE)
686     ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr);
687 #endif
688     ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr);
689 #endif
690     ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr);
691     ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr);
692     ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr);
693     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
694   }
695 
696 #if defined(PETSC_HAVE_POPEN)
697   {
698   char machine[128];
699   ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr);
700   if (flg1) {
701     ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr);
702   }
703   }
704 #endif
705 
706   ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr);
707   if (flg1) {
708     ierr = PetscSleep(si);CHKERRQ(ierr);
709   }
710 
711   ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
712   if (flg1) {
713     ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr);
714     if (f) {
715       ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr);
716     }
717   }
718 
719 #if defined(PETSC_HAVE_VIENNACL)
720   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
721   if (!flg3) {
722     ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr);
723   }
724   ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr);
725   PetscViennaCLSynchronize = flg3;
726   ierr = PetscViennaCLInit();CHKERRQ(ierr);
727 #endif
728 
729   /*
730      Creates the logging data structures; this is enabled even if logging is not turned on
731      This is the last thing we do before returning to the user code to prevent having the
732      logging numbers contaminated by any startup time associated with MPI and the GPUs
733   */
734 #if defined(PETSC_USE_LOG)
735   ierr = PetscLogInitialize();CHKERRQ(ierr);
736 #endif
737 
738   PetscFunctionReturn(0);
739 }
740