xref: /petsc/src/sys/objects/pinit.c (revision d9822059a04b3bd78629edfbf3ebfea74b8f6e57)
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 #if defined(PETSC_USE_SCALAR___FLOAT128)
333 MPI_Op MPIU_MAX = 0;
334 MPI_Op MPIU_MIN = 0;
335 
336 EXTERN_C_BEGIN
337 #undef __FUNCT__
338 #define __FUNCT__ "PetscMax_Local"
339 void  PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
340 {
341   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
342   PetscInt    i,count = *cnt;
343 
344   PetscFunctionBegin;
345   if (*datatype != MPIU_SCALAR) {
346     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
347     MPI_Abort(MPI_COMM_WORLD,1);
348   }
349 
350   for (i=0; i<count; i++) {
351     xout[i] += PetscMax(xout[i],xin[i]);
352   }
353   PetscFunctionReturnVoid();
354 }
355 EXTERN_C_END
356 
357 EXTERN_C_BEGIN
358 #undef __FUNCT__
359 #define __FUNCT__ "PetscMin_Local"
360 void  PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
361 {
362   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
363   PetscInt    i,count = *cnt;
364 
365   PetscFunctionBegin;
366   if (*datatype != MPIU_SCALAR) {
367     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
368     MPI_Abort(MPI_COMM_WORLD,1);
369   }
370 
371   for (i=0; i<count; i++) {
372     xout[i] += PetscMin(xout[i],xin[i]);
373   }
374   PetscFunctionReturnVoid();
375 }
376 EXTERN_C_END
377 #endif
378 
379 EXTERN_C_BEGIN
380 #undef __FUNCT__
381 #define __FUNCT__ "Petsc_DelCounter"
382 /*
383    Private routine to delete internal tag/name counter storage when a communicator is freed.
384 
385    This is called by MPI, not by users.
386 
387    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
388 
389 */
390 PetscMPIInt  MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
391 {
392   PetscErrorCode ierr;
393 
394   PetscFunctionBegin;
395   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
396   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
397   PetscFunctionReturn(MPI_SUCCESS);
398 }
399 EXTERN_C_END
400 
401 EXTERN_C_BEGIN
402 #undef __FUNCT__
403 #define __FUNCT__ "Petsc_DelComm"
404 /*
405   This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the
406   the external MPI_Comm drops its reference to the internal MPI_Comm
407 
408   This is called by MPI, not by users.
409 
410   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
411 
412 */
413 PetscMPIInt  MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
414 {
415   PetscErrorCode ierr;
416 
417   PetscFunctionBegin;
418   ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
419   /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */
420   PetscFunctionReturn(MPI_SUCCESS);
421 }
422 EXTERN_C_END
423 
424 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
425 #if !defined(PETSC_WORDS_BIGENDIAN)
426 EXTERN_C_BEGIN
427 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
428 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
429 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
430 EXTERN_C_END
431 #endif
432 #endif
433 
434 int  PetscGlobalArgc   = 0;
435 char **PetscGlobalArgs = 0;
436 
437 #undef __FUNCT__
438 #define __FUNCT__ "PetscGetArgs"
439 /*@C
440    PetscGetArgs - Allows you to access the raw command line arguments anywhere
441      after PetscInitialize() is called but before PetscFinalize().
442 
443    Not Collective
444 
445    Output Parameters:
446 +  argc - count of number of command line arguments
447 -  args - the command line arguments
448 
449    Level: intermediate
450 
451    Notes:
452       This is usually used to pass the command line arguments into other libraries
453    that are called internally deep in PETSc or the application.
454 
455       The first argument contains the program name as is normal for C arguments.
456 
457    Concepts: command line arguments
458 
459 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
460 
461 @*/
462 PetscErrorCode  PetscGetArgs(int *argc,char ***args)
463 {
464   PetscFunctionBegin;
465   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
466   *argc = PetscGlobalArgc;
467   *args = PetscGlobalArgs;
468   PetscFunctionReturn(0);
469 }
470 
471 #undef __FUNCT__
472 #define __FUNCT__ "PetscGetArguments"
473 /*@C
474    PetscGetArguments - Allows you to access the  command line arguments anywhere
475      after PetscInitialize() is called but before PetscFinalize().
476 
477    Not Collective
478 
479    Output Parameters:
480 .  args - the command line arguments
481 
482    Level: intermediate
483 
484    Notes:
485       This does NOT start with the program name and IS null terminated (final arg is void)
486 
487    Concepts: command line arguments
488 
489 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
490 
491 @*/
492 PetscErrorCode  PetscGetArguments(char ***args)
493 {
494   PetscInt       i,argc = PetscGlobalArgc;
495   PetscErrorCode ierr;
496 
497   PetscFunctionBegin;
498   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
499   if (!argc) {*args = 0; PetscFunctionReturn(0);}
500   ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr);
501   for (i=0; i<argc-1; i++) {
502     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
503   }
504   (*args)[argc-1] = 0;
505   PetscFunctionReturn(0);
506 }
507 
508 #undef __FUNCT__
509 #define __FUNCT__ "PetscFreeArguments"
510 /*@C
511    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
512 
513    Not Collective
514 
515    Output Parameters:
516 .  args - the command line arguments
517 
518    Level: intermediate
519 
520    Concepts: command line arguments
521 
522 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
523 
524 @*/
525 PetscErrorCode  PetscFreeArguments(char **args)
526 {
527   PetscInt       i = 0;
528   PetscErrorCode ierr;
529 
530   PetscFunctionBegin;
531   if (!args) {PetscFunctionReturn(0);}
532   while (args[i]) {
533     ierr = PetscFree(args[i]);CHKERRQ(ierr);
534     i++;
535   }
536   ierr = PetscFree(args);CHKERRQ(ierr);
537   PetscFunctionReturn(0);
538 }
539 
540 #undef __FUNCT__
541 #define __FUNCT__ "PetscInitialize"
542 /*@C
543    PetscInitialize - Initializes the PETSc database and MPI.
544    PetscInitialize() calls MPI_Init() if that has yet to be called,
545    so this routine should always be called near the beginning of
546    your program -- usually the very first line!
547 
548    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
549 
550    Input Parameters:
551 +  argc - count of number of command line arguments
552 .  args - the command line arguments
553 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for
554           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
555 -  help - [optional] Help message to print, use PETSC_NULL for no message
556 
557    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
558    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
559    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
560    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
561    if different subcommunicators of the job are doing different things with PETSc.
562 
563    Options Database Keys:
564 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
565 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
566 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
567 .  -on_error_abort calls abort() when error detected (no traceback)
568 .  -on_error_mpiabort calls MPI_abort() when error detected
569 .  -error_output_stderr prints error messages to stderr instead of the default stdout
570 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
571 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
572 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
573 .  -stop_for_debugger - Print message on how to attach debugger manually to
574                         process and wait (-debugger_pause) seconds for attachment
575 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
576 .  -malloc no - Indicates not to use error-checking malloc
577 .  -malloc_debug - check for memory corruption at EVERY malloc or free
578 .  -fp_trap - Stops on floating point exceptions (Note that on the
579               IBM RS6000 this slows code by at least a factor of 10.)
580 .  -no_signal_handler - Indicates not to trap error signals
581 .  -shared_tmp - indicates /tmp directory is shared by all processors
582 .  -not_shared_tmp - each processor has own /tmp
583 .  -tmp - alternative name of /tmp directory
584 .  -get_total_flops - returns total flops done by all processors
585 -  -memory_info - Print memory usage at end of run
586 
587    Options Database Keys for Profiling:
588    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
589 +  -log_trace [filename] - Print traces of all PETSc calls
590         to the screen (useful to determine where a program
591         hangs without running in the debugger).  See PetscLogTraceBegin().
592 .  -info <optional filename> - Prints verbose information to the screen
593 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
594 
595    Environmental Variables:
596 +   PETSC_TMP - alternative tmp directory
597 .   PETSC_SHARED_TMP - tmp is shared by all processes
598 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
599 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
600 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
601 
602 
603    Level: beginner
604 
605    Notes:
606    If for some reason you must call MPI_Init() separately, call
607    it before PetscInitialize().
608 
609    Fortran Version:
610    In Fortran this routine has the format
611 $       call PetscInitialize(file,ierr)
612 
613 +   ierr - error return code
614 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
615           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
616 
617    Important Fortran Note:
618    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
619    null character string; you CANNOT just use PETSC_NULL as
620    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.
621 
622    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
623    calling PetscInitialize().
624 
625    Concepts: initializing PETSc
626 
627 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
628 
629 @*/
630 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
631 {
632   PetscErrorCode ierr;
633   PetscMPIInt    flag, size;
634   PetscInt       nodesize;
635   PetscBool      flg;
636   char           hostname[256];
637 
638   PetscFunctionBegin;
639   if (PetscInitializeCalled) PetscFunctionReturn(0);
640 
641   /* these must be initialized in a routine, not as a constant declaration*/
642   PETSC_STDOUT = stdout;
643   PETSC_STDERR = stderr;
644 
645   ierr = PetscOptionsCreate();CHKERRQ(ierr);
646 
647   /*
648      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
649      it that it sets args[0] on all processors to be args[0] on the first processor.
650   */
651   if (argc && *argc) {
652     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
653   } else {
654     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
655   }
656 
657   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
658   if (!flag) {
659     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");
660     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
661     PetscBeganMPI = PETSC_TRUE;
662   }
663   if (argc && args) {
664     PetscGlobalArgc = *argc;
665     PetscGlobalArgs = *args;
666   }
667   PetscFinalizeCalled   = PETSC_FALSE;
668 
669   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
670     PETSC_COMM_WORLD = MPI_COMM_WORLD;
671   }
672   ierr = MPI_Errhandler_set(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
673 
674   /* Done after init due to a bug in MPICH-GM? */
675   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
676 
677   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
678   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
679 
680 #if defined(PETSC_USE_COMPLEX)
681   /*
682      Initialized the global complex variable; this is because with
683      shared libraries the constructors for global variables
684      are not called; at least on IRIX.
685   */
686   {
687 #if defined(PETSC_CLANGUAGE_CXX)
688     PetscScalar ic(0.0,1.0);
689     PETSC_i = ic;
690 #else
691     PETSC_i = I;
692 #endif
693   }
694 
695 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
696   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
697   ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
698   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPI_C_COMPLEX);CHKERRQ(ierr);
699   ierr = MPI_Type_commit(&MPI_C_COMPLEX);CHKERRQ(ierr);
700   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
701 #endif
702 #endif
703 
704   /*
705      Create the PETSc MPI reduction operator that sums of the first
706      half of the entries and maxes the second half.
707   */
708   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
709 
710 #if defined(PETSC_USE_SCALAR___FLOAT128)
711   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
712   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
713   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
714   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
715   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
716 #endif
717 
718   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
719   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
720   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
721   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
722 
723   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
724   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
725 
726   /*
727      Attributes to be set on PETSc communicators
728   */
729   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
730   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
731   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
732 
733   /*
734      Build the options database
735   */
736   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
737 
738 
739   /*
740      Print main application help message
741   */
742   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
743   if (help && flg) {
744     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
745   }
746   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
747 
748   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
749 #if defined(PETSC_USE_LOG)
750   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
751 #endif
752 
753   /*
754      Load the dynamic libraries (on machines that support them), this registers all
755      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
756   */
757   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
758 
759   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
760   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
761   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
762   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
763 
764   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
765   /* Check the options database for options related to the options database itself */
766   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
767 
768 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
769   /*
770       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
771 
772       Currently not used because it is not supported by MPICH.
773   */
774 #if !defined(PETSC_WORDS_BIGENDIAN)
775   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
776 #endif
777 #endif
778 
779   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
780   if (flg) {
781 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
782     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
783 #else
784     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
785 #endif
786   } else {
787     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
788     if (flg) {
789       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
790       if (PetscOpenMPWorker) { /* if worker then never enter user code */
791         ierr = PetscEnd();
792       }
793     }
794   }
795 
796 #if defined(PETSC_HAVE_CUDA)
797   cublasInit();
798 #endif
799 
800 #if defined(PETSC_HAVE_AMS)
801   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
802   if (flg) {
803     PetscAMSPublishAll = PETSC_TRUE;
804   }
805 #endif
806 
807   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
808   if (flg) {
809     PetscInitializeCalled = PETSC_TRUE;
810     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
811   }
812 
813   /*
814       Once we are completedly initialized then we can set this variables
815   */
816   PetscInitializeCalled = PETSC_TRUE;
817   PetscFunctionReturn(0);
818 }
819 
820 extern PetscObject *PetscObjects;
821 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
822 
823 #undef __FUNCT__
824 #define __FUNCT__ "PetscFinalize"
825 /*@C
826    PetscFinalize - Checks for options to be called at the conclusion
827    of the program. MPI_Finalize() is called only if the user had not
828    called MPI_Init() before calling PetscInitialize().
829 
830    Collective on PETSC_COMM_WORLD
831 
832    Options Database Keys:
833 +  -options_table - Calls PetscOptionsView()
834 .  -options_left - Prints unused options that remain in the database
835 .  -objects_left  - Prints list of all objects that have not been freed
836 .  -mpidump - Calls PetscMPIDump()
837 .  -malloc_dump - Calls PetscMallocDump()
838 .  -malloc_info - Prints total memory usage
839 -  -malloc_log - Prints summary of memory usage
840 
841    Options Database Keys for Profiling:
842    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
843 +  -log_summary [filename] - Prints summary of flop and timing
844         information to screen. If the filename is specified the
845         summary is written to the file.  See PetscLogView().
846 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
847         See PetscLogPrintSViewPython().
848 .  -log_all [filename] - Logs extensive profiling information
849         See PetscLogDump().
850 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
851 .  -log_sync - Log the synchronization in scatters, inner products
852         and norms
853 -  -log_mpe [filename] - Creates a logfile viewable by the
854       utility Upshot/Nupshot (in MPICH distribution)
855 
856    Level: beginner
857 
858    Note:
859    See PetscInitialize() for more general runtime options.
860 
861 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
862 @*/
863 PetscErrorCode  PetscFinalize(void)
864 {
865   PetscErrorCode ierr;
866   PetscMPIInt    rank;
867   PetscInt       i,nopt;
868   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
869 #if defined(PETSC_HAVE_AMS)
870   PetscBool      flg = PETSC_FALSE;
871 #endif
872 #if defined(PETSC_USE_LOG)
873   char           mname[PETSC_MAX_PATH_LEN];
874 #endif
875 
876   PetscFunctionBegin;
877 
878   if (!PetscInitializeCalled) {
879     printf("PetscInitialize() must be called before PetscFinalize()\n");
880     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
881   }
882   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
883 
884 #if defined(PETSC_HAVE_AMS)
885   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
886   if (flg) {
887     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
888   }
889 #endif
890 
891   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
892 
893   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
894   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
895   if (!flg2) {
896     flg2 = PETSC_FALSE;
897     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
898   }
899   if (flg2) {
900     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
901   }
902 
903 #if defined(PETSC_USE_LOG)
904   flg1 = PETSC_FALSE;
905   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
906   if (flg1) {
907     PetscLogDouble flops = 0;
908     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
909     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
910   }
911 #endif
912 
913 
914 #if defined(PETSC_USE_LOG)
915 #if defined(PETSC_HAVE_MPE)
916   mname[0] = 0;
917   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
918   if (flg1){
919     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
920     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
921   }
922 #endif
923   mname[0] = 0;
924   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
925   if (flg1) {
926     PetscViewer viewer;
927     if (mname[0])  {
928       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
929       ierr = PetscLogView(viewer);CHKERRQ(ierr);
930       ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
931     } else {
932       viewer = PETSC_VIEWER_STDOUT_WORLD;
933       ierr = PetscLogView(viewer);CHKERRQ(ierr);
934     }
935   }
936 
937   mname[0] = 0;
938   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
939   if (flg1) {
940     PetscViewer viewer;
941     if (mname[0])  {
942       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
943       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
944       ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
945     } else {
946       viewer = PETSC_VIEWER_STDOUT_WORLD;
947       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
948     }
949   }
950 
951   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
952   if (flg1) {
953     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
954     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
955   }
956 
957   mname[0] = 0;
958   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
959   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
960   if (flg1 || flg2){
961     if (mname[0]) PetscLogDump(mname);
962     else          PetscLogDump(0);
963   }
964 #endif
965 
966 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_USE_PTHREAD)
967   if (PetscStackActive) {
968     ierr = PetscStackDestroy();CHKERRQ(ierr);
969   }
970 #endif
971 
972   flg1 = PETSC_FALSE;
973   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
974   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
975   flg1 = PETSC_FALSE;
976   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
977   if (flg1) {
978     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
979   }
980   flg1 = PETSC_FALSE;
981   flg2 = PETSC_FALSE;
982   /* preemptive call to avoid listing this option in options table as unused */
983   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
984   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
985 
986   if (flg2) {
987     if (!rank) {ierr = PetscOptionsView(PETSC_NULL);CHKERRQ(ierr);}
988   }
989 
990   /* to prevent PETSc -options_left from warning */
991   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
992   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
993   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
994 
995   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
996     flg3 = PETSC_FALSE; /* default value is required */
997     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
998     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
999     if (flg3) {
1000       if (!flg2) { /* have not yet printed the options */
1001 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1002       }
1003       if (!nopt) {
1004 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1005       } else if (nopt == 1) {
1006 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1007       } else {
1008 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
1009       }
1010     }
1011 #if defined(PETSC_USE_DEBUG)
1012     if (nopt && !flg3 && !flg1) {
1013       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1014       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1015       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1016     } else if (nopt && flg3) {
1017 #else
1018     if (nopt && flg3) {
1019 #endif
1020       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1021     }
1022   }
1023 
1024   /*
1025      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1026   */
1027   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1028 
1029   /*
1030        List all objects the user may have forgot to free
1031   */
1032   if (objects_left && PetscObjectsCounts) {
1033     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1034   }
1035   for (i=0; i<PetscObjectsMaxCounts; i++) {
1036     if (PetscObjects[i]) {
1037       if (objects_left) {
1038         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1039       }
1040     }
1041   }
1042   /* cannot actually destroy the left over objects, but destroy the list */
1043   PetscObjectsCounts    = 0;
1044   PetscObjectsMaxCounts = 0;
1045   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1046 
1047 
1048 #if defined(PETSC_USE_LOG)
1049   ierr = PetscLogDestroy();CHKERRQ(ierr);
1050 #endif
1051 
1052   /*
1053        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1054   */
1055   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1056 
1057   /*
1058      Destroy any packages that registered a finalize
1059   */
1060   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1061 
1062   /*
1063      Destroy all the function registration lists created
1064   */
1065   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1066 
1067   if (petsc_history) {
1068     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1069     petsc_history = 0;
1070   }
1071 
1072   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1073 
1074   {
1075     char fname[PETSC_MAX_PATH_LEN];
1076     FILE *fd;
1077     int  err;
1078 
1079     fname[0] = 0;
1080     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1081     if (flg1 && fname[0]) {
1082       char sname[PETSC_MAX_PATH_LEN];
1083 
1084       sprintf(sname,"%s_%d",fname,rank);
1085       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1086       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1087       err = fclose(fd);
1088       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1089     } else if (flg1) {
1090       MPI_Comm local_comm;
1091 
1092       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1093       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1094         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1095       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1096       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1097     }
1098   }
1099   {
1100     char fname[PETSC_MAX_PATH_LEN];
1101     FILE *fd;
1102 
1103     fname[0] = 0;
1104     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1105     if (flg1 && fname[0]) {
1106       char sname[PETSC_MAX_PATH_LEN];
1107       int  err;
1108 
1109       sprintf(sname,"%s_%d",fname,rank);
1110       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1111       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1112       err = fclose(fd);
1113       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1114     } else if (flg1) {
1115       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1116     }
1117   }
1118   /* Can be destroyed only after all the options are used */
1119   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1120 
1121   PetscGlobalArgc = 0;
1122   PetscGlobalArgs = 0;
1123 
1124 #if defined(PETSC_USE_SCALAR___FLOAT128)
1125   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1126   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1127   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1128   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1129 #endif
1130 
1131 #if defined(PETSC_USE_COMPLEX)
1132 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1133   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1134   ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1135   ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr);
1136 #endif
1137 #endif
1138   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1139   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1140   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1141   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1142   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1143 
1144   /*
1145      Destroy any known inner communicators and attributes pointing to them
1146      Note this will not destroy any new communicators the user has created
1147  */
1148   {
1149     PetscCommCounter *counter;
1150     PetscMPIInt      flg;
1151     MPI_Comm         icomm;
1152     void             *ptr;
1153     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1154     if (flg) {
1155       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1156       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1157       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1158       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1159 
1160       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1161       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1162       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1163       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1164     }
1165     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1166     if (flg) {
1167       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1168       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1169       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1170       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1171 
1172       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1173       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1174       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1175       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1176     }
1177   }
1178 
1179   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1180   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1181   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1182 
1183   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1184   if (PetscBeganMPI) {
1185 #if defined(PETSC_HAVE_MPI_FINALIZED)
1186     PetscMPIInt flag;
1187     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1188     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1189 #endif
1190     ierr = MPI_Finalize();CHKERRQ(ierr);
1191   }
1192 
1193   if (PETSC_ZOPEFD){
1194     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
1195     else fprintf(PETSC_STDOUT, "<<<end>>>");
1196   }
1197 
1198 #if defined(PETSC_HAVE_CUDA)
1199   cublasShutdown();
1200 #endif
1201 /*
1202 
1203      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1204    the communicator has some outstanding requests on it. Specifically if the
1205    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1206    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1207    is never freed as it should be. Thus one may obtain messages of the form
1208    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1209    memory was not freed.
1210 
1211 */
1212   ierr = PetscMallocClear();CHKERRQ(ierr);
1213   PetscInitializeCalled = PETSC_FALSE;
1214   PetscFinalizeCalled   = PETSC_TRUE;
1215   PetscFunctionReturn(ierr);
1216 }
1217 
1218