xref: /petsc/src/sys/objects/pinit.c (revision 854411e3feba584d9b82fdb5b3b4407cc76e1d54)
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 #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) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_SCALAR___FLOAT128)
308 MPI_Op MPIU_SUM = 0;
309 
310 EXTERN_C_BEGIN
311 #undef __FUNCT__
312 #define __FUNCT__ "PetscSum_Local"
313 void  PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
314 {
315   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
316   PetscInt    i,count = *cnt;
317 
318   PetscFunctionBegin;
319   if (*datatype != MPIU_SCALAR) {
320     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
321     MPI_Abort(MPI_COMM_WORLD,1);
322   }
323 
324   for (i=0; i<count; i++) {
325     xout[i] += xin[i];
326   }
327   PetscFunctionReturnVoid();
328 }
329 EXTERN_C_END
330 #endif
331 
332 EXTERN_C_BEGIN
333 #undef __FUNCT__
334 #define __FUNCT__ "Petsc_DelCounter"
335 /*
336    Private routine to delete internal tag/name counter storage when a communicator is freed.
337 
338    This is called by MPI, not by users.
339 
340    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
341 
342 */
343 PetscMPIInt  MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
344 {
345   PetscErrorCode ierr;
346 
347   PetscFunctionBegin;
348   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
349   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
350   PetscFunctionReturn(MPI_SUCCESS);
351 }
352 EXTERN_C_END
353 
354 EXTERN_C_BEGIN
355 #undef __FUNCT__
356 #define __FUNCT__ "Petsc_DelComm"
357 /*
358   This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the
359   the external MPI_Comm drops its reference to the internal MPI_Comm
360 
361   This is called by MPI, not by users.
362 
363   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
364 
365 */
366 PetscMPIInt  MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
367 {
368   PetscErrorCode ierr;
369 
370   PetscFunctionBegin;
371   ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
372   /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */
373   PetscFunctionReturn(MPI_SUCCESS);
374 }
375 EXTERN_C_END
376 
377 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
378 #if !defined(PETSC_WORDS_BIGENDIAN)
379 EXTERN_C_BEGIN
380 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
381 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
382 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
383 EXTERN_C_END
384 #endif
385 #endif
386 
387 int  PetscGlobalArgc   = 0;
388 char **PetscGlobalArgs = 0;
389 
390 #undef __FUNCT__
391 #define __FUNCT__ "PetscGetArgs"
392 /*@C
393    PetscGetArgs - Allows you to access the raw command line arguments anywhere
394      after PetscInitialize() is called but before PetscFinalize().
395 
396    Not Collective
397 
398    Output Parameters:
399 +  argc - count of number of command line arguments
400 -  args - the command line arguments
401 
402    Level: intermediate
403 
404    Notes:
405       This is usually used to pass the command line arguments into other libraries
406    that are called internally deep in PETSc or the application.
407 
408       The first argument contains the program name as is normal for C arguments.
409 
410    Concepts: command line arguments
411 
412 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
413 
414 @*/
415 PetscErrorCode  PetscGetArgs(int *argc,char ***args)
416 {
417   PetscFunctionBegin;
418   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
419   *argc = PetscGlobalArgc;
420   *args = PetscGlobalArgs;
421   PetscFunctionReturn(0);
422 }
423 
424 #undef __FUNCT__
425 #define __FUNCT__ "PetscGetArguments"
426 /*@C
427    PetscGetArguments - Allows you to access the  command line arguments anywhere
428      after PetscInitialize() is called but before PetscFinalize().
429 
430    Not Collective
431 
432    Output Parameters:
433 .  args - the command line arguments
434 
435    Level: intermediate
436 
437    Notes:
438       This does NOT start with the program name and IS null terminated (final arg is void)
439 
440    Concepts: command line arguments
441 
442 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
443 
444 @*/
445 PetscErrorCode  PetscGetArguments(char ***args)
446 {
447   PetscInt       i,argc = PetscGlobalArgc;
448   PetscErrorCode ierr;
449 
450   PetscFunctionBegin;
451   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
452   if (!argc) {*args = 0; PetscFunctionReturn(0);}
453   ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr);
454   for (i=0; i<argc-1; i++) {
455     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
456   }
457   (*args)[argc-1] = 0;
458   PetscFunctionReturn(0);
459 }
460 
461 #undef __FUNCT__
462 #define __FUNCT__ "PetscFreeArguments"
463 /*@C
464    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
465 
466    Not Collective
467 
468    Output Parameters:
469 .  args - the command line arguments
470 
471    Level: intermediate
472 
473    Concepts: command line arguments
474 
475 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
476 
477 @*/
478 PetscErrorCode  PetscFreeArguments(char **args)
479 {
480   PetscInt       i = 0;
481   PetscErrorCode ierr;
482 
483   PetscFunctionBegin;
484   if (!args) {PetscFunctionReturn(0);}
485   while (args[i]) {
486     ierr = PetscFree(args[i]);CHKERRQ(ierr);
487     i++;
488   }
489   ierr = PetscFree(args);CHKERRQ(ierr);
490   PetscFunctionReturn(0);
491 }
492 
493 #undef __FUNCT__
494 #define __FUNCT__ "PetscInitialize"
495 /*@C
496    PetscInitialize - Initializes the PETSc database and MPI.
497    PetscInitialize() calls MPI_Init() if that has yet to be called,
498    so this routine should always be called near the beginning of
499    your program -- usually the very first line!
500 
501    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
502 
503    Input Parameters:
504 +  argc - count of number of command line arguments
505 .  args - the command line arguments
506 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for
507           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
508 -  help - [optional] Help message to print, use PETSC_NULL for no message
509 
510    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
511    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
512    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
513    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
514    if different subcommunicators of the job are doing different things with PETSc.
515 
516    Options Database Keys:
517 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
518 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
519 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
520 .  -on_error_abort calls abort() when error detected (no traceback)
521 .  -on_error_mpiabort calls MPI_abort() when error detected
522 .  -error_output_stderr prints error messages to stderr instead of the default stdout
523 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
524 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
525 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
526 .  -stop_for_debugger - Print message on how to attach debugger manually to
527                         process and wait (-debugger_pause) seconds for attachment
528 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
529 .  -malloc no - Indicates not to use error-checking malloc
530 .  -malloc_debug - check for memory corruption at EVERY malloc or free
531 .  -fp_trap - Stops on floating point exceptions (Note that on the
532               IBM RS6000 this slows code by at least a factor of 10.)
533 .  -no_signal_handler - Indicates not to trap error signals
534 .  -shared_tmp - indicates /tmp directory is shared by all processors
535 .  -not_shared_tmp - each processor has own /tmp
536 .  -tmp - alternative name of /tmp directory
537 .  -get_total_flops - returns total flops done by all processors
538 -  -memory_info - Print memory usage at end of run
539 
540    Options Database Keys for Profiling:
541    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
542 +  -log_trace [filename] - Print traces of all PETSc calls
543         to the screen (useful to determine where a program
544         hangs without running in the debugger).  See PetscLogTraceBegin().
545 .  -info <optional filename> - Prints verbose information to the screen
546 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
547 
548    Environmental Variables:
549 +   PETSC_TMP - alternative tmp directory
550 .   PETSC_SHARED_TMP - tmp is shared by all processes
551 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
552 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
553 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
554 
555 
556    Level: beginner
557 
558    Notes:
559    If for some reason you must call MPI_Init() separately, call
560    it before PetscInitialize().
561 
562    Fortran Version:
563    In Fortran this routine has the format
564 $       call PetscInitialize(file,ierr)
565 
566 +   ierr - error return code
567 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
568           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
569 
570    Important Fortran Note:
571    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
572    null character string; you CANNOT just use PETSC_NULL as
573    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.
574 
575    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
576    calling PetscInitialize().
577 
578    Concepts: initializing PETSc
579 
580 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
581 
582 @*/
583 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
584 {
585   PetscErrorCode ierr;
586   PetscMPIInt    flag, size;
587   PetscInt       nodesize;
588   PetscBool      flg;
589   char           hostname[256];
590 
591   PetscFunctionBegin;
592   if (PetscInitializeCalled) PetscFunctionReturn(0);
593 
594   /* these must be initialized in a routine, not as a constant declaration*/
595   PETSC_STDOUT = stdout;
596   PETSC_STDERR = stderr;
597 
598   ierr = PetscOptionsCreate();CHKERRQ(ierr);
599 
600   /*
601      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
602      it that it sets args[0] on all processors to be args[0] on the first processor.
603   */
604   if (argc && *argc) {
605     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
606   } else {
607     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
608   }
609 
610   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
611   if (!flag) {
612     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");
613     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
614     PetscBeganMPI = PETSC_TRUE;
615   }
616   if (argc && args) {
617     PetscGlobalArgc = *argc;
618     PetscGlobalArgs = *args;
619   }
620   PetscFinalizeCalled   = PETSC_FALSE;
621 
622   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
623     PETSC_COMM_WORLD = MPI_COMM_WORLD;
624   }
625   ierr = MPI_Errhandler_set(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
626 
627   /* Done after init due to a bug in MPICH-GM? */
628   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
629 
630   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
631   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
632 
633 #if defined(PETSC_USE_COMPLEX)
634   /*
635      Initialized the global complex variable; this is because with
636      shared libraries the constructors for global variables
637      are not called; at least on IRIX.
638   */
639   {
640 #if defined(PETSC_CLANGUAGE_CXX)
641     PetscScalar ic(0.0,1.0);
642     PETSC_i = ic;
643 #else
644     PETSC_i = I;
645 #endif
646   }
647 
648 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
649   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
650   ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
651   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPI_C_COMPLEX);CHKERRQ(ierr);
652   ierr = MPI_Type_commit(&MPI_C_COMPLEX);CHKERRQ(ierr);
653   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
654 #endif
655 #endif
656 
657   /*
658      Create the PETSc MPI reduction operator that sums of the first
659      half of the entries and maxes the second half.
660   */
661   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
662 
663 #if defined(PETSC_USE_SCALAR___FLOAT128)
664   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
665   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
666   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
667 #endif
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 
747 #if defined(PETSC_HAVE_CUDA)
748   cublasInit();
749 #endif
750 
751 #if defined(PETSC_HAVE_AMS)
752   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
753   if (flg) {
754     PetscAMSPublishAll = PETSC_TRUE;
755   }
756 #endif
757 
758   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
759   if (flg) {
760     PetscInitializeCalled = PETSC_TRUE;
761     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
762   }
763 
764   /*
765       Once we are completedly initialized then we can set this variables
766   */
767   PetscInitializeCalled = PETSC_TRUE;
768   PetscFunctionReturn(0);
769 }
770 
771 extern PetscObject *PetscObjects;
772 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
773 
774 #undef __FUNCT__
775 #define __FUNCT__ "PetscFinalize"
776 /*@C
777    PetscFinalize - Checks for options to be called at the conclusion
778    of the program. MPI_Finalize() is called only if the user had not
779    called MPI_Init() before calling PetscInitialize().
780 
781    Collective on PETSC_COMM_WORLD
782 
783    Options Database Keys:
784 +  -options_table - Calls PetscOptionsView()
785 .  -options_left - Prints unused options that remain in the database
786 .  -objects_left  - Prints list of all objects that have not been freed
787 .  -mpidump - Calls PetscMPIDump()
788 .  -malloc_dump - Calls PetscMallocDump()
789 .  -malloc_info - Prints total memory usage
790 -  -malloc_log - Prints summary of memory usage
791 
792    Options Database Keys for Profiling:
793    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
794 +  -log_summary [filename] - Prints summary of flop and timing
795         information to screen. If the filename is specified the
796         summary is written to the file.  See PetscLogView().
797 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
798         See PetscLogPrintSViewPython().
799 .  -log_all [filename] - Logs extensive profiling information
800         See PetscLogDump().
801 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
802 .  -log_sync - Log the synchronization in scatters, inner products
803         and norms
804 -  -log_mpe [filename] - Creates a logfile viewable by the
805       utility Upshot/Nupshot (in MPICH distribution)
806 
807    Level: beginner
808 
809    Note:
810    See PetscInitialize() for more general runtime options.
811 
812 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
813 @*/
814 PetscErrorCode  PetscFinalize(void)
815 {
816   PetscErrorCode ierr;
817   PetscMPIInt    rank;
818   PetscInt       i,nopt;
819   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
820 #if defined(PETSC_HAVE_AMS)
821   PetscBool      flg = PETSC_FALSE;
822 #endif
823 #if defined(PETSC_USE_LOG)
824   char           mname[PETSC_MAX_PATH_LEN];
825 #endif
826 
827   PetscFunctionBegin;
828 
829   if (!PetscInitializeCalled) {
830     printf("PetscInitialize() must be called before PetscFinalize()\n");
831     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
832   }
833   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
834 
835 #if defined(PETSC_HAVE_AMS)
836   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
837   if (flg) {
838     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
839   }
840 #endif
841 
842   ierr = PetscOpenMPFinalize();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   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
997 
998 
999 #if defined(PETSC_USE_LOG)
1000   ierr = PetscLogDestroy();CHKERRQ(ierr);
1001 #endif
1002 
1003   /*
1004        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1005   */
1006   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1007 
1008   /*
1009      Destroy any packages that registered a finalize
1010   */
1011   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1012 
1013   /*
1014      Destroy all the function registration lists created
1015   */
1016   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1017 
1018   if (petsc_history) {
1019     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1020     petsc_history = 0;
1021   }
1022 
1023   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1024 
1025   {
1026     char fname[PETSC_MAX_PATH_LEN];
1027     FILE *fd;
1028     int  err;
1029 
1030     fname[0] = 0;
1031     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1032     if (flg1 && fname[0]) {
1033       char sname[PETSC_MAX_PATH_LEN];
1034 
1035       sprintf(sname,"%s_%d",fname,rank);
1036       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1037       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1038       err = fclose(fd);
1039       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1040     } else if (flg1) {
1041       MPI_Comm local_comm;
1042 
1043       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1044       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1045         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1046       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1047       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1048     }
1049   }
1050   {
1051     char fname[PETSC_MAX_PATH_LEN];
1052     FILE *fd;
1053 
1054     fname[0] = 0;
1055     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1056     if (flg1 && fname[0]) {
1057       char sname[PETSC_MAX_PATH_LEN];
1058       int  err;
1059 
1060       sprintf(sname,"%s_%d",fname,rank);
1061       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1062       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1063       err = fclose(fd);
1064       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1065     } else if (flg1) {
1066       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1067     }
1068   }
1069   /* Can be destroyed only after all the options are used */
1070   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1071 
1072   PetscGlobalArgc = 0;
1073   PetscGlobalArgs = 0;
1074 
1075 #if defined(PETSC_USE_SCALAR___FLOAT128)
1076   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1077   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1078 #endif
1079 
1080 #if defined(PETSC_USE_COMPLEX)
1081 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1082   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1083   ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1084   ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr);
1085 #endif
1086 #endif
1087   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1088   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1089   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1090   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1091   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1092 
1093   /*
1094      Destroy any known inner communicators and attributes pointing to them
1095      Note this will not destroy any new communicators the user has created
1096  */
1097   {
1098     PetscCommCounter *counter;
1099     PetscMPIInt      flg;
1100     MPI_Comm         icomm;
1101     void             *ptr;
1102     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1103     if (flg) {
1104       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1105       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1106       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1107       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1108 
1109       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1110       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1111       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1112       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1113     }
1114     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1115     if (flg) {
1116       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1117       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1118       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1119       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1120 
1121       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1122       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1123       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1124       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1125     }
1126   }
1127 
1128   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1129   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1130   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1131 
1132   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1133   if (PetscBeganMPI) {
1134 #if defined(PETSC_HAVE_MPI_FINALIZED)
1135     PetscMPIInt flag;
1136     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1137     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1138 #endif
1139     ierr = MPI_Finalize();CHKERRQ(ierr);
1140   }
1141 
1142   if (PETSC_ZOPEFD){
1143     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
1144     else fprintf(PETSC_STDOUT, "<<<end>>>");
1145   }
1146 
1147 #if defined(PETSC_HAVE_CUDA)
1148   cublasShutdown();
1149 #endif
1150 /*
1151 
1152      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1153    the communicator has some outstanding requests on it. Specifically if the
1154    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1155    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1156    is never freed as it should be. Thus one may obtain messages of the form
1157    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1158    memory was not freed.
1159 
1160 */
1161   ierr = PetscMallocClear();CHKERRQ(ierr);
1162   PetscInitializeCalled = PETSC_FALSE;
1163   PetscFinalizeCalled   = PETSC_TRUE;
1164   PetscFunctionReturn(ierr);
1165 }
1166 
1167