xref: /petsc/src/sys/objects/pinit.c (revision 663ba86aeb5feb887c4e53d1424b714197d7ad21)
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_CUDA)
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, p;
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   for(p = 0; p < PetscGlobalSize; ++p) {
825     if (p == PetscGlobalRank) {cublasInit();}
826     ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
827   }
828 #endif
829 
830 #if defined(PETSC_HAVE_AMS)
831   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
832   if (flg) {
833     PetscAMSPublishAll = PETSC_TRUE;
834   }
835 #endif
836 
837   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
838   if (flg) {
839     PetscInitializeCalled = PETSC_TRUE;
840     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
841   }
842 
843   ierr = PetscThreadCommInitializePackage(PETSC_NULL);CHKERRQ(ierr);
844 
845 #if defined(PETSC_USE_DEBUG)
846   PetscThreadLocalRegister(&petscstack); /* Creates petscstack_key if needed */
847   ierr = PetscStackCreate();CHKERRQ(ierr);
848 #endif
849 
850   /*
851       Once we are completedly initialized then we can set this variables
852   */
853   PetscInitializeCalled = PETSC_TRUE;
854   PetscFunctionReturn(0);
855 }
856 
857 extern PetscObject *PetscObjects;
858 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
859 
860 #undef __FUNCT__
861 #define __FUNCT__ "PetscFinalize"
862 /*@C
863    PetscFinalize - Checks for options to be called at the conclusion
864    of the program. MPI_Finalize() is called only if the user had not
865    called MPI_Init() before calling PetscInitialize().
866 
867    Collective on PETSC_COMM_WORLD
868 
869    Options Database Keys:
870 +  -options_table - Calls PetscOptionsView()
871 .  -options_left - Prints unused options that remain in the database
872 .  -objects_left  - Prints list of all objects that have not been freed
873 .  -mpidump - Calls PetscMPIDump()
874 .  -malloc_dump - Calls PetscMallocDump()
875 .  -malloc_info - Prints total memory usage
876 -  -malloc_log - Prints summary of memory usage
877 
878    Options Database Keys for Profiling:
879    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
880 +  -log_summary [filename] - Prints summary of flop and timing
881         information to screen. If the filename is specified the
882         summary is written to the file.  See PetscLogView().
883 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
884         See PetscLogPrintSViewPython().
885 .  -log_all [filename] - Logs extensive profiling information
886         See PetscLogDump().
887 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
888 .  -log_sync - Log the synchronization in scatters, inner products
889         and norms
890 -  -log_mpe [filename] - Creates a logfile viewable by the
891       utility Upshot/Nupshot (in MPICH distribution)
892 
893    Level: beginner
894 
895    Note:
896    See PetscInitialize() for more general runtime options.
897 
898 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
899 @*/
900 PetscErrorCode  PetscFinalize(void)
901 {
902   PetscErrorCode ierr;
903   PetscMPIInt    rank, p;
904   PetscInt       i,nopt;
905   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
906 #if defined(PETSC_HAVE_AMS)
907   PetscBool      flg = PETSC_FALSE;
908 #endif
909 #if defined(PETSC_USE_LOG)
910   char           mname[PETSC_MAX_PATH_LEN];
911 #endif
912 
913   PetscFunctionBegin;
914 
915   if (!PetscInitializeCalled) {
916     printf("PetscInitialize() must be called before PetscFinalize()\n");
917     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
918   }
919   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
920 
921 #if defined(PETSC_HAVE_AMS)
922   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
923   if (flg) {
924     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
925   }
926 #endif
927 
928   ierr = PetscHMPIFinalize();CHKERRQ(ierr);
929 
930   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
931   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
932   if (!flg2) {
933     flg2 = PETSC_FALSE;
934     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
935   }
936   if (flg2) {
937     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
938   }
939 
940 #if defined(PETSC_USE_LOG)
941   flg1 = PETSC_FALSE;
942   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
943   if (flg1) {
944     PetscLogDouble flops = 0;
945     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
946     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
947   }
948 #endif
949 
950 
951 #if defined(PETSC_USE_LOG)
952 #if defined(PETSC_HAVE_MPE)
953   mname[0] = 0;
954   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
955   if (flg1){
956     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
957     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
958   }
959 #endif
960   mname[0] = 0;
961   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
962   if (flg1) {
963     PetscViewer viewer;
964     if (mname[0])  {
965       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
966       ierr = PetscLogView(viewer);CHKERRQ(ierr);
967       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
968     } else {
969       viewer = PETSC_VIEWER_STDOUT_WORLD;
970       ierr = PetscLogView(viewer);CHKERRQ(ierr);
971     }
972   }
973 
974   mname[0] = 0;
975   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
976   if (flg1) {
977     PetscViewer viewer;
978     if (mname[0])  {
979       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
980       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
981       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
982     } else {
983       viewer = PETSC_VIEWER_STDOUT_WORLD;
984       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
985     }
986   }
987 
988   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
989   if (flg1) {
990     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
991     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
992   }
993 
994   mname[0] = 0;
995   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
996   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
997   if (flg1 || flg2){
998     if (mname[0]) PetscLogDump(mname);
999     else          PetscLogDump(0);
1000   }
1001 #endif
1002 
1003 #if defined(PETSC_USE_DEBUG)
1004   ierr = PetscStackDestroy();CHKERRQ(ierr);
1005 #endif
1006 
1007   flg1 = PETSC_FALSE;
1008   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
1009   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1010   flg1 = PETSC_FALSE;
1011   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
1012   if (flg1) {
1013     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1014   }
1015   flg1 = PETSC_FALSE;
1016   flg2 = PETSC_FALSE;
1017   /* preemptive call to avoid listing this option in options table as unused */
1018   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1019   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
1020 
1021   if (flg2) {
1022     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1023   }
1024 
1025   /* to prevent PETSc -options_left from warning */
1026   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1027   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1028   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
1029 
1030   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1031     flg3 = PETSC_FALSE; /* default value is required */
1032     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1033     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1034     if (flg3) {
1035       if (!flg2) { /* have not yet printed the options */
1036 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1037       }
1038       if (!nopt) {
1039 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1040       } else if (nopt == 1) {
1041 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1042       } else {
1043 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1044       }
1045     }
1046 #if defined(PETSC_USE_DEBUG)
1047     if (nopt && !flg3 && !flg1) {
1048       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1049       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1050       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1051     } else if (nopt && flg3) {
1052 #else
1053     if (nopt && flg3) {
1054 #endif
1055       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1056     }
1057   }
1058 
1059   /*
1060      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1061   */
1062   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1063 
1064   /*
1065        List all objects the user may have forgot to free
1066   */
1067   if (objects_left && PetscObjectsCounts) {
1068     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1069   }
1070   for (i=0; i<PetscObjectsMaxCounts; i++) {
1071     if (PetscObjects[i]) {
1072       if (objects_left) {
1073         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1074       }
1075     }
1076   }
1077   /* cannot actually destroy the left over objects, but destroy the list */
1078   PetscObjectsCounts    = 0;
1079   PetscObjectsMaxCounts = 0;
1080   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1081 
1082 
1083 #if defined(PETSC_USE_LOG)
1084   ierr = PetscLogDestroy();CHKERRQ(ierr);
1085 #endif
1086 
1087   /*
1088        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1089   */
1090   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1091 
1092   /*
1093        Free all the registered op functions, such as MatOpList, etc
1094   */
1095   ierr = PetscOpFListDestroyAll();CHKERRQ(ierr);
1096 
1097   /*
1098      Destroy any packages that registered a finalize
1099   */
1100   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1101 
1102   /*
1103      Destroy all the function registration lists created
1104   */
1105   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1106 
1107   if (petsc_history) {
1108     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1109     petsc_history = 0;
1110   }
1111 
1112   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1113 
1114   {
1115     char fname[PETSC_MAX_PATH_LEN];
1116     FILE *fd;
1117     int  err;
1118 
1119     fname[0] = 0;
1120     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1121     flg2 = PETSC_FALSE;
1122     ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr);
1123 #if defined(PETSC_USE_DEBUG)
1124     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1125 #else
1126     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1127 #endif
1128     if (flg1 && fname[0]) {
1129       char sname[PETSC_MAX_PATH_LEN];
1130 
1131       sprintf(sname,"%s_%d",fname,rank);
1132       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1133       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1134       err = fclose(fd);
1135       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1136     } else if (flg1 || flg2) {
1137       MPI_Comm local_comm;
1138 
1139       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1140       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1141         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1142       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1143       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1144     }
1145   }
1146   {
1147     char fname[PETSC_MAX_PATH_LEN];
1148     FILE *fd = PETSC_NULL;
1149 
1150     fname[0] = 0;
1151     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1152     ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1153     if (flg1 && fname[0]) {
1154       int  err;
1155 
1156       if (!rank) {
1157         fd = fopen(fname,"w");
1158         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1159       }
1160       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1161       if (fd) {
1162         err = fclose(fd);
1163         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1164       }
1165     } else if (flg1 || flg2) {
1166       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1167     }
1168   }
1169   /* Can be destroyed only after all the options are used */
1170   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1171 
1172   PetscGlobalArgc = 0;
1173   PetscGlobalArgs = 0;
1174 
1175 #if defined(PETSC_USE_REAL___FLOAT128)
1176   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1177 #if defined(PETSC_USE_COMPLEX)
1178   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1179 #endif
1180   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1181   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1182 #endif
1183 
1184 #if defined(PETSC_USE_COMPLEX)
1185 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1186   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1187   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1188 #endif
1189 #endif
1190 
1191 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1192   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1193 #endif
1194 
1195   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1196   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1197   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1198   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1199   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1200 
1201   /*
1202      Destroy any known inner MPI_Comm's and attributes pointing to them
1203      Note this will not destroy any new communicators the user has created.
1204 
1205      If all PETSc objects were not destroyed those left over objects will have hanging references to
1206      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1207  */
1208   {
1209     PetscCommCounter *counter;
1210     PetscMPIInt      flg;
1211     MPI_Comm         icomm;
1212     void             *ptr;
1213     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1214     if (flg) {
1215       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1216       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1217       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1218       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1219 
1220       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1221       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1222       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1223     }
1224     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1225     if (flg) {
1226       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1227       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1228       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1229       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1230 
1231       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1232       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1233       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1234     }
1235   }
1236 
1237   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1238   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1239   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1240 
1241 #if defined(PETSC_HAVE_CUDA)
1242   for(p = 0; p < PetscGlobalSize; ++p) {
1243     if (p == PetscGlobalRank) {cublasShutdown();}
1244     ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1245   }
1246 #endif
1247 
1248   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1249   if (PetscBeganMPI) {
1250 #if defined(PETSC_HAVE_MPI_FINALIZED)
1251     PetscMPIInt flag;
1252     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1253     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1254 #endif
1255     ierr = MPI_Finalize();CHKERRQ(ierr);
1256   }
1257 /*
1258 
1259      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1260    the communicator has some outstanding requests on it. Specifically if the
1261    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1262    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1263    is never freed as it should be. Thus one may obtain messages of the form
1264    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1265    memory was not freed.
1266 
1267 */
1268   ierr = PetscMallocClear();CHKERRQ(ierr);
1269   PetscInitializeCalled = PETSC_FALSE;
1270   PetscFinalizeCalled   = PETSC_TRUE;
1271   PetscFunctionReturn(ierr);
1272 }
1273 
1274 #if defined(PETSC_MISSING_LAPACK_lsame_)
1275 EXTERN_C_BEGIN
1276 int lsame_(char *a,char *b)
1277 {
1278   if (*a == *b) return 1;
1279   if (*a + 32 == *b) return 1;
1280   if (*a - 32 == *b) return 1;
1281   return 0;
1282 }
1283 EXTERN_C_END
1284 #endif
1285 
1286 #if defined(PETSC_MISSING_LAPACK_lsame)
1287 EXTERN_C_BEGIN
1288 int lsame(char *a,char *b)
1289 {
1290   if (*a == *b) return 1;
1291   if (*a + 32 == *b) return 1;
1292   if (*a - 32 == *b) return 1;
1293   return 0;
1294 }
1295 EXTERN_C_END
1296 #endif
1297