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