xref: /petsc/src/sys/objects/pinit.c (revision 74b43855c84902f9769613ba74e50feff6557f3a)
1 
2 /*
3    This file defines the initialization of PETSc, including PetscInitialize()
4 */
5 
6 #include <petscsys.h>        /*I  "petscsys.h"   I*/
7 
8 #if defined(PETSC_HAVE_CUSP)
9 #include <cublas.h>
10 #endif
11 
12 #include <petscthreadcomm.h>
13 
14 #if defined(PETSC_USE_LOG)
15 extern PetscErrorCode PetscLogBegin_Private(void);
16 #endif
17 extern PetscBool  PetscHMPIWorker;
18 
19 /* -----------------------------------------------------------------------------------------*/
20 
21 extern FILE *petsc_history;
22 
23 extern PetscErrorCode PetscInitialize_DynamicLibraries(void);
24 extern PetscErrorCode PetscFinalize_DynamicLibraries(void);
25 extern PetscErrorCode PetscFListDestroyAll(void);
26 extern PetscErrorCode PetscOpFListDestroyAll(void);
27 extern PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
28 extern PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
29 extern PetscErrorCode PetscCloseHistoryFile(FILE **);
30 
31 /* 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_key;
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 #if defined(PETSC_USE_COMPLEX)
701   /*
702      Initialized the global complex variable; this is because with
703      shared libraries the constructors for global variables
704      are not called; at least on IRIX.
705   */
706   {
707 #if defined(PETSC_CLANGUAGE_CXX)
708     PetscScalar ic(0.0,1.0);
709     PETSC_i = ic;
710 #else
711     PETSC_i = I;
712 #endif
713   }
714 
715 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
716   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
717   ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
718   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr);
719   ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr);
720   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
721 #endif
722 #endif
723 
724   /*
725      Create the PETSc MPI reduction operator that sums of the first
726      half of the entries and maxes the second half.
727   */
728   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
729 
730 #if defined(PETSC_USE_REAL___FLOAT128)
731   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
732   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
733 #if defined(PETSC_USE_COMPLEX)
734   ierr = MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);CHKERRQ(ierr);
735   ierr = MPI_Type_commit(&MPIU___COMPLEX128);CHKERRQ(ierr);
736 #endif
737   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
738   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
739   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);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   if (PetscStackActive) {
1000     ierr = PetscStackDestroy();CHKERRQ(ierr);
1001   }
1002 #endif
1003 
1004   flg1 = PETSC_FALSE;
1005   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
1006   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1007   flg1 = PETSC_FALSE;
1008   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
1009   if (flg1) {
1010     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1011   }
1012   flg1 = PETSC_FALSE;
1013   flg2 = PETSC_FALSE;
1014   /* preemptive call to avoid listing this option in options table as unused */
1015   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1016   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
1017 
1018   if (flg2) {
1019     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1020   }
1021 
1022   /* to prevent PETSc -options_left from warning */
1023   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1024   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1025   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
1026 
1027   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1028     flg3 = PETSC_FALSE; /* default value is required */
1029     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1030     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1031     if (flg3) {
1032       if (!flg2) { /* have not yet printed the options */
1033 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1034       }
1035       if (!nopt) {
1036 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1037       } else if (nopt == 1) {
1038 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1039       } else {
1040 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1041       }
1042     }
1043 #if defined(PETSC_USE_DEBUG)
1044     if (nopt && !flg3 && !flg1) {
1045       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1046       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1047       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1048     } else if (nopt && flg3) {
1049 #else
1050     if (nopt && flg3) {
1051 #endif
1052       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1053     }
1054   }
1055 
1056   /*
1057      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1058   */
1059   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1060 
1061   /*
1062        List all objects the user may have forgot to free
1063   */
1064   if (objects_left && PetscObjectsCounts) {
1065     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1066   }
1067   for (i=0; i<PetscObjectsMaxCounts; i++) {
1068     if (PetscObjects[i]) {
1069       if (objects_left) {
1070         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1071       }
1072     }
1073   }
1074   /* cannot actually destroy the left over objects, but destroy the list */
1075   PetscObjectsCounts    = 0;
1076   PetscObjectsMaxCounts = 0;
1077   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1078 
1079 
1080 #if defined(PETSC_USE_LOG)
1081   ierr = PetscLogDestroy();CHKERRQ(ierr);
1082 #endif
1083 
1084   /*
1085        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1086   */
1087   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1088 
1089   /*
1090        Free all the registered op functions, such as MatOpList, etc
1091   */
1092   ierr = PetscOpFListDestroyAll();CHKERRQ(ierr);
1093 
1094   /*
1095      Destroy any packages that registered a finalize
1096   */
1097   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1098 
1099   /*
1100      Destroy all the function registration lists created
1101   */
1102   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1103 
1104   if (petsc_history) {
1105     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1106     petsc_history = 0;
1107   }
1108 
1109   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1110 
1111   {
1112     char fname[PETSC_MAX_PATH_LEN];
1113     FILE *fd;
1114     int  err;
1115 
1116     fname[0] = 0;
1117     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1118     flg2 = PETSC_FALSE;
1119     ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr);
1120 #if defined(PETSC_USE_DEBUG)
1121     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1122 #else
1123     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1124 #endif
1125     if (flg1 && fname[0]) {
1126       char sname[PETSC_MAX_PATH_LEN];
1127 
1128       sprintf(sname,"%s_%d",fname,rank);
1129       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1130       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1131       err = fclose(fd);
1132       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1133     } else if (flg1 || flg2) {
1134       MPI_Comm local_comm;
1135 
1136       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1137       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1138         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1139       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1140       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1141     }
1142   }
1143   {
1144     char fname[PETSC_MAX_PATH_LEN];
1145     FILE *fd = PETSC_NULL;
1146 
1147     fname[0] = 0;
1148     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1149     ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1150     if (flg1 && fname[0]) {
1151       int  err;
1152 
1153       if (!rank) {
1154         fd = fopen(fname,"w");
1155         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1156       }
1157       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1158       if (fd) {
1159         err = fclose(fd);
1160         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1161       }
1162     } else if (flg1 || flg2) {
1163       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1164     }
1165   }
1166   /* Can be destroyed only after all the options are used */
1167   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1168 
1169   PetscGlobalArgc = 0;
1170   PetscGlobalArgs = 0;
1171 
1172 #if defined(PETSC_USE_REAL___FLOAT128)
1173   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1174 #if defined(PETSC_USE_COMPLEX)
1175   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1176 #endif
1177   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1178   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1179   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1180 #endif
1181 
1182 #if defined(PETSC_USE_COMPLEX)
1183 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1184   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1185   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1186   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1187 #endif
1188 #endif
1189   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1190   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1191   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1192   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1193   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1194 
1195   /*
1196      Destroy any known inner MPI_Comm's and attributes pointing to them
1197      Note this will not destroy any new communicators the user has created.
1198 
1199      If all PETSc objects were not destroyed those left over objects will have hanging references to
1200      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1201  */
1202   {
1203     PetscCommCounter *counter;
1204     PetscMPIInt      flg;
1205     MPI_Comm         icomm;
1206     void             *ptr;
1207     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1208     if (flg) {
1209       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1210       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1211       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1212       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1213 
1214       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1215       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1216       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1217     }
1218     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1219     if (flg) {
1220       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1221       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1222       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1223       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1224 
1225       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1226       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1227       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1228     }
1229   }
1230 
1231   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1232   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1233   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1234 
1235   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1236   if (PetscBeganMPI) {
1237 #if defined(PETSC_HAVE_MPI_FINALIZED)
1238     PetscMPIInt flag;
1239     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1240     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1241 #endif
1242     ierr = MPI_Finalize();CHKERRQ(ierr);
1243   }
1244 
1245 #if defined(PETSC_HAVE_CUDA)
1246   cublasShutdown();
1247 #endif
1248 /*
1249 
1250      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1251    the communicator has some outstanding requests on it. Specifically if the
1252    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1253    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1254    is never freed as it should be. Thus one may obtain messages of the form
1255    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1256    memory was not freed.
1257 
1258 */
1259   ierr = PetscMallocClear();CHKERRQ(ierr);
1260   PetscInitializeCalled = PETSC_FALSE;
1261   PetscFinalizeCalled   = PETSC_TRUE;
1262   PetscFunctionReturn(ierr);
1263 }
1264 
1265 #if defined(PETSC_MISSING_LAPACK_lsame_)
1266 EXTERN_C_BEGIN
1267 int lsame_(char *a,char *b)
1268 {
1269   if (*a == *b) return 1;
1270   if (*a + 32 == *b) return 1;
1271   if (*a - 32 == *b) return 1;
1272   return 0;
1273 }
1274 EXTERN_C_END
1275 #endif
1276 
1277 #if defined(PETSC_MISSING_LAPACK_lsame)
1278 EXTERN_C_BEGIN
1279 int lsame(char *a,char *b)
1280 {
1281   if (*a == *b) return 1;
1282   if (*a + 32 == *b) return 1;
1283   if (*a - 32 == *b) return 1;
1284   return 0;
1285 }
1286 EXTERN_C_END
1287 #endif
1288