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