xref: /petsc/src/sys/objects/pinit.c (revision cd6526761e44e2ac7b4afaaf511785e78693abcc)
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 -  -server <port> - start PETSc webserver (default port is 8080)
595 
596    Options Database Keys for Profiling:
597    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
598 +  -log_trace [filename] - Print traces of all PETSc calls
599         to the screen (useful to determine where a program
600         hangs without running in the debugger).  See PetscLogTraceBegin().
601 .  -info <optional filename> - Prints verbose information to the screen
602 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
603 
604    Environmental Variables:
605 +   PETSC_TMP - alternative tmp directory
606 .   PETSC_SHARED_TMP - tmp is shared by all processes
607 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
608 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
609 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
610 
611 
612    Level: beginner
613 
614    Notes:
615    If for some reason you must call MPI_Init() separately, call
616    it before PetscInitialize().
617 
618    Fortran Version:
619    In Fortran this routine has the format
620 $       call PetscInitialize(file,ierr)
621 
622 +   ierr - error return code
623 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
624           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
625 
626    Important Fortran Note:
627    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
628    null character string; you CANNOT just use PETSC_NULL as
629    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.
630 
631    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
632    calling PetscInitialize().
633 
634    Concepts: initializing PETSc
635 
636 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
637 
638 @*/
639 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
640 {
641   PetscErrorCode ierr;
642   PetscMPIInt    flag, size;
643   PetscInt       nodesize;
644   PetscBool      flg;
645   char           hostname[256];
646 
647   PetscFunctionBegin;
648   if (PetscInitializeCalled) PetscFunctionReturn(0);
649 
650   /* these must be initialized in a routine, not as a constant declaration*/
651   PETSC_STDOUT = stdout;
652   PETSC_STDERR = stderr;
653 
654   ierr = PetscOptionsCreate();CHKERRQ(ierr);
655 
656   /*
657      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
658      it that it sets args[0] on all processors to be args[0] on the first processor.
659   */
660   if (argc && *argc) {
661     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
662   } else {
663     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
664   }
665 
666   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
667   if (!flag) {
668     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");
669     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
670     PetscBeganMPI = PETSC_TRUE;
671   }
672   if (argc && args) {
673     PetscGlobalArgc = *argc;
674     PetscGlobalArgs = *args;
675   }
676   PetscFinalizeCalled   = PETSC_FALSE;
677 
678   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
679     PETSC_COMM_WORLD = MPI_COMM_WORLD;
680   }
681   ierr = MPI_Errhandler_set(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
682 
683   /* Done after init due to a bug in MPICH-GM? */
684   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
685 
686   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
687   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
688 
689 #if defined(PETSC_USE_COMPLEX)
690   /*
691      Initialized the global complex variable; this is because with
692      shared libraries the constructors for global variables
693      are not called; at least on IRIX.
694   */
695   {
696 #if defined(PETSC_CLANGUAGE_CXX)
697     PetscScalar ic(0.0,1.0);
698     PETSC_i = ic;
699 #else
700     PETSC_i = I;
701 #endif
702   }
703 
704 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
705   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
706   ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
707   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPI_C_COMPLEX);CHKERRQ(ierr);
708   ierr = MPI_Type_commit(&MPI_C_COMPLEX);CHKERRQ(ierr);
709   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
710 #endif
711 #endif
712 
713   /*
714      Create the PETSc MPI reduction operator that sums of the first
715      half of the entries and maxes the second half.
716   */
717   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
718 
719 #if defined(PETSC_USE_REAL___FLOAT128)
720   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
721   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
722   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
723   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
724   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
725 #endif
726 
727   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
728   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
729   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
730   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
731 
732   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
733   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
734 
735   /*
736      Attributes to be set on PETSc communicators
737   */
738   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
739   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
740   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
741 
742   /*
743      Build the options database
744   */
745   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
746 
747 
748   /*
749      Print main application help message
750   */
751   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
752   if (help && flg) {
753     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
754   }
755   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
756 
757   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
758 #if defined(PETSC_USE_LOG)
759   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
760 #endif
761 
762   /*
763      Load the dynamic libraries (on machines that support them), this registers all
764      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
765   */
766   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
767 
768   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
769   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
770   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
771   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
772 
773   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
774   /* Check the options database for options related to the options database itself */
775   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
776 
777 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
778   /*
779       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
780 
781       Currently not used because it is not supported by MPICH.
782   */
783 #if !defined(PETSC_WORDS_BIGENDIAN)
784   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
785 #endif
786 #endif
787 
788   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
789   if (flg) {
790 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
791     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
792 #else
793     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
794 #endif
795   } else {
796     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
797     if (flg) {
798       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
799       if (PetscOpenMPWorker) { /* if worker then never enter user code */
800         ierr = PetscEnd();
801       }
802     }
803   }
804 
805 #if defined(PETSC_HAVE_CUDA)
806   cublasInit();
807 #endif
808 
809 #if defined(PETSC_HAVE_AMS)
810   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
811   if (flg) {
812     PetscAMSPublishAll = PETSC_TRUE;
813   }
814 #endif
815 
816   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
817   if (flg) {
818     PetscInitializeCalled = PETSC_TRUE;
819     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
820   }
821 
822   /*
823       Once we are completedly initialized then we can set this variables
824   */
825   PetscInitializeCalled = PETSC_TRUE;
826   PetscFunctionReturn(0);
827 }
828 
829 extern PetscObject *PetscObjects;
830 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
831 
832 #undef __FUNCT__
833 #define __FUNCT__ "PetscFinalize"
834 /*@C
835    PetscFinalize - Checks for options to be called at the conclusion
836    of the program. MPI_Finalize() is called only if the user had not
837    called MPI_Init() before calling PetscInitialize().
838 
839    Collective on PETSC_COMM_WORLD
840 
841    Options Database Keys:
842 +  -options_table - Calls PetscOptionsView()
843 .  -options_left - Prints unused options that remain in the database
844 .  -objects_left  - Prints list of all objects that have not been freed
845 .  -mpidump - Calls PetscMPIDump()
846 .  -malloc_dump - Calls PetscMallocDump()
847 .  -malloc_info - Prints total memory usage
848 -  -malloc_log - Prints summary of memory usage
849 
850    Options Database Keys for Profiling:
851    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
852 +  -log_summary [filename] - Prints summary of flop and timing
853         information to screen. If the filename is specified the
854         summary is written to the file.  See PetscLogView().
855 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
856         See PetscLogPrintSViewPython().
857 .  -log_all [filename] - Logs extensive profiling information
858         See PetscLogDump().
859 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
860 .  -log_sync - Log the synchronization in scatters, inner products
861         and norms
862 -  -log_mpe [filename] - Creates a logfile viewable by the
863       utility Upshot/Nupshot (in MPICH distribution)
864 
865    Level: beginner
866 
867    Note:
868    See PetscInitialize() for more general runtime options.
869 
870 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
871 @*/
872 PetscErrorCode  PetscFinalize(void)
873 {
874   PetscErrorCode ierr;
875   PetscMPIInt    rank;
876   PetscInt       i,nopt;
877   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE;
878 #if defined(PETSC_HAVE_AMS)
879   PetscBool      flg = PETSC_FALSE;
880 #endif
881 #if defined(PETSC_USE_LOG)
882   char           mname[PETSC_MAX_PATH_LEN];
883 #endif
884 
885   PetscFunctionBegin;
886 
887   if (!PetscInitializeCalled) {
888     printf("PetscInitialize() must be called before PetscFinalize()\n");
889     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
890   }
891   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
892 
893 #if defined(PETSC_HAVE_AMS)
894   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
895   if (flg) {
896     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
897   }
898 #endif
899 
900   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
901 
902   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
903   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
904   if (!flg2) {
905     flg2 = PETSC_FALSE;
906     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
907   }
908   if (flg2) {
909     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
910   }
911 
912 #if defined(PETSC_USE_LOG)
913   flg1 = PETSC_FALSE;
914   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
915   if (flg1) {
916     PetscLogDouble flops = 0;
917     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
918     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
919   }
920 #endif
921 
922 
923 #if defined(PETSC_USE_LOG)
924 #if defined(PETSC_HAVE_MPE)
925   mname[0] = 0;
926   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
927   if (flg1){
928     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
929     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
930   }
931 #endif
932   mname[0] = 0;
933   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
934   if (flg1) {
935     PetscViewer viewer;
936     if (mname[0])  {
937       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
938       ierr = PetscLogView(viewer);CHKERRQ(ierr);
939       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
940     } else {
941       viewer = PETSC_VIEWER_STDOUT_WORLD;
942       ierr = PetscLogView(viewer);CHKERRQ(ierr);
943     }
944   }
945 
946   mname[0] = 0;
947   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
948   if (flg1) {
949     PetscViewer viewer;
950     if (mname[0])  {
951       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
952       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
953       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
954     } else {
955       viewer = PETSC_VIEWER_STDOUT_WORLD;
956       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
957     }
958   }
959 
960   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
961   if (flg1) {
962     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
963     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
964   }
965 
966   mname[0] = 0;
967   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
968   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
969   if (flg1 || flg2){
970     if (mname[0]) PetscLogDump(mname);
971     else          PetscLogDump(0);
972   }
973 #endif
974 
975 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_USE_PTHREAD)
976   if (PetscStackActive) {
977     ierr = PetscStackDestroy();CHKERRQ(ierr);
978   }
979 #endif
980 
981   flg1 = PETSC_FALSE;
982   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
983   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
984   flg1 = PETSC_FALSE;
985   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
986   if (flg1) {
987     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
988   }
989   flg1 = PETSC_FALSE;
990   flg2 = PETSC_FALSE;
991   /* preemptive call to avoid listing this option in options table as unused */
992   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
993   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
994 
995   if (flg2) {
996     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
997   }
998 
999   /* to prevent PETSc -options_left from warning */
1000   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1001   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1002   ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr);
1003 
1004   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
1005     flg3 = PETSC_FALSE; /* default value is required */
1006     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1007     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1008     if (flg3) {
1009       if (!flg2) { /* have not yet printed the options */
1010 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1011       }
1012       if (!nopt) {
1013 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1014       } else if (nopt == 1) {
1015 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1016       } else {
1017 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1018       }
1019     }
1020 #if defined(PETSC_USE_DEBUG)
1021     if (nopt && !flg3 && !flg1) {
1022       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1023       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1024       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1025     } else if (nopt && flg3) {
1026 #else
1027     if (nopt && flg3) {
1028 #endif
1029       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1030     }
1031   }
1032 
1033   /*
1034      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1035   */
1036   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1037 
1038   /*
1039        List all objects the user may have forgot to free
1040   */
1041   if (objects_left && PetscObjectsCounts) {
1042     ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts);
1043   }
1044   for (i=0; i<PetscObjectsMaxCounts; i++) {
1045     if (PetscObjects[i]) {
1046       if (objects_left) {
1047         ierr = PetscPrintf(PETSC_COMM_WORLD,"  %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr);
1048       }
1049     }
1050   }
1051   /* cannot actually destroy the left over objects, but destroy the list */
1052   PetscObjectsCounts    = 0;
1053   PetscObjectsMaxCounts = 0;
1054   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1055 
1056 
1057 #if defined(PETSC_USE_LOG)
1058   ierr = PetscLogDestroy();CHKERRQ(ierr);
1059 #endif
1060 
1061   /*
1062        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1063   */
1064   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1065 
1066   /*
1067      Destroy any packages that registered a finalize
1068   */
1069   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1070 
1071   /*
1072      Destroy all the function registration lists created
1073   */
1074   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1075 
1076   if (petsc_history) {
1077     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1078     petsc_history = 0;
1079   }
1080 
1081   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1082 
1083   {
1084     char fname[PETSC_MAX_PATH_LEN];
1085     FILE *fd;
1086     int  err;
1087 
1088     fname[0] = 0;
1089     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1090     if (flg1 && fname[0]) {
1091       char sname[PETSC_MAX_PATH_LEN];
1092 
1093       sprintf(sname,"%s_%d",fname,rank);
1094       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1095       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1096       err = fclose(fd);
1097       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1098     } else if (flg1) {
1099       MPI_Comm local_comm;
1100 
1101       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1102       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1103         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1104       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1105       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1106     }
1107   }
1108   {
1109     char fname[PETSC_MAX_PATH_LEN];
1110     FILE *fd;
1111 
1112     fname[0] = 0;
1113     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1114     if (flg1 && fname[0]) {
1115       char sname[PETSC_MAX_PATH_LEN];
1116       int  err;
1117 
1118       sprintf(sname,"%s_%d",fname,rank);
1119       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1120       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1121       err = fclose(fd);
1122       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1123     } else if (flg1) {
1124       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1125     }
1126   }
1127   /* Can be destroyed only after all the options are used */
1128   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1129 
1130   PetscGlobalArgc = 0;
1131   PetscGlobalArgs = 0;
1132 
1133 #if defined(PETSC_USE_REAL___FLOAT128)
1134   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1135   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1136   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1137   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1138 #endif
1139 
1140 #if defined(PETSC_USE_COMPLEX)
1141 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1142   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1143   ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1144   ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr);
1145 #endif
1146 #endif
1147   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1148   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1149   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1150   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1151   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1152 
1153   /*
1154      Destroy any known inner communicators and attributes pointing to them
1155      Note this will not destroy any new communicators the user has created
1156  */
1157   {
1158     PetscCommCounter *counter;
1159     PetscMPIInt      flg;
1160     MPI_Comm         icomm;
1161     void             *ptr;
1162     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1163     if (flg) {
1164       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1165       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1166       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1167       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1168 
1169       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1170       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1171       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1172       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1173     }
1174     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1175     if (flg) {
1176       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1177       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1178       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1179       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1180 
1181       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1182       ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr);
1183       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1184       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1185     }
1186   }
1187 
1188   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1189   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1190   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1191 
1192   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
1193   if (PetscBeganMPI) {
1194 #if defined(PETSC_HAVE_MPI_FINALIZED)
1195     PetscMPIInt flag;
1196     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1197     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1198 #endif
1199     ierr = MPI_Finalize();CHKERRQ(ierr);
1200   }
1201 
1202   if (PETSC_ZOPEFD){
1203     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
1204     else fprintf(PETSC_STDOUT, "<<<end>>>");
1205   }
1206 
1207 #if defined(PETSC_HAVE_CUDA)
1208   cublasShutdown();
1209 #endif
1210 /*
1211 
1212      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1213    the communicator has some outstanding requests on it. Specifically if the
1214    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1215    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1216    is never freed as it should be. Thus one may obtain messages of the form
1217    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1218    memory was not freed.
1219 
1220 */
1221   ierr = PetscMallocClear();CHKERRQ(ierr);
1222   PetscInitializeCalled = PETSC_FALSE;
1223   PetscFinalizeCalled   = PETSC_TRUE;
1224   PetscFunctionReturn(ierr);
1225 }
1226 
1227