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