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