xref: /petsc/src/sys/objects/init.c (revision f932c7a3d16c4c0b2320cabb21626a529033bc3d)
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 <default yes,no> - do the initialization in PetscInitialize(). If -cuda_initialize no is used then the default initialization is done automatically
207                                when the first CUDA call is made unless you call PetscCUDAInitialize() before any CUDA operations are performed
208 .  -cuda_view - view information about the CUDA devices
209 .  -cuda_synchronize - wait at the end of asynchronize CUDA calls so that their time gets credited to the current event; default with -log_view
210 -  -cuda_set_device <gpu> - integer number of the device
211 
212   Notes:
213    Initializing cuBLAS takes about 1/2 second there it is done by default in PetscInitialize() before logging begins
214 
215 @*/
216 PetscErrorCode PetscCUDAInitialize(MPI_Comm comm)
217 {
218   PetscErrorCode        ierr;
219   PetscInt              deviceOpt = 0;
220   PetscBool             cuda_view_flag = PETSC_FALSE,flg;
221   struct cudaDeviceProp prop;
222   int                   devCount,device,devicecnt;
223   cudaError_t           err = cudaSuccess;
224   PetscMPIInt           rank,size;
225 
226   PetscFunctionBegin;
227   /*
228      If collecting logging information, by default, wait for GPU to complete its operations
229      before returning to the CPU in order to get accurate timings of each event
230   */
231   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&PetscCUDASynchronize);CHKERRQ(ierr);
232   if (!PetscCUDASynchronize) {
233     ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&PetscCUDASynchronize);CHKERRQ(ierr);
234   }
235 
236   ierr = PetscOptionsBegin(comm,NULL,"CUDA options","Sys");CHKERRQ(ierr);
237   ierr = PetscOptionsInt("-cuda_set_device","Set all MPI ranks to use the specified CUDA device",NULL,deviceOpt,&deviceOpt,&flg);CHKERRQ(ierr);
238   device = (int)deviceOpt;
239   ierr = PetscOptionsBool("-cuda_synchronize","Wait for the GPU to complete operations before returning to the CPU",NULL,PetscCUDASynchronize,&PetscCUDASynchronize,NULL);CHKERRQ(ierr);
240   ierr = PetscOptionsDeprecated("-cuda_show_devices","-cuda_view","3.12",NULL);CHKERRQ(ierr);
241   ierr = PetscOptionsName("-cuda_view","Display CUDA device information and assignments",NULL,&cuda_view_flag);CHKERRQ(ierr);
242   ierr = PetscOptionsEnd();CHKERRQ(ierr);
243   if (!PetscCUDAInitialized) {
244     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
245 
246     if (size>1 && !flg) {
247       /* check to see if we force multiple ranks to hit the same GPU */
248       /* we're not using the same GPU on multiple MPI threads. So try to allocated different   GPUs to different processes */
249 
250       /* First get the device count */
251       err   = cudaGetDeviceCount(&devCount);
252       if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err));
253 
254       /* next determine the rank and then set the device via a mod */
255       ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
256       device = rank % devCount;
257     }
258     err = cudaSetDevice(device);
259     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDevice %s",cudaGetErrorString(err));
260 
261     /* set the device flags so that it can map host memory */
262     err = cudaSetDeviceFlags(cudaDeviceMapHost);
263     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDeviceFlags %s",cudaGetErrorString(err));
264 
265     ierr = PetscCUBLASInitializeHandle();CHKERRQ(ierr);
266     PetscCUDAInitialized = PETSC_TRUE;
267   }
268   if (cuda_view_flag) {
269     ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
270     err = cudaGetDeviceCount(&devCount);
271     if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err));
272     for (devicecnt = 0; devicecnt < devCount; ++devicecnt) {
273       err = cudaGetDeviceProperties(&prop,devicecnt);
274       if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceProperties %s",cudaGetErrorString(err));
275       ierr = PetscPrintf(comm, "CUDA device %d: %s\n", devicecnt, prop.name);CHKERRQ(ierr);
276     }
277     ierr = PetscSynchronizedPrintf(comm,"[%d] Using CUDA device %d.\n",rank,device);CHKERRQ(ierr);
278     ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr);
279   }
280   PetscFunctionReturn(0);
281 }
282 #endif
283 
284 /*@C
285    PetscEnd - Calls PetscFinalize() and then ends the program. This is useful if one
286      wishes a clean exit somewhere deep in the program.
287 
288    Collective on PETSC_COMM_WORLD
289 
290    Options Database Keys are the same as for PetscFinalize()
291 
292    Level: advanced
293 
294    Note:
295    See PetscInitialize() for more general runtime options.
296 
297 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscFinalize()
298 @*/
299 PetscErrorCode  PetscEnd(void)
300 {
301   PetscFunctionBegin;
302   PetscFinalize();
303   exit(0);
304   return 0;
305 }
306 
307 PetscBool PetscOptionsPublish = PETSC_FALSE;
308 PETSC_INTERN PetscErrorCode PetscSetUseHBWMalloc_Private(void);
309 PETSC_INTERN PetscBool      petscsetmallocvisited;
310 static       char           emacsmachinename[256];
311 
312 PetscErrorCode (*PetscExternalVersionFunction)(MPI_Comm) = 0;
313 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm)    = 0;
314 
315 /*@C
316    PetscSetHelpVersionFunctions - Sets functions that print help and version information
317    before the PETSc help and version information is printed. Must call BEFORE PetscInitialize().
318    This routine enables a "higher-level" package that uses PETSc to print its messages first.
319 
320    Input Parameter:
321 +  help - the help function (may be NULL)
322 -  version - the version function (may be NULL)
323 
324    Level: developer
325 
326 @*/
327 PetscErrorCode  PetscSetHelpVersionFunctions(PetscErrorCode (*help)(MPI_Comm),PetscErrorCode (*version)(MPI_Comm))
328 {
329   PetscFunctionBegin;
330   PetscExternalHelpFunction    = help;
331   PetscExternalVersionFunction = version;
332   PetscFunctionReturn(0);
333 }
334 
335 #if defined(PETSC_USE_LOG)
336 PETSC_INTERN PetscBool   PetscObjectsLog;
337 #endif
338 
339 PETSC_INTERN PetscErrorCode  PetscOptionsCheckInitial_Private(void)
340 {
341   char              string[64],mname[PETSC_MAX_PATH_LEN],*f;
342   MPI_Comm          comm = PETSC_COMM_WORLD;
343   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flag;
344   PetscErrorCode    ierr;
345   PetscReal         si;
346   PetscInt          intensity;
347   int               i;
348   PetscMPIInt       rank;
349   char              version[256],helpoptions[256];
350 #if defined(PETSC_USE_LOG)
351   PetscViewerFormat format;
352   PetscBool         flg4 = PETSC_FALSE;
353 #endif
354 #if defined(PETSC_HAVE_CUDA)
355   PetscBool         initCuda = PETSC_TRUE;
356 #endif
357 
358   PetscFunctionBegin;
359   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
360 
361 #if !defined(PETSC_HAVE_THREADSAFETY)
362   if (!(PETSC_RUNNING_ON_VALGRIND)) {
363     /*
364       Setup the memory management; support for tracing malloc() usage
365     */
366     PetscBool         mdebug = PETSC_FALSE, eachcall = PETSC_FALSE, initializenan = PETSC_FALSE, mlog = PETSC_FALSE;
367 
368 #if defined(PETSC_USE_DEBUG)
369     mdebug        = PETSC_TRUE;
370     initializenan = PETSC_TRUE;
371     ierr   = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr);
372 #else
373     /* don't warn about unused option */
374     ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr);
375     flg1 = PETSC_FALSE;
376 #endif
377     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_debug",&flg2,&flg3);CHKERRQ(ierr);
378     if (flg1 || flg2) {
379       mdebug        = PETSC_TRUE;
380       eachcall      = PETSC_TRUE;
381       initializenan = PETSC_TRUE;
382     } else if (flg3 && !flg2) {
383       mdebug        = PETSC_FALSE;
384       eachcall      = PETSC_FALSE;
385       initializenan = PETSC_FALSE;
386     }
387 
388     ierr = PetscOptionsHasName(NULL,NULL,"-malloc_view",&mlog);CHKERRQ(ierr);
389     if (mlog) {
390       mdebug = PETSC_TRUE;
391     }
392     /* the next line is deprecated */
393     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc",&mdebug,NULL);CHKERRQ(ierr);
394     ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&mdebug,NULL);CHKERRQ(ierr);
395     ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&mdebug,NULL);CHKERRQ(ierr);
396     if (mdebug) {
397       ierr = PetscMallocSetDebug(eachcall,initializenan);CHKERRQ(ierr);
398     }
399     if (mlog) {
400       PetscReal logthreshold = 0;
401       ierr = PetscOptionsGetReal(NULL,NULL,"-malloc_view_threshold",&logthreshold,NULL);CHKERRQ(ierr);
402       ierr = PetscMallocViewSet(logthreshold);CHKERRQ(ierr);
403     }
404   }
405 
406   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr);
407   if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);}
408   flg1 = PETSC_FALSE;
409   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr);
410   /* ignore this option if malloc is already set */
411   if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);}
412 
413   flg1 = PETSC_FALSE;
414   ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr);
415   if (!flg1) {
416     flg1 = PETSC_FALSE;
417     ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr);
418   }
419   if (flg1) {
420     ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr);
421   }
422 #endif
423 
424 #if defined(PETSC_USE_LOG)
425   ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr);
426 #endif
427 
428   /*
429       Set the display variable for graphics
430   */
431   ierr = PetscSetDisplay();CHKERRQ(ierr);
432 
433   /*
434       Print the PETSc version information
435   */
436   ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr);
437   ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr);
438   ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr);
439   if (flg1 || flg2 || flg3) {
440 
441     /*
442        Print "higher-level" package version message
443     */
444     if (PetscExternalVersionFunction) {
445       ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr);
446     }
447 
448     ierr = PetscGetVersion(version,256);CHKERRQ(ierr);
449     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
450     ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr);
451     ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr);
452     ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr);
453     ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr);
454     ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr);
455     ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr);
456     ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr);
457   }
458 
459   /*
460        Print "higher-level" package help message
461   */
462   if (flg3) {
463     if (PetscExternalHelpFunction) {
464       ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr);
465     }
466   }
467 
468   ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr);
469   if (flg1) {
470     ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr);
471     if (flg2) {
472       ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr);
473       ierr = PetscFreeMPIResources();CHKERRQ(ierr);
474       ierr = MPI_Finalize();CHKERRQ(ierr);
475       exit(0);
476     }
477   }
478 
479   /*
480       Setup the error handling
481   */
482   flg1 = PETSC_FALSE;
483   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr);
484   if (flg1) {
485     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr);
486     ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
487   }
488   flg1 = PETSC_FALSE;
489   ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr);
490   if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,0);CHKERRQ(ierr);}
491   flg1 = PETSC_FALSE;
492   ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr);
493   if (flg1) {
494     ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr);
495   }
496   flg1 = PETSC_FALSE;
497   ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
498   if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);}
499   flg1 = PETSC_FALSE;
500   ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,&flag);CHKERRQ(ierr);
501   if (flag) {ierr = PetscSetFPTrap((PetscFPTrap)flg1);CHKERRQ(ierr);}
502   ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr);
503   if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);}
504 
505   /*
506       Setup debugger information
507   */
508   ierr = PetscSetDefaultDebugger();CHKERRQ(ierr);
509   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr);
510   if (flg1) {
511     MPI_Errhandler err_handler;
512 
513     ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
514     ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr);
515     ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
516     ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,0);CHKERRQ(ierr);
517   }
518   ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr);
519   if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); }
520   ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr);
521   ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr);
522   if (flg1 || flg2) {
523     PetscMPIInt    size;
524     PetscInt       lsize,*nodes;
525     MPI_Errhandler err_handler;
526     /*
527        we have to make sure that all processors have opened
528        connections to all other processors, otherwise once the
529        debugger has stated it is likely to receive a SIGUSR1
530        and kill the program.
531     */
532     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
533     if (size > 2) {
534       PetscMPIInt dummy = 0;
535       MPI_Status  status;
536       for (i=0; i<size; i++) {
537         if (rank != i) {
538           ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr);
539         }
540       }
541       for (i=0; i<size; i++) {
542         if (rank != i) {
543           ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr);
544         }
545       }
546     }
547     /* check if this processor node should be in debugger */
548     ierr  = PetscMalloc1(size,&nodes);CHKERRQ(ierr);
549     lsize = size;
550     ierr  = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr);
551     if (flag) {
552       for (i=0; i<lsize; i++) {
553         if (nodes[i] == rank) { flag = PETSC_FALSE; break; }
554       }
555     }
556     if (!flag) {
557       ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr);
558       ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr);
559       if (flg1) {
560         ierr = PetscAttachDebugger();CHKERRQ(ierr);
561       } else {
562         ierr = PetscStopForDebugger();CHKERRQ(ierr);
563       }
564       ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr);
565       ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr);
566     }
567     ierr = PetscFree(nodes);CHKERRQ(ierr);
568   }
569 
570   ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr);
571   if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);}
572 
573   /*
574         Setup profiling and logging
575   */
576 #if defined(PETSC_USE_INFO)
577   {
578     char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0;
579     ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr);
580     if (flg1 && logname[0]) {
581       ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr);
582     } else if (flg1) {
583       ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr);
584     }
585   }
586 #endif
587 #if defined(PETSC_USE_LOG)
588   mname[0] = 0;
589   ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
590   if (flg1) {
591     if (mname[0]) {
592       ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr);
593     } else {
594       ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr);
595     }
596   }
597 
598   ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr);
599 
600 #if defined(PETSC_HAVE_MPE)
601   flg1 = PETSC_FALSE;
602   ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr);
603   if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);}
604 #endif
605   flg1 = PETSC_FALSE;
606   flg3 = PETSC_FALSE;
607   ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr);
608   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
609   if (flg1)                      { ierr = PetscLogAllBegin();CHKERRQ(ierr); }
610   else if (flg3)                 { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);}
611 
612   ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr);
613   if (flg1) {
614     char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN];
615     FILE *file;
616     if (mname[0]) {
617       PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank);
618       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
619       file = fopen(fname,"w");
620       if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname);
621     } else file = PETSC_STDOUT;
622     ierr = PetscLogTraceBegin(file);CHKERRQ(ierr);
623   }
624 
625   ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr);
626   if (flg4) {
627     if (format == PETSC_VIEWER_ASCII_XML) {
628       ierr = PetscLogNestedBegin();CHKERRQ(ierr);
629     } else {
630       ierr = PetscLogDefaultBegin();CHKERRQ(ierr);
631     }
632   }
633   if (flg4 && format == PETSC_VIEWER_ASCII_XML) {
634     PetscReal threshold = PetscRealConstant(0.01);
635     ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr);
636     if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);}
637   }
638 #endif
639 
640   ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr);
641 
642 #if defined(PETSC_HAVE_CUDA)
643   ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr);
644   ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr);
645   ierr = PetscOptionsEnd();CHKERRQ(ierr);
646   if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);}
647 #endif
648 
649   /*
650        Print basic help message
651   */
652   ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr);
653   if (flg1) {
654     ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr);
655     ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr);
656     ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr);
657     ierr = (*PetscHelpPrintf)(comm,"       only when run in the debugger\n");CHKERRQ(ierr);
658     ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
659     ierr = (*PetscHelpPrintf)(comm,"       start the debugger in new xterm\n");CHKERRQ(ierr);
660     ierr = (*PetscHelpPrintf)(comm,"       unless noxterm is given\n");CHKERRQ(ierr);
661     ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr);
662     ierr = (*PetscHelpPrintf)(comm,"       start all processes in the debugger\n");CHKERRQ(ierr);
663     ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr);
664     ierr = (*PetscHelpPrintf)(comm,"    emacs jumps to error file\n");CHKERRQ(ierr);
665     ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr);
666     ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr);
667     ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr);
668     ierr = (*PetscHelpPrintf)(comm,"                      waits the delay for you to attach\n");CHKERRQ(ierr);
669     ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr);
670     ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr);
671     ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr);
672     ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr);
673     ierr = (*PetscHelpPrintf)(comm,"           note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr);
674     ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr);
675     ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr);
676     ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr);
677     ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr);
678     ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr);
679     ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr);
680     ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr);
681     ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr);
682     ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr);
683     ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr);
684     ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr);
685     ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr);
686     ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr);
687 #if defined(PETSC_USE_LOG)
688     ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr);
689     ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr);
690     ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr);
691 #if defined(PETSC_HAVE_MPE)
692     ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr);
693 #endif
694     ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr);
695 #endif
696     ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr);
697     ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr);
698     ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr);
699     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
700   }
701 
702 #if defined(PETSC_HAVE_POPEN)
703   {
704   char machine[128];
705   ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr);
706   if (flg1) {
707     ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr);
708   }
709   }
710 #endif
711 
712   ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr);
713   if (flg1) {
714     ierr = PetscSleep(si);CHKERRQ(ierr);
715   }
716 
717   ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
718   if (flg1) {
719     ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr);
720     if (f) {
721       ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr);
722     }
723   }
724 
725 #if defined(PETSC_HAVE_VIENNACL)
726   ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr);
727   if (!flg3) {
728     ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr);
729   }
730   ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr);
731   PetscViennaCLSynchronize = flg3;
732   ierr = PetscViennaCLInit();CHKERRQ(ierr);
733 #endif
734 
735   /*
736      Creates the logging data structures; this is enabled even if logging is not turned on
737      This is the last thing we do before returning to the user code to prevent having the
738      logging numbers contaminated by any startup time associated with MPI and the GPUs
739   */
740 #if defined(PETSC_USE_LOG)
741   ierr = PetscLogInitialize();CHKERRQ(ierr);
742 #endif
743 
744   PetscFunctionReturn(0);
745 }
746