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