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