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