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