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