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