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