xref: /petsc/src/sys/objects/pinit.c (revision 0c293d8b461cefff78b1805e317a4318512b344d)
1 
2 /*
3    This file defines the initialization of PETSc, including PetscInitialize()
4 */
5 #include <petsc-private/petscimpl.h>        /*I  "petscsys.h"   I*/
6 #include <petscvalgrind.h>
7 #include <petscviewer.h>
8 
9 #if defined(PETSC_HAVE_CUDA)
10 #include <cublas.h>
11 #endif
12 
13 #include <petscthreadcomm.h>
14 
15 #if defined(PETSC_USE_LOG)
16 extern PetscErrorCode PetscLogBegin_Private(void);
17 #endif
18 
19 #if defined(PETSC_SERIALIZE_FUNCTIONS)
20 PetscFPT PetscFPTData = 0;
21 #endif
22 
23 #if defined(PETSC_HAVE_SAWS)
24 #include <petscviewersaws.h>
25 #endif
26 /* -----------------------------------------------------------------------------------------*/
27 
28 extern FILE *petsc_history;
29 
30 extern PetscErrorCode PetscInitialize_DynamicLibraries(void);
31 extern PetscErrorCode PetscFinalize_DynamicLibraries(void);
32 extern PetscErrorCode PetscFunctionListPrintAll(void);
33 extern PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
34 extern PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
35 extern PetscErrorCode PetscCloseHistoryFile(FILE**);
36 
37 /* user may set this BEFORE calling PetscInitialize() */
38 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;
39 
40 PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
41 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
42 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
43 
44 /*
45      Declare and set all the string names of the PETSc enums
46 */
47 const char *const PetscBools[]     = {"FALSE","TRUE","PetscBool","PETSC_",0};
48 const char *const PetscCopyModes[] = {"COPY_VALUES","OWN_POINTER","USE_POINTER","PetscCopyMode","PETSC_",0};
49 const char *const PetscDataTypes[] = {"INT","DOUBLE","COMPLEX","LONG","SHORT","FLOAT",
50                                       "CHAR","LOGICAL","ENUM","BOOL","LONGDOUBLE","OBJECT","FUNCTION","PetscDataType","PETSC_",0};
51 
52 PetscBool PetscPreLoadingUsed = PETSC_FALSE;
53 PetscBool PetscPreLoadingOn   = PETSC_FALSE;
54 
55 PetscInt PetscHotRegionDepth;
56 
57 /*
58        Checks the options database for initializations related to the
59     PETSc components
60 */
61 #undef __FUNCT__
62 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
63 PetscErrorCode  PetscOptionsCheckInitial_Components(void)
64 {
65   PetscBool      flg1;
66   PetscErrorCode ierr;
67 
68   PetscFunctionBegin;
69   ierr = PetscOptionsHasName(NULL,"-help",&flg1);CHKERRQ(ierr);
70   if (flg1) {
71 #if defined(PETSC_USE_LOG)
72     MPI_Comm comm = PETSC_COMM_WORLD;
73     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
74     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
75     ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
76     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
77 #endif
78   }
79   PetscFunctionReturn(0);
80 }
81 
82 #undef __FUNCT__
83 #define __FUNCT__ "PetscInitializeNoPointers"
84 /*
85       PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args
86 
87    Collective
88 
89    Level: advanced
90 
91     Notes: this is called only by the PETSc MATLAB and Julia interface. Even though it might start MPI it sets the flag to
92      indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to
93      be called multiple times from MATLAB and Julia without the problem of trying to initialize MPI more than once.
94 
95      Turns off PETSc signal handling because that can interact with MATLAB's signal handling causing random crashes.
96 
97 .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments()
98 */
99 PetscErrorCode  PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help)
100 {
101   PetscErrorCode ierr;
102   int            myargc   = argc;
103   char           **myargs = args;
104 
105   PetscFunctionBegin;
106   ierr = PetscInitialize(&myargc,&myargs,filename,help);CHKERRQ(ierr);
107   ierr = PetscPopSignalHandler();CHKERRQ(ierr);
108   PetscBeganMPI = PETSC_FALSE;
109   PetscFunctionReturn(ierr);
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PetscGetPETSC_COMM_SELF"
114 /*
115       Used by MATLAB and Julia interface to get communicator
116 */
117 PetscErrorCode  PetscGetPETSC_COMM_SELF(MPI_Comm *comm)
118 {
119   PetscFunctionBegin;
120   *comm = PETSC_COMM_SELF;
121   PetscFunctionReturn(0);
122 }
123 
124 #undef __FUNCT__
125 #define __FUNCT__ "PetscInitializeNoArguments"
126 /*@C
127       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
128         the command line arguments.
129 
130    Collective
131 
132    Level: advanced
133 
134 .seealso: PetscInitialize(), PetscInitializeFortran()
135 @*/
136 PetscErrorCode  PetscInitializeNoArguments(void)
137 {
138   PetscErrorCode ierr;
139   int            argc   = 0;
140   char           **args = 0;
141 
142   PetscFunctionBegin;
143   ierr = PetscInitialize(&argc,&args,NULL,NULL);
144   PetscFunctionReturn(ierr);
145 }
146 
147 #undef __FUNCT__
148 #define __FUNCT__ "PetscInitialized"
149 /*@
150       PetscInitialized - Determine whether PETSc is initialized.
151 
152    Level: beginner
153 
154 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
155 @*/
156 PetscErrorCode PetscInitialized(PetscBool  *isInitialized)
157 {
158   *isInitialized = PetscInitializeCalled;
159   return 0;
160 }
161 
162 #undef __FUNCT__
163 #define __FUNCT__ "PetscFinalized"
164 /*@
165       PetscFinalized - Determine whether PetscFinalize() has been called yet
166 
167    Level: developer
168 
169 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
170 @*/
171 PetscErrorCode  PetscFinalized(PetscBool  *isFinalized)
172 {
173   *isFinalized = PetscFinalizeCalled;
174   return 0;
175 }
176 
177 extern PetscErrorCode PetscOptionsCheckInitial_Private(void);
178 
179 /*
180        This function is the MPI reduction operation used to compute the sum of the
181    first half of the datatype and the max of the second half.
182 */
183 MPI_Op PetscMaxSum_Op = 0;
184 
185 #undef __FUNCT__
186 #define __FUNCT__ "PetscMaxSum_Local"
187 PETSC_EXTERN void MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
188 {
189   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
190 
191   PetscFunctionBegin;
192   if (*datatype != MPIU_2INT) {
193     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
194     MPI_Abort(MPI_COMM_WORLD,1);
195   }
196 
197   for (i=0; i<count; i++) {
198     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
199     xout[2*i+1] += xin[2*i+1];
200   }
201   PetscFunctionReturnVoid();
202 }
203 
204 /*
205     Returns the max of the first entry owned by this processor and the
206 sum of the second entry.
207 
208     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
209 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
210 there would be no place to store the both needed results.
211 */
212 #undef __FUNCT__
213 #define __FUNCT__ "PetscMaxSum"
214 PetscErrorCode  PetscMaxSum(MPI_Comm comm,const PetscInt sizes[],PetscInt *max,PetscInt *sum)
215 {
216   PetscMPIInt    size,rank;
217   struct {PetscInt max,sum;} *work;
218   PetscErrorCode ierr;
219 
220   PetscFunctionBegin;
221   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
222   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
223   ierr = PetscMalloc1(size,&work);CHKERRQ(ierr);
224   ierr = MPI_Allreduce((void*)sizes,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
225   *max = work[rank].max;
226   *sum = work[rank].sum;
227   ierr = PetscFree(work);CHKERRQ(ierr);
228   PetscFunctionReturn(0);
229 }
230 
231 /* ----------------------------------------------------------------------------*/
232 
233 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
234 MPI_Op MPIU_SUM = 0;
235 
236 #undef __FUNCT__
237 #define __FUNCT__ "PetscSum_Local"
238 PETSC_EXTERN void PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
239 {
240   PetscInt i,count = *cnt;
241 
242   PetscFunctionBegin;
243   if (*datatype == MPIU_REAL) {
244     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
245     for (i=0; i<count; i++) xout[i] += xin[i];
246   }
247 #if defined(PETSC_HAVE_COMPLEX)
248   else if (*datatype == MPIU_COMPLEX) {
249     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
250     for (i=0; i<count; i++) xout[i] += xin[i];
251   }
252 #endif
253   else {
254     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
255     MPI_Abort(MPI_COMM_WORLD,1);
256   }
257   PetscFunctionReturnVoid();
258 }
259 #endif
260 
261 #if defined(PETSC_USE_REAL___FLOAT128)
262 MPI_Op MPIU_MAX = 0;
263 MPI_Op MPIU_MIN = 0;
264 
265 #undef __FUNCT__
266 #define __FUNCT__ "PetscMax_Local"
267 PETSC_EXTERN void PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
268 {
269   PetscInt i,count = *cnt;
270 
271   PetscFunctionBegin;
272   if (*datatype == MPIU_REAL) {
273     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
274     for (i=0; i<count; i++) xout[i] = PetscMax(xout[i],xin[i]);
275   }
276 #if defined(PETSC_HAVE_COMPLEX)
277   else if (*datatype == MPIU_COMPLEX) {
278     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
279     for (i=0; i<count; i++) {
280       xout[i] = PetscRealPartComplex(xout[i])<PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
281     }
282   }
283 #endif
284   else {
285     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
286     MPI_Abort(MPI_COMM_WORLD,1);
287   }
288   PetscFunctionReturnVoid();
289 }
290 
291 #undef __FUNCT__
292 #define __FUNCT__ "PetscMin_Local"
293 PETSC_EXTERN void PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
294 {
295   PetscInt    i,count = *cnt;
296 
297   PetscFunctionBegin;
298   if (*datatype == MPIU_REAL) {
299     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
300     for (i=0; i<count; i++) xout[i] = PetscMin(xout[i],xin[i]);
301   }
302 #if defined(PETSC_HAVE_COMPLEX)
303   else if (*datatype == MPIU_COMPLEX) {
304     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
305     for (i=0; i<count; i++) {
306       xout[i] = PetscRealPartComplex(xout[i])>PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
307     }
308   }
309 #endif
310   else {
311     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types");
312     MPI_Abort(MPI_COMM_WORLD,1);
313   }
314   PetscFunctionReturnVoid();
315 }
316 #endif
317 
318 #undef __FUNCT__
319 #define __FUNCT__ "Petsc_DelCounter"
320 /*
321    Private routine to delete internal tag/name counter storage when a communicator is freed.
322 
323    This is called by MPI, not by users. This is called by MPI_Comm_free() when the communicator that has this  data as an attribute is freed.
324 
325    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
326 
327 */
328 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
329 {
330   PetscErrorCode ierr;
331 
332   PetscFunctionBegin;
333   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
334   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
335   PetscFunctionReturn(MPI_SUCCESS);
336 }
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "Petsc_DelComm_Outer"
340 /*
341   This is invoked on the outer comm as a result of either PetscCommDestroy() (via MPI_Attr_delete) or when the user
342   calls MPI_Comm_free().
343 
344   This is the only entry point for breaking the links between inner and outer comms.
345 
346   This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator.
347 
348   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
349 
350 */
351 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Outer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
352 {
353   PetscErrorCode ierr;
354   PetscMPIInt    flg;
355   union {MPI_Comm comm; void *ptr;} icomm,ocomm;
356 
357   PetscFunctionBegin;
358   if (keyval != Petsc_InnerComm_keyval) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Unexpected keyval");
359   icomm.ptr = attr_val;
360 
361   ierr = MPI_Attr_get(icomm.comm,Petsc_OuterComm_keyval,&ocomm,&flg);CHKERRQ(ierr);
362   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected reference to outer comm");
363   if (ocomm.comm != comm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm has reference to non-matching outer comm");
364   ierr = MPI_Attr_delete(icomm.comm,Petsc_OuterComm_keyval);CHKERRQ(ierr); /* Calls Petsc_DelComm_Inner */
365   ierr = PetscInfo1(0,"User MPI_Comm %ld is being freed after removing reference from inner PETSc comm to this outer comm\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
366   PetscFunctionReturn(MPI_SUCCESS);
367 }
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "Petsc_DelComm_Inner"
371 /*
372  * This is invoked on the inner comm when Petsc_DelComm_Outer calls MPI_Attr_delete.  It should not be reached any other way.
373  */
374 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Inner(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
375 {
376   PetscErrorCode ierr;
377 
378   PetscFunctionBegin;
379   ierr = PetscInfo1(0,"Removing reference to PETSc communicator embedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
380   PetscFunctionReturn(MPI_SUCCESS);
381 }
382 
383 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
384 #if !defined(PETSC_WORDS_BIGENDIAN)
385 PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
386 PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
387 PETSC_EXTERN PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
388 #endif
389 #endif
390 
391 int  PetscGlobalArgc   = 0;
392 char **PetscGlobalArgs = 0;
393 PetscSegBuffer PetscCitationsList;
394 
395 #undef __FUNCT__
396 #define __FUNCT__ "PetscCitationsInitialize"
397 PetscErrorCode PetscCitationsInitialize()
398 {
399   PetscErrorCode ierr;
400 
401   PetscFunctionBegin;
402   ierr = PetscSegBufferCreate(1,10000,&PetscCitationsList);CHKERRQ(ierr);
403   ierr = PetscCitationsRegister("@TechReport{petsc-user-ref,\n  Author = {Satish Balay and Shrirang Abhyankar and Mark F. Adams and Jed Brown and Peter Brune\n            and Kris Buschelman and Victor Eijkhout and William D. Gropp\n            and Dinesh Kaushik and Matthew G. Knepley\n            and Lois Curfman McInnes and Karl Rupp and Barry F. Smith\n            and Hong Zhang},\n  Title = {{PETS}c Users Manual},\n  Number = {ANL-95/11 - Revision 3.5},\n  Institution = {Argonne National Laboratory},\n  Year = {2014}\n}\n",NULL);CHKERRQ(ierr);
404   ierr = PetscCitationsRegister("@InProceedings{petsc-efficient,\n  Author = {Satish Balay and William D. Gropp and Lois Curfman McInnes and Barry F. Smith},\n  Title = {Efficient Management of Parallelism in Object Oriented Numerical Software Libraries},\n  Booktitle = {Modern Software Tools in Scientific Computing},\n  Editor = {E. Arge and A. M. Bruaset and H. P. Langtangen},\n  Pages = {163--202},\n  Publisher = {Birkh{\\\"{a}}user Press},\n  Year = {1997}\n}\n",NULL);CHKERRQ(ierr);
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "PetscGetArgs"
410 /*@C
411    PetscGetArgs - Allows you to access the raw command line arguments anywhere
412      after PetscInitialize() is called but before PetscFinalize().
413 
414    Not Collective
415 
416    Output Parameters:
417 +  argc - count of number of command line arguments
418 -  args - the command line arguments
419 
420    Level: intermediate
421 
422    Notes:
423       This is usually used to pass the command line arguments into other libraries
424    that are called internally deep in PETSc or the application.
425 
426       The first argument contains the program name as is normal for C arguments.
427 
428    Concepts: command line arguments
429 
430 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
431 
432 @*/
433 PetscErrorCode  PetscGetArgs(int *argc,char ***args)
434 {
435   PetscFunctionBegin;
436   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
437   *argc = PetscGlobalArgc;
438   *args = PetscGlobalArgs;
439   PetscFunctionReturn(0);
440 }
441 
442 #undef __FUNCT__
443 #define __FUNCT__ "PetscGetArguments"
444 /*@C
445    PetscGetArguments - Allows you to access the  command line arguments anywhere
446      after PetscInitialize() is called but before PetscFinalize().
447 
448    Not Collective
449 
450    Output Parameters:
451 .  args - the command line arguments
452 
453    Level: intermediate
454 
455    Notes:
456       This does NOT start with the program name and IS null terminated (final arg is void)
457 
458    Concepts: command line arguments
459 
460 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
461 
462 @*/
463 PetscErrorCode  PetscGetArguments(char ***args)
464 {
465   PetscInt       i,argc = PetscGlobalArgc;
466   PetscErrorCode ierr;
467 
468   PetscFunctionBegin;
469   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
470   if (!argc) {*args = 0; PetscFunctionReturn(0);}
471   ierr = PetscMalloc1(argc,args);CHKERRQ(ierr);
472   for (i=0; i<argc-1; i++) {
473     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
474   }
475   (*args)[argc-1] = 0;
476   PetscFunctionReturn(0);
477 }
478 
479 #undef __FUNCT__
480 #define __FUNCT__ "PetscFreeArguments"
481 /*@C
482    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
483 
484    Not Collective
485 
486    Output Parameters:
487 .  args - the command line arguments
488 
489    Level: intermediate
490 
491    Concepts: command line arguments
492 
493 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
494 
495 @*/
496 PetscErrorCode  PetscFreeArguments(char **args)
497 {
498   PetscInt       i = 0;
499   PetscErrorCode ierr;
500 
501   PetscFunctionBegin;
502   if (!args) PetscFunctionReturn(0);
503   while (args[i]) {
504     ierr = PetscFree(args[i]);CHKERRQ(ierr);
505     i++;
506   }
507   ierr = PetscFree(args);CHKERRQ(ierr);
508   PetscFunctionReturn(0);
509 }
510 
511 #if defined(PETSC_HAVE_SAWS)
512 #include <petscconfiginfo.h>
513 
514 #undef __FUNCT__
515 #define __FUNCT__ "PetscInitializeSAWs"
516 PetscErrorCode  PetscInitializeSAWs(const char help[])
517 {
518   if (!PetscGlobalRank) {
519     char           cert[PETSC_MAX_PATH_LEN],root[PETSC_MAX_PATH_LEN],*intro,programname[64],*appline,*options,version[64];
520     int            port;
521     PetscBool      flg,rootlocal = PETSC_FALSE,flg2;
522     size_t         applinelen,introlen;
523     PetscErrorCode ierr;
524 
525     ierr = PetscOptionsHasName(NULL,"-saws_log",&flg);CHKERRQ(ierr);
526     if (flg) {
527       char  sawslog[PETSC_MAX_PATH_LEN];
528 
529       ierr = PetscOptionsGetString(NULL,"-saws_log",sawslog,PETSC_MAX_PATH_LEN,NULL);CHKERRQ(ierr);
530       if (sawslog[0]) {
531         PetscStackCallSAWs(SAWs_Set_Use_Logfile,(sawslog));
532       } else {
533         PetscStackCallSAWs(SAWs_Set_Use_Logfile,(NULL));
534       }
535     }
536     ierr = PetscOptionsGetString(NULL,"-saws_https",cert,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
537     if (flg) {
538       PetscStackCallSAWs(SAWs_Set_Use_HTTPS,(cert));
539     }
540     ierr = PetscOptionsGetInt(NULL,"-saws_port",&port,&flg);CHKERRQ(ierr);
541     if (flg) {
542       PetscStackCallSAWs(SAWs_Set_Port,(port));
543     }
544     ierr = PetscOptionsGetString(NULL,"-saws_root",root,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
545     if (flg) {
546       PetscStackCallSAWs(SAWs_Set_Document_Root,(root));CHKERRQ(ierr);
547       ierr = PetscStrcmp(root,".",&rootlocal);CHKERRQ(ierr);
548     }
549     ierr = PetscOptionsHasName(NULL,"-saws_local",&flg2);CHKERRQ(ierr);
550     if (flg2) {
551       char jsdir[PETSC_MAX_PATH_LEN];
552       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"-saws_local option requires -saws_root option");
553       ierr = PetscSNPrintf(jsdir,PETSC_MAX_PATH_LEN,"%s/js",root);CHKERRQ(ierr);
554       ierr = PetscTestDirectory(jsdir,'r',&flg);CHKERRQ(ierr);
555       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"-saws_local option requires js directory in root directory");
556       PetscStackCallSAWs(SAWs_Push_Local_Header,());CHKERRQ(ierr);
557     }
558     ierr = PetscGetProgramName(programname,64);CHKERRQ(ierr);
559     ierr = PetscStrlen(help,&applinelen);CHKERRQ(ierr);
560     introlen   = 4096 + applinelen;
561     applinelen += 256;
562     ierr = PetscMalloc(applinelen,&appline);CHKERRQ(ierr);
563     ierr = PetscMalloc(introlen,&intro);CHKERRQ(ierr);
564 
565     if (rootlocal) {
566       ierr = PetscSNPrintf(appline,applinelen,"%s.c.html",programname);CHKERRQ(ierr);
567       ierr = PetscTestFile(appline,'r',&rootlocal);CHKERRQ(ierr);
568     }
569     ierr = PetscOptionsGetAll(&options);CHKERRQ(ierr);
570     if (rootlocal && help) {
571       ierr = PetscSNPrintf(appline,applinelen,"<center> Running <a href=\"%s.c.html\">%s</a> %s</center><br><center><pre>%s</pre></center><br>\n",programname,programname,options,help);
572     } else if (help) {
573       ierr = PetscSNPrintf(appline,applinelen,"<center>Running %s %s</center><br><center><pre>%s</pre></center><br>\n",programname,options,help);
574     } else {
575       ierr = PetscSNPrintf(appline,applinelen,"<center> Running %s %s</center><br>\n",programname,options);
576     }
577     ierr = PetscFree(options);CHKERRQ(ierr);
578     ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
579     ierr = PetscSNPrintf(intro,introlen,"<body>\n"
580                                     "<center><h2> <a href=\"http://www.mcs.anl.gov/petsc\">PETSc</a> Application Web server powered by <a href=\"https://bitbucket.org/saws/saws\">SAWs</a> </h2></center>\n"
581                                     "<center>This is the default PETSc application dashboard, from it you can access any published PETSc objects or logging data</center><br><center>%s configured with %s</center><br>\n"
582                                     "%s",version,petscconfigureoptions,appline);
583     PetscStackCallSAWs(SAWs_Push_Body,("index.html",0,intro));
584     ierr = PetscFree(intro);CHKERRQ(ierr);
585     ierr = PetscFree(appline);CHKERRQ(ierr);
586     PetscStackCallSAWs(SAWs_Initialize,());
587     ierr = PetscCitationsRegister("@TechReport{ saws,\n"
588                                   "  Author = {Matt Otten and Jed Brown and Barry Smith},\n"
589                                   "  Title  = {Scientific Application Web Server (SAWs) Users Manual},\n"
590                                   "  Institution = {Argonne National Laboratory},\n"
591                                   "  Year   = 2013\n}\n",NULL);CHKERRQ(ierr);
592   }
593   PetscFunctionReturn(0);
594 }
595 #endif
596 
597 #undef __FUNCT__
598 #define __FUNCT__ "PetscInitialize"
599 /*@C
600    PetscInitialize - Initializes the PETSc database and MPI.
601    PetscInitialize() calls MPI_Init() if that has yet to be called,
602    so this routine should always be called near the beginning of
603    your program -- usually the very first line!
604 
605    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
606 
607    Input Parameters:
608 +  argc - count of number of command line arguments
609 .  args - the command line arguments
610 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL to not check for
611           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
612 -  help - [optional] Help message to print, use NULL for no message
613 
614    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
615    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
616    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
617    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
618    if different subcommunicators of the job are doing different things with PETSc.
619 
620    Options Database Keys:
621 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
622 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
623 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
624 .  -on_error_abort calls abort() when error detected (no traceback)
625 .  -on_error_mpiabort calls MPI_abort() when error detected
626 .  -error_output_stderr prints error messages to stderr instead of the default stdout
627 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
628 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
629 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
630 .  -stop_for_debugger - Print message on how to attach debugger manually to
631                         process and wait (-debugger_pause) seconds for attachment
632 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
633 .  -malloc no - Indicates not to use error-checking malloc
634 .  -malloc_debug - check for memory corruption at EVERY malloc or free
635 .  -malloc_dump - prints a list of all unfreed memory at the end of the run
636 .  -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds
637 .  -fp_trap - Stops on floating point exceptions (Note that on the
638               IBM RS6000 this slows code by at least a factor of 10.)
639 .  -no_signal_handler - Indicates not to trap error signals
640 .  -shared_tmp - indicates /tmp directory is shared by all processors
641 .  -not_shared_tmp - each processor has own /tmp
642 .  -tmp - alternative name of /tmp directory
643 .  -get_total_flops - returns total flops done by all processors
644 -  -memory_info - Print memory usage at end of run
645 
646    Options Database Keys for Profiling:
647    See Users-Manual: ch_profiling for details.
648 +  -info <optional filename> - Prints verbose information to the screen
649 .  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
650 .  -log_sync - Log the synchronization in scatters, inner products and norms
651 .  -log_trace [filename] - Print traces of all PETSc calls to the screen (useful to determine where a program
652         hangs without running in the debugger).  See PetscLogTraceBegin().
653 .  -log_summary [filename] - Prints summary of flop and timing information to screen. If the filename is specified the
654         summary is written to the file.  See PetscLogView().
655 .  -log_all [filename] - Logs extensive profiling information  See PetscLogDump().
656 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
657 -  -log_mpe [filename] - Creates a logfile viewable by the utility Jumpshot (in MPICH distribution)
658 
659     Only one of -log_trace, -log_summary, -log_all, -log, or -log_mpe may be used at a time
660 
661    Environmental Variables:
662 +   PETSC_TMP - alternative tmp directory
663 .   PETSC_SHARED_TMP - tmp is shared by all processes
664 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
665 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
666 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
667 
668 
669    Level: beginner
670 
671    Notes:
672    If for some reason you must call MPI_Init() separately, call
673    it before PetscInitialize().
674 
675    Fortran Version:
676    In Fortran this routine has the format
677 $       call PetscInitialize(file,ierr)
678 
679 +   ierr - error return code
680 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL_CHARACTER to not check for
681           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
682 
683    Important Fortran Note:
684    In Fortran, you MUST use NULL_CHARACTER to indicate a
685    null character string; you CANNOT just use NULL as
686    in the C version. See Users-Manual: ch_fortran for details.
687 
688    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
689    calling PetscInitialize().
690 
691    Concepts: initializing PETSc
692 
693 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
694 
695 @*/
696 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
697 {
698   PetscErrorCode ierr;
699   PetscMPIInt    flag, size;
700   PetscBool      flg;
701   char           hostname[256];
702 
703   PetscFunctionBegin;
704   if (PetscInitializeCalled) PetscFunctionReturn(0);
705 
706   /* these must be initialized in a routine, not as a constant declaration*/
707   PETSC_STDOUT = stdout;
708   PETSC_STDERR = stderr;
709 
710   /* on Windows - set printf to default to printing 2 digit exponents */
711 #if defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
712   _set_output_format(_TWO_DIGIT_EXPONENT);
713 #endif
714 
715   ierr = PetscOptionsCreate();CHKERRQ(ierr);
716 
717   /*
718      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
719      it that it sets args[0] on all processors to be args[0] on the first processor.
720   */
721   if (argc && *argc) {
722     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
723   } else {
724     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
725   }
726 
727   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
728   if (!flag) {
729     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");
730 #if defined(PETSC_HAVE_MPI_INIT_THREAD)
731     {
732       PetscMPIInt provided;
733       ierr = MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);CHKERRQ(ierr);
734     }
735 #else
736     ierr = MPI_Init(argc,args);CHKERRQ(ierr);
737 #endif
738     PetscBeganMPI = PETSC_TRUE;
739   }
740   if (argc && args) {
741     PetscGlobalArgc = *argc;
742     PetscGlobalArgs = *args;
743   }
744   PetscFinalizeCalled = PETSC_FALSE;
745 
746   if (PETSC_COMM_WORLD == MPI_COMM_NULL) PETSC_COMM_WORLD = MPI_COMM_WORLD;
747   ierr = MPI_Comm_set_errhandler(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
748 
749   /* Done after init due to a bug in MPICH-GM? */
750   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
751 
752   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
753   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
754 
755   MPIU_BOOL = MPI_INT;
756   MPIU_ENUM = MPI_INT;
757 
758   /*
759      Initialized the global complex variable; this is because with
760      shared libraries the constructors for global variables
761      are not called; at least on IRIX.
762   */
763 #if defined(PETSC_HAVE_COMPLEX)
764   {
765 #if defined(PETSC_CLANGUAGE_CXX)
766     PetscComplex ic(0.0,1.0);
767     PETSC_i = ic;
768 #elif defined(PETSC_CLANGUAGE_C)
769     PETSC_i = _Complex_I;
770 #endif
771   }
772 
773 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
774   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
775   ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
776   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr);
777   ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr);
778 #endif
779 #endif /* PETSC_HAVE_COMPLEX */
780 
781   /*
782      Create the PETSc MPI reduction operator that sums of the first
783      half of the entries and maxes the second half.
784   */
785   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
786 
787 #if defined(PETSC_USE_REAL___FLOAT128)
788   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
789   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
790 #if defined(PETSC_HAVE_COMPLEX)
791   ierr = MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);CHKERRQ(ierr);
792   ierr = MPI_Type_commit(&MPIU___COMPLEX128);CHKERRQ(ierr);
793 #endif
794   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
795   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
796 #endif
797 
798 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
799   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
800 #endif
801 
802   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
803   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
804 
805 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
806   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
807   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
808 #endif
809 
810 
811   /*
812      Attributes to be set on PETSc communicators
813   */
814   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
815   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Outer,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
816   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Inner,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
817 
818   /*
819      Build the options database
820   */
821   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
822 
823 
824   /*
825      Print main application help message
826   */
827   ierr = PetscOptionsHasName(NULL,"-help",&flg);CHKERRQ(ierr);
828   if (help && flg) {
829     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
830   }
831   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
832 
833   ierr = PetscCitationsInitialize();CHKERRQ(ierr);
834 
835 #if defined(PETSC_HAVE_SAWS)
836   ierr = PetscInitializeSAWs(help);CHKERRQ(ierr);
837 #endif
838 
839   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
840 #if defined(PETSC_USE_LOG)
841   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
842 #endif
843 
844   /*
845      Load the dynamic libraries (on machines that support them), this registers all
846      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
847   */
848   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
849 
850   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
851   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
852   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
853   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
854 
855   /* Ensure that threadcomm-related keyval exists, so that PetscOptionsSetFromOptions can use PetscCommDuplicate. */
856   ierr = PetscThreadCommInitializePackage();CHKERRQ(ierr);
857 
858   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
859   /* Check the options database for options related to the options database itself */
860   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
861 
862 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
863   /*
864       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
865 
866       Currently not used because it is not supported by MPICH.
867   */
868 #if !defined(PETSC_WORDS_BIGENDIAN)
869   ierr = MPI_Register_datarep((char*)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,NULL);CHKERRQ(ierr);
870 #endif
871 #endif
872 
873 #if defined(PETSC_HAVE_CUDA)
874   flg  = PETSC_TRUE;
875   ierr = PetscOptionsGetBool(NULL,"-cublas",&flg,NULL);CHKERRQ(ierr);
876   if (flg) {
877     PetscMPIInt p;
878     for (p = 0; p < PetscGlobalSize; ++p) {
879       if (p == PetscGlobalRank) cublasInit();
880       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
881     }
882   }
883 #endif
884 
885   ierr = PetscOptionsHasName(NULL,"-python",&flg);CHKERRQ(ierr);
886   if (flg) {
887     PetscInitializeCalled = PETSC_TRUE;
888     ierr = PetscPythonInitialize(NULL,NULL);CHKERRQ(ierr);
889   }
890 
891   /*
892       Setup building of stack frames for all function calls
893   */
894   PetscThreadLocalRegister((PetscThreadKey*)&petscstack); /* Creates pthread_key */
895 #if defined(PETSC_USE_DEBUG)
896   ierr = PetscStackCreate();CHKERRQ(ierr);
897 #endif
898 
899 #if defined(PETSC_SERIALIZE_FUNCTIONS)
900   ierr = PetscFPTCreate(10000);CHKERRQ(ierr);
901 #endif
902 
903 
904   /*
905       Once we are completedly initialized then we can set this variables
906   */
907   PetscInitializeCalled = PETSC_TRUE;
908   PetscFunctionReturn(0);
909 }
910 
911 #if defined(PETSC_USE_LOG)
912 extern PetscObject *PetscObjects;
913 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
914 #endif
915 
916 #undef __FUNCT__
917 #define __FUNCT__ "PetscFinalize"
918 /*@C
919    PetscFinalize - Checks for options to be called at the conclusion
920    of the program. MPI_Finalize() is called only if the user had not
921    called MPI_Init() before calling PetscInitialize().
922 
923    Collective on PETSC_COMM_WORLD
924 
925    Options Database Keys:
926 +  -options_table - Calls PetscOptionsView()
927 .  -options_left - Prints unused options that remain in the database
928 .  -objects_dump [all] - Prints list of objects allocated by the user that have not been freed, the option all cause all outstanding objects to be listed
929 .  -mpidump - Calls PetscMPIDump()
930 .  -malloc_dump - Calls PetscMallocDump()
931 .  -malloc_info - Prints total memory usage
932 -  -malloc_log - Prints summary of memory usage
933 
934    Level: beginner
935 
936    Note:
937    See PetscInitialize() for more general runtime options.
938 
939 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
940 @*/
941 PetscErrorCode  PetscFinalize(void)
942 {
943   PetscErrorCode ierr;
944   PetscMPIInt    rank;
945   PetscInt       nopt;
946   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
947   PetscBool      flg;
948 #if defined(PETSC_USE_LOG)
949   char           mname[PETSC_MAX_PATH_LEN];
950 #endif
951 
952   PetscFunctionBegin;
953   if (!PetscInitializeCalled) {
954     printf("PetscInitialize() must be called before PetscFinalize()\n");
955     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
956   }
957   ierr = PetscInfo(NULL,"PetscFinalize() called\n");CHKERRQ(ierr);
958 
959   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
960 
961   ierr = PetscOptionsHasName(NULL,"-citations",&flg);CHKERRQ(ierr);
962   if (flg) {
963     char  *cits, filename[PETSC_MAX_PATH_LEN];
964     FILE  *fd = PETSC_STDOUT;
965 
966     ierr = PetscOptionsGetString(NULL,"-citations",filename,PETSC_MAX_PATH_LEN,NULL);CHKERRQ(ierr);
967     if (filename[0]) {
968       ierr = PetscFOpen(PETSC_COMM_WORLD,filename,"w",&fd);CHKERRQ(ierr);
969     }
970     ierr = PetscSegBufferGet(PetscCitationsList,1,&cits);CHKERRQ(ierr);
971     cits[0] = 0;
972     ierr = PetscSegBufferExtractAlloc(PetscCitationsList,&cits);CHKERRQ(ierr);
973     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"If you publish results based on this computation please cite the following:\n");CHKERRQ(ierr);
974     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");CHKERRQ(ierr);
975     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"%s",cits);CHKERRQ(ierr);
976     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");CHKERRQ(ierr);
977     ierr = PetscFClose(PETSC_COMM_WORLD,fd);CHKERRQ(ierr);
978     ierr = PetscFree(cits);CHKERRQ(ierr);
979   }
980   ierr = PetscSegBufferDestroy(&PetscCitationsList);CHKERRQ(ierr);
981 
982 #if defined(PETSC_HAVE_SSL) && defined(PETSC_USE_SOCKET_VIEWER)
983   /* TextBelt is run for testing purposes only, please do not use this feature often */
984   {
985     PetscInt nmax = 2;
986     char     **buffs;
987     ierr = PetscMalloc1(2,&buffs);CHKERRQ(ierr);
988     ierr = PetscOptionsGetStringArray(NULL,"-textbelt",buffs,&nmax,&flg1);CHKERRQ(ierr);
989     if (flg1) {
990       if (!nmax) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER,"-textbelt requires either the phone number or number,\"message\"");
991       if (nmax == 1) {
992         ierr = PetscMalloc1(128,&buffs[1]);CHKERRQ(ierr);
993         ierr = PetscGetProgramName(buffs[1],32);CHKERRQ(ierr);
994         ierr = PetscStrcat(buffs[1]," has completed");CHKERRQ(ierr);
995       }
996       ierr = PetscTextBelt(PETSC_COMM_WORLD,buffs[0],buffs[1],NULL);CHKERRQ(ierr);
997       ierr = PetscFree(buffs[0]);CHKERRQ(ierr);
998       ierr = PetscFree(buffs[1]);CHKERRQ(ierr);
999     }
1000     ierr = PetscFree(buffs);CHKERRQ(ierr);
1001   }
1002 #endif
1003   /*
1004     It should be safe to cancel the options monitors, since we don't expect to be setting options
1005     here (at least that are worth monitoring).  Monitors ought to be released so that they release
1006     whatever memory was allocated there before -malloc_dump reports unfreed memory.
1007   */
1008   ierr = PetscOptionsMonitorCancel();CHKERRQ(ierr);
1009 
1010 #if defined(PETSC_SERIALIZE_FUNCTIONS)
1011   ierr = PetscFPTDestroy();CHKERRQ(ierr);
1012 #endif
1013 
1014 
1015 #if defined(PETSC_HAVE_SAWS)
1016   flg = PETSC_FALSE;
1017   ierr = PetscOptionsGetBool(NULL,"-saw_options",&flg,NULL);CHKERRQ(ierr);
1018   if (flg) {
1019     ierr = PetscOptionsSAWsDestroy();CHKERRQ(ierr);
1020   }
1021 #endif
1022 
1023 #if defined(PETSC_HAVE_X)
1024   flg1 = PETSC_FALSE;
1025   ierr = PetscOptionsGetBool(NULL,"-x_virtual",&flg1,NULL);CHKERRQ(ierr);
1026   if (flg1) {
1027     /*  this is a crude hack, but better than nothing */
1028     ierr = PetscPOpen(PETSC_COMM_WORLD,NULL,"pkill -9 Xvfb","r",NULL);CHKERRQ(ierr);
1029   }
1030 #endif
1031 
1032   ierr = PetscOptionsGetBool(NULL,"-malloc_info",&flg2,NULL);CHKERRQ(ierr);
1033   if (!flg2) {
1034     flg2 = PETSC_FALSE;
1035     ierr = PetscOptionsGetBool(NULL,"-memory_info",&flg2,NULL);CHKERRQ(ierr);
1036   }
1037   if (flg2) {
1038     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
1039   }
1040 
1041 #if defined(PETSC_USE_LOG)
1042   flg1 = PETSC_FALSE;
1043   ierr = PetscOptionsGetBool(NULL,"-get_total_flops",&flg1,NULL);CHKERRQ(ierr);
1044   if (flg1) {
1045     PetscLogDouble flops = 0;
1046     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
1047     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
1048   }
1049 #endif
1050 
1051 
1052 #if defined(PETSC_USE_LOG)
1053 #if defined(PETSC_HAVE_MPE)
1054   mname[0] = 0;
1055 
1056   ierr = PetscOptionsGetString(NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1057   if (flg1) {
1058     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
1059     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
1060   }
1061 #endif
1062   mname[0] = 0;
1063 
1064   ierr = PetscLogViewFromOptions();CHKERRQ(ierr);
1065   ierr = PetscOptionsGetString(NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1066   if (flg1) {
1067     PetscViewer viewer;
1068     if (mname[0]) {
1069       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
1070       ierr = PetscLogView(viewer);CHKERRQ(ierr);
1071       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1072     } else {
1073       viewer = PETSC_VIEWER_STDOUT_WORLD;
1074       ierr   = PetscLogView(viewer);CHKERRQ(ierr);
1075     }
1076   }
1077   mname[0] = 0;
1078 
1079   ierr = PetscOptionsGetString(NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1080   ierr = PetscOptionsGetString(NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
1081   if (flg1 || flg2) {
1082     if (mname[0]) PetscLogDump(mname);
1083     else          PetscLogDump(0);
1084   }
1085 #endif
1086 
1087   /*
1088      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1089   */
1090   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1091 
1092   ierr = PetscStackDestroy();CHKERRQ(ierr);
1093   PetscThreadLocalDestroy((PetscThreadKey)petscstack); /* Deletes pthread_key */
1094 
1095   flg1 = PETSC_FALSE;
1096   ierr = PetscOptionsGetBool(NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
1097   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1098   flg1 = PETSC_FALSE;
1099   ierr = PetscOptionsGetBool(NULL,"-mpidump",&flg1,NULL);CHKERRQ(ierr);
1100   if (flg1) {
1101     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1102   }
1103   flg1 = PETSC_FALSE;
1104   flg2 = PETSC_FALSE;
1105   /* preemptive call to avoid listing this option in options table as unused */
1106   ierr = PetscOptionsHasName(NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1107   ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1108   ierr = PetscOptionsGetBool(NULL,"-options_view",&flg2,NULL);CHKERRQ(ierr);
1109 
1110   if (flg2) {
1111     PetscViewer viewer;
1112     ierr = PetscViewerCreate(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1113     ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
1114     ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1115     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1116   }
1117 
1118   /* to prevent PETSc -options_left from warning */
1119   ierr = PetscOptionsHasName(NULL,"-nox",&flg1);CHKERRQ(ierr);
1120   ierr = PetscOptionsHasName(NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1121 
1122   flg3 = PETSC_FALSE; /* default value is required */
1123   ierr = PetscOptionsGetBool(NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1124   ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1125   if (flg3) {
1126     if (!flg2) { /* have not yet printed the options */
1127       PetscViewer viewer;
1128       ierr = PetscViewerCreate(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1129       ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
1130       ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1131       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1132     }
1133     if (!nopt) {
1134       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1135     } else if (nopt == 1) {
1136       ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1137     } else {
1138       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1139     }
1140   }
1141 #if defined(PETSC_USE_DEBUG)
1142   if (nopt && !flg3 && !flg1) {
1143     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1144     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1145     ierr = PetscOptionsLeft();CHKERRQ(ierr);
1146   } else if (nopt && flg3) {
1147 #else
1148   if (nopt && flg3) {
1149 #endif
1150     ierr = PetscOptionsLeft();CHKERRQ(ierr);
1151   }
1152 
1153 #if defined(PETSC_HAVE_SAWS)
1154   if (!PetscGlobalRank) {
1155     ierr = PetscStackSAWsViewOff();CHKERRQ(ierr);
1156     PetscStackCallSAWs(SAWs_Finalize,());
1157   }
1158 #endif
1159 
1160   {
1161     PetscThreadComm tcomm_world;
1162     ierr = PetscGetThreadCommWorld(&tcomm_world);CHKERRQ(ierr);
1163     /* Free global thread communicator */
1164     ierr = PetscThreadCommDestroy(&tcomm_world);CHKERRQ(ierr);
1165   }
1166 
1167 #if defined(PETSC_USE_LOG)
1168   /*
1169        List all objects the user may have forgot to free
1170   */
1171   ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1172   if (flg1) {
1173     MPI_Comm local_comm;
1174     char     string[64];
1175 
1176     ierr = PetscOptionsGetString(NULL,"-objects_dump",string,64,NULL);CHKERRQ(ierr);
1177     ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1178     ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1179     ierr = PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);CHKERRQ(ierr);
1180     ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1181     ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1182   }
1183 #endif
1184 
1185 #if defined(PETSC_USE_LOG)
1186   PetscObjectsCounts    = 0;
1187   PetscObjectsMaxCounts = 0;
1188   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1189 #endif
1190 
1191 #if defined(PETSC_USE_LOG)
1192   ierr = PetscLogDestroy();CHKERRQ(ierr);
1193 #endif
1194 
1195   /*
1196      Close any open dynamic libraries
1197   */
1198   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1199 
1200   /*
1201      Destroy any packages that registered a finalize
1202   */
1203   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1204 
1205   /*
1206      Print PetscFunctionLists that have not been properly freed
1207 
1208   ierr = PetscFunctionListPrintAll();CHKERRQ(ierr);
1209   */
1210 
1211   if (petsc_history) {
1212     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1213     petsc_history = 0;
1214   }
1215 
1216   ierr = PetscInfoAllow(PETSC_FALSE,NULL);CHKERRQ(ierr);
1217 
1218   {
1219     char fname[PETSC_MAX_PATH_LEN];
1220     FILE *fd;
1221     int  err;
1222 
1223     fname[0] = 0;
1224 
1225     ierr = PetscOptionsGetString(NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1226     flg2 = PETSC_FALSE;
1227     ierr = PetscOptionsGetBool(NULL,"-malloc_test",&flg2,NULL);CHKERRQ(ierr);
1228 #if defined(PETSC_USE_DEBUG)
1229     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1230 #else
1231     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1232 #endif
1233     if (flg1 && fname[0]) {
1234       char sname[PETSC_MAX_PATH_LEN];
1235 
1236       sprintf(sname,"%s_%d",fname,rank);
1237       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1238       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1239       err  = fclose(fd);
1240       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1241     } else if (flg1 || flg2) {
1242       MPI_Comm local_comm;
1243 
1244       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1245       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1246       ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1247       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1248       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1249     }
1250   }
1251 
1252   {
1253     char fname[PETSC_MAX_PATH_LEN];
1254     FILE *fd = NULL;
1255 
1256     fname[0] = 0;
1257 
1258     ierr = PetscOptionsGetString(NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1259     ierr = PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1260     if (flg1 && fname[0]) {
1261       int err;
1262 
1263       if (!rank) {
1264         fd = fopen(fname,"w");
1265         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1266       }
1267       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1268       if (fd) {
1269         err = fclose(fd);
1270         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1271       }
1272     } else if (flg1 || flg2) {
1273       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1274     }
1275   }
1276 
1277 #if defined(PETSC_HAVE_CUDA)
1278   flg  = PETSC_TRUE;
1279   ierr = PetscOptionsGetBool(NULL,"-cublas",&flg,NULL);CHKERRQ(ierr);
1280   if (flg) {
1281     PetscInt p;
1282     for (p = 0; p < PetscGlobalSize; ++p) {
1283       if (p == PetscGlobalRank) cublasShutdown();
1284       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1285     }
1286   }
1287 #endif
1288 
1289   /* Can be destroyed only after all the options are used */
1290   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1291 
1292   PetscGlobalArgc = 0;
1293   PetscGlobalArgs = 0;
1294 
1295 #if defined(PETSC_USE_REAL___FLOAT128)
1296   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1297 #if defined(PETSC_HAVE_COMPLEX)
1298   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1299 #endif
1300   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1301   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1302 #endif
1303 
1304 #if defined(PETSC_HAVE_COMPLEX)
1305 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1306   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1307   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1308 #endif
1309 #endif
1310 
1311 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1312   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1313 #endif
1314 
1315   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1316 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
1317   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1318 #endif
1319   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1320 
1321   /*
1322      Destroy any known inner MPI_Comm's and attributes pointing to them
1323      Note this will not destroy any new communicators the user has created.
1324 
1325      If all PETSc objects were not destroyed those left over objects will have hanging references to
1326      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1327  */
1328   {
1329     PetscCommCounter *counter;
1330     PetscMPIInt      flg;
1331     MPI_Comm         icomm;
1332     union {MPI_Comm comm; void *ptr;} ucomm;
1333     ierr = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1334     if (flg) {
1335       icomm = ucomm.comm;
1336       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1337       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1338 
1339       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1340       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1341       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1342     }
1343     ierr = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1344     if (flg) {
1345       icomm = ucomm.comm;
1346       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1347       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1348 
1349       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1350       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1351       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1352     }
1353   }
1354 
1355   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1356   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1357   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1358 
1359   if (PetscBeganMPI) {
1360 #if defined(PETSC_HAVE_MPI_FINALIZED)
1361     PetscMPIInt flag;
1362     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1363     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1364 #endif
1365     ierr = MPI_Finalize();CHKERRQ(ierr);
1366   }
1367 /*
1368 
1369      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1370    the communicator has some outstanding requests on it. Specifically if the
1371    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1372    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1373    is never freed as it should be. Thus one may obtain messages of the form
1374    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1375    memory was not freed.
1376 
1377 */
1378   ierr = PetscMallocClear();CHKERRQ(ierr);
1379 
1380   PetscInitializeCalled = PETSC_FALSE;
1381   PetscFinalizeCalled   = PETSC_TRUE;
1382   PetscFunctionReturn(ierr);
1383 }
1384 
1385 #if defined(PETSC_MISSING_LAPACK_lsame_)
1386 PETSC_EXTERN int lsame_(char *a,char *b)
1387 {
1388   if (*a == *b) return 1;
1389   if (*a + 32 == *b) return 1;
1390   if (*a - 32 == *b) return 1;
1391   return 0;
1392 }
1393 #endif
1394 
1395 #if defined(PETSC_MISSING_LAPACK_lsame)
1396 PETSC_EXTERN int lsame(char *a,char *b)
1397 {
1398   if (*a == *b) return 1;
1399   if (*a + 32 == *b) return 1;
1400   if (*a - 32 == *b) return 1;
1401   return 0;
1402 }
1403 #endif
1404