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