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