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