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