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