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