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