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