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