xref: /petsc/src/sys/objects/pinit.c (revision c90a1750bdbee6915dd9fc4c3be647ac513fbcb1)
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)
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 #if defined(PETSC_USE_SCALAR___FLOAT128)
670   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
671   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
672 #endif
673 
674   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
675   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
676   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
677   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
678 
679   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
680   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
681 
682   /*
683      Attributes to be set on PETSc communicators
684   */
685   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
686   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
687   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
688 
689   /*
690      Build the options database
691   */
692   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
693 
694 
695   /*
696      Print main application help message
697   */
698   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
699   if (help && flg) {
700     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
701   }
702   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
703 
704   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
705 #if defined(PETSC_USE_LOG)
706   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
707 #endif
708 
709   /*
710      Load the dynamic libraries (on machines that support them), this registers all
711      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
712   */
713   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
714 
715   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
716   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
717   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
718   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
719 
720   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
721   /* Check the options database for options related to the options database itself */
722   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
723 
724 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
725   /*
726       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
727 
728       Currently not used because it is not supported by MPICH.
729   */
730 #if !defined(PETSC_WORDS_BIGENDIAN)
731   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
732 #endif
733 #endif
734 
735   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
736   if (flg) {
737 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
738     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
739 #else
740     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
741 #endif
742   } else {
743     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
744     if (flg) {
745       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
746       if (PetscOpenMPWorker) { /* if worker then never enter user code */
747         ierr = PetscEnd();
748       }
749     }
750   }
751 
752 #if defined(PETSC_HAVE_CUDA)
753   cublasInit();
754 #endif
755 
756 #if defined(PETSC_HAVE_AMS)
757   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
758   if (flg) {
759     PetscAMSPublishAll = PETSC_TRUE;
760   }
761 #endif
762 
763   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
764   if (flg) {
765     PetscInitializeCalled = PETSC_TRUE;
766     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
767   }
768 
769   /*
770       Once we are completedly initialized then we can set this variables
771   */
772   PetscInitializeCalled = PETSC_TRUE;
773   PetscFunctionReturn(0);
774 }
775 
776 extern PetscObject *PetscObjects;
777 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
778 
779 #undef __FUNCT__
780 #define __FUNCT__ "PetscFinalize"
781 /*@C
782    PetscFinalize - Checks for options to be called at the conclusion
783    of the program. MPI_Finalize() is called only if the user had not
784    called MPI_Init() before calling PetscInitialize().
785 
786    Collective on PETSC_COMM_WORLD
787 
788    Options Database Keys:
789 +  -options_table - Calls PetscOptionsView()
790 .  -options_left - Prints unused options that remain in the database
791 .  -objects_left  - Prints list of all objects that have not been freed
792 .  -mpidump - Calls PetscMPIDump()
793 .  -malloc_dump - Calls PetscMallocDump()
794 .  -malloc_info - Prints total memory usage
795 -  -malloc_log - Prints summary of memory usage
796 
797    Options Database Keys for Profiling:
798    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
799 +  -log_summary [filename] - Prints summary of flop and timing
800         information to screen. If the filename is specified the
801         summary is written to the file.  See PetscLogView().
802 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
803         See PetscLogPrintSViewPython().
804 .  -log_all [filename] - Logs extensive profiling information
805         See PetscLogDump().
806 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
807 .  -log_sync - Log the synchronization in scatters, inner products
808         and norms
809 -  -log_mpe [filename] - Creates a logfile viewable by the
810       utility Upshot/Nupshot (in MPICH distribution)
811 
812    Level: beginner
813 
814    Note:
815    See PetscInitialize() for more general runtime options.
816 
817 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
818 @*/
819 PetscErrorCode  PetscFinalize(void)
820 {
821   PetscErrorCode ierr;
822   PetscMPIInt    rank;
823   PetscInt       i,nopt;
824   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
825 #if defined(PETSC_HAVE_AMS)
826   PetscBool      flg = PETSC_FALSE;
827 #endif
828 #if defined(PETSC_USE_LOG)
829   char           mname[PETSC_MAX_PATH_LEN];
830 #endif
831 
832   PetscFunctionBegin;
833 
834   if (!PetscInitializeCalled) {
835     printf("PetscInitialize() must be called before PetscFinalize()\n");
836     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
837   }
838   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
839 
840 #if defined(PETSC_HAVE_AMS)
841   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
842   if (flg) {
843     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
844   }
845 #endif
846 
847   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
848 
849   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
850   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
851   if (!flg2) {
852     flg2 = PETSC_FALSE;
853     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
854   }
855   if (flg2) {
856     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
857   }
858 
859 #if defined(PETSC_USE_LOG)
860   flg1 = PETSC_FALSE;
861   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
862   if (flg1) {
863     PetscLogDouble flops = 0;
864     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
865     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
866   }
867 #endif
868 
869 
870 #if defined(PETSC_USE_LOG)
871 #if defined(PETSC_HAVE_MPE)
872   mname[0] = 0;
873   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
874   if (flg1){
875     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
876     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
877   }
878 #endif
879   mname[0] = 0;
880   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
881   if (flg1) {
882     PetscViewer viewer;
883     if (mname[0])  {
884       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
885       ierr = PetscLogView(viewer);CHKERRQ(ierr);
886       ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
887     } else {
888       viewer = PETSC_VIEWER_STDOUT_WORLD;
889       ierr = PetscLogView(viewer);CHKERRQ(ierr);
890     }
891   }
892 
893   mname[0] = 0;
894   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
895   if (flg1) {
896     PetscViewer viewer;
897     if (mname[0])  {
898       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
899       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
900       ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
901     } else {
902       viewer = PETSC_VIEWER_STDOUT_WORLD;
903       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
904     }
905   }
906 
907   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
908   if (flg1) {
909     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
910     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
911   }
912 
913   mname[0] = 0;
914   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
915   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
916   if (flg1 || flg2){
917     if (mname[0]) PetscLogDump(mname);
918     else          PetscLogDump(0);
919   }
920 #endif
921 
922 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_USE_PTHREAD)
923   if (PetscStackActive) {
924     ierr = PetscStackDestroy();CHKERRQ(ierr);
925   }
926 #endif
927 
928   flg1 = PETSC_FALSE;
929   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
930   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
931   flg1 = PETSC_FALSE;
932   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
933   if (flg1) {
934     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
935   }
936   flg1 = PETSC_FALSE;
937   flg2 = PETSC_FALSE;
938   /* preemptive call to avoid listing this option in options table as unused */
939   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
940   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
941 
942   if (flg2) {
943     if (!rank) {ierr = PetscOptionsView(PETSC_NULL);CHKERRQ(ierr);}
944   }
945 
946   /* to prevent PETSc -options_left from warning */
947   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
948   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
949   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
950 
951   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
952     flg3 = PETSC_FALSE; /* default value is required */
953     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
954     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
955     if (flg3) {
956       if (!flg2) { /* have not yet printed the options */
957 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
958       }
959       if (!nopt) {
960 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
961       } else if (nopt == 1) {
962 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
963       } else {
964 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
965       }
966     }
967 #if defined(PETSC_USE_DEBUG)
968     if (nopt && !flg3 && !flg1) {
969       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
970       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
971       ierr = PetscOptionsLeft();CHKERRQ(ierr);
972     } else if (nopt && flg3) {
973 #else
974     if (nopt && flg3) {
975 #endif
976       ierr = PetscOptionsLeft();CHKERRQ(ierr);
977     }
978   }
979 
980   /*
981      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
982   */
983   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
984 
985   /*
986        List all objects the user may have forgot to free
987   */
988   if (objects_left && PetscObjectsCounts) {
989     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
990   }
991   for (i=0; i<PetscObjectsMaxCounts; i++) {
992     if (PetscObjects[i]) {
993       if (objects_left) {
994         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
995       }
996     }
997   }
998   /* cannot actually destroy the left over objects, but destroy the list */
999   PetscObjectsCounts    = 0;
1000   PetscObjectsMaxCounts = 0;
1001   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1002 
1003 
1004 #if defined(PETSC_USE_LOG)
1005   ierr = PetscLogDestroy();CHKERRQ(ierr);
1006 #endif
1007 
1008   /*
1009        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1010   */
1011   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1012 
1013   /*
1014      Destroy any packages that registered a finalize
1015   */
1016   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1017 
1018   /*
1019      Destroy all the function registration lists created
1020   */
1021   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1022 
1023   if (petsc_history) {
1024     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1025     petsc_history = 0;
1026   }
1027 
1028   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1029 
1030   {
1031     char fname[PETSC_MAX_PATH_LEN];
1032     FILE *fd;
1033     int  err;
1034 
1035     fname[0] = 0;
1036     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1037     if (flg1 && fname[0]) {
1038       char sname[PETSC_MAX_PATH_LEN];
1039 
1040       sprintf(sname,"%s_%d",fname,rank);
1041       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1042       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1043       err = fclose(fd);
1044       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1045     } else if (flg1) {
1046       MPI_Comm local_comm;
1047 
1048       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1049       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1050         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1051       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1052       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1053     }
1054   }
1055   {
1056     char fname[PETSC_MAX_PATH_LEN];
1057     FILE *fd;
1058 
1059     fname[0] = 0;
1060     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1061     if (flg1 && fname[0]) {
1062       char sname[PETSC_MAX_PATH_LEN];
1063       int  err;
1064 
1065       sprintf(sname,"%s_%d",fname,rank);
1066       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1067       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1068       err = fclose(fd);
1069       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1070     } else if (flg1) {
1071       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1072     }
1073   }
1074   /* Can be destroyed only after all the options are used */
1075   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1076 
1077   PetscGlobalArgc = 0;
1078   PetscGlobalArgs = 0;
1079 
1080 #if defined(PETSC_USE_SCALAR___FLOAT128)
1081   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1082 #endif
1083 
1084 #if defined(PETSC_USE_COMPLEX)
1085 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1086   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1087   ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1088   ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr);
1089 #endif
1090 #endif
1091   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1092   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1093   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1094   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1095   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1096 
1097   /*
1098      Destroy any known inner communicators and attributes pointing to them
1099      Note this will not destroy any new communicators the user has created
1100  */
1101   {
1102     PetscCommCounter *counter;
1103     PetscMPIInt      flg;
1104     MPI_Comm         icomm;
1105     void             *ptr;
1106     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1107     if (flg) {
1108       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1109       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1110       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1111       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1112 
1113       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1114       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1115       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1116       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1117     }
1118     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1119     if (flg) {
1120       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1121       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1122       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1123       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1124 
1125       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1126       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1127       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1128       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1129     }
1130   }
1131 
1132   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1133   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1134   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1135 
1136   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1137   if (PetscBeganMPI) {
1138 #if defined(PETSC_HAVE_MPI_FINALIZED)
1139     PetscMPIInt flag;
1140     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1141     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1142 #endif
1143     ierr = MPI_Finalize();CHKERRQ(ierr);
1144   }
1145 
1146   if (PETSC_ZOPEFD){
1147     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
1148     else fprintf(PETSC_STDOUT, "<<<end>>>");
1149   }
1150 
1151 #if defined(PETSC_HAVE_CUDA)
1152   cublasShutdown();
1153 #endif
1154 /*
1155 
1156      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1157    the communicator has some outstanding requests on it. Specifically if the
1158    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1159    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1160    is never freed as it should be. Thus one may obtain messages of the form
1161    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1162    memory was not freed.
1163 
1164 */
1165   ierr = PetscMallocClear();CHKERRQ(ierr);
1166   PetscInitializeCalled = PETSC_FALSE;
1167   PetscFinalizeCalled   = PETSC_TRUE;
1168   PetscFunctionReturn(ierr);
1169 }
1170 
1171