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