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