xref: /petsc/src/sys/objects/pinit.c (revision 6723443207085105c1b76b29608cdd628c504083)
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 PetscFunctionListPrintAll(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 /*
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(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 #undef __FUNCT__
80 #define __FUNCT__ "PetscInitializeNoPointers"
81 /*
82       PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args
83 
84    Collective
85 
86    Level: advanced
87 
88     Notes: this is called only by the PETSc MATLAB and Julia interface. Even though it might start MPI it sets the flag to
89      indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to
90      be called multiple times from MATLAB and Julia without the problem of trying to initialize MPI more than once.
91 
92      Turns off PETSc signal handling because that can interact with MATLAB's signal handling causing random crashes.
93 
94 .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments()
95 */
96 PetscErrorCode  PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help)
97 {
98   PetscErrorCode ierr;
99   int            myargc   = argc;
100   char           **myargs = args;
101 
102   PetscFunctionBegin;
103   ierr = PetscInitialize(&myargc,&myargs,filename,help);CHKERRQ(ierr);
104   ierr = PetscPopSignalHandler();CHKERRQ(ierr);
105   PetscBeganMPI = PETSC_FALSE;
106   PetscFunctionReturn(ierr);
107 }
108 
109 #undef __FUNCT__
110 #define __FUNCT__ "PetscGetPETSC_COMM_SELF"
111 /*
112       Used by MATLAB and Julia interface to get communicator
113 */
114 PetscErrorCode  PetscGetPETSC_COMM_SELF(MPI_Comm *comm)
115 {
116   PetscFunctionBegin;
117   *comm = PETSC_COMM_SELF;
118   PetscFunctionReturn(0);
119 }
120 
121 #undef __FUNCT__
122 #define __FUNCT__ "PetscInitializeNoArguments"
123 /*@C
124       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
125         the command line arguments.
126 
127    Collective
128 
129    Level: advanced
130 
131 .seealso: PetscInitialize(), PetscInitializeFortran()
132 @*/
133 PetscErrorCode  PetscInitializeNoArguments(void)
134 {
135   PetscErrorCode ierr;
136   int            argc   = 0;
137   char           **args = 0;
138 
139   PetscFunctionBegin;
140   ierr = PetscInitialize(&argc,&args,NULL,NULL);
141   PetscFunctionReturn(ierr);
142 }
143 
144 #undef __FUNCT__
145 #define __FUNCT__ "PetscInitialized"
146 /*@
147       PetscInitialized - Determine whether PETSc is initialized.
148 
149    Level: beginner
150 
151 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
152 @*/
153 PetscErrorCode PetscInitialized(PetscBool  *isInitialized)
154 {
155   *isInitialized = PetscInitializeCalled;
156   return 0;
157 }
158 
159 #undef __FUNCT__
160 #define __FUNCT__ "PetscFinalized"
161 /*@
162       PetscFinalized - Determine whether PetscFinalize() has been called yet
163 
164    Level: developer
165 
166 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
167 @*/
168 PetscErrorCode  PetscFinalized(PetscBool  *isFinalized)
169 {
170   *isFinalized = PetscFinalizeCalled;
171   return 0;
172 }
173 
174 extern PetscErrorCode PetscOptionsCheckInitial_Private(void);
175 
176 /*
177        This function is the MPI reduction operation used to compute the sum of the
178    first half of the datatype and the max of the second half.
179 */
180 MPI_Op PetscMaxSum_Op = 0;
181 
182 #undef __FUNCT__
183 #define __FUNCT__ "PetscMaxSum_Local"
184 PETSC_EXTERN void MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
185 {
186   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
187 
188   PetscFunctionBegin;
189   if (*datatype != MPIU_2INT) {
190     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
191     MPI_Abort(MPI_COMM_WORLD,1);
192   }
193 
194   for (i=0; i<count; i++) {
195     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
196     xout[2*i+1] += xin[2*i+1];
197   }
198   PetscFunctionReturnVoid();
199 }
200 
201 /*
202     Returns the max of the first entry owned by this processor and the
203 sum of the second entry.
204 
205     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
206 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
207 there would be no place to store the both needed results.
208 */
209 #undef __FUNCT__
210 #define __FUNCT__ "PetscMaxSum"
211 PetscErrorCode  PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
212 {
213   PetscMPIInt    size,rank;
214   struct {PetscInt max,sum;} *work;
215   PetscErrorCode ierr;
216 
217   PetscFunctionBegin;
218   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
219   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
220   ierr = PetscMalloc(size*sizeof(*work),&work);CHKERRQ(ierr);
221   ierr = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
222   *max = work[rank].max;
223   *sum = work[rank].sum;
224   ierr = PetscFree(work);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /* ----------------------------------------------------------------------------*/
229 MPI_Op  PetscADMax_Op = 0;
230 
231 #undef __FUNCT__
232 #define __FUNCT__ "PetscADMax_Local"
233 PETSC_EXTERN void MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
234 {
235   PetscScalar *xin = (PetscScalar*)in,*xout = (PetscScalar*)out;
236   PetscInt    i,count = *cnt;
237 
238   PetscFunctionBegin;
239   if (*datatype != MPIU_2SCALAR) {
240     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
241     MPI_Abort(MPI_COMM_WORLD,1);
242   }
243 
244   for (i=0; i<count; i++) {
245     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
246       xout[2*i]   = xin[2*i];
247       xout[2*i+1] = xin[2*i+1];
248     }
249   }
250   PetscFunctionReturnVoid();
251 }
252 
253 MPI_Op PetscADMin_Op = 0;
254 
255 #undef __FUNCT__
256 #define __FUNCT__ "PetscADMin_Local"
257 PETSC_EXTERN void MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
258 {
259   PetscScalar *xin = (PetscScalar*)in,*xout = (PetscScalar*)out;
260   PetscInt    i,count = *cnt;
261 
262   PetscFunctionBegin;
263   if (*datatype != MPIU_2SCALAR) {
264     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
265     MPI_Abort(MPI_COMM_WORLD,1);
266   }
267 
268   for (i=0; i<count; i++) {
269     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
270       xout[2*i]   = xin[2*i];
271       xout[2*i+1] = xin[2*i+1];
272     }
273   }
274   PetscFunctionReturnVoid();
275 }
276 /* ---------------------------------------------------------------------------------------*/
277 
278 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
279 MPI_Op MPIU_SUM = 0;
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "PetscSum_Local"
283 PETSC_EXTERN void PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
284 {
285   PetscInt i,count = *cnt;
286 
287   PetscFunctionBegin;
288   if (*datatype == MPIU_REAL) {
289     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
290     for (i=0; i<count; i++) xout[i] += xin[i];
291   }
292 #if defined(PETSC_HAVE_COMPLEX)
293   else if (*datatype == MPIU_COMPLEX) {
294     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
295     for (i=0; i<count; i++) xout[i] += xin[i];
296   }
297 #endif
298   else {
299     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
300     MPI_Abort(MPI_COMM_WORLD,1);
301   }
302   PetscFunctionReturnVoid();
303 }
304 #endif
305 
306 #if defined(PETSC_USE_REAL___FLOAT128)
307 MPI_Op MPIU_MAX = 0;
308 MPI_Op MPIU_MIN = 0;
309 
310 #undef __FUNCT__
311 #define __FUNCT__ "PetscMax_Local"
312 PETSC_EXTERN void PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
313 {
314   PetscInt i,count = *cnt;
315 
316   PetscFunctionBegin;
317   if (*datatype == MPIU_REAL) {
318     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
319     for (i=0; i<count; i++) xout[i] = PetscMax(xout[i],xin[i]);
320   }
321 #if defined(PETSC_HAVE_COMPLEX)
322   else if (*datatype == MPIU_COMPLEX) {
323     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
324     for (i=0; i<count; i++) {
325       xout[i] = PetscRealPartComplex(xout[i])<PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
326     }
327   }
328 #endif
329   else {
330     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
331     MPI_Abort(MPI_COMM_WORLD,1);
332   }
333   PetscFunctionReturnVoid();
334 }
335 
336 #undef __FUNCT__
337 #define __FUNCT__ "PetscMin_Local"
338 PETSC_EXTERN void PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
339 {
340   PetscInt    i,count = *cnt;
341 
342   PetscFunctionBegin;
343   if (*datatype == MPIU_REAL) {
344     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
345     for (i=0; i<count; i++) xout[i] = PetscMin(xout[i],xin[i]);
346   }
347 #if defined(PETSC_HAVE_COMPLEX)
348   else if (*datatype == MPIU_COMPLEX) {
349     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
350     for (i=0; i<count; i++) {
351       xout[i] = PetscRealPartComplex(xout[i])>PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
352     }
353   }
354 #endif
355   else {
356     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types");
357     MPI_Abort(MPI_COMM_WORLD,1);
358   }
359   PetscFunctionReturnVoid();
360 }
361 #endif
362 
363 #undef __FUNCT__
364 #define __FUNCT__ "Petsc_DelCounter"
365 /*
366    Private routine to delete internal tag/name counter storage when a communicator is freed.
367 
368    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.
369 
370    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
371 
372 */
373 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
374 {
375   PetscErrorCode ierr;
376 
377   PetscFunctionBegin;
378   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
379   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
380   PetscFunctionReturn(MPI_SUCCESS);
381 }
382 
383 #undef __FUNCT__
384 #define __FUNCT__ "Petsc_DelComm_Outer"
385 /*
386   This is invoked on the outer comm as a result of either PetscCommDestroy() (via MPI_Attr_delete) or when the user
387   calls MPI_Comm_free().
388 
389   This is the only entry point for breaking the links between inner and outer comms.
390 
391   This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator.
392 
393   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
394 
395 */
396 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Outer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
397 {
398   PetscErrorCode ierr;
399   PetscMPIInt    flg;
400   union {MPI_Comm comm; void *ptr;} icomm,ocomm;
401 
402   PetscFunctionBegin;
403   if (keyval != Petsc_InnerComm_keyval) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Unexpected keyval");
404   icomm.ptr = attr_val;
405 
406   ierr = MPI_Attr_get(icomm.comm,Petsc_OuterComm_keyval,&ocomm,&flg);CHKERRQ(ierr);
407   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected reference to outer comm");
408   if (ocomm.comm != comm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm has reference to non-matching outer comm");
409   ierr = MPI_Attr_delete(icomm.comm,Petsc_OuterComm_keyval);CHKERRQ(ierr); /* Calls Petsc_DelComm_Inner */
410   ierr = PetscInfo1(0,"User MPI_Comm %ld is being freed after removing reference from inner PETSc comm to this outer comm\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
411   PetscFunctionReturn(MPI_SUCCESS);
412 }
413 
414 #undef __FUNCT__
415 #define __FUNCT__ "Petsc_DelComm_Inner"
416 /*
417  * This is invoked on the inner comm when Petsc_DelComm_Outer calls MPI_Attr_delete.  It should not be reached any other way.
418  */
419 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Inner(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
420 {
421   PetscErrorCode ierr;
422 
423   PetscFunctionBegin;
424   ierr = PetscInfo1(0,"Removing reference to PETSc communicator embedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
425   PetscFunctionReturn(MPI_SUCCESS);
426 }
427 
428 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
429 #if !defined(PETSC_WORDS_BIGENDIAN)
430 PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
431 PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
432 PETSC_EXTERN 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 +  -info <optional filename> - Prints verbose information to the screen
594 .  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
595 .  -log_sync - Log the synchronization in scatters, inner products and norms
596 .  -log_trace [filename] - Print traces of all PETSc calls to the screen (useful to determine where a program
597         hangs without running in the debugger).  See PetscLogTraceBegin().
598 .  -log_summary [filename] - Prints summary of flop and timing information to screen. If the filename is specified the
599         summary is written to the file.  See PetscLogView().
600 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen. See PetscLogPrintSViewPython().
601 .  -log_all [filename] - Logs extensive profiling information  See PetscLogDump().
602 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
603 -  -log_mpe [filename] - Creates a logfile viewable by the utility Jumpshot (in MPICH distribution)
604 
605     Only one of -log_trace, -log_summary, -log_all, -log, or -log_mpe may be used at a time
606 
607    Environmental Variables:
608 +   PETSC_TMP - alternative tmp directory
609 .   PETSC_SHARED_TMP - tmp is shared by all processes
610 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
611 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
612 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
613 
614 
615    Level: beginner
616 
617    Notes:
618    If for some reason you must call MPI_Init() separately, call
619    it before PetscInitialize().
620 
621    Fortran Version:
622    In Fortran this routine has the format
623 $       call PetscInitialize(file,ierr)
624 
625 +   ierr - error return code
626 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL_CHARACTER to not check for
627           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
628 
629    Important Fortran Note:
630    In Fortran, you MUST use NULL_CHARACTER to indicate a
631    null character string; you CANNOT just use NULL as
632    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.
633 
634    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
635    calling PetscInitialize().
636 
637    Concepts: initializing PETSc
638 
639 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
640 
641 @*/
642 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
643 {
644   PetscErrorCode ierr;
645   PetscMPIInt    flag, size;
646   PetscInt       nodesize;
647   PetscBool      flg;
648   char           hostname[256];
649 
650   PetscFunctionBegin;
651   if (PetscInitializeCalled) PetscFunctionReturn(0);
652 
653   /* these must be initialized in a routine, not as a constant declaration*/
654   PETSC_STDOUT = stdout;
655   PETSC_STDERR = stderr;
656 
657   ierr = PetscOptionsCreate();CHKERRQ(ierr);
658 
659   /*
660      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
661      it that it sets args[0] on all processors to be args[0] on the first processor.
662   */
663   if (argc && *argc) {
664     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
665   } else {
666     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
667   }
668 
669   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
670   if (!flag) {
671     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");
672 #if defined(PETSC_HAVE_MPI_INIT_THREAD)
673     {
674       PetscMPIInt provided;
675       ierr = MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);CHKERRQ(ierr);
676     }
677 #else
678     ierr = MPI_Init(argc,args);CHKERRQ(ierr);
679 #endif
680     PetscBeganMPI = PETSC_TRUE;
681   }
682   if (argc && args) {
683     PetscGlobalArgc = *argc;
684     PetscGlobalArgs = *args;
685   }
686   PetscFinalizeCalled = PETSC_FALSE;
687 
688   if (PETSC_COMM_WORLD == MPI_COMM_NULL) PETSC_COMM_WORLD = MPI_COMM_WORLD;
689   ierr = MPI_Comm_set_errhandler(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
690 
691   /* Done after init due to a bug in MPICH-GM? */
692   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
693 
694   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
695   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
696 
697   MPIU_BOOL = MPI_INT;
698   MPIU_ENUM = MPI_INT;
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_HAVE_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_HAVE_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 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
750   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
751   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
752 #endif
753 
754   /*
755      Attributes to be set on PETSc communicators
756   */
757   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
758   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Outer,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
759   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Inner,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
760 
761   /*
762      Build the options database
763   */
764   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
765 
766 
767   /*
768      Print main application help message
769   */
770   ierr = PetscOptionsHasName(NULL,"-help",&flg);CHKERRQ(ierr);
771   if (help && flg) {
772     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
773   }
774   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
775 
776   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
777 #if defined(PETSC_USE_LOG)
778   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
779 #endif
780 
781   /*
782      Load the dynamic libraries (on machines that support them), this registers all
783      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
784   */
785   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
786 
787   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
788   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
789   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
790   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
791 
792   /* Ensure that threadcomm-related keyval exists, so that PetscOptionsSetFromOptions can use PetscCommDuplicate. */
793   ierr = PetscThreadCommInitializePackage();CHKERRQ(ierr);
794 
795   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
796   /* Check the options database for options related to the options database itself */
797   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
798 
799 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
800   /*
801       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
802 
803       Currently not used because it is not supported by MPICH.
804   */
805 #if !defined(PETSC_WORDS_BIGENDIAN)
806   ierr = MPI_Register_datarep((char*)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,NULL);CHKERRQ(ierr);
807 #endif
808 #endif
809 
810   ierr = PetscOptionsGetInt(NULL,"-hmpi_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
811   if (flg) {
812 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
813     ierr = PetscHMPISpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
814 #else
815     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead");
816 #endif
817   } else {
818     ierr = PetscOptionsGetInt(NULL,"-hmpi_merge_size",&nodesize,&flg);CHKERRQ(ierr);
819     if (flg) {
820       ierr = PetscHMPIMerge((PetscMPIInt) nodesize,NULL,NULL);CHKERRQ(ierr);
821       if (PetscHMPIWorker) { /* if worker then never enter user code */
822         PetscInitializeCalled = PETSC_TRUE;
823         PetscEnd();
824       }
825     }
826   }
827 
828 #if defined(PETSC_HAVE_CUDA)
829   {
830     PetscMPIInt p;
831     for (p = 0; p < PetscGlobalSize; ++p) {
832       if (p == PetscGlobalRank) cublasInit();
833       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
834     }
835   }
836 #endif
837 
838   ierr = PetscOptionsHasName(NULL,"-python",&flg);CHKERRQ(ierr);
839   if (flg) {
840     PetscInitializeCalled = PETSC_TRUE;
841     ierr = PetscPythonInitialize(NULL,NULL);CHKERRQ(ierr);
842   }
843 
844   /*
845       Setup building of stack frames for all function calls
846   */
847   PetscThreadLocalRegister((PetscThreadKey*)&petscstack); /* Creates pthread_key */
848 #if defined(PETSC_USE_DEBUG)
849   ierr = PetscStackCreate();CHKERRQ(ierr);
850 #endif
851 
852 #if defined(PETSC_SERIALIZE_FUNCTIONS)
853   ierr = PetscFPTCreate(10000);CHKERRQ(ierr);
854 #endif
855 
856   /*
857       Once we are completedly initialized then we can set this variables
858   */
859   PetscInitializeCalled = PETSC_TRUE;
860   PetscFunctionReturn(0);
861 }
862 
863 extern PetscObject *PetscObjects;
864 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
865 
866 #undef __FUNCT__
867 #define __FUNCT__ "PetscFinalize"
868 /*@C
869    PetscFinalize - Checks for options to be called at the conclusion
870    of the program. MPI_Finalize() is called only if the user had not
871    called MPI_Init() before calling PetscInitialize().
872 
873    Collective on PETSC_COMM_WORLD
874 
875    Options Database Keys:
876 +  -options_table - Calls PetscOptionsView()
877 .  -options_left - Prints unused options that remain in the database
878 .  -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
879 .  -mpidump - Calls PetscMPIDump()
880 .  -malloc_dump - Calls PetscMallocDump()
881 .  -malloc_info - Prints total memory usage
882 -  -malloc_log - Prints summary of memory usage
883 
884    Level: beginner
885 
886    Note:
887    See PetscInitialize() for more general runtime options.
888 
889 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
890 @*/
891 PetscErrorCode  PetscFinalize(void)
892 {
893   PetscErrorCode ierr;
894   PetscMPIInt    rank;
895   PetscInt       nopt;
896   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
897 #if defined(PETSC_HAVE_AMS)
898   PetscBool      flg = PETSC_FALSE;
899 #endif
900 #if defined(PETSC_USE_LOG)
901   char           mname[PETSC_MAX_PATH_LEN];
902 #endif
903 
904   PetscFunctionBegin;
905   if (!PetscInitializeCalled) {
906     printf("PetscInitialize() must be called before PetscFinalize()\n");
907     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
908   }
909   ierr = PetscInfo(NULL,"PetscFinalize() called\n");CHKERRQ(ierr);
910 
911   /*
912     It should be safe to cancel the options monitors, since we don't expect to be setting options
913     here (at least that are worth monitoring).  Monitors ought to be released so that they release
914     whatever memory was allocated there before -malloc_dump reports unfreed memory.
915   */
916   ierr = PetscOptionsMonitorCancel();CHKERRQ(ierr);
917 
918 #if defined(PETSC_SERIALIZE_FUNCTIONS)
919   ierr = PetscFPTDestroy();CHKERRQ(ierr);
920 #endif
921 
922 
923 #if defined(PETSC_HAVE_AMS)
924   ierr = PetscOptionsGetBool(NULL,"-options_gui",&flg,NULL);CHKERRQ(ierr);
925   if (flg) {
926     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
927   }
928 #endif
929 
930 #if defined(PETSC_HAVE_SERVER)
931   flg1 = PETSC_FALSE;
932   ierr = PetscOptionsGetBool(NULL,"-server",&flg1,NULL);CHKERRQ(ierr);
933   if (flg1) {
934     /*  this is a crude hack, but better than nothing */
935     ierr = PetscPOpen(PETSC_COMM_WORLD,NULL,"pkill -9 petscwebserver","r",NULL);CHKERRQ(ierr);
936   }
937 #endif
938 
939   ierr = PetscHMPIFinalize();CHKERRQ(ierr);
940 
941   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
942   ierr = PetscOptionsGetBool(NULL,"-malloc_info",&flg2,NULL);CHKERRQ(ierr);
943   if (!flg2) {
944     flg2 = PETSC_FALSE;
945     ierr = PetscOptionsGetBool(NULL,"-memory_info",&flg2,NULL);CHKERRQ(ierr);
946   }
947   if (flg2) {
948     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
949   }
950 
951 #if defined(PETSC_USE_LOG)
952   flg1 = PETSC_FALSE;
953   ierr = PetscOptionsGetBool(NULL,"-get_total_flops",&flg1,NULL);CHKERRQ(ierr);
954   if (flg1) {
955     PetscLogDouble flops = 0;
956     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
957     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
958   }
959 #endif
960 
961 
962 #if defined(PETSC_USE_LOG)
963 #if defined(PETSC_HAVE_MPE)
964   mname[0] = 0;
965 
966   ierr = PetscOptionsGetString(NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
967   if (flg1) {
968     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
969     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
970   }
971 #endif
972   mname[0] = 0;
973 
974   ierr = PetscOptionsGetString(NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
975   if (flg1) {
976     PetscViewer viewer;
977     if (mname[0]) {
978       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
979       ierr = PetscLogView(viewer);CHKERRQ(ierr);
980       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
981     } else {
982       viewer = PETSC_VIEWER_STDOUT_WORLD;
983       ierr   = PetscLogView(viewer);CHKERRQ(ierr);
984     }
985   }
986 
987   mname[0] = 0;
988 
989   ierr = PetscOptionsGetString(NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
990   if (flg1) {
991     PetscViewer viewer;
992     if (mname[0]) {
993       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
994       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
995       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
996     } else {
997       viewer = PETSC_VIEWER_STDOUT_WORLD;
998       ierr   = PetscLogViewPython(viewer);CHKERRQ(ierr);
999     }
1000   }
1001 
1002   ierr = PetscOptionsGetString(NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1003   if (flg1) {
1004     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
1005     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
1006   }
1007 
1008   mname[0] = 0;
1009 
1010   ierr = PetscOptionsGetString(NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1011   ierr = PetscOptionsGetString(NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
1012   if (flg1 || flg2) {
1013     if (mname[0]) PetscLogDump(mname);
1014     else          PetscLogDump(0);
1015   }
1016 #endif
1017 
1018   /*
1019      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1020   */
1021   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1022 
1023   ierr = PetscStackDestroy();CHKERRQ(ierr);
1024   PetscThreadLocalDestroy((PetscThreadKey)petscstack); /* Deletes pthread_key */
1025 
1026   flg1 = PETSC_FALSE;
1027   ierr = PetscOptionsGetBool(NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
1028   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1029   flg1 = PETSC_FALSE;
1030   ierr = PetscOptionsGetBool(NULL,"-mpidump",&flg1,NULL);CHKERRQ(ierr);
1031   if (flg1) {
1032     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1033   }
1034   flg1 = PETSC_FALSE;
1035   flg2 = PETSC_FALSE;
1036   /* preemptive call to avoid listing this option in options table as unused */
1037   ierr = PetscOptionsHasName(NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1038   ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1039   ierr = PetscOptionsGetBool(NULL,"-options_table",&flg2,NULL);CHKERRQ(ierr);
1040 
1041   if (flg2) {
1042     PetscViewer viewer;
1043     ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1044     ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1045     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1046   }
1047 
1048   /* to prevent PETSc -options_left from warning */
1049   ierr = PetscOptionsHasName(NULL,"-nox",&flg1);CHKERRQ(ierr);
1050   ierr = PetscOptionsHasName(NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1051 
1052   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1053     flg3 = PETSC_FALSE; /* default value is required */
1054     ierr = PetscOptionsGetBool(NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1055     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1056     if (flg3) {
1057       if (!flg2) { /* have not yet printed the options */
1058         PetscViewer viewer;
1059         ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1060         ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1061         ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1062       }
1063       if (!nopt) {
1064         ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1065       } else if (nopt == 1) {
1066         ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1067       } else {
1068         ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1069       }
1070     }
1071 #if defined(PETSC_USE_DEBUG)
1072     if (nopt && !flg3 && !flg1) {
1073       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1074       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1075       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1076     } else if (nopt && flg3) {
1077 #else
1078     if (nopt && flg3) {
1079 #endif
1080       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1081     }
1082   }
1083 
1084   {
1085     PetscThreadComm tcomm_world;
1086     ierr = PetscGetThreadCommWorld(&tcomm_world);CHKERRQ(ierr);
1087     /* Free global thread communicator */
1088     ierr = PetscThreadCommDestroy(&tcomm_world);CHKERRQ(ierr);
1089   }
1090 
1091   /*
1092        List all objects the user may have forgot to free
1093   */
1094   ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1095   if (flg1) {
1096     MPI_Comm local_comm;
1097     char     string[64];
1098 
1099     ierr = PetscOptionsGetString(NULL,"-objects_dump",string,64,NULL);CHKERRQ(ierr);
1100     ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1101     ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1102     ierr = PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);CHKERRQ(ierr);
1103     ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1104     ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1105   }
1106   PetscObjectsCounts    = 0;
1107   PetscObjectsMaxCounts = 0;
1108 
1109   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1110 
1111 #if defined(PETSC_USE_LOG)
1112   ierr = PetscLogDestroy();CHKERRQ(ierr);
1113 #endif
1114 
1115   /*
1116      Destroy any packages that registered a finalize
1117   */
1118   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1119 
1120   /*
1121      Destroy all the function registration lists created
1122   */
1123   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1124 
1125   /*
1126      Print PetscFunctionLists that have not been properly freed
1127 
1128   ierr = PetscFunctionListPrintAll();CHKERRQ(ierr);
1129   */
1130 
1131   if (petsc_history) {
1132     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1133     petsc_history = 0;
1134   }
1135 
1136   ierr = PetscInfoAllow(PETSC_FALSE,NULL);CHKERRQ(ierr);
1137 
1138   {
1139     char fname[PETSC_MAX_PATH_LEN];
1140     FILE *fd;
1141     int  err;
1142 
1143     fname[0] = 0;
1144 
1145     ierr = PetscOptionsGetString(NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1146     flg2 = PETSC_FALSE;
1147     ierr = PetscOptionsGetBool(NULL,"-malloc_test",&flg2,NULL);CHKERRQ(ierr);
1148 #if defined(PETSC_USE_DEBUG)
1149     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1150 #else
1151     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1152 #endif
1153     if (flg1 && fname[0]) {
1154       char sname[PETSC_MAX_PATH_LEN];
1155 
1156       sprintf(sname,"%s_%d",fname,rank);
1157       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1158       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1159       err  = fclose(fd);
1160       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1161     } else if (flg1 || flg2) {
1162       MPI_Comm local_comm;
1163 
1164       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1165       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1166       ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1167       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1168       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1169     }
1170   }
1171 
1172   {
1173     char fname[PETSC_MAX_PATH_LEN];
1174     FILE *fd = NULL;
1175 
1176     fname[0] = 0;
1177 
1178     ierr = PetscOptionsGetString(NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1179     ierr = PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1180     if (flg1 && fname[0]) {
1181       int err;
1182 
1183       if (!rank) {
1184         fd = fopen(fname,"w");
1185         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1186       }
1187       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1188       if (fd) {
1189         err = fclose(fd);
1190         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1191       }
1192     } else if (flg1 || flg2) {
1193       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1194     }
1195   }
1196   /* Can be destroyed only after all the options are used */
1197   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1198 
1199   PetscGlobalArgc = 0;
1200   PetscGlobalArgs = 0;
1201 
1202 #if defined(PETSC_USE_REAL___FLOAT128)
1203   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1204 #if defined(PETSC_HAVE_COMPLEX)
1205   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1206 #endif
1207   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1208   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1209 #endif
1210 
1211 #if defined(PETSC_HAVE_COMPLEX)
1212 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1213   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1214   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1215 #endif
1216 #endif
1217 
1218 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1219   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1220 #endif
1221 
1222   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1223 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
1224   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1225 #endif
1226   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1227   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1228   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1229 
1230   /*
1231      Destroy any known inner MPI_Comm's and attributes pointing to them
1232      Note this will not destroy any new communicators the user has created.
1233 
1234      If all PETSc objects were not destroyed those left over objects will have hanging references to
1235      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1236  */
1237   {
1238     PetscCommCounter *counter;
1239     PetscMPIInt      flg;
1240     MPI_Comm         icomm;
1241     union {MPI_Comm comm; void *ptr;} ucomm;
1242     ierr = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1243     if (flg) {
1244       icomm = ucomm.comm;
1245       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1246       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1247 
1248       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1249       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1250       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1251     }
1252     ierr = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1253     if (flg) {
1254       icomm = ucomm.comm;
1255       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1256       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1257 
1258       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1259       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1260       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1261     }
1262   }
1263 
1264   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1265   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1266   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1267 
1268 #if defined(PETSC_HAVE_CUDA)
1269   {
1270     PetscInt p;
1271     for (p = 0; p < PetscGlobalSize; ++p) {
1272       if (p == PetscGlobalRank) cublasShutdown();
1273       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1274     }
1275   }
1276 #endif
1277 
1278   if (PetscBeganMPI) {
1279 #if defined(PETSC_HAVE_MPI_FINALIZED)
1280     PetscMPIInt flag;
1281     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1282     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1283 #endif
1284     ierr = MPI_Finalize();CHKERRQ(ierr);
1285   }
1286 /*
1287 
1288      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1289    the communicator has some outstanding requests on it. Specifically if the
1290    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1291    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1292    is never freed as it should be. Thus one may obtain messages of the form
1293    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1294    memory was not freed.
1295 
1296 */
1297   ierr = PetscMallocClear();CHKERRQ(ierr);
1298 
1299   PetscInitializeCalled = PETSC_FALSE;
1300   PetscFinalizeCalled   = PETSC_TRUE;
1301   PetscFunctionReturn(ierr);
1302 }
1303 
1304 #if defined(PETSC_MISSING_LAPACK_lsame_)
1305 PETSC_EXTERN int lsame_(char *a,char *b)
1306 {
1307   if (*a == *b) return 1;
1308   if (*a + 32 == *b) return 1;
1309   if (*a - 32 == *b) return 1;
1310   return 0;
1311 }
1312 #endif
1313 
1314 #if defined(PETSC_MISSING_LAPACK_lsame)
1315 PETSC_EXTERN int lsame(char *a,char *b)
1316 {
1317   if (*a == *b) return 1;
1318   if (*a + 32 == *b) return 1;
1319   if (*a - 32 == *b) return 1;
1320   return 0;
1321 }
1322 #endif
1323