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