xref: /petsc/src/sys/objects/pinit.c (revision 6a6fc655e6b1b6c3ff84be1691b1c5064ef5f4c2)
1 
2 /*
3    This file defines the initialization of PETSc, including PetscInitialize()
4 */
5 
6 #include <petscsys.h>        /*I  "petscsys.h"   I*/
7 
8 #if defined(PETSC_HAVE_CUSP)
9 #include <cublas.h>
10 #endif
11 
12 #include <petscthreadcomm.h>
13 
14 #if defined(PETSC_USE_LOG)
15 extern PetscErrorCode PetscLogBegin_Private(void);
16 #endif
17 extern PetscBool  PetscHMPIWorker;
18 
19 /* -----------------------------------------------------------------------------------------*/
20 
21 extern FILE *petsc_history;
22 
23 extern PetscErrorCode PetscInitialize_DynamicLibraries(void);
24 extern PetscErrorCode PetscFinalize_DynamicLibraries(void);
25 extern PetscErrorCode PetscFListDestroyAll(void);
26 extern PetscErrorCode PetscOpFListDestroyAll(void);
27 extern PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
28 extern PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
29 extern PetscErrorCode PetscCloseHistoryFile(FILE **);
30 
31 #if defined(PETSC_HAVE_PTHREADCLASSES)
32 # include <../src/sys/objects/pthread/pthreadimpl.h>
33 #endif
34 
35 /* user may set this BEFORE calling PetscInitialize() */
36 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;
37 
38 PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
39 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
40 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
41 
42 /*
43      Declare and set all the string names of the PETSc enums
44 */
45 const char *const PetscBools[]     = {"FALSE","TRUE","PetscBool","PETSC_",0};
46 const char *const PetscCopyModes[] = {"COPY_VALUES","OWN_POINTER","USE_POINTER","PetscCopyMode","PETSC_",0};
47 const char *const PetscDataTypes[] = {"INT","DOUBLE","COMPLEX","LONG","SHORT","FLOAT",
48                                 "CHAR","LOGICAL","ENUM","BOOL","LONGDOUBLE","OBJECT","PetscDataType","PETSC_",0};
49 
50 PetscBool  PetscPreLoadingUsed = PETSC_FALSE;
51 PetscBool  PetscPreLoadingOn   = PETSC_FALSE;
52 
53 /*
54        Checks the options database for initializations related to the
55     PETSc components
56 */
57 #undef __FUNCT__
58 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
59 PetscErrorCode  PetscOptionsCheckInitial_Components(void)
60 {
61   PetscBool  flg1;
62   PetscErrorCode ierr;
63 
64   PetscFunctionBegin;
65   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr);
66   if (flg1) {
67 #if defined (PETSC_USE_LOG)
68     MPI_Comm   comm = PETSC_COMM_WORLD;
69     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
70     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
71     ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
72     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
73 #endif
74   }
75   PetscFunctionReturn(0);
76 }
77 
78 extern PetscBool PetscBeganMPI;
79 
80 #undef __FUNCT__
81 #define __FUNCT__ "PetscInitializeNoPointers"
82 /*
83       PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args
84 
85    Collective
86 
87    Level: advanced
88 
89     Notes: this is called only by the PETSc MATLAB and Julia interface. Even though it might start MPI it sets the flag to
90      indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to
91      be called multiple times from MATLAB and Julia without the problem of trying to initialize MPI more than once.
92 
93      Turns off PETSc signal handling because that can interact with MATLAB's signal handling causing random crashes.
94 
95 .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments()
96 */
97 PetscErrorCode  PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help)
98 {
99   PetscErrorCode ierr;
100   int            myargc = argc;
101   char           **myargs = args;
102 
103   PetscFunctionBegin;
104   ierr = PetscInitialize(&myargc,&myargs,filename,help);
105   ierr = PetscPopSignalHandler();CHKERRQ(ierr);
106   PetscBeganMPI = PETSC_FALSE;
107   PetscFunctionReturn(ierr);
108 }
109 
110 #undef __FUNCT__
111 #define __FUNCT__ "PetscGetPETSC_COMM_SELF"
112 /*
113       Used by MATLAB and Julia interface to get communicator
114 */
115 PetscErrorCode  PetscGetPETSC_COMM_SELF(MPI_Comm *comm)
116 {
117   PetscFunctionBegin;
118   *comm = PETSC_COMM_SELF;
119   PetscFunctionReturn(0);
120 }
121 
122 #undef __FUNCT__
123 #define __FUNCT__ "PetscInitializeNoArguments"
124 /*@C
125       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
126         the command line arguments.
127 
128    Collective
129 
130    Level: advanced
131 
132 .seealso: PetscInitialize(), PetscInitializeFortran()
133 @*/
134 PetscErrorCode  PetscInitializeNoArguments(void)
135 {
136   PetscErrorCode ierr;
137   int            argc = 0;
138   char           **args = 0;
139 
140   PetscFunctionBegin;
141   ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
142   PetscFunctionReturn(ierr);
143 }
144 
145 #undef __FUNCT__
146 #define __FUNCT__ "PetscInitialized"
147 /*@
148       PetscInitialized - Determine whether PETSc is initialized.
149 
150 7   Level: beginner
151 
152 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
153 @*/
154 PetscErrorCode  PetscInitialized(PetscBool  *isInitialized)
155 {
156   PetscFunctionBegin;
157   PetscValidPointer(isInitialized, 1);
158   *isInitialized = PetscInitializeCalled;
159   PetscFunctionReturn(0);
160 }
161 
162 #undef __FUNCT__
163 #define __FUNCT__ "PetscFinalized"
164 /*@
165       PetscFinalized - Determine whether PetscFinalize() has been called yet
166 
167    Level: developer
168 
169 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
170 @*/
171 PetscErrorCode  PetscFinalized(PetscBool  *isFinalized)
172 {
173   PetscFunctionBegin;
174   PetscValidPointer(isFinalized, 1);
175   *isFinalized = PetscFinalizeCalled;
176   PetscFunctionReturn(0);
177 }
178 
179 extern PetscErrorCode        PetscOptionsCheckInitial_Private(void);
180 extern PetscBool  PetscBeganMPI;
181 
182 /*
183        This function is the MPI reduction operation used to compute the sum of the
184    first half of the datatype and the max of the second half.
185 */
186 MPI_Op PetscMaxSum_Op = 0;
187 
188 EXTERN_C_BEGIN
189 #undef __FUNCT__
190 #define __FUNCT__ "PetscMaxSum_Local"
191 void  MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
192 {
193   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
194 
195   PetscFunctionBegin;
196   if (*datatype != MPIU_2INT) {
197     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
198     MPI_Abort(MPI_COMM_WORLD,1);
199   }
200 
201   for (i=0; i<count; i++) {
202     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
203     xout[2*i+1] += xin[2*i+1];
204   }
205   PetscFunctionReturnVoid();
206 }
207 EXTERN_C_END
208 
209 /*
210     Returns the max of the first entry owned by this processor and the
211 sum of the second entry.
212 
213     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
214 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
215 there would be no place to store the both needed results.
216 */
217 #undef __FUNCT__
218 #define __FUNCT__ "PetscMaxSum"
219 PetscErrorCode  PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
220 {
221   PetscMPIInt    size,rank;
222   PetscInt       *work;
223   PetscErrorCode ierr;
224 
225   PetscFunctionBegin;
226   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
227   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
228   ierr   = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
229   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
230   *max   = work[2*rank];
231   *sum   = work[2*rank+1];
232   ierr   = PetscFree(work);CHKERRQ(ierr);
233   PetscFunctionReturn(0);
234 }
235 
236 /* ----------------------------------------------------------------------------*/
237 MPI_Op  PetscADMax_Op = 0;
238 
239 EXTERN_C_BEGIN
240 #undef __FUNCT__
241 #define __FUNCT__ "PetscADMax_Local"
242 void  MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
243 {
244   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
245   PetscInt    i,count = *cnt;
246 
247   PetscFunctionBegin;
248   if (*datatype != MPIU_2SCALAR) {
249     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
250     MPI_Abort(MPI_COMM_WORLD,1);
251   }
252 
253   for (i=0; i<count; i++) {
254     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
255       xout[2*i]   = xin[2*i];
256       xout[2*i+1] = xin[2*i+1];
257     }
258   }
259   PetscFunctionReturnVoid();
260 }
261 EXTERN_C_END
262 
263 MPI_Op  PetscADMin_Op = 0;
264 
265 EXTERN_C_BEGIN
266 #undef __FUNCT__
267 #define __FUNCT__ "PetscADMin_Local"
268 void  MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
269 {
270   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
271   PetscInt    i,count = *cnt;
272 
273   PetscFunctionBegin;
274   if (*datatype != MPIU_2SCALAR) {
275     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
276     MPI_Abort(MPI_COMM_WORLD,1);
277   }
278 
279   for (i=0; i<count; i++) {
280     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
281       xout[2*i]   = xin[2*i];
282       xout[2*i+1] = xin[2*i+1];
283     }
284   }
285   PetscFunctionReturnVoid();
286 }
287 EXTERN_C_END
288 /* ---------------------------------------------------------------------------------------*/
289 
290 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
291 MPI_Op MPIU_SUM = 0;
292 
293 EXTERN_C_BEGIN
294 #undef __FUNCT__
295 #define __FUNCT__ "PetscSum_Local"
296 void  PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
297 {
298   PetscInt    i,count = *cnt;
299 
300   PetscFunctionBegin;
301   if (*datatype == MPIU_SCALAR) {
302     PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
303     for (i=0; i<count; i++) {
304       xout[i] += xin[i];
305     }
306   } else if (*datatype == MPIU_REAL) {
307     PetscReal *xin = (PetscReal *)in,*xout = (PetscReal*)out;
308     for (i=0; i<count; i++) {
309       xout[i] += xin[i];
310     }
311   } else {
312     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types");
313     MPI_Abort(MPI_COMM_WORLD,1);
314   }
315   PetscFunctionReturnVoid();
316 }
317 EXTERN_C_END
318 #endif
319 
320 #if defined(PETSC_USE_REAL___FLOAT128)
321 MPI_Op MPIU_MAX = 0;
322 MPI_Op MPIU_MIN = 0;
323 
324 EXTERN_C_BEGIN
325 #undef __FUNCT__
326 #define __FUNCT__ "PetscMax_Local"
327 void  PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
328 {
329   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
330   PetscInt    i,count = *cnt;
331 
332   PetscFunctionBegin;
333   if (*datatype != MPIU_SCALAR) {
334     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
335     MPI_Abort(MPI_COMM_WORLD,1);
336   }
337 
338   for (i=0; i<count; i++) {
339     xout[i] = PetscMax(xout[i],xin[i]);
340   }
341   PetscFunctionReturnVoid();
342 }
343 EXTERN_C_END
344 
345 EXTERN_C_BEGIN
346 #undef __FUNCT__
347 #define __FUNCT__ "PetscMin_Local"
348 void  PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
349 {
350   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
351   PetscInt    i,count = *cnt;
352 
353   PetscFunctionBegin;
354   if (*datatype != MPIU_SCALAR) {
355     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
356     MPI_Abort(MPI_COMM_WORLD,1);
357   }
358 
359   for (i=0; i<count; i++) {
360     xout[i] = PetscMin(xout[i],xin[i]);
361   }
362   PetscFunctionReturnVoid();
363 }
364 EXTERN_C_END
365 #endif
366 
367 EXTERN_C_BEGIN
368 #undef __FUNCT__
369 #define __FUNCT__ "Petsc_DelCounter"
370 /*
371    Private routine to delete internal tag/name counter storage when a communicator is freed.
372 
373    This is called by MPI, not by users. This is called by MPI_Comm_free() when the communicator that has this  data as an attribute is freed.
374 
375    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
376 
377 */
378 PetscMPIInt  MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
379 {
380   PetscErrorCode ierr;
381 
382   PetscFunctionBegin;
383   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
384   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
385   PetscFunctionReturn(MPI_SUCCESS);
386 }
387 EXTERN_C_END
388 
389 EXTERN_C_BEGIN
390 #undef __FUNCT__
391 #define __FUNCT__ "Petsc_DelComm"
392 /*
393   This does not actually free anything, it simply marks when a reference count to an internal or external MPI_Comm reaches zero and the
394   the external MPI_Comm drops its reference to the internal or external MPI_Comm
395 
396   This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator.
397 
398   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
399 
400 */
401 PetscMPIInt  MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
402 {
403   PetscErrorCode   ierr;
404   PetscMPIInt      flg;
405   MPI_Comm         icomm;
406   void             *ptr;
407 
408   PetscFunctionBegin;
409   ierr  = MPI_Attr_get(comm,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
410   if (flg) {
411     /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
412     ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
413     ierr = MPI_Attr_get(icomm,Petsc_OuterComm_keyval,&ptr,&flg);CHKERRQ(ierr);
414     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected reference to outer comm");
415     ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
416     ierr = PetscInfo1(0,"User MPI_Comm m %ld is being freed, removing reference from inner PETSc comm to this outer comm\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
417   } else {
418     ierr = PetscInfo1(0,"Removing reference to PETSc communicator imbedded in a user MPI_Comm m %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
419   }
420   PetscFunctionReturn(MPI_SUCCESS);
421 }
422 EXTERN_C_END
423 
424 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
425 #if !defined(PETSC_WORDS_BIGENDIAN)
426 EXTERN_C_BEGIN
427 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
428 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
429 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
430 EXTERN_C_END
431 #endif
432 #endif
433 
434 int  PetscGlobalArgc   = 0;
435 char **PetscGlobalArgs = 0;
436 
437 #undef __FUNCT__
438 #define __FUNCT__ "PetscGetArgs"
439 /*@C
440    PetscGetArgs - Allows you to access the raw command line arguments anywhere
441      after PetscInitialize() is called but before PetscFinalize().
442 
443    Not Collective
444 
445    Output Parameters:
446 +  argc - count of number of command line arguments
447 -  args - the command line arguments
448 
449    Level: intermediate
450 
451    Notes:
452       This is usually used to pass the command line arguments into other libraries
453    that are called internally deep in PETSc or the application.
454 
455       The first argument contains the program name as is normal for C arguments.
456 
457    Concepts: command line arguments
458 
459 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
460 
461 @*/
462 PetscErrorCode  PetscGetArgs(int *argc,char ***args)
463 {
464   PetscFunctionBegin;
465   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
466   *argc = PetscGlobalArgc;
467   *args = PetscGlobalArgs;
468   PetscFunctionReturn(0);
469 }
470 
471 #undef __FUNCT__
472 #define __FUNCT__ "PetscGetArguments"
473 /*@C
474    PetscGetArguments - Allows you to access the  command line arguments anywhere
475      after PetscInitialize() is called but before PetscFinalize().
476 
477    Not Collective
478 
479    Output Parameters:
480 .  args - the command line arguments
481 
482    Level: intermediate
483 
484    Notes:
485       This does NOT start with the program name and IS null terminated (final arg is void)
486 
487    Concepts: command line arguments
488 
489 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
490 
491 @*/
492 PetscErrorCode  PetscGetArguments(char ***args)
493 {
494   PetscInt       i,argc = PetscGlobalArgc;
495   PetscErrorCode ierr;
496 
497   PetscFunctionBegin;
498   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
499   if (!argc) {*args = 0; PetscFunctionReturn(0);}
500   ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr);
501   for (i=0; i<argc-1; i++) {
502     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
503   }
504   (*args)[argc-1] = 0;
505   PetscFunctionReturn(0);
506 }
507 
508 #undef __FUNCT__
509 #define __FUNCT__ "PetscFreeArguments"
510 /*@C
511    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
512 
513    Not Collective
514 
515    Output Parameters:
516 .  args - the command line arguments
517 
518    Level: intermediate
519 
520    Concepts: command line arguments
521 
522 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
523 
524 @*/
525 PetscErrorCode  PetscFreeArguments(char **args)
526 {
527   PetscInt       i = 0;
528   PetscErrorCode ierr;
529 
530   PetscFunctionBegin;
531   if (!args) {PetscFunctionReturn(0);}
532   while (args[i]) {
533     ierr = PetscFree(args[i]);CHKERRQ(ierr);
534     i++;
535   }
536   ierr = PetscFree(args);CHKERRQ(ierr);
537   PetscFunctionReturn(0);
538 }
539 
540 #undef __FUNCT__
541 #define __FUNCT__ "PetscInitialize"
542 /*@C
543    PetscInitialize - Initializes the PETSc database and MPI.
544    PetscInitialize() calls MPI_Init() if that has yet to be called,
545    so this routine should always be called near the beginning of
546    your program -- usually the very first line!
547 
548    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
549 
550    Input Parameters:
551 +  argc - count of number of command line arguments
552 .  args - the command line arguments
553 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for
554           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
555 -  help - [optional] Help message to print, use PETSC_NULL for no message
556 
557    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
558    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
559    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
560    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
561    if different subcommunicators of the job are doing different things with PETSc.
562 
563    Options Database Keys:
564 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
565 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
566 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
567 .  -on_error_abort calls abort() when error detected (no traceback)
568 .  -on_error_mpiabort calls MPI_abort() when error detected
569 .  -error_output_stderr prints error messages to stderr instead of the default stdout
570 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
571 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
572 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
573 .  -stop_for_debugger - Print message on how to attach debugger manually to
574                         process and wait (-debugger_pause) seconds for attachment
575 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
576 .  -malloc no - Indicates not to use error-checking malloc
577 .  -malloc_debug - check for memory corruption at EVERY malloc or free
578 .  -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds
579 .  -fp_trap - Stops on floating point exceptions (Note that on the
580               IBM RS6000 this slows code by at least a factor of 10.)
581 .  -no_signal_handler - Indicates not to trap error signals
582 .  -shared_tmp - indicates /tmp directory is shared by all processors
583 .  -not_shared_tmp - each processor has own /tmp
584 .  -tmp - alternative name of /tmp directory
585 .  -get_total_flops - returns total flops done by all processors
586 .  -memory_info - Print memory usage at end of run
587 -  -server <port> - start PETSc webserver (default port is 8080)
588 
589    Options Database Keys for Profiling:
590    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
591 +  -log_trace [filename] - Print traces of all PETSc calls
592         to the screen (useful to determine where a program
593         hangs without running in the debugger).  See PetscLogTraceBegin().
594 .  -info <optional filename> - Prints verbose information to the screen
595 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
596 
597    Environmental Variables:
598 +   PETSC_TMP - alternative tmp directory
599 .   PETSC_SHARED_TMP - tmp is shared by all processes
600 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
601 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
602 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
603 
604 
605    Level: beginner
606 
607    Notes:
608    If for some reason you must call MPI_Init() separately, call
609    it before PetscInitialize().
610 
611    Fortran Version:
612    In Fortran this routine has the format
613 $       call PetscInitialize(file,ierr)
614 
615 +   ierr - error return code
616 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
617           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
618 
619    Important Fortran Note:
620    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
621    null character string; you CANNOT just use PETSC_NULL as
622    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.
623 
624    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
625    calling PetscInitialize().
626 
627    Concepts: initializing PETSc
628 
629 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
630 
631 @*/
632 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
633 {
634   PetscErrorCode ierr;
635   PetscMPIInt    flag, size;
636   PetscInt       nodesize;
637   PetscBool      flg;
638   char           hostname[256];
639 
640   PetscFunctionBegin;
641   if (PetscInitializeCalled) PetscFunctionReturn(0);
642 
643   /* these must be initialized in a routine, not as a constant declaration*/
644   PETSC_STDOUT = stdout;
645   PETSC_STDERR = stderr;
646 
647   ierr = PetscOptionsCreate();CHKERRQ(ierr);
648 
649   /*
650      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
651      it that it sets args[0] on all processors to be args[0] on the first processor.
652   */
653   if (argc && *argc) {
654     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
655   } else {
656     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
657   }
658 
659   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
660   if (!flag) {
661     if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
662 #if defined(PETSC_HAVE_MPI_INIT_THREAD)
663     {
664       PetscMPIInt provided;
665       ierr = MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);CHKERRQ(ierr);
666     }
667 #else
668     ierr = MPI_Init(argc,args);CHKERRQ(ierr);
669 #endif
670     PetscBeganMPI = PETSC_TRUE;
671   }
672   if (argc && args) {
673     PetscGlobalArgc = *argc;
674     PetscGlobalArgs = *args;
675   }
676   PetscFinalizeCalled   = PETSC_FALSE;
677 
678   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
679     PETSC_COMM_WORLD = MPI_COMM_WORLD;
680   }
681   ierr = MPI_Errhandler_set(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
682 
683   /* Done after init due to a bug in MPICH-GM? */
684   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
685 
686   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
687   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
688 
689 #if defined(PETSC_USE_COMPLEX)
690   /*
691      Initialized the global complex variable; this is because with
692      shared libraries the constructors for global variables
693      are not called; at least on IRIX.
694   */
695   {
696 #if defined(PETSC_CLANGUAGE_CXX)
697     PetscScalar ic(0.0,1.0);
698     PETSC_i = ic;
699 #else
700     PETSC_i = I;
701 #endif
702   }
703 
704 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
705   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
706   ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
707   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr);
708   ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr);
709   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
710 #endif
711 #endif
712 
713   /*
714      Create the PETSc MPI reduction operator that sums of the first
715      half of the entries and maxes the second half.
716   */
717   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
718 
719 #if defined(PETSC_USE_REAL___FLOAT128)
720   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
721   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
722   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
723   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
724   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
725 #endif
726 
727   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
728   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
729   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
730   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
731 
732   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
733   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
734 
735   /*
736      Attributes to be set on PETSc communicators
737   */
738   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
739   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
740   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
741 
742   /*
743      Build the options database
744   */
745   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
746 
747 
748   /*
749      Print main application help message
750   */
751   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
752   if (help && flg) {
753     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
754   }
755   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
756 
757   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
758 #if defined(PETSC_USE_LOG)
759   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
760 #endif
761 
762   /*
763      Load the dynamic libraries (on machines that support them), this registers all
764      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
765   */
766   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
767 
768   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
769   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
770   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
771   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
772 
773   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
774   /* Check the options database for options related to the options database itself */
775   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
776 
777 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
778   /*
779       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
780 
781       Currently not used because it is not supported by MPICH.
782   */
783 #if !defined(PETSC_WORDS_BIGENDIAN)
784   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
785 #endif
786 #endif
787 
788   ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
789   if (flg) {
790 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
791     ierr = PetscHMPISpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
792 #else
793     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead");
794 #endif
795   } else {
796     ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_merge_size",&nodesize,&flg);CHKERRQ(ierr);
797     if (flg) {
798       ierr = PetscHMPIMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
799       if (PetscHMPIWorker) { /* if worker then never enter user code */
800         PetscInitializeCalled = PETSC_TRUE;
801         ierr = PetscEnd();
802       }
803     }
804   }
805 
806 #if defined(PETSC_HAVE_CUDA)
807   cublasInit();
808 #endif
809 
810 #if defined(PETSC_HAVE_AMS)
811   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
812   if (flg) {
813     PetscAMSPublishAll = PETSC_TRUE;
814   }
815 #endif
816 
817   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
818   if (flg) {
819     PetscInitializeCalled = PETSC_TRUE;
820     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
821   }
822 
823 #if defined(PETSC_THREADCOMM_ACTIVE)
824   ierr = PetscThreadCommInitializePackage(PETSC_NULL);CHKERRQ(ierr);
825 #endif
826 
827   /*
828       Once we are completedly initialized then we can set this variables
829   */
830   PetscInitializeCalled = PETSC_TRUE;
831   PetscFunctionReturn(0);
832 }
833 
834 extern PetscObject *PetscObjects;
835 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
836 
837 #undef __FUNCT__
838 #define __FUNCT__ "PetscFinalize"
839 /*@C
840    PetscFinalize - Checks for options to be called at the conclusion
841    of the program. MPI_Finalize() is called only if the user had not
842    called MPI_Init() before calling PetscInitialize().
843 
844    Collective on PETSC_COMM_WORLD
845 
846    Options Database Keys:
847 +  -options_table - Calls PetscOptionsView()
848 .  -options_left - Prints unused options that remain in the database
849 .  -objects_left  - Prints list of all objects that have not been freed
850 .  -mpidump - Calls PetscMPIDump()
851 .  -malloc_dump - Calls PetscMallocDump()
852 .  -malloc_info - Prints total memory usage
853 -  -malloc_log - Prints summary of memory usage
854 
855    Options Database Keys for Profiling:
856    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
857 +  -log_summary [filename] - Prints summary of flop and timing
858         information to screen. If the filename is specified the
859         summary is written to the file.  See PetscLogView().
860 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
861         See PetscLogPrintSViewPython().
862 .  -log_all [filename] - Logs extensive profiling information
863         See PetscLogDump().
864 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
865 .  -log_sync - Log the synchronization in scatters, inner products
866         and norms
867 -  -log_mpe [filename] - Creates a logfile viewable by the
868       utility Upshot/Nupshot (in MPICH distribution)
869 
870    Level: beginner
871 
872    Note:
873    See PetscInitialize() for more general runtime options.
874 
875 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
876 @*/
877 PetscErrorCode  PetscFinalize(void)
878 {
879   PetscErrorCode ierr;
880   PetscMPIInt    rank;
881   PetscInt       i,nopt;
882   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
883 #if defined(PETSC_HAVE_AMS)
884   PetscBool      flg = PETSC_FALSE;
885 #endif
886 #if defined(PETSC_USE_LOG)
887   char           mname[PETSC_MAX_PATH_LEN];
888 #endif
889 
890   PetscFunctionBegin;
891 
892   if (!PetscInitializeCalled) {
893     printf("PetscInitialize() must be called before PetscFinalize()\n");
894     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
895   }
896   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
897 
898 #if defined(PETSC_HAVE_AMS)
899   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
900   if (flg) {
901     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
902   }
903 #endif
904 
905   ierr = PetscHMPIFinalize();CHKERRQ(ierr);
906 
907 #if defined(PETSC_HAVE_PTHREADCLASSES)
908   ierr = PetscThreadsFinalize();CHKERRQ(ierr);
909 #endif
910 
911   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
912   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
913   if (!flg2) {
914     flg2 = PETSC_FALSE;
915     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
916   }
917   if (flg2) {
918     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
919   }
920 
921 #if defined(PETSC_USE_LOG)
922   flg1 = PETSC_FALSE;
923   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
924   if (flg1) {
925     PetscLogDouble flops = 0;
926     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
927     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
928   }
929 #endif
930 
931 
932 #if defined(PETSC_USE_LOG)
933 #if defined(PETSC_HAVE_MPE)
934   mname[0] = 0;
935   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
936   if (flg1){
937     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
938     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
939   }
940 #endif
941   mname[0] = 0;
942   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
943   if (flg1) {
944     PetscViewer viewer;
945     if (mname[0])  {
946       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
947       ierr = PetscLogView(viewer);CHKERRQ(ierr);
948       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
949     } else {
950       viewer = PETSC_VIEWER_STDOUT_WORLD;
951       ierr = PetscLogView(viewer);CHKERRQ(ierr);
952     }
953   }
954 
955   mname[0] = 0;
956   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
957   if (flg1) {
958     PetscViewer viewer;
959     if (mname[0])  {
960       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
961       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
962       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
963     } else {
964       viewer = PETSC_VIEWER_STDOUT_WORLD;
965       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
966     }
967   }
968 
969   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
970   if (flg1) {
971     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
972     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
973   }
974 
975   mname[0] = 0;
976   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
977   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
978   if (flg1 || flg2){
979     if (mname[0]) PetscLogDump(mname);
980     else          PetscLogDump(0);
981   }
982 #endif
983 
984 #if defined(PETSC_USE_DEBUG)
985   if (PetscStackActive) {
986     ierr = PetscStackDestroy();CHKERRQ(ierr);
987   }
988 #endif
989 
990   flg1 = PETSC_FALSE;
991   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
992   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
993   flg1 = PETSC_FALSE;
994   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
995   if (flg1) {
996     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
997   }
998   flg1 = PETSC_FALSE;
999   flg2 = PETSC_FALSE;
1000   /* preemptive call to avoid listing this option in options table as unused */
1001   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1002   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
1003 
1004   if (flg2) {
1005     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1006   }
1007 
1008   /* to prevent PETSc -options_left from warning */
1009   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1010   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1011   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
1012 
1013   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1014     flg3 = PETSC_FALSE; /* default value is required */
1015     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1016     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1017     if (flg3) {
1018       if (!flg2) { /* have not yet printed the options */
1019 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1020       }
1021       if (!nopt) {
1022 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1023       } else if (nopt == 1) {
1024 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1025       } else {
1026 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1027       }
1028     }
1029 #if defined(PETSC_USE_DEBUG)
1030     if (nopt && !flg3 && !flg1) {
1031       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1032       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1033       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1034     } else if (nopt && flg3) {
1035 #else
1036     if (nopt && flg3) {
1037 #endif
1038       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1039     }
1040   }
1041 
1042   /*
1043      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1044   */
1045   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1046 
1047   /*
1048        List all objects the user may have forgot to free
1049   */
1050   if (objects_left && PetscObjectsCounts) {
1051     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1052   }
1053   for (i=0; i<PetscObjectsMaxCounts; i++) {
1054     if (PetscObjects[i]) {
1055       if (objects_left) {
1056         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1057       }
1058     }
1059   }
1060   /* cannot actually destroy the left over objects, but destroy the list */
1061   PetscObjectsCounts    = 0;
1062   PetscObjectsMaxCounts = 0;
1063   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1064 
1065 
1066 #if defined(PETSC_USE_LOG)
1067   ierr = PetscLogDestroy();CHKERRQ(ierr);
1068 #endif
1069 
1070   /*
1071        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1072   */
1073   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1074 
1075   /*
1076        Free all the registered op functions, such as MatOpList, etc
1077   */
1078   ierr = PetscOpFListDestroyAll();CHKERRQ(ierr);
1079 
1080   /*
1081      Destroy any packages that registered a finalize
1082   */
1083   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1084 
1085   /*
1086      Destroy all the function registration lists created
1087   */
1088   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1089 
1090   if (petsc_history) {
1091     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1092     petsc_history = 0;
1093   }
1094 
1095   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1096 
1097   {
1098     char fname[PETSC_MAX_PATH_LEN];
1099     FILE *fd;
1100     int  err;
1101 
1102     fname[0] = 0;
1103     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1104     flg2 = PETSC_FALSE;
1105     ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr);
1106 #if defined(PETSC_USE_DEBUG)
1107     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1108 #else
1109     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1110 #endif
1111     if (flg1 && fname[0]) {
1112       char sname[PETSC_MAX_PATH_LEN];
1113 
1114       sprintf(sname,"%s_%d",fname,rank);
1115       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1116       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1117       err = fclose(fd);
1118       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1119     } else if (flg1 || flg2) {
1120       MPI_Comm local_comm;
1121 
1122       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1123       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1124         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1125       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1126       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1127     }
1128   }
1129   {
1130     char fname[PETSC_MAX_PATH_LEN];
1131     FILE *fd;
1132 
1133     fname[0] = 0;
1134     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1135     if (flg1 && fname[0]) {
1136       char sname[PETSC_MAX_PATH_LEN];
1137       int  err;
1138 
1139       sprintf(sname,"%s_%d",fname,rank);
1140       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1141       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1142       err = fclose(fd);
1143       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1144     } else if (flg1) {
1145       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1146     }
1147   }
1148   /* Can be destroyed only after all the options are used */
1149   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1150 
1151   PetscGlobalArgc = 0;
1152   PetscGlobalArgs = 0;
1153 
1154 #if defined(PETSC_USE_REAL___FLOAT128)
1155   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1156   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1157   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1158   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1159 #endif
1160 
1161 #if defined(PETSC_USE_COMPLEX)
1162 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1163   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1164   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1165   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1166 #endif
1167 #endif
1168   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1169   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1170   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1171   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1172   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1173 
1174   /*
1175      Destroy any known inner MPI_Comm's and attributes pointing to them
1176      Note this will not destroy any new communicators the user has created.
1177 
1178      If all PETSc objects were not destroyed those left over objects will have hanging references to
1179      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1180  */
1181   {
1182     PetscCommCounter *counter;
1183     PetscMPIInt      flg;
1184     MPI_Comm         icomm;
1185     void             *ptr;
1186     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1187     if (flg) {
1188       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1189       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1190       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1191       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1192 
1193       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1194       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1195       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1196     }
1197     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1198     if (flg) {
1199       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1200       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1201       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1202       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1203 
1204       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1205       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1206       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1207     }
1208   }
1209 
1210   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1211   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1212   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1213 
1214   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1215   if (PetscBeganMPI) {
1216 #if defined(PETSC_HAVE_MPI_FINALIZED)
1217     PetscMPIInt flag;
1218     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1219     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1220 #endif
1221     ierr = MPI_Finalize();CHKERRQ(ierr);
1222   }
1223 
1224 #if defined(PETSC_HAVE_CUDA)
1225   cublasShutdown();
1226 #endif
1227 /*
1228 
1229      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1230    the communicator has some outstanding requests on it. Specifically if the
1231    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1232    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1233    is never freed as it should be. Thus one may obtain messages of the form
1234    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1235    memory was not freed.
1236 
1237 */
1238   ierr = PetscMallocClear();CHKERRQ(ierr);
1239   PetscInitializeCalled = PETSC_FALSE;
1240   PetscFinalizeCalled   = PETSC_TRUE;
1241   PetscFunctionReturn(ierr);
1242 }
1243 
1244 #if defined(PETSC_MISSING_LAPACK_lsame_)
1245 EXTERN_C_BEGIN
1246 int lsame_(char *a,char *b)
1247 {
1248   if (*a == *b) return 1;
1249   if (*a + 32 == *b) return 1;
1250   if (*a - 32 == *b) return 1;
1251   return 0;
1252 }
1253 EXTERN_C_END
1254 #endif
1255 
1256 #if defined(PETSC_MISSING_LAPACK_lsame)
1257 EXTERN_C_BEGIN
1258 int lsame(char *a,char *b)
1259 {
1260   if (*a == *b) return 1;
1261   if (*a + 32 == *b) return 1;
1262   if (*a - 32 == *b) return 1;
1263   return 0;
1264 }
1265 EXTERN_C_END
1266 #endif
1267