xref: /petsc/src/sys/objects/pinit.c (revision adcec1e53b1fc19aa0d23dc8f01b9147301e4f11)
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   PetscInt       *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(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
235   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
236   *max   = work[2*rank];
237   *sum   = work[2*rank+1];
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   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
761   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
762 
763   /*
764      Attributes to be set on PETSc communicators
765   */
766   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
767   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
768   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
769 
770   /*
771      Build the options database
772   */
773   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
774 
775 
776   /*
777      Print main application help message
778   */
779   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
780   if (help && flg) {
781     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
782   }
783   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
784 
785   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
786 #if defined(PETSC_USE_LOG)
787   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
788 #endif
789 
790   /*
791      Load the dynamic libraries (on machines that support them), this registers all
792      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
793   */
794   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
795 
796   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
797   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
798   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
799   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
800 
801   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
802   /* Check the options database for options related to the options database itself */
803   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
804 
805 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
806   /*
807       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
808 
809       Currently not used because it is not supported by MPICH.
810   */
811 #if !defined(PETSC_WORDS_BIGENDIAN)
812   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
813 #endif
814 #endif
815 
816   ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
817   if (flg) {
818 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
819     ierr = PetscHMPISpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
820 #else
821     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead");
822 #endif
823   } else {
824     ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_merge_size",&nodesize,&flg);CHKERRQ(ierr);
825     if (flg) {
826       ierr = PetscHMPIMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
827       if (PetscHMPIWorker) { /* if worker then never enter user code */
828         PetscInitializeCalled = PETSC_TRUE;
829         ierr = PetscEnd();
830       }
831     }
832   }
833 
834 #if defined(PETSC_HAVE_CUDA)
835   {
836     PetscMPIInt p;
837     for (p = 0; p < PetscGlobalSize; ++p) {
838       if (p == PetscGlobalRank) {cublasInit();}
839       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
840     }
841   }
842 #endif
843 
844 #if defined(PETSC_HAVE_AMS)
845   ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr);
846   if (flg) {
847     PetscAMSPublishAll = PETSC_TRUE;
848   }
849 #endif
850 
851   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
852   if (flg) {
853     PetscInitializeCalled = PETSC_TRUE;
854     ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
855   }
856 
857   ierr = PetscThreadCommInitializePackage(PETSC_NULL);CHKERRQ(ierr);
858 
859 #if defined(PETSC_USE_DEBUG)
860   PetscThreadLocalRegister(&petscstack); /* Creates petscstack_key if needed */
861   ierr = PetscStackCreate();CHKERRQ(ierr);
862 #endif
863 
864 #if defined(PETSC_SERIALIZE_FUNCTIONS)
865   ierr = PetscFPTCreate(10000);CHKERRQ(ierr);
866 #endif
867 
868   /*
869       Once we are completedly initialized then we can set this variables
870   */
871   PetscInitializeCalled = PETSC_TRUE;
872   PetscFunctionReturn(0);
873 }
874 
875 extern PetscObject *PetscObjects;
876 extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;
877 
878 #undef __FUNCT__
879 #define __FUNCT__ "PetscFinalize"
880 /*@C
881    PetscFinalize - Checks for options to be called at the conclusion
882    of the program. MPI_Finalize() is called only if the user had not
883    called MPI_Init() before calling PetscInitialize().
884 
885    Collective on PETSC_COMM_WORLD
886 
887    Options Database Keys:
888 +  -options_table - Calls PetscOptionsView()
889 .  -options_left - Prints unused options that remain in the database
890 .  -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
891 .  -mpidump - Calls PetscMPIDump()
892 .  -malloc_dump - Calls PetscMallocDump()
893 .  -malloc_info - Prints total memory usage
894 -  -malloc_log - Prints summary of memory usage
895 
896    Options Database Keys for Profiling:
897    See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details.
898 +  -log_summary [filename] - Prints summary of flop and timing
899         information to screen. If the filename is specified the
900         summary is written to the file.  See PetscLogView().
901 .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
902         See PetscLogPrintSViewPython().
903 .  -log_all [filename] - Logs extensive profiling information
904         See PetscLogDump().
905 .  -log [filename] - Logs basic profiline information  See PetscLogDump().
906 .  -log_sync - Log the synchronization in scatters, inner products
907         and norms
908 -  -log_mpe [filename] - Creates a logfile viewable by the
909       utility Upshot/Nupshot (in MPICH distribution)
910 
911    Level: beginner
912 
913    Note:
914    See PetscInitialize() for more general runtime options.
915 
916 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
917 @*/
918 PetscErrorCode  PetscFinalize(void)
919 {
920   PetscErrorCode ierr;
921   PetscMPIInt    rank;
922   PetscInt       nopt;
923   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
924 #if defined(PETSC_HAVE_AMS)
925   PetscBool      flg = PETSC_FALSE;
926 #endif
927 #if defined(PETSC_USE_LOG)
928   char           mname[PETSC_MAX_PATH_LEN];
929 #endif
930 
931   PetscFunctionBegin;
932 
933   if (!PetscInitializeCalled) {
934     printf("PetscInitialize() must be called before PetscFinalize()\n");
935     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
936   }
937   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");CHKERRQ(ierr);
938 
939 #if defined(PETSC_SERIALIZE_FUNCTIONS)
940   ierr = PetscFPTDestroy();CHKERRQ(ierr);
941 #endif
942 
943 
944 #if defined(PETSC_HAVE_AMS)
945   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr);
946   if (flg) {
947     ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr);
948   }
949 #endif
950 
951   ierr = PetscHMPIFinalize();CHKERRQ(ierr);
952 
953   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
954   ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
955   if (!flg2) {
956     flg2 = PETSC_FALSE;
957     ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
958   }
959   if (flg2) {
960     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
961   }
962 
963 #if defined(PETSC_USE_LOG)
964   flg1 = PETSC_FALSE;
965   ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
966   if (flg1) {
967     PetscLogDouble flops = 0;
968     ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
969     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
970   }
971 #endif
972 
973 
974 #if defined(PETSC_USE_LOG)
975 #if defined(PETSC_HAVE_MPE)
976   mname[0] = 0;
977   ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
978   if (flg1){
979     if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
980     else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
981   }
982 #endif
983   mname[0] = 0;
984   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
985   if (flg1) {
986     PetscViewer viewer;
987     if (mname[0])  {
988       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
989       ierr = PetscLogView(viewer);CHKERRQ(ierr);
990       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
991     } else {
992       viewer = PETSC_VIEWER_STDOUT_WORLD;
993       ierr = PetscLogView(viewer);CHKERRQ(ierr);
994     }
995   }
996 
997   mname[0] = 0;
998   ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
999   if (flg1) {
1000     PetscViewer viewer;
1001     if (mname[0])  {
1002       ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr);
1003       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
1004       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1005     } else {
1006       viewer = PETSC_VIEWER_STDOUT_WORLD;
1007       ierr = PetscLogViewPython(viewer);CHKERRQ(ierr);
1008     }
1009   }
1010 
1011   ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1012   if (flg1) {
1013     if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
1014     else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
1015   }
1016 
1017   mname[0] = 0;
1018   ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
1019   ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
1020   if (flg1 || flg2){
1021     if (mname[0]) PetscLogDump(mname);
1022     else          PetscLogDump(0);
1023   }
1024 #endif
1025 
1026   /*
1027      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1028   */
1029   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
1030 
1031 #if defined(PETSC_USE_DEBUG)
1032   ierr = PetscStackDestroy();CHKERRQ(ierr);
1033 #endif
1034 
1035   flg1 = PETSC_FALSE;
1036   ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
1037   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
1038   flg1 = PETSC_FALSE;
1039   ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
1040   if (flg1) {
1041     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
1042   }
1043   flg1 = PETSC_FALSE;
1044   flg2 = PETSC_FALSE;
1045   /* preemptive call to avoid listing this option in options table as unused */
1046   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
1047   ierr = PetscOptionsHasName(PETSC_NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1048   ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
1049 
1050   if (flg2) {
1051     ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1052   }
1053 
1054   /* to prevent PETSc -options_left from warning */
1055   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr);
1056   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr);
1057 
1058   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1059     flg3 = PETSC_FALSE; /* default value is required */
1060     ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
1061     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
1062     if (flg3) {
1063       if (!flg2) { /* have not yet printed the options */
1064 	ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1065       }
1066       if (!nopt) {
1067 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
1068       } else if (nopt == 1) {
1069 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
1070       } else {
1071 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr);
1072       }
1073     }
1074 #if defined(PETSC_USE_DEBUG)
1075     if (nopt && !flg3 && !flg1) {
1076       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
1077       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
1078       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1079     } else if (nopt && flg3) {
1080 #else
1081     if (nopt && flg3) {
1082 #endif
1083       ierr = PetscOptionsLeft();CHKERRQ(ierr);
1084     }
1085   }
1086 
1087   /*
1088        List all objects the user may have forgot to free
1089   */
1090   ierr = PetscOptionsHasName(PETSC_NULL,"-objects_dump",&flg1);CHKERRQ(ierr);
1091   if (flg1) {
1092     MPI_Comm  local_comm;
1093     char      string[64];
1094 
1095     ierr = PetscOptionsGetString(PETSC_NULL,"-objects_dump",string,64,PETSC_NULL);CHKERRQ(ierr);
1096     ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1097     ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1098     ierr = PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);CHKERRQ(ierr);
1099     ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1100     ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1101   }
1102   PetscObjectsCounts    = 0;
1103   PetscObjectsMaxCounts = 0;
1104   ierr = PetscFree(PetscObjects);CHKERRQ(ierr);
1105 
1106 
1107 #if defined(PETSC_USE_LOG)
1108   ierr = PetscLogDestroy();CHKERRQ(ierr);
1109 #endif
1110 
1111   /*
1112        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
1113   */
1114   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
1115 
1116   /*
1117        Free all the registered op functions, such as MatOpList, etc
1118   */
1119   ierr = PetscOpFListDestroyAll();CHKERRQ(ierr);
1120 
1121   /*
1122      Destroy any packages that registered a finalize
1123   */
1124   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
1125 
1126   /*
1127      Destroy all the function registration lists created
1128   */
1129   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
1130 
1131   if (petsc_history) {
1132     ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
1133     petsc_history = 0;
1134   }
1135 
1136   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
1137 
1138   {
1139     char fname[PETSC_MAX_PATH_LEN];
1140     FILE *fd;
1141     int  err;
1142 
1143     fname[0] = 0;
1144     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
1145     flg2 = PETSC_FALSE;
1146     ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr);
1147 #if defined(PETSC_USE_DEBUG)
1148     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1149 #else
1150     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1151 #endif
1152     if (flg1 && fname[0]) {
1153       char sname[PETSC_MAX_PATH_LEN];
1154 
1155       sprintf(sname,"%s_%d",fname,rank);
1156       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1157       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
1158       err = fclose(fd);
1159       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1160     } else if (flg1 || flg2) {
1161       MPI_Comm local_comm;
1162 
1163       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
1164       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
1165         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
1166       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
1167       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
1168     }
1169   }
1170 
1171   {
1172     char fname[PETSC_MAX_PATH_LEN];
1173     FILE *fd = PETSC_NULL;
1174 
1175     fname[0] = 0;
1176     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
1177     ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr);
1178     if (flg1 && fname[0]) {
1179       int  err;
1180 
1181       if (!rank) {
1182         fd = fopen(fname,"w");
1183         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1184       }
1185       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
1186       if (fd) {
1187         err = fclose(fd);
1188         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1189       }
1190     } else if (flg1 || flg2) {
1191       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
1192     }
1193   }
1194   /* Can be destroyed only after all the options are used */
1195   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
1196 
1197   PetscGlobalArgc = 0;
1198   PetscGlobalArgs = 0;
1199 
1200 #if defined(PETSC_USE_REAL___FLOAT128)
1201   ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr);
1202 #if defined(PETSC_HAVE_COMPLEX)
1203   ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr);
1204 #endif
1205   ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr);
1206   ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr);
1207 #endif
1208 
1209 #if defined(PETSC_HAVE_COMPLEX)
1210 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1211   ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
1212   ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr);
1213 #endif
1214 #endif
1215 
1216 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1217   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
1218 #endif
1219 
1220   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
1221   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
1222   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
1223   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
1224   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
1225 
1226   /*
1227      Destroy any known inner MPI_Comm's and attributes pointing to them
1228      Note this will not destroy any new communicators the user has created.
1229 
1230      If all PETSc objects were not destroyed those left over objects will have hanging references to
1231      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1232  */
1233   {
1234     PetscCommCounter *counter;
1235     PetscMPIInt      flg;
1236     MPI_Comm         icomm;
1237     void             *ptr;
1238     ierr  = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1239     if (flg) {
1240       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1241       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1242       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1243       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1244 
1245       ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1246       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1247       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1248     }
1249     ierr  = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr);
1250     if (flg) {
1251       /*  Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers  */
1252       ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr);
1253       ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr);
1254       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");
1255 
1256       ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr);
1257       ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr);
1258       ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr);
1259     }
1260   }
1261 
1262   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
1263   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
1264   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
1265 
1266 #if defined(PETSC_HAVE_CUDA)
1267   {
1268     PetscInt p;
1269     for (p = 0; p < PetscGlobalSize; ++p) {
1270       if (p == PetscGlobalRank) {cublasShutdown();}
1271       ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr);
1272     }
1273   }
1274 #endif
1275 
1276   if (PetscBeganMPI) {
1277 #if defined(PETSC_HAVE_MPI_FINALIZED)
1278     PetscMPIInt flag;
1279     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
1280     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1281 #endif
1282     ierr = MPI_Finalize();CHKERRQ(ierr);
1283   }
1284 /*
1285 
1286      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1287    the communicator has some outstanding requests on it. Specifically if the
1288    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1289    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1290    is never freed as it should be. Thus one may obtain messages of the form
1291    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1292    memory was not freed.
1293 
1294 */
1295   ierr = PetscMallocClear();CHKERRQ(ierr);
1296   PetscInitializeCalled = PETSC_FALSE;
1297   PetscFinalizeCalled   = PETSC_TRUE;
1298   PetscFunctionReturn(ierr);
1299 }
1300 
1301 #if defined(PETSC_MISSING_LAPACK_lsame_)
1302 EXTERN_C_BEGIN
1303 int lsame_(char *a,char *b)
1304 {
1305   if (*a == *b) return 1;
1306   if (*a + 32 == *b) return 1;
1307   if (*a - 32 == *b) return 1;
1308   return 0;
1309 }
1310 EXTERN_C_END
1311 #endif
1312 
1313 #if defined(PETSC_MISSING_LAPACK_lsame)
1314 EXTERN_C_BEGIN
1315 int lsame(char *a,char *b)
1316 {
1317   if (*a == *b) return 1;
1318   if (*a + 32 == *b) return 1;
1319   if (*a - 32 == *b) return 1;
1320   return 0;
1321 }
1322 EXTERN_C_END
1323 #endif
1324