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