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