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