xref: /petsc/src/sys/objects/pinit.c (revision cb9d8021f64c572d262e10034bbd2fb15469a2b9)
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     /* char           sawsurl[256]; */
525 
526     ierr = PetscOptionsHasName(NULL,"-saws_log",&flg);CHKERRQ(ierr);
527     if (flg) {
528       char  sawslog[PETSC_MAX_PATH_LEN];
529 
530       ierr = PetscOptionsGetString(NULL,"-saws_log",sawslog,PETSC_MAX_PATH_LEN,NULL);CHKERRQ(ierr);
531       if (sawslog[0]) {
532         PetscStackCallSAWs(SAWs_Set_Use_Logfile,(sawslog));
533       } else {
534         PetscStackCallSAWs(SAWs_Set_Use_Logfile,(NULL));
535       }
536     }
537     ierr = PetscOptionsGetString(NULL,"-saws_https",cert,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
538     if (flg) {
539       PetscStackCallSAWs(SAWs_Set_Use_HTTPS,(cert));
540     }
541     ierr = PetscOptionsGetInt(NULL,"-saws_port",&port,&flg);CHKERRQ(ierr);
542     if (flg) {
543       PetscStackCallSAWs(SAWs_Set_Port,(port));
544     }
545     ierr = PetscOptionsGetString(NULL,"-saws_root",root,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
546     if (flg) {
547       PetscStackCallSAWs(SAWs_Set_Document_Root,(root));CHKERRQ(ierr);
548       ierr = PetscStrcmp(root,".",&rootlocal);CHKERRQ(ierr);
549     } else {
550       ierr = PetscOptionsHasName(NULL,"-saws_options",&flg);CHKERRQ(ierr);
551       if (flg) {
552         ierr = PetscStrreplace(PETSC_COMM_WORLD,"${PETSC_DIR}/share/petsc/saws",root,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
553         PetscStackCallSAWs(SAWs_Set_Document_Root,(root));CHKERRQ(ierr);
554       }
555     }
556     ierr = PetscOptionsHasName(NULL,"-saws_local",&flg2);CHKERRQ(ierr);
557     if (flg2) {
558       char jsdir[PETSC_MAX_PATH_LEN];
559       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"-saws_local option requires -saws_root option");
560       ierr = PetscSNPrintf(jsdir,PETSC_MAX_PATH_LEN,"%s/js",root);CHKERRQ(ierr);
561       ierr = PetscTestDirectory(jsdir,'r',&flg);CHKERRQ(ierr);
562       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"-saws_local option requires js directory in root directory");
563       PetscStackCallSAWs(SAWs_Push_Local_Header,());CHKERRQ(ierr);
564     }
565     ierr = PetscGetProgramName(programname,64);CHKERRQ(ierr);
566     ierr = PetscStrlen(help,&applinelen);CHKERRQ(ierr);
567     introlen   = 4096 + applinelen;
568     applinelen += 1024;
569     ierr = PetscMalloc(applinelen,&appline);CHKERRQ(ierr);
570     ierr = PetscMalloc(introlen,&intro);CHKERRQ(ierr);
571 
572     if (rootlocal) {
573       ierr = PetscSNPrintf(appline,applinelen,"%s.c.html",programname);CHKERRQ(ierr);
574       ierr = PetscTestFile(appline,'r',&rootlocal);CHKERRQ(ierr);
575     }
576     ierr = PetscOptionsGetAll(&options);CHKERRQ(ierr);
577     if (rootlocal && help) {
578       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);
579     } else if (help) {
580       ierr = PetscSNPrintf(appline,applinelen,"<center>Running %s %s</center><br><center><pre>%s</pre></center><br>",programname,options,help);
581     } else {
582       ierr = PetscSNPrintf(appline,applinelen,"<center> Running %s %s</center><br>\n",programname,options);
583     }
584     ierr = PetscFree(options);CHKERRQ(ierr);
585     ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
586     ierr = PetscSNPrintf(intro,introlen,"<body>\n"
587                                     "<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"
588                                     "<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"
589                                     "%s",version,petscconfigureoptions,appline);
590     PetscStackCallSAWs(SAWs_Push_Body,("index.html",0,intro));
591     ierr = PetscFree(intro);CHKERRQ(ierr);
592     ierr = PetscFree(appline);CHKERRQ(ierr);
593     PetscStackCallSAWs(SAWs_Initialize,());
594     /* PetscStackCallSAWs(SAWs_Get_FullURL,(sizeof(sawsurl),sawsurl));
595      ierr = PetscPrintf(PETSC_COMM_WORLD,"Point your browser to %s for SAWs\n",sawsurl);CHKERRQ(ierr); */
596     ierr = PetscCitationsRegister("@TechReport{ saws,\n"
597                                   "  Author = {Matt Otten and Jed Brown and Barry Smith},\n"
598                                   "  Title  = {Scientific Application Web Server (SAWs) Users Manual},\n"
599                                   "  Institution = {Argonne National Laboratory},\n"
600                                   "  Year   = 2013\n}\n",NULL);CHKERRQ(ierr);
601   }
602   PetscFunctionReturn(0);
603 }
604 #endif
605 
606 #undef __FUNCT__
607 #define __FUNCT__ "PetscInitialize"
608 /*@C
609    PetscInitialize - Initializes the PETSc database and MPI.
610    PetscInitialize() calls MPI_Init() if that has yet to be called,
611    so this routine should always be called near the beginning of
612    your program -- usually the very first line!
613 
614    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
615 
616    Input Parameters:
617 +  argc - count of number of command line arguments
618 .  args - the command line arguments
619 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL to not check for
620           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
621 -  help - [optional] Help message to print, use NULL for no message
622 
623    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
624    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
625    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
626    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
627    if different subcommunicators of the job are doing different things with PETSc.
628 
629    Options Database Keys:
630 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
631 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
632 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
633 .  -on_error_abort calls abort() when error detected (no traceback)
634 .  -on_error_mpiabort calls MPI_abort() when error detected
635 .  -error_output_stderr prints error messages to stderr instead of the default stdout
636 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
637 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
638 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
639 .  -stop_for_debugger - Print message on how to attach debugger manually to
640                         process and wait (-debugger_pause) seconds for attachment
641 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
642 .  -malloc no - Indicates not to use error-checking malloc
643 .  -malloc_debug - check for memory corruption at EVERY malloc or free
644 .  -malloc_dump - prints a list of all unfreed memory at the end of the run
645 .  -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds
646 .  -fp_trap - Stops on floating point exceptions (Note that on the
647               IBM RS6000 this slows code by at least a factor of 10.)
648 .  -no_signal_handler - Indicates not to trap error signals
649 .  -shared_tmp - indicates /tmp directory is shared by all processors
650 .  -not_shared_tmp - each processor has own /tmp
651 .  -tmp - alternative name of /tmp directory
652 .  -get_total_flops - returns total flops done by all processors
653 -  -memory_info - Print memory usage at end of run
654 
655    Options Database Keys for Profiling:
656    See Users-Manual: ch_profiling for details.
657 +  -info <optional filename> - Prints verbose information to the screen
658 .  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
659 .  -log_sync - Log the synchronization in scatters, inner products and norms
660 .  -log_trace [filename] - Print traces of all PETSc calls to the screen (useful to determine where a program
661         hangs without running in the debugger).  See PetscLogTraceBegin().
662 .  -log_summary [filename] - Prints summary of flop and timing information to screen. If the filename is specified the
663         summary is written to the file.  See PetscLogView().
664 .  -log_all [filename] - Logs extensive profiling information  See PetscLogDump().
665 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
666 -  -log_mpe [filename] - Creates a logfile viewable by the utility Jumpshot (in MPICH distribution)
667 
668     Only one of -log_trace, -log_summary, -log_all, -log, or -log_mpe may be used at a time
669 
670    Environmental Variables:
671 +   PETSC_TMP - alternative tmp directory
672 .   PETSC_SHARED_TMP - tmp is shared by all processes
673 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
674 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
675 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
676 
677 
678    Level: beginner
679 
680    Notes:
681    If for some reason you must call MPI_Init() separately, call
682    it before PetscInitialize().
683 
684    Fortran Version:
685    In Fortran this routine has the format
686 $       call PetscInitialize(file,ierr)
687 
688 +   ierr - error return code
689 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
690           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
691 
692    Important Fortran Note:
693    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
694    null character string; you CANNOT just use NULL as
695    in the C version. See Users-Manual: ch_fortran for details.
696 
697    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
698    calling PetscInitialize().
699 
700    Concepts: initializing PETSc
701 
702 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
703 
704 @*/
705 PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
706 {
707   PetscErrorCode ierr;
708   PetscMPIInt    flag, size;
709   PetscBool      flg;
710   char           hostname[256];
711 
712   PetscFunctionBegin;
713   if (PetscInitializeCalled) PetscFunctionReturn(0);
714 
715   /* these must be initialized in a routine, not as a constant declaration*/
716   PETSC_STDOUT = stdout;
717   PETSC_STDERR = stderr;
718 
719   /* on Windows - set printf to default to printing 2 digit exponents */
720 #if defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
721   _set_output_format(_TWO_DIGIT_EXPONENT);
722 #endif
723 
724   ierr = PetscOptionsCreate();CHKERRQ(ierr);
725 
726   /*
727      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
728      it that it sets args[0] on all processors to be args[0] on the first processor.
729   */
730   if (argc && *argc) {
731     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
732   } else {
733     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
734   }
735 
736   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
737   if (!flag) {
738     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");
739 #if defined(PETSC_HAVE_MPI_INIT_THREAD)
740     {
741       PetscMPIInt provided;
742       ierr = MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);CHKERRQ(ierr);
743     }
744 #else
745     ierr = MPI_Init(argc,args);CHKERRQ(ierr);
746 #endif
747     PetscBeganMPI = PETSC_TRUE;
748   }
749   if (argc && args) {
750     PetscGlobalArgc = *argc;
751     PetscGlobalArgs = *args;
752   }
753   PetscFinalizeCalled = PETSC_FALSE;
754 
755   if (PETSC_COMM_WORLD == MPI_COMM_NULL) PETSC_COMM_WORLD = MPI_COMM_WORLD;
756   ierr = MPI_Comm_set_errhandler(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr);
757 
758   /* Done after init due to a bug in MPICH-GM? */
759   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
760 
761   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
762   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
763 
764   MPIU_BOOL = MPI_INT;
765   MPIU_ENUM = MPI_INT;
766 
767   /*
768      Initialized the global complex variable; this is because with
769      shared libraries the constructors for global variables
770      are not called; at least on IRIX.
771   */
772 #if defined(PETSC_HAVE_COMPLEX)
773   {
774 #if defined(PETSC_CLANGUAGE_CXX)
775     PetscComplex ic(0.0,1.0);
776     PETSC_i = ic;
777 #elif defined(PETSC_CLANGUAGE_C)
778     PETSC_i = _Complex_I;
779 #endif
780   }
781 
782 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
783   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
784   ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
785   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr);
786   ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr);
787 #endif
788 #endif /* PETSC_HAVE_COMPLEX */
789 
790   /*
791      Create the PETSc MPI reduction operator that sums of the first
792      half of the entries and maxes the second half.
793   */
794   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
795 
796 #if defined(PETSC_USE_REAL___FLOAT128)
797   ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr);
798   ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr);
799 #if defined(PETSC_HAVE_COMPLEX)
800   ierr = MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);CHKERRQ(ierr);
801   ierr = MPI_Type_commit(&MPIU___COMPLEX128);CHKERRQ(ierr);
802 #endif
803   ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr);
804   ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr);
805 #endif
806 
807 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
808   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
809 #endif
810 
811   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
812   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
813 
814 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
815   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
816   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
817 #endif
818 
819 
820   /*
821      Attributes to be set on PETSc communicators
822   */
823   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
824   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Outer,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
825   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Inner,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
826 
827   /*
828      Build the options database
829   */
830   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
831 
832 
833   /*
834      Print main application help message
835   */
836   ierr = PetscOptionsHasName(NULL,"-help",&flg);CHKERRQ(ierr);
837   if (help && flg) {
838     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
839   }
840   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
841 
842   ierr = PetscCitationsInitialize();CHKERRQ(ierr);
843 
844 #if defined(PETSC_HAVE_SAWS)
845   ierr = PetscInitializeSAWs(help);CHKERRQ(ierr);
846 #endif
847 
848   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
849 #if defined(PETSC_USE_LOG)
850   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
851 #endif
852 
853   /*
854      Load the dynamic libraries (on machines that support them), this registers all
855      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
856   */
857   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
858 
859   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
860   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
861   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
862   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
863 
864   /* Ensure that threadcomm-related keyval exists, so that PetscOptionsSetFromOptions can use PetscCommDuplicate. */
865   ierr = PetscThreadCommInitializePackage();CHKERRQ(ierr);
866 
867   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
868   /* Check the options database for options related to the options database itself */
869   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
870 
871 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
872   /*
873       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
874 
875       Currently not used because it is not supported by MPICH.
876   */
877 #if !defined(PETSC_WORDS_BIGENDIAN)
878   ierr = MPI_Register_datarep((char*)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,NULL);CHKERRQ(ierr);
879 #endif
880 #endif
881 
882 #if defined(PETSC_HAVE_CUDA)
883   flg  = PETSC_TRUE;
884   ierr = PetscOptionsGetBool(NULL,"-cublas",&flg,NULL);CHKERRQ(ierr);
885   if (flg) {
886     PetscMPIInt p;
887     for (p = 0; p < PetscGlobalSize; ++p) {
888       if (p == PetscGlobalRank) cublasInit();
889       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
890     }
891   }
892 #endif
893 
894   ierr = PetscOptionsHasName(NULL,"-python",&flg);CHKERRQ(ierr);
895   if (flg) {
896     PetscInitializeCalled = PETSC_TRUE;
897     ierr = PetscPythonInitialize(NULL,NULL);CHKERRQ(ierr);
898   }
899 
900   /*
901       Setup building of stack frames for all function calls
902   */
903   PetscThreadLocalRegister((PetscThreadKey*)&petscstack); /* Creates pthread_key */
904 #if defined(PETSC_USE_DEBUG)
905   ierr = PetscStackCreate();CHKERRQ(ierr);
906 #endif
907 
908 #if defined(PETSC_SERIALIZE_FUNCTIONS)
909   ierr = PetscFPTCreate(10000);CHKERRQ(ierr);
910 #endif
911 
912 
913   /*
914       Once we are completedly initialized then we can set this variables
915   */
916   PetscInitializeCalled = PETSC_TRUE;
917   PetscFunctionReturn(0);
918 }
919 
920 #if defined(PETSC_USE_LOG)
921 extern PetscObject *PetscObjects;
922 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
923 extern PetscBool   PetscObjectsLog;
924 #endif
925 
926 #undef __FUNCT__
927 #define __FUNCT__ "PetscFinalize"
928 /*@C
929    PetscFinalize - Checks for options to be called at the conclusion
930    of the program. MPI_Finalize() is called only if the user had not
931    called MPI_Init() before calling PetscInitialize().
932 
933    Collective on PETSC_COMM_WORLD
934 
935    Options Database Keys:
936 +  -options_table - Calls PetscOptionsView()
937 .  -options_left - Prints unused options that remain in the database
938 .  -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
939 .  -mpidump - Calls PetscMPIDump()
940 .  -malloc_dump - Calls PetscMallocDump()
941 .  -malloc_info - Prints total memory usage
942 -  -malloc_log - Prints summary of memory usage
943 
944    Level: beginner
945 
946    Note:
947    See PetscInitialize() for more general runtime options.
948 
949 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
950 @*/
951 PetscErrorCode  PetscFinalize(void)
952 {
953   PetscErrorCode ierr;
954   PetscMPIInt    rank;
955   PetscInt       nopt;
956   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
957   PetscBool      flg;
958 #if defined(PETSC_USE_LOG)
959   char           mname[PETSC_MAX_PATH_LEN];
960 #endif
961 
962   PetscFunctionBegin;
963   if (!PetscInitializeCalled) {
964     printf("PetscInitialize() must be called before PetscFinalize()\n");
965     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
966   }
967   ierr = PetscInfo(NULL,"PetscFinalize() called\n");CHKERRQ(ierr);
968 
969   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
970 
971   ierr = PetscOptionsHasName(NULL,"-citations",&flg);CHKERRQ(ierr);
972   if (flg) {
973     char  *cits, filename[PETSC_MAX_PATH_LEN];
974     FILE  *fd = PETSC_STDOUT;
975 
976     ierr = PetscOptionsGetString(NULL,"-citations",filename,PETSC_MAX_PATH_LEN,NULL);CHKERRQ(ierr);
977     if (filename[0]) {
978       ierr = PetscFOpen(PETSC_COMM_WORLD,filename,"w",&fd);CHKERRQ(ierr);
979     }
980     ierr = PetscSegBufferGet(PetscCitationsList,1,&cits);CHKERRQ(ierr);
981     cits[0] = 0;
982     ierr = PetscSegBufferExtractAlloc(PetscCitationsList,&cits);CHKERRQ(ierr);
983     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"If you publish results based on this computation please cite the following:\n");CHKERRQ(ierr);
984     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");CHKERRQ(ierr);
985     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"%s",cits);CHKERRQ(ierr);
986     ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");CHKERRQ(ierr);
987     ierr = PetscFClose(PETSC_COMM_WORLD,fd);CHKERRQ(ierr);
988     ierr = PetscFree(cits);CHKERRQ(ierr);
989   }
990   ierr = PetscSegBufferDestroy(&PetscCitationsList);CHKERRQ(ierr);
991 
992 #if defined(PETSC_HAVE_SSL) && defined(PETSC_USE_SOCKET_VIEWER)
993   /* TextBelt is run for testing purposes only, please do not use this feature often */
994   {
995     PetscInt nmax = 2;
996     char     **buffs;
997     ierr = PetscMalloc1(2,&buffs);CHKERRQ(ierr);
998     ierr = PetscOptionsGetStringArray(NULL,"-textbelt",buffs,&nmax,&flg1);CHKERRQ(ierr);
999     if (flg1) {
1000       if (!nmax) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER,"-textbelt requires either the phone number or number,\"message\"");
1001       if (nmax == 1) {
1002         ierr = PetscMalloc1(128,&buffs[1]);CHKERRQ(ierr);
1003         ierr = PetscGetProgramName(buffs[1],32);CHKERRQ(ierr);
1004         ierr = PetscStrcat(buffs[1]," has completed");CHKERRQ(ierr);
1005       }
1006       ierr = PetscTextBelt(PETSC_COMM_WORLD,buffs[0],buffs[1],NULL);CHKERRQ(ierr);
1007       ierr = PetscFree(buffs[0]);CHKERRQ(ierr);
1008       ierr = PetscFree(buffs[1]);CHKERRQ(ierr);
1009     }
1010     ierr = PetscFree(buffs);CHKERRQ(ierr);
1011   }
1012 #endif
1013   /*
1014     It should be safe to cancel the options monitors, since we don't expect to be setting options
1015     here (at least that are worth monitoring).  Monitors ought to be released so that they release
1016     whatever memory was allocated there before -malloc_dump reports unfreed memory.
1017   */
1018   ierr = PetscOptionsMonitorCancel();CHKERRQ(ierr);
1019 
1020 #if defined(PETSC_SERIALIZE_FUNCTIONS)
1021   ierr = PetscFPTDestroy();CHKERRQ(ierr);
1022 #endif
1023 
1024 
1025 #if defined(PETSC_HAVE_SAWS)
1026   flg = PETSC_FALSE;
1027   ierr = PetscOptionsGetBool(NULL,"-saw_options",&flg,NULL);CHKERRQ(ierr);
1028   if (flg) {
1029     ierr = PetscOptionsSAWsDestroy();CHKERRQ(ierr);
1030   }
1031 #endif
1032 
1033 #if defined(PETSC_HAVE_X)
1034   flg1 = PETSC_FALSE;
1035   ierr = PetscOptionsGetBool(NULL,"-x_virtual",&flg1,NULL);CHKERRQ(ierr);
1036   if (flg1) {
1037     /*  this is a crude hack, but better than nothing */
1038     ierr = PetscPOpen(PETSC_COMM_WORLD,NULL,"pkill -9 Xvfb","r",NULL);CHKERRQ(ierr);
1039   }
1040 #endif
1041 
1042 #if !defined(PETSC_HAVE_THREADSAFETY)
1043   ierr = PetscOptionsGetBool(NULL,"-malloc_info",&flg2,NULL);CHKERRQ(ierr);
1044   if (!flg2) {
1045     flg2 = PETSC_FALSE;
1046     ierr = PetscOptionsGetBool(NULL,"-memory_info",&flg2,NULL);CHKERRQ(ierr);
1047   }
1048   if (flg2) {
1049     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
1050   }
1051 #endif
1052 
1053 #if defined(PETSC_USE_LOG)
1054   flg1 = PETSC_FALSE;
1055   ierr = PetscOptionsGetBool(NULL,"-get_total_flops",&flg1,NULL);CHKERRQ(ierr);
1056   if (flg1) {
1057     PetscLogDouble flops = 0;
1058     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
1059     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
1060   }
1061 #endif
1062 
1063 
1064 #if defined(PETSC_USE_LOG)
1065 #if defined(PETSC_HAVE_MPE)
1066   mname[0] = 0;
1067 
1068   ierr = PetscOptionsGetString(NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1069   if (flg1) {
1070     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
1071     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
1072   }
1073 #endif
1074   mname[0] = 0;
1075 
1076   ierr = PetscLogViewFromOptions();CHKERRQ(ierr);
1077   ierr = PetscOptionsGetString(NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1078   if (flg1) {
1079     PetscViewer viewer;
1080     if (mname[0]) {
1081       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
1082       ierr = PetscLogView(viewer);CHKERRQ(ierr);
1083       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1084     } else {
1085       viewer = PETSC_VIEWER_STDOUT_WORLD;
1086       ierr   = PetscLogView(viewer);CHKERRQ(ierr);
1087     }
1088   }
1089   mname[0] = 0;
1090 
1091   ierr = PetscOptionsGetString(NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1092   ierr = PetscOptionsGetString(NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
1093   if (flg1 || flg2) {
1094     if (mname[0]) PetscLogDump(mname);
1095     else          PetscLogDump(0);
1096   }
1097 #endif
1098 
1099   /*
1100      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1101   */
1102   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1103 
1104   ierr = PetscStackDestroy();CHKERRQ(ierr);
1105   PetscThreadLocalDestroy((PetscThreadKey)petscstack); /* Deletes pthread_key */
1106 
1107   flg1 = PETSC_FALSE;
1108   ierr = PetscOptionsGetBool(NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr);
1109   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1110   flg1 = PETSC_FALSE;
1111   ierr = PetscOptionsGetBool(NULL,"-mpidump",&flg1,NULL);CHKERRQ(ierr);
1112   if (flg1) {
1113     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1114   }
1115   flg1 = PETSC_FALSE;
1116   flg2 = PETSC_FALSE;
1117   /* preemptive call to avoid listing this option in options table as unused */
1118   ierr = PetscOptionsHasName(NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1119   ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1120   ierr = PetscOptionsGetBool(NULL,"-options_view",&flg2,NULL);CHKERRQ(ierr);
1121 
1122   if (flg2) {
1123     PetscViewer viewer;
1124     ierr = PetscViewerCreate(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1125     ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
1126     ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1127     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1128   }
1129 
1130   /* to prevent PETSc -options_left from warning */
1131   ierr = PetscOptionsHasName(NULL,"-nox",&flg1);CHKERRQ(ierr);
1132   ierr = PetscOptionsHasName(NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1133 
1134   flg3 = PETSC_FALSE; /* default value is required */
1135   ierr = PetscOptionsGetBool(NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1136   ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1137   if (flg3) {
1138     if (!flg2) { /* have not yet printed the options */
1139       PetscViewer viewer;
1140       ierr = PetscViewerCreate(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
1141       ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr);
1142       ierr = PetscOptionsView(viewer);CHKERRQ(ierr);
1143       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1144     }
1145     if (!nopt) {
1146       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1147     } else if (nopt == 1) {
1148       ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1149     } else {
1150       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1151     }
1152   }
1153 #if defined(PETSC_USE_DEBUG)
1154   if (nopt && !flg3 && !flg1) {
1155     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1156     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1157     ierr = PetscOptionsLeft();CHKERRQ(ierr);
1158   } else if (nopt && flg3) {
1159 #else
1160   if (nopt && flg3) {
1161 #endif
1162     ierr = PetscOptionsLeft();CHKERRQ(ierr);
1163   }
1164 
1165 #if defined(PETSC_HAVE_SAWS)
1166   if (!PetscGlobalRank) {
1167     ierr = PetscStackSAWsViewOff();CHKERRQ(ierr);
1168     PetscStackCallSAWs(SAWs_Finalize,());
1169   }
1170 #endif
1171 
1172   {
1173     PetscThreadComm tcomm_world;
1174     ierr = PetscGetThreadCommWorld(&tcomm_world);CHKERRQ(ierr);
1175     /* Free global thread communicator */
1176     ierr = PetscThreadCommDestroy(&tcomm_world);CHKERRQ(ierr);
1177   }
1178 
1179 #if defined(PETSC_USE_LOG)
1180   /*
1181        List all objects the user may have forgot to free
1182   */
1183   if (PetscObjectsLog) {
1184     ierr = PetscOptionsHasName(NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1185     if (flg1) {
1186       MPI_Comm local_comm;
1187       char     string[64];
1188 
1189       ierr = PetscOptionsGetString(NULL,"-objects_dump",string,64,NULL);CHKERRQ(ierr);
1190       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1191       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1192       ierr = PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);CHKERRQ(ierr);
1193       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1194       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1195     }
1196   }
1197 #endif
1198 
1199 #if defined(PETSC_USE_LOG)
1200   PetscObjectsCounts    = 0;
1201   PetscObjectsMaxCounts = 0;
1202   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1203 #endif
1204 
1205 #if defined(PETSC_USE_LOG)
1206   ierr = PetscLogDestroy();CHKERRQ(ierr);
1207 #endif
1208 
1209   /*
1210      Close any open dynamic libraries
1211   */
1212   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1213 
1214   /*
1215      Destroy any packages that registered a finalize
1216   */
1217   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1218 
1219   /*
1220      Print PetscFunctionLists that have not been properly freed
1221 
1222   ierr = PetscFunctionListPrintAll();CHKERRQ(ierr);
1223   */
1224 
1225   if (petsc_history) {
1226     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1227     petsc_history = 0;
1228   }
1229 
1230   ierr = PetscInfoAllow(PETSC_FALSE,NULL);CHKERRQ(ierr);
1231 
1232 #if !defined(PETSC_HAVE_THREADSAFETY)
1233   {
1234     char fname[PETSC_MAX_PATH_LEN];
1235     FILE *fd;
1236     int  err;
1237 
1238     fname[0] = 0;
1239 
1240     ierr = PetscOptionsGetString(NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1241     flg2 = PETSC_FALSE;
1242     ierr = PetscOptionsGetBool(NULL,"-malloc_test",&flg2,NULL);CHKERRQ(ierr);
1243 #if defined(PETSC_USE_DEBUG)
1244     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1245 #else
1246     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1247 #endif
1248     if (flg1 && fname[0]) {
1249       char sname[PETSC_MAX_PATH_LEN];
1250 
1251       sprintf(sname,"%s_%d",fname,rank);
1252       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1253       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1254       err  = fclose(fd);
1255       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1256     } else if (flg1 || flg2) {
1257       MPI_Comm local_comm;
1258 
1259       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1260       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1261       ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1262       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1263       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1264     }
1265   }
1266 
1267   {
1268     char fname[PETSC_MAX_PATH_LEN];
1269     FILE *fd = NULL;
1270 
1271     fname[0] = 0;
1272 
1273     ierr = PetscOptionsGetString(NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1274     ierr = PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1275     if (flg1 && fname[0]) {
1276       int err;
1277 
1278       if (!rank) {
1279         fd = fopen(fname,"w");
1280         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1281       }
1282       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1283       if (fd) {
1284         err = fclose(fd);
1285         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1286       }
1287     } else if (flg1 || flg2) {
1288       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1289     }
1290   }
1291 #endif
1292 
1293 #if defined(PETSC_HAVE_CUDA)
1294   flg  = PETSC_TRUE;
1295   ierr = PetscOptionsGetBool(NULL,"-cublas",&flg,NULL);CHKERRQ(ierr);
1296   if (flg) {
1297     PetscInt p;
1298     for (p = 0; p < PetscGlobalSize; ++p) {
1299       if (p == PetscGlobalRank) cublasShutdown();
1300       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1301     }
1302   }
1303 #endif
1304 
1305   /* Can be destroyed only after all the options are used */
1306   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1307 
1308   PetscGlobalArgc = 0;
1309   PetscGlobalArgs = 0;
1310 
1311 #if defined(PETSC_USE_REAL___FLOAT128)
1312   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1313 #if defined(PETSC_HAVE_COMPLEX)
1314   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1315 #endif
1316   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1317   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1318 #endif
1319 
1320 #if defined(PETSC_HAVE_COMPLEX)
1321 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1322   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1323   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1324 #endif
1325 #endif
1326 
1327 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1328   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1329 #endif
1330 
1331   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1332 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
1333   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1334 #endif
1335   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1336 
1337   /*
1338      Destroy any known inner MPI_Comm's and attributes pointing to them
1339      Note this will not destroy any new communicators the user has created.
1340 
1341      If all PETSc objects were not destroyed those left over objects will have hanging references to
1342      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1343  */
1344   {
1345     PetscCommCounter *counter;
1346     PetscMPIInt      flg;
1347     MPI_Comm         icomm;
1348     union {MPI_Comm comm; void *ptr;} ucomm;
1349     ierr = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1350     if (flg) {
1351       icomm = ucomm.comm;
1352       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1353       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1354 
1355       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1356       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1357       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1358     }
1359     ierr = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ucomm,&flg);CHKERRQ(ierr);
1360     if (flg) {
1361       icomm = ucomm.comm;
1362       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1363       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1364 
1365       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1366       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1367       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1368     }
1369   }
1370 
1371   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1372   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1373   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1374 
1375   if (PetscBeganMPI) {
1376 #if defined(PETSC_HAVE_MPI_FINALIZED)
1377     PetscMPIInt flag;
1378     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1379     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1380 #endif
1381     ierr = MPI_Finalize();CHKERRQ(ierr);
1382   }
1383 /*
1384 
1385      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1386    the communicator has some outstanding requests on it. Specifically if the
1387    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1388    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1389    is never freed as it should be. Thus one may obtain messages of the form
1390    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1391    memory was not freed.
1392 
1393 */
1394   ierr = PetscMallocClear();CHKERRQ(ierr);
1395 
1396   PetscInitializeCalled = PETSC_FALSE;
1397   PetscFinalizeCalled   = PETSC_TRUE;
1398   PetscFunctionReturn(ierr);
1399 }
1400 
1401 #if defined(PETSC_MISSING_LAPACK_lsame_)
1402 PETSC_EXTERN int lsame_(char *a,char *b)
1403 {
1404   if (*a == *b) return 1;
1405   if (*a + 32 == *b) return 1;
1406   if (*a - 32 == *b) return 1;
1407   return 0;
1408 }
1409 #endif
1410 
1411 #if defined(PETSC_MISSING_LAPACK_lsame)
1412 PETSC_EXTERN int lsame(char *a,char *b)
1413 {
1414   if (*a == *b) return 1;
1415   if (*a + 32 == *b) return 1;
1416   if (*a - 32 == *b) return 1;
1417   return 0;
1418 }
1419 #endif
1420