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