xref: /petsc/src/sys/objects/pinit.c (revision 43208f3fbfb2a0d489265d03b5883f57f56e054f)
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_CUDA)
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 #if defined(PETSC_HAVE_COMPLEX)
706   {
707 #if defined(PETSC_CLANGUAGE_CXX)
708     PetscComplex ic(0.0,1.0);
709     PETSC_i = ic;
710 #elif defined(PETSC_CLANGUAGE_C)
711     PETSC_i = _Complex_I;
712 #endif
713   }
714 
715 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
716   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&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 #endif
721 #endif /* PETSC_HAVE_COMPLEX */
722 
723   /*
724      Create the PETSc MPI reduction operator that sums of the first
725      half of the entries and maxes the second half.
726   */
727   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
728 
729 #if defined(PETSC_USE_REAL___FLOAT128)
730   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
731   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
732 #if defined(PETSC_USE_COMPLEX)
733   ierr = MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);CHKERRQ(ierr);
734   ierr = MPI_Type_commit(&MPIU___COMPLEX128);CHKERRQ(ierr);
735 #endif
736   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
737   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
738 #endif
739 
740 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
741   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
742 #endif
743 
744   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
745   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
746   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
747   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
748 
749   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
750   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
751 
752   /*
753      Attributes to be set on PETSc communicators
754   */
755   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
756   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
757   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
758 
759   /*
760      Build the options database
761   */
762   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
763 
764 
765   /*
766      Print main application help message
767   */
768   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
769   if (help && flg) {
770     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
771   }
772   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
773 
774   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
775 #if defined(PETSC_USE_LOG)
776   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
777 #endif
778 
779   /*
780      Load the dynamic libraries (on machines that support them), this registers all
781      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
782   */
783   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
784 
785   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
786   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
787   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
788   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
789 
790   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
791   /* Check the options database for options related to the options database itself */
792   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
793 
794 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
795   /*
796       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
797 
798       Currently not used because it is not supported by MPICH.
799   */
800 #if !defined(PETSC_WORDS_BIGENDIAN)
801   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
802 #endif
803 #endif
804 
805   ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
806   if (flg) {
807 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
808     ierr = PetscHMPISpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
809 #else
810     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead");
811 #endif
812   } else {
813     ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_merge_size",&nodesize,&flg);CHKERRQ(ierr);
814     if (flg) {
815       ierr = PetscHMPIMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
816       if (PetscHMPIWorker) { /* if worker then never enter user code */
817         PetscInitializeCalled = PETSC_TRUE;
818         ierr = PetscEnd();
819       }
820     }
821   }
822 
823 #if defined(PETSC_HAVE_CUDA)
824   {
825     PetscMPIInt p;
826     for (p = 0; p < PetscGlobalSize; ++p) {
827       if (p == PetscGlobalRank) {cublasInit();}
828       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
829     }
830   }
831 #endif
832 
833 #if defined(PETSC_HAVE_AMS)
834   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
835   if (flg) {
836     PetscAMSPublishAll = PETSC_TRUE;
837   }
838 #endif
839 
840   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
841   if (flg) {
842     PetscInitializeCalled = PETSC_TRUE;
843     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
844   }
845 
846   ierr = PetscThreadCommInitializePackage(PETSC_NULL);CHKERRQ(ierr);
847 
848 #if defined(PETSC_USE_DEBUG)
849   PetscThreadLocalRegister(&petscstack); /* Creates petscstack_key if needed */
850   ierr = PetscStackCreate();CHKERRQ(ierr);
851 #endif
852 
853   /*
854       Once we are completedly initialized then we can set this variables
855   */
856   PetscInitializeCalled = PETSC_TRUE;
857   PetscFunctionReturn(0);
858 }
859 
860 extern PetscObject *PetscObjects;
861 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
862 
863 #undef __FUNCT__
864 #define __FUNCT__ "PetscFinalize"
865 /*@C
866    PetscFinalize - Checks for options to be called at the conclusion
867    of the program. MPI_Finalize() is called only if the user had not
868    called MPI_Init() before calling PetscInitialize().
869 
870    Collective on PETSC_COMM_WORLD
871 
872    Options Database Keys:
873 +  -options_table - Calls PetscOptionsView()
874 .  -options_left - Prints unused options that remain in the database
875 .  -objects_left  - Prints list of all objects that have not been freed
876 .  -mpidump - Calls PetscMPIDump()
877 .  -malloc_dump - Calls PetscMallocDump()
878 .  -malloc_info - Prints total memory usage
879 -  -malloc_log - Prints summary of memory usage
880 
881    Options Database Keys for Profiling:
882    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
883 +  -log_summary [filename] - Prints summary of flop and timing
884         information to screen. If the filename is specified the
885         summary is written to the file.  See PetscLogView().
886 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
887         See PetscLogPrintSViewPython().
888 .  -log_all [filename] - Logs extensive profiling information
889         See PetscLogDump().
890 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
891 .  -log_sync - Log the synchronization in scatters, inner products
892         and norms
893 -  -log_mpe [filename] - Creates a logfile viewable by the
894       utility Upshot/Nupshot (in MPICH distribution)
895 
896    Level: beginner
897 
898    Note:
899    See PetscInitialize() for more general runtime options.
900 
901 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
902 @*/
903 PetscErrorCode  PetscFinalize(void)
904 {
905   PetscErrorCode ierr;
906   PetscMPIInt    rank;
907   PetscInt       i,nopt;
908   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
909 #if defined(PETSC_HAVE_AMS)
910   PetscBool      flg = PETSC_FALSE;
911 #endif
912 #if defined(PETSC_USE_LOG)
913   char           mname[PETSC_MAX_PATH_LEN];
914 #endif
915 
916   PetscFunctionBegin;
917 
918   if (!PetscInitializeCalled) {
919     printf("PetscInitialize() must be called before PetscFinalize()\n");
920     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
921   }
922   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
923 
924 #if defined(PETSC_HAVE_AMS)
925   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
926   if (flg) {
927     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
928   }
929 #endif
930 
931   ierr = PetscHMPIFinalize();CHKERRQ(ierr);
932 
933   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
934   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
935   if (!flg2) {
936     flg2 = PETSC_FALSE;
937     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
938   }
939   if (flg2) {
940     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
941   }
942 
943 #if defined(PETSC_USE_LOG)
944   flg1 = PETSC_FALSE;
945   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
946   if (flg1) {
947     PetscLogDouble flops = 0;
948     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
949     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
950   }
951 #endif
952 
953 
954 #if defined(PETSC_USE_LOG)
955 #if defined(PETSC_HAVE_MPE)
956   mname[0] = 0;
957   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
958   if (flg1){
959     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
960     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
961   }
962 #endif
963   mname[0] = 0;
964   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
965   if (flg1) {
966     PetscViewer viewer;
967     if (mname[0])  {
968       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
969       ierr = PetscLogView(viewer);CHKERRQ(ierr);
970       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
971     } else {
972       viewer = PETSC_VIEWER_STDOUT_WORLD;
973       ierr = PetscLogView(viewer);CHKERRQ(ierr);
974     }
975   }
976 
977   mname[0] = 0;
978   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
979   if (flg1) {
980     PetscViewer viewer;
981     if (mname[0])  {
982       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
983       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
984       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
985     } else {
986       viewer = PETSC_VIEWER_STDOUT_WORLD;
987       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
988     }
989   }
990 
991   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
992   if (flg1) {
993     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
994     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
995   }
996 
997   mname[0] = 0;
998   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
999   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
1000   if (flg1 || flg2){
1001     if (mname[0]) PetscLogDump(mname);
1002     else          PetscLogDump(0);
1003   }
1004 #endif
1005 
1006 #if defined(PETSC_USE_DEBUG)
1007   ierr = PetscStackDestroy();CHKERRQ(ierr);
1008 #endif
1009 
1010   flg1 = PETSC_FALSE;
1011   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
1012   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1013   flg1 = PETSC_FALSE;
1014   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
1015   if (flg1) {
1016     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1017   }
1018   flg1 = PETSC_FALSE;
1019   flg2 = PETSC_FALSE;
1020   /* preemptive call to avoid listing this option in options table as unused */
1021   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1022   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
1023 
1024   if (flg2) {
1025     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1026   }
1027 
1028   /* to prevent PETSc -options_left from warning */
1029   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1030   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1031   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
1032 
1033   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1034     flg3 = PETSC_FALSE; /* default value is required */
1035     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1036     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1037     if (flg3) {
1038       if (!flg2) { /* have not yet printed the options */
1039 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1040       }
1041       if (!nopt) {
1042 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1043       } else if (nopt == 1) {
1044 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1045       } else {
1046 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1047       }
1048     }
1049 #if defined(PETSC_USE_DEBUG)
1050     if (nopt && !flg3 && !flg1) {
1051       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1052       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1053       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1054     } else if (nopt && flg3) {
1055 #else
1056     if (nopt && flg3) {
1057 #endif
1058       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1059     }
1060   }
1061 
1062   /*
1063      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1064   */
1065   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1066 
1067   /*
1068        List all objects the user may have forgot to free
1069   */
1070   if (objects_left && PetscObjectsCounts) {
1071     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1072   }
1073   for (i=0; i<PetscObjectsMaxCounts; i++) {
1074     if (PetscObjects[i]) {
1075       if (objects_left) {
1076         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1077       }
1078     }
1079   }
1080   /* cannot actually destroy the left over objects, but destroy the list */
1081   PetscObjectsCounts    = 0;
1082   PetscObjectsMaxCounts = 0;
1083   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1084 
1085 
1086 #if defined(PETSC_USE_LOG)
1087   ierr = PetscLogDestroy();CHKERRQ(ierr);
1088 #endif
1089 
1090   /*
1091        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1092   */
1093   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1094 
1095   /*
1096        Free all the registered op functions, such as MatOpList, etc
1097   */
1098   ierr = PetscOpFListDestroyAll();CHKERRQ(ierr);
1099 
1100   /*
1101      Destroy any packages that registered a finalize
1102   */
1103   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1104 
1105   /*
1106      Destroy all the function registration lists created
1107   */
1108   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1109 
1110   if (petsc_history) {
1111     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1112     petsc_history = 0;
1113   }
1114 
1115   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1116 
1117   {
1118     char fname[PETSC_MAX_PATH_LEN];
1119     FILE *fd;
1120     int  err;
1121 
1122     fname[0] = 0;
1123     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1124     flg2 = PETSC_FALSE;
1125     ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr);
1126 #if defined(PETSC_USE_DEBUG)
1127     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1128 #else
1129     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1130 #endif
1131     if (flg1 && fname[0]) {
1132       char sname[PETSC_MAX_PATH_LEN];
1133 
1134       sprintf(sname,"%s_%d",fname,rank);
1135       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1136       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1137       err = fclose(fd);
1138       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1139     } else if (flg1 || flg2) {
1140       MPI_Comm local_comm;
1141 
1142       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1143       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1144         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1145       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1146       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1147     }
1148   }
1149   {
1150     char fname[PETSC_MAX_PATH_LEN];
1151     FILE *fd = PETSC_NULL;
1152 
1153     fname[0] = 0;
1154     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1155     ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1156     if (flg1 && fname[0]) {
1157       int  err;
1158 
1159       if (!rank) {
1160         fd = fopen(fname,"w");
1161         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1162       }
1163       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1164       if (fd) {
1165         err = fclose(fd);
1166         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1167       }
1168     } else if (flg1 || flg2) {
1169       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1170     }
1171   }
1172   /* Can be destroyed only after all the options are used */
1173   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1174 
1175   PetscGlobalArgc = 0;
1176   PetscGlobalArgs = 0;
1177 
1178 #if defined(PETSC_USE_REAL___FLOAT128)
1179   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1180 #if defined(PETSC_USE_COMPLEX)
1181   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1182 #endif
1183   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1184   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1185 #endif
1186 
1187 #if defined(PETSC_USE_COMPLEX)
1188 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1189   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1190   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1191 #endif
1192 #endif
1193 
1194 #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1195   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1196 #endif
1197 
1198   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1199   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1200   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1201   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1202   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1203 
1204   /*
1205      Destroy any known inner MPI_Comm's and attributes pointing to them
1206      Note this will not destroy any new communicators the user has created.
1207 
1208      If all PETSc objects were not destroyed those left over objects will have hanging references to
1209      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1210  */
1211   {
1212     PetscCommCounter *counter;
1213     PetscMPIInt      flg;
1214     MPI_Comm         icomm;
1215     void             *ptr;
1216     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1217     if (flg) {
1218       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1219       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1220       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1221       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1222 
1223       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1224       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1225       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1226     }
1227     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1228     if (flg) {
1229       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1230       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1231       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1232       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1233 
1234       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1235       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1236       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1237     }
1238   }
1239 
1240   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1241   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1242   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1243 
1244 #if defined(PETSC_HAVE_CUDA)
1245   {
1246     PetscInt p;
1247     for (p = 0; p < PetscGlobalSize; ++p) {
1248       if (p == PetscGlobalRank) {cublasShutdown();}
1249       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1250     }
1251   }
1252 #endif
1253 
1254   if (PetscBeganMPI) {
1255 #if defined(PETSC_HAVE_MPI_FINALIZED)
1256     PetscMPIInt flag;
1257     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1258     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1259 #endif
1260     ierr = MPI_Finalize();CHKERRQ(ierr);
1261   }
1262 /*
1263 
1264      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1265    the communicator has some outstanding requests on it. Specifically if the
1266    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1267    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1268    is never freed as it should be. Thus one may obtain messages of the form
1269    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1270    memory was not freed.
1271 
1272 */
1273   ierr = PetscMallocClear();CHKERRQ(ierr);
1274   PetscInitializeCalled = PETSC_FALSE;
1275   PetscFinalizeCalled   = PETSC_TRUE;
1276   PetscFunctionReturn(ierr);
1277 }
1278 
1279 #if defined(PETSC_MISSING_LAPACK_lsame_)
1280 EXTERN_C_BEGIN
1281 int lsame_(char *a,char *b)
1282 {
1283   if (*a == *b) return 1;
1284   if (*a + 32 == *b) return 1;
1285   if (*a - 32 == *b) return 1;
1286   return 0;
1287 }
1288 EXTERN_C_END
1289 #endif
1290 
1291 #if defined(PETSC_MISSING_LAPACK_lsame)
1292 EXTERN_C_BEGIN
1293 int lsame(char *a,char *b)
1294 {
1295   if (*a == *b) return 1;
1296   if (*a + 32 == *b) return 1;
1297   if (*a - 32 == *b) return 1;
1298   return 0;
1299 }
1300 EXTERN_C_END
1301 #endif
1302