xref: /petsc/src/sys/objects/pinit.c (revision fad68dfa178c86155e5d5291689bc2f3ad36ac6f)
1 #define PETSC_DLL
2 /*
3    This file defines the initialization of PETSc, including PetscInitialize()
4 */
5 
6 #include "petsc.h"        /*I  "petsc.h"   I*/
7 #include "petscsys.h"
8 
9 #if defined(PETSC_USE_LOG)
10 EXTERN PetscErrorCode PetscLogBegin_Private(void);
11 #endif
12 
13 /* -----------------------------------------------------------------------------------------*/
14 
15 extern FILE *petsc_history;
16 
17 EXTERN PetscErrorCode PetscInitialize_DynamicLibraries(void);
18 EXTERN PetscErrorCode PetscFinalize_DynamicLibraries(void);
19 EXTERN PetscErrorCode PetscFListDestroyAll(void);
20 EXTERN PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
21 EXTERN PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
22 EXTERN PetscErrorCode PetscLogCloseHistoryFile(FILE **);
23 
24 /* this is used by the _, __, and ___ macros (see include/petscerror.h) */
25 PetscErrorCode __gierr = 0;
26 
27 /* user may set this BEFORE calling PetscInitialize() */
28 MPI_Comm PETSC_COMM_WORLD = 0;
29 
30 /*
31      Declare and set all the string names of the PETSc enums
32 */
33 const char *PetscTruths[]    = {"FALSE","TRUE","PetscTruth","PETSC_",0};
34 const char *PetscDataTypes[] = {"INT", "DOUBLE", "COMPLEX",
35                                 "LONG","SHORT",  "FLOAT",
36                                 "CHAR","LOGICAL","ENUM","TRUTH","PetscDataType","PETSC_",0};
37 
38 #if defined (PETSC_USE_LOG)
39 PetscCookie PETSC_LARGEST_COOKIE = PETSC_COOKIE;
40 #else
41 PetscCookie PETSC_LARGEST_COOKIE = 0;
42 #endif
43 PetscCookie PETSC_OBJECT_COOKIE = 0;
44 
45 PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
46 PetscTruth PetscPreLoadingOn   = PETSC_FALSE;
47 
48 /*
49        Checks the options database for initializations related to the
50     PETSc components
51 */
52 #undef __FUNCT__
53 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
54 PetscErrorCode PETSC_DLLEXPORT PetscOptionsCheckInitial_Components(void)
55 {
56   PetscTruth flg1;
57   PetscErrorCode ierr;
58 
59   PetscFunctionBegin;
60   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr);
61   if (flg1) {
62 #if defined (PETSC_USE_LOG)
63     MPI_Comm   comm = PETSC_COMM_WORLD;
64     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
65     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
66     ierr = (*PetscHelpPrintf)(comm," -verbose_info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
67     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
68 #endif
69   }
70   PetscFunctionReturn(0);
71 }
72 
73 #undef __FUNCT__
74 #define __FUNCT__ "PetscInitializeNoArguments"
75 /*@C
76       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
77         the command line arguments.
78 
79    Collective
80 
81    Level: advanced
82 
83 .seealso: PetscInitialize(), PetscInitializeFortran()
84 @*/
85 PetscErrorCode PETSC_DLLEXPORT PetscInitializeNoArguments(void)
86 {
87   PetscErrorCode ierr;
88   int            argc = 0;
89   char           **args = 0;
90 
91   PetscFunctionBegin;
92   ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
93   PetscFunctionReturn(ierr);
94 }
95 
96 #undef __FUNCT__
97 #define __FUNCT__ "PetscInitialized"
98 /*@
99       PetscInitialized - Determine whether PETSc is initialized.
100 
101    Level: beginner
102 
103 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
104 @*/
105 PetscErrorCode PETSC_DLLEXPORT PetscInitialized(PetscTruth *isInitialized)
106 {
107   PetscFunctionBegin;
108   PetscValidPointer(isInitialized, 1);
109   *isInitialized = PetscInitializeCalled;
110   PetscFunctionReturn(0);
111 }
112 
113 #undef __FUNCT__
114 #define __FUNCT__ "PetscFinalized"
115 /*@
116       PetscFinalized - Determine whether PetscFinalize() has been called yet
117 
118    Level: developer
119 
120 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
121 @*/
122 PetscErrorCode PETSC_DLLEXPORT PetscFinalized(PetscTruth *isFinalized)
123 {
124   PetscFunctionBegin;
125   PetscValidPointer(isFinalized, 1);
126   *isFinalized = PetscFinalizeCalled;
127   PetscFunctionReturn(0);
128 }
129 
130 EXTERN PetscErrorCode        PetscOptionsCheckInitial_Private(void);
131 extern PetscTruth PetscBeganMPI;
132 
133 /*
134        This function is the MPI reduction operation used to compute the sum of the
135    first half of the datatype and the max of the second half.
136 */
137 MPI_Op PetscMaxSum_Op = 0;
138 
139 EXTERN_C_BEGIN
140 #undef __FUNCT__
141 #define __FUNCT__ "PetscMaxSum_Local"
142 void PETSC_DLLEXPORT PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
143 {
144   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
145 
146   PetscFunctionBegin;
147   if (*datatype != MPIU_2INT) {
148     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
149     MPI_Abort(MPI_COMM_WORLD,1);
150   }
151 
152   for (i=0; i<count; i++) {
153     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
154     xout[2*i+1] += xin[2*i+1];
155   }
156   PetscStackPop;
157   return;
158 }
159 EXTERN_C_END
160 
161 /*
162     Returns the max of the first entry owned by this processor and the
163 sum of the second entry.
164 */
165 #undef __FUNCT__
166 #define __FUNCT__ "PetscMaxSum"
167 PetscErrorCode PETSC_DLLEXPORT PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
168 {
169   PetscMPIInt    size,rank;
170   PetscInt       *work;
171   PetscErrorCode ierr;
172 
173   PetscFunctionBegin;
174   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
175   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
176   ierr   = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
177   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
178   *max   = work[2*rank];
179   *sum   = work[2*rank+1];
180   ierr   = PetscFree(work);CHKERRQ(ierr);
181   PetscFunctionReturn(0);
182 }
183 
184 /* ----------------------------------------------------------------------------*/
185 MPI_Op PETSC_DLLEXPORT PetscADMax_Op = 0;
186 
187 EXTERN_C_BEGIN
188 #undef __FUNCT__
189 #define __FUNCT__ "PetscADMax_Local"
190 void PETSC_DLLEXPORT PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
191 {
192   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
193   PetscInt    i,count = *cnt;
194 
195   PetscFunctionBegin;
196   if (*datatype != MPIU_2SCALAR) {
197     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
198     MPI_Abort(MPI_COMM_WORLD,1);
199   }
200 
201   for (i=0; i<count; i++) {
202     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
203       xout[2*i]   = xin[2*i];
204       xout[2*i+1] = xin[2*i+1];
205     }
206   }
207 
208   PetscStackPop;
209   return;
210 }
211 EXTERN_C_END
212 
213 MPI_Op PETSC_DLLEXPORT PetscADMin_Op = 0;
214 
215 EXTERN_C_BEGIN
216 #undef __FUNCT__
217 #define __FUNCT__ "PetscADMin_Local"
218 void PETSC_DLLEXPORT PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
219 {
220   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
221   PetscInt    i,count = *cnt;
222 
223   PetscFunctionBegin;
224   if (*datatype != MPIU_2SCALAR) {
225     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
226     MPI_Abort(MPI_COMM_WORLD,1);
227   }
228 
229   for (i=0; i<count; i++) {
230     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
231       xout[2*i]   = xin[2*i];
232       xout[2*i+1] = xin[2*i+1];
233     }
234   }
235 
236   PetscStackPop;
237   return;
238 }
239 EXTERN_C_END
240 /* ---------------------------------------------------------------------------------------*/
241 
242 #if defined(PETSC_USE_COMPLEX)
243 MPI_Op PetscSum_Op = 0;
244 
245 EXTERN_C_BEGIN
246 #undef __FUNCT__
247 #define __FUNCT__ "PetscSum_Local"
248 void PETSC_DLLEXPORT PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
249 {
250   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
251   PetscInt         i,count = *cnt;
252 
253   PetscFunctionBegin;
254   if (*datatype != MPIU_SCALAR) {
255     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
256     MPI_Abort(MPI_COMM_WORLD,1);
257   }
258 
259   for (i=0; i<count; i++) {
260     xout[i] += xin[i];
261   }
262 
263   PetscStackPop;
264   return;
265 }
266 EXTERN_C_END
267 #endif
268 
269 static int  PetscGlobalArgc   = 0;
270 static char **PetscGlobalArgs = 0;
271 
272 #undef __FUNCT__
273 #define __FUNCT__ "PetscGetArgs"
274 /*@C
275    PetscGetArgs - Allows you to access the raw command line arguments anywhere
276      after PetscInitialize() is called but before PetscFinalize().
277 
278    Not Collective
279 
280    Output Parameters:
281 +  argc - count of number of command line arguments
282 -  args - the command line arguments
283 
284    Level: intermediate
285 
286    Notes:
287       This is usually used to pass the command line arguments into other libraries
288    that are called internally deep in PETSc or the application.
289 
290    Concepts: command line arguments
291 
292 .seealso: PetscFinalize(), PetscInitializeFortran()
293 
294 @*/
295 PetscErrorCode PETSC_DLLEXPORT PetscGetArgs(int *argc,char ***args)
296 {
297   PetscFunctionBegin;
298   if (!PetscGlobalArgs) {
299     SETERRQ(PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
300   }
301   *argc = PetscGlobalArgc;
302   *args = PetscGlobalArgs;
303   PetscFunctionReturn(0);
304 }
305 
306 #undef __FUNCT__
307 #define __FUNCT__ "PetscInitialize"
308 /*@C
309    PetscInitialize - Initializes the PETSc database and MPI.
310    PetscInitialize() calls MPI_Init() if that has yet to be called,
311    so this routine should always be called near the beginning of
312    your program -- usually the very first line!
313 
314    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
315 
316    Input Parameters:
317 +  argc - count of number of command line arguments
318 .  args - the command line arguments
319 .  file - [optional] PETSc database file, defaults to ~username/.petscrc
320           (use PETSC_NULL for default)
321 -  help - [optional] Help message to print, use PETSC_NULL for no message
322 
323    If you wish PETSc to run on a subcommunicator of MPI_COMM_WORLD, create that
324    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize()
325 
326    Options Database Keys:
327 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
328 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
329 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
330 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
331 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
332 .  -stop_for_debugger - Print message on how to attach debugger manually to
333                         process and wait (-debugger_pause) seconds for attachment
334 .  -malloc - Indicates use of PETSc error-checking malloc
335 .  -malloc no - Indicates not to use error-checking malloc
336 .  -fp_trap - Stops on floating point exceptions (Note that on the
337               IBM RS6000 this slows code by at least a factor of 10.)
338 .  -no_signal_handler - Indicates not to trap error signals
339 .  -shared_tmp - indicates /tmp directory is shared by all processors
340 .  -not_shared_tmp - each processor has own /tmp
341 .  -tmp - alternative name of /tmp directory
342 .  -get_total_flops - returns total flops done by all processors
343 -  -memory_info - Print memory usage at end of run
344 
345    Options Database Keys for Profiling:
346    See the Profiling chapter of the users manual for details.
347 +  -log_trace [filename] - Print traces of all PETSc calls
348         to the screen (useful to determine where a program
349         hangs without running in the debugger).  See PetscLogTraceBegin().
350 .  -verbose_info <optional filename> - Prints verbose information to the screen
351 -  -verbose_info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
352 
353    Environmental Variables:
354 +   PETSC_TMP - alternative tmp directory
355 .   PETSC_SHARED_TMP - tmp is shared by all processes
356 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
357 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
358 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
359 
360 
361    Level: beginner
362 
363    Notes:
364    If for some reason you must call MPI_Init() separately, call
365    it before PetscInitialize().
366 
367    Fortran Version:
368    In Fortran this routine has the format
369 $       call PetscInitialize(file,ierr)
370 
371 +   ierr - error return code
372 -   file - [optional] PETSc database file name, defaults to
373            ~username/.petscrc (use PETSC_NULL_CHARACTER for default)
374 
375    Important Fortran Note:
376    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
377    null character string; you CANNOT just use PETSC_NULL as
378    in the C version.  See the users manual for details.
379 
380 
381    Concepts: initializing PETSc
382 
383 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs()
384 
385 @*/
386 PetscErrorCode PETSC_DLLEXPORT PetscInitialize(int *argc,char ***args,const char file[],const char help[])
387 {
388   PetscErrorCode ierr;
389   PetscMPIInt    flag, size;
390   PetscTruth     flg;
391   char           hostname[256];
392 
393   PetscFunctionBegin;
394   if (PetscInitializeCalled) PetscFunctionReturn(0);
395 
396   /* this must be initialized in a routine, not as a constant declaration*/
397   PETSC_STDOUT = stdout;
398 
399   ierr = PetscOptionsCreate();CHKERRQ(ierr);
400 
401   /*
402      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
403      it that it sets args[0] on all processors to be args[0] on the first processor.
404   */
405   if (argc && *argc) {
406     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
407   } else {
408     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
409   }
410 
411 
412   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
413   if (!flag) {
414     if (PETSC_COMM_WORLD) SETERRQ(PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
415     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
416     PetscBeganMPI = PETSC_TRUE;
417   }
418   if (argc && args) {
419     PetscGlobalArgc = *argc;
420     PetscGlobalArgs = *args;
421   }
422   PetscInitializeCalled = PETSC_TRUE;
423   PetscFinalizeCalled   = PETSC_FALSE;
424 
425   if (!PETSC_COMM_WORLD) {
426     PETSC_COMM_WORLD = MPI_COMM_WORLD;
427   }
428 
429   /* Done after init due to a bug in MPICH-GM? */
430   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
431 
432   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
433   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
434 
435 #if defined(PETSC_USE_COMPLEX)
436   /*
437      Initialized the global complex variable; this is because with
438      shared libraries the constructors for global variables
439      are not called; at least on IRIX.
440   */
441   {
442     PetscScalar ic(0.0,1.0);
443     PETSC_i = ic;
444   }
445   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_COMPLEX);CHKERRQ(ierr);
446   ierr = MPI_Type_commit(&MPIU_COMPLEX);CHKERRQ(ierr);
447   ierr = MPI_Op_create(PetscSum_Local,1,&PetscSum_Op);CHKERRQ(ierr);
448 #endif
449 
450   /*
451      Create the PETSc MPI reduction operator that sums of the first
452      half of the entries and maxes the second half.
453   */
454   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
455 
456   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
457   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
458   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
459   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
460 
461   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
462   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
463 
464   /*
465      Build the options database and check for user setup requests
466   */
467   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
468 
469   /*
470      Print main application help message
471   */
472   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
473   if (help && flg) {
474     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
475   }
476   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
477 
478   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
479 #if defined(PETSC_USE_LOG)
480   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
481 #endif
482 
483   /*
484      Load the dynamic libraries (on machines that support them), this registers all
485      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
486   */
487   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
488 
489   /*
490      Initialize all the default viewers
491   */
492   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
493   ierr = PetscVerboseInfo((0,"PetscInitialize:PETSc successfully started: number of processors = %d\n",size));CHKERRQ(ierr);
494   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
495   ierr = PetscVerboseInfo((0,"PetscInitialize:Running on machine: %s\n",hostname));CHKERRQ(ierr);
496 
497   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
498 
499   PetscFunctionReturn(ierr);
500 }
501 
502 
503 #undef __FUNCT__
504 #define __FUNCT__ "PetscFinalize"
505 /*@C
506    PetscFinalize - Checks for options to be called at the conclusion
507    of the program. MPI_Finalize() is called only if the user had not
508    called MPI_Init() before calling PetscInitialize().
509 
510    Collective on PETSC_COMM_WORLD
511 
512    Options Database Keys:
513 +  -options_table - Calls PetscOptionsPrint()
514 .  -options_left - Prints unused options that remain in the database
515 .  -options_left no - Does not print unused options that remain in the database
516 .  -mpidump - Calls PetscMPIDump()
517 .  -malloc_dump - Calls PetscMallocDump()
518 .  -malloc_info - Prints total memory usage
519 .  -malloc_debug - Calls PetscMallocDebug(), checks allocated memory for corruption while running
520 -  -malloc_log - Prints summary of memory usage
521 
522    Options Database Keys for Profiling:
523    See the Profiling chapter of the users manual for details.
524 +  -log_summary [filename] - Prints summary of flop and timing
525         information to screen. If the filename is specified the
526         summary is written to the file. (for code compiled with
527         PETSC_USE_LOG).  See PetscLogPrintSummary().
528 .  -log_all [filename] - Logs extensive profiling information
529         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
530 .  -log [filename] - Logs basic profiline information (for
531         code compiled with PETSC_USE_LOG).  See PetscLogDump().
532 .  -log_sync - Log the synchronization in scatters, inner products
533         and norms
534 -  -log_mpe [filename] - Creates a logfile viewable by the
535       utility Upshot/Nupshot (in MPICH distribution)
536 
537    Level: beginner
538 
539    Note:
540    See PetscInitialize() for more general runtime options.
541 
542 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
543 @*/
544 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
545 {
546   PetscErrorCode ierr;
547   PetscMPIInt    rank;
548   int            nopt;
549   PetscTruth     flg1,flg2,flg3;
550 
551   PetscFunctionBegin;
552 
553   if (!PetscInitializeCalled) {
554     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
555     PetscFunctionReturn(0);
556   }
557 
558   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
559   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_info",&flg2);CHKERRQ(ierr);
560   if (!flg2) {
561     ierr = PetscOptionsHasName(PETSC_NULL,"-memory_info",&flg2);CHKERRQ(ierr);
562   }
563   if (flg2) {
564     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
565   }
566 
567   /* Destroy auxiliary packages */
568 #if defined(PETSC_HAVE_MATHEMATICA)
569   ierr = PetscViewerMathematicaFinalizePackage();CHKERRQ(ierr);
570 #endif
571 
572   /*
573      Destroy all the function registration lists created
574   */
575   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
576 
577 #if defined(PETSC_USE_LOG)
578   ierr = PetscOptionsHasName(PETSC_NULL,"-get_total_flops",&flg1);CHKERRQ(ierr);
579   if (flg1) {
580     PetscLogDouble flops = 0;
581     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
582     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
583   }
584 #endif
585 
586   /*
587      Free all objects registered with PetscObjectRegisterDestroy() such ast
588     PETSC_VIEWER_XXX_().
589   */
590   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
591 
592 #if defined(PETSC_USE_DEBUG)
593   if (PetscStackActive) {
594     ierr = PetscStackDestroy();CHKERRQ(ierr);
595   }
596 #endif
597 
598 #if defined(PETSC_USE_LOG)
599   {
600     char mname[PETSC_MAX_PATH_LEN];
601 #if defined(PETSC_HAVE_MPE)
602     mname[0] = 0;
603     ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
604     if (flg1){
605       if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
606       else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
607     }
608 #endif
609     mname[0] = 0;
610     ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
611     if (flg1) {
612       if (mname[0])  {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
613       else           {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
614     }
615 
616     mname[0] = 0;
617     ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
618     ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
619     if (flg1 || flg2){
620       if (mname[0]) PetscLogDump(mname);
621       else          PetscLogDump(0);
622     }
623     ierr = PetscLogDestroy();CHKERRQ(ierr);
624   }
625 #endif
626   ierr = PetscOptionsHasName(PETSC_NULL,"-no_signal_handler",&flg1);CHKERRQ(ierr);
627   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
628   ierr = PetscOptionsHasName(PETSC_NULL,"-mpidump",&flg1);CHKERRQ(ierr);
629   if (flg1) {
630     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
631   }
632   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
633   ierr = PetscOptionsHasName(PETSC_NULL,"-options_table",&flg2);CHKERRQ(ierr);
634   if (flg2) {
635     if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);}
636   }
637 
638   /* to prevent PETSc -options_left from warning */
639   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
640   ierr = PetscOptionsHasName(PETSC_NULL,"-error_output_stderr",&flg1);CHKERRQ(ierr);
641 
642   flg3 = PETSC_FALSE;
643   ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,PETSC_NULL);CHKERRQ(ierr);
644   ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
645   if (flg3) {
646     if (!flg2) { /* have not yet printed the options */
647       ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);
648     }
649     if (!nopt) {
650       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
651     } else if (nopt == 1) {
652       ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
653     } else {
654       ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
655     }
656   }
657 #if defined(PETSC_USE_DEBUG)
658   if (nopt && !flg3) {
659     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
660     ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
661     ierr = PetscOptionsLeft();CHKERRQ(ierr);
662   } else if (nopt && flg3) {
663 #else
664   if (nopt && flg3) {
665 #endif
666     ierr = PetscOptionsLeft();CHKERRQ(ierr);
667   }
668 
669   ierr = PetscOptionsHasName(PETSC_NULL,"-log_history",&flg1);CHKERRQ(ierr);
670   if (flg1) {
671     ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
672     petsc_history = 0;
673   }
674 
675   ierr = PetscVerboseInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
676 
677   /*
678        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
679   */
680   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
681 
682   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
683   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log",&flg3);CHKERRQ(ierr);
684   if (flg1) {
685     char fname[PETSC_MAX_PATH_LEN];
686     FILE *fd;
687 
688     fname[0] = 0;
689     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
690     if (flg1 && fname[0]) {
691       char sname[PETSC_MAX_PATH_LEN];
692 
693       sprintf(sname,"%s_%d",fname,rank);
694       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
695       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
696       fclose(fd);
697     } else {
698       MPI_Comm local_comm;
699 
700       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
701       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
702         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
703       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
704       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
705     }
706   }
707   if (flg3) {
708     char fname[PETSC_MAX_PATH_LEN];
709     FILE *fd;
710 
711     fname[0] = 0;
712     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
713     if (flg1 && fname[0]) {
714       char sname[PETSC_MAX_PATH_LEN];
715 
716       sprintf(sname,"%s_%d",fname,rank);
717       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
718       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
719       fclose(fd);
720     } else {
721       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
722     }
723   }
724   /* Can be destroyed only after all the options are used */
725   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
726 
727   PetscGlobalArgc = 0;
728   PetscGlobalArgs = 0;
729 
730 #if defined(PETSC_USE_COMPLEX)
731   ierr = MPI_Op_free(&PetscSum_Op);CHKERRQ(ierr);
732   ierr = MPI_Type_free(&MPIU_COMPLEX);CHKERRQ(ierr);
733 #endif
734   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
735   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
736   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
737   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
738   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
739 
740   ierr = PetscVerboseInfo((0,"PetscFinalize:PETSc successfully ended!\n"));CHKERRQ(ierr);
741   if (PetscBeganMPI) {
742     ierr = MPI_Finalize();CHKERRQ(ierr);
743   }
744 
745 /*
746 
747      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
748    the communicator has some outstanding requests on it. Specifically if the
749    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
750    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
751    is never freed as it should be. Thus one may obtain messages of the form
752    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
753    memory was not freed.
754 
755 */
756   ierr = PetscClearMalloc();CHKERRQ(ierr);
757   PetscInitializeCalled = PETSC_FALSE;
758   PetscFinalizeCalled   = PETSC_TRUE;
759   PetscFunctionReturn(ierr);
760 }
761 
762 /*
763      These may be used in code that ADIC is to be used on
764 */
765 
766 #undef __FUNCT__
767 #define __FUNCT__ "PetscGlobalMax"
768 /*@C
769       PetscGlobalMax - Computes the maximum value over several processors
770 
771      Collective on MPI_Comm
772 
773    Input Parameters:
774 +   local - the local value
775 -   comm - the processors that find the maximum
776 
777    Output Parameter:
778 .   result - the maximum value
779 
780    Level: intermediate
781 
782    Notes:
783      These functions are to be used inside user functions that are to be processed with
784    ADIC. PETSc will automatically provide differentiated versions of these functions
785 
786 .seealso: PetscGlobalMin(), PetscGlobalSum()
787 @*/
788 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal* local,PetscReal* result,MPI_Comm comm)
789 {
790   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MAX,comm);
791 }
792 
793 #undef __FUNCT__
794 #define __FUNCT__ "PetscGlobalMin"
795 /*@C
796       PetscGlobalMin - Computes the minimum value over several processors
797 
798      Collective on MPI_Comm
799 
800    Input Parameters:
801 +   local - the local value
802 -   comm - the processors that find the minimum
803 
804    Output Parameter:
805 .   result - the minimum value
806 
807    Level: intermediate
808 
809    Notes:
810      These functions are to be used inside user functions that are to be processed with
811    ADIC. PETSc will automatically provide differentiated versions of these functions
812 
813 .seealso: PetscGlobalMax(), PetscGlobalSum()
814 @*/
815 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal* local,PetscReal* result,MPI_Comm comm)
816 {
817   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MIN,comm);
818 }
819 
820 #undef __FUNCT__
821 #define __FUNCT__ "PetscGlobalSum"
822 /*@C
823       PetscGlobalSum - Computes the sum over sever processors
824 
825      Collective on MPI_Comm
826 
827    Input Parameters:
828 +   local - the local value
829 -   comm - the processors that find the sum
830 
831    Output Parameter:
832 .   result - the sum
833 
834    Level: intermediate
835 
836    Notes:
837      These functions are to be used inside user functions that are to be processed with
838    ADIC. PETSc will automatically provide differentiated versions of these functions
839 
840 .seealso: PetscGlobalMin(), PetscGlobalMax()
841 @*/
842 PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar* local,PetscScalar* result,MPI_Comm comm)
843 {
844   return MPI_Allreduce(local,result,1,MPIU_SCALAR,PetscSum_Op,comm);
845 }
846 
847 
848