xref: /petsc/src/sys/objects/pinit.c (revision 289f3aa11b3ac459c99a6895ea3b9e0a0e6ded3a)
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 extern PetscTruth PetscOpenMPWorker;
13 
14 /* -----------------------------------------------------------------------------------------*/
15 
16 extern FILE *petsc_history;
17 
18 EXTERN PetscErrorCode PetscInitialize_DynamicLibraries(void);
19 EXTERN PetscErrorCode PetscFinalize_DynamicLibraries(void);
20 EXTERN PetscErrorCode PetscFListDestroyAll(void);
21 EXTERN PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
22 EXTERN PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
23 EXTERN PetscErrorCode PetscLogCloseHistoryFile(FILE **);
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 = MPI_COMM_NULL;
30 
31 PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
32 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
33 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
34 
35 /*
36      Declare and set all the string names of the PETSc enums
37 */
38 const char *PetscTruths[]    = {"FALSE","TRUE","PetscTruth","PETSC_",0};
39 const char *PetscDataTypes[] = {"INT", "DOUBLE", "COMPLEX",
40                                 "LONG","SHORT",  "FLOAT",
41                                 "CHAR","LOGICAL","ENUM","TRUTH","LONGDOUBLE","PetscDataType","PETSC_",0};
42 
43 PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
44 PetscTruth PetscPreLoadingOn   = PETSC_FALSE;
45 
46 /*
47        Checks the options database for initializations related to the
48     PETSc components
49 */
50 #undef __FUNCT__
51 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
52 PetscErrorCode PETSC_DLLEXPORT PetscOptionsCheckInitial_Components(void)
53 {
54   PetscTruth flg1;
55   PetscErrorCode ierr;
56 
57   PetscFunctionBegin;
58   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr);
59   if (flg1) {
60 #if defined (PETSC_USE_LOG)
61     MPI_Comm   comm = PETSC_COMM_WORLD;
62     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
63     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
64     ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
65     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
66 #endif
67   }
68   PetscFunctionReturn(0);
69 }
70 
71 #undef __FUNCT__
72 #define __FUNCT__ "PetscInitializeNoArguments"
73 /*@C
74       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
75         the command line arguments.
76 
77    Collective
78 
79    Level: advanced
80 
81 .seealso: PetscInitialize(), PetscInitializeFortran()
82 @*/
83 PetscErrorCode PETSC_DLLEXPORT PetscInitializeNoArguments(void)
84 {
85   PetscErrorCode ierr;
86   int            argc = 0;
87   char           **args = 0;
88 
89   PetscFunctionBegin;
90   ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
91   PetscFunctionReturn(ierr);
92 }
93 
94 #undef __FUNCT__
95 #define __FUNCT__ "PetscInitialized"
96 /*@
97       PetscInitialized - Determine whether PETSc is initialized.
98 
99 7   Level: beginner
100 
101 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
102 @*/
103 PetscErrorCode PETSC_DLLEXPORT PetscInitialized(PetscTruth *isInitialized)
104 {
105   PetscFunctionBegin;
106   PetscValidPointer(isInitialized, 1);
107   *isInitialized = PetscInitializeCalled;
108   PetscFunctionReturn(0);
109 }
110 
111 #undef __FUNCT__
112 #define __FUNCT__ "PetscFinalized"
113 /*@
114       PetscFinalized - Determine whether PetscFinalize() has been called yet
115 
116    Level: developer
117 
118 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
119 @*/
120 PetscErrorCode PETSC_DLLEXPORT PetscFinalized(PetscTruth *isFinalized)
121 {
122   PetscFunctionBegin;
123   PetscValidPointer(isFinalized, 1);
124   *isFinalized = PetscFinalizeCalled;
125   PetscFunctionReturn(0);
126 }
127 
128 EXTERN PetscErrorCode        PetscOptionsCheckInitial_Private(void);
129 extern PetscTruth PetscBeganMPI;
130 
131 /*
132        This function is the MPI reduction operation used to compute the sum of the
133    first half of the datatype and the max of the second half.
134 */
135 MPI_Op PetscMaxSum_Op = 0;
136 
137 EXTERN_C_BEGIN
138 #undef __FUNCT__
139 #define __FUNCT__ "PetscMaxSum_Local"
140 void PETSC_DLLEXPORT MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
141 {
142   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
143 
144   PetscFunctionBegin;
145   if (*datatype != MPIU_2INT) {
146     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
147     MPI_Abort(MPI_COMM_WORLD,1);
148   }
149 
150   for (i=0; i<count; i++) {
151     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
152     xout[2*i+1] += xin[2*i+1];
153   }
154   PetscStackPop;
155   return;
156 }
157 EXTERN_C_END
158 
159 /*
160     Returns the max of the first entry owned by this processor and the
161 sum of the second entry.
162 
163     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
164 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
165 there would be no place to store the both needed results.
166 */
167 #undef __FUNCT__
168 #define __FUNCT__ "PetscMaxSum"
169 PetscErrorCode PETSC_DLLEXPORT PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
170 {
171   PetscMPIInt    size,rank;
172   PetscInt       *work;
173   PetscErrorCode ierr;
174 
175   PetscFunctionBegin;
176   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
177   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
178   ierr   = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
179   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
180   *max   = work[2*rank];
181   *sum   = work[2*rank+1];
182   ierr   = PetscFree(work);CHKERRQ(ierr);
183   PetscFunctionReturn(0);
184 }
185 
186 /* ----------------------------------------------------------------------------*/
187 MPI_Op PETSC_DLLEXPORT PetscADMax_Op = 0;
188 
189 EXTERN_C_BEGIN
190 #undef __FUNCT__
191 #define __FUNCT__ "PetscADMax_Local"
192 void PETSC_DLLEXPORT MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
193 {
194   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
195   PetscInt    i,count = *cnt;
196 
197   PetscFunctionBegin;
198   if (*datatype != MPIU_2SCALAR) {
199     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
200     MPI_Abort(MPI_COMM_WORLD,1);
201   }
202 
203   for (i=0; i<count; i++) {
204     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
205       xout[2*i]   = xin[2*i];
206       xout[2*i+1] = xin[2*i+1];
207     }
208   }
209 
210   PetscStackPop;
211   return;
212 }
213 EXTERN_C_END
214 
215 MPI_Op PETSC_DLLEXPORT PetscADMin_Op = 0;
216 
217 EXTERN_C_BEGIN
218 #undef __FUNCT__
219 #define __FUNCT__ "PetscADMin_Local"
220 void PETSC_DLLEXPORT MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
221 {
222   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
223   PetscInt    i,count = *cnt;
224 
225   PetscFunctionBegin;
226   if (*datatype != MPIU_2SCALAR) {
227     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
228     MPI_Abort(MPI_COMM_WORLD,1);
229   }
230 
231   for (i=0; i<count; i++) {
232     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
233       xout[2*i]   = xin[2*i];
234       xout[2*i+1] = xin[2*i+1];
235     }
236   }
237 
238   PetscStackPop;
239   return;
240 }
241 EXTERN_C_END
242 /* ---------------------------------------------------------------------------------------*/
243 
244 #if defined(PETSC_USE_COMPLEX)
245 
246 /*
247     This operation is only needed when using complex numbers with older MPI that does not support complex numbers
248 */
249 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
250 MPI_Op MPIU_SUM = 0;
251 
252 EXTERN_C_BEGIN
253 #undef __FUNCT__
254 #define __FUNCT__ "PetscSum_Local"
255 void PETSC_DLLEXPORT PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
256 {
257   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
258   PetscInt    i,count = *cnt;
259 
260   PetscFunctionBegin;
261   if (*datatype != MPIU_SCALAR) {
262     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
263     MPI_Abort(MPI_COMM_WORLD,1);
264   }
265 
266   for (i=0; i<count; i++) {
267     xout[i] += xin[i];
268   }
269 
270   PetscStackPop;
271   return;
272 }
273 EXTERN_C_END
274 #endif
275 #endif
276 
277 EXTERN_C_BEGIN
278 #undef __FUNCT__
279 #define __FUNCT__ "Petsc_DelCounter"
280 /*
281    Private routine to delete internal tag/name counter storage when a communicator is freed.
282 
283    This is called by MPI, not by users.
284 
285    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
286 
287 */
288 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
289 {
290   PetscErrorCode ierr;
291 
292   PetscFunctionBegin;
293   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
294   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
295   PetscFunctionReturn(MPI_SUCCESS);
296 }
297 EXTERN_C_END
298 
299 EXTERN_C_BEGIN
300 #undef __FUNCT__
301 #define __FUNCT__ "Petsc_DelComm"
302 /*
303   This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the
304   the external MPI_Comm drops its reference to the internal MPI_Comm
305 
306   This is called by MPI, not by users.
307 
308   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
309 
310 */
311 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
312 {
313   PetscErrorCode ierr;
314 
315   PetscFunctionBegin;
316   ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
317   /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */
318   PetscFunctionReturn(MPI_SUCCESS);
319 }
320 EXTERN_C_END
321 
322 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
323 #if !defined(PETSC_WORDS_BIGENDIAN)
324 EXTERN_C_BEGIN
325 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
326 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
327 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
328 EXTERN_C_END
329 #endif
330 #endif
331 
332 int  PetscGlobalArgc   = 0;
333 char **PetscGlobalArgs = 0;
334 
335 #undef __FUNCT__
336 #define __FUNCT__ "PetscGetArgs"
337 /*@C
338    PetscGetArgs - Allows you to access the raw command line arguments anywhere
339      after PetscInitialize() is called but before PetscFinalize().
340 
341    Not Collective
342 
343    Output Parameters:
344 +  argc - count of number of command line arguments
345 -  args - the command line arguments
346 
347    Level: intermediate
348 
349    Notes:
350       This is usually used to pass the command line arguments into other libraries
351    that are called internally deep in PETSc or the application.
352 
353    Concepts: command line arguments
354 
355 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
356 
357 @*/
358 PetscErrorCode PETSC_DLLEXPORT PetscGetArgs(int *argc,char ***args)
359 {
360   PetscFunctionBegin;
361   if (!PetscInitializeCalled && PetscFinalizeCalled) {
362     SETERRQ(PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
363   }
364   *argc = PetscGlobalArgc;
365   *args = PetscGlobalArgs;
366   PetscFunctionReturn(0);
367 }
368 
369 #undef __FUNCT__
370 #define __FUNCT__ "PetscGetArguments"
371 /*@C
372    PetscGetArguments - Allows you to access the  command line arguments anywhere
373      after PetscInitialize() is called but before PetscFinalize().
374 
375    Not Collective
376 
377    Output Parameters:
378 .  args - the command line arguments
379 
380    Level: intermediate
381 
382    Notes:
383       This does NOT start with the program name and IS null terminated (final arg is void)
384 
385    Concepts: command line arguments
386 
387 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
388 
389 @*/
390 PetscErrorCode PETSC_DLLEXPORT PetscGetArguments(char ***args)
391 {
392   PetscInt       i,argc = PetscGlobalArgc;
393   PetscErrorCode ierr;
394 
395   PetscFunctionBegin;
396   if (!PetscInitializeCalled && PetscFinalizeCalled) {
397     SETERRQ(PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
398   }
399   if (!argc) {*args = 0; PetscFunctionReturn(0);}
400   ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr);
401   for (i=0; i<argc-1; i++) {
402     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
403   }
404   (*args)[argc-1] = 0;
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "PetscFreeArguments"
410 /*@C
411    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
412 
413    Not Collective
414 
415    Output Parameters:
416 .  args - the command line arguments
417 
418    Level: intermediate
419 
420    Concepts: command line arguments
421 
422 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
423 
424 @*/
425 PetscErrorCode PETSC_DLLEXPORT PetscFreeArguments(char **args)
426 {
427   PetscInt       i = 0;
428   PetscErrorCode ierr;
429 
430   PetscFunctionBegin;
431   if (!args) {PetscFunctionReturn(0);}
432   while (args[i]) {
433     ierr = PetscFree(args[i]);CHKERRQ(ierr);
434     i++;
435   }
436   ierr = PetscFree(args);CHKERRQ(ierr);
437   PetscFunctionReturn(0);
438 }
439 
440 #undef __FUNCT__
441 #define __FUNCT__ "PetscInitialize"
442 /*@C
443    PetscInitialize - Initializes the PETSc database and MPI.
444    PetscInitialize() calls MPI_Init() if that has yet to be called,
445    so this routine should always be called near the beginning of
446    your program -- usually the very first line!
447 
448    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
449 
450    Input Parameters:
451 +  argc - count of number of command line arguments
452 .  args - the command line arguments
453 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for
454           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
455 -  help - [optional] Help message to print, use PETSC_NULL for no message
456 
457    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
458    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
459    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
460    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
461    if different subcommunicators of the job are doing different things with PETSc.
462 
463    Options Database Keys:
464 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
465 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
466 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
467 .  -on_error_abort calls abort() when error detected (no traceback)
468 .  -on_error_mpiabort calls MPI_abort() when error detected
469 .  -error_output_stderr prints error messages to stderr instead of the default stdout
470 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
471 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
472 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
473 .  -stop_for_debugger - Print message on how to attach debugger manually to
474                         process and wait (-debugger_pause) seconds for attachment
475 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
476 .  -malloc no - Indicates not to use error-checking malloc
477 .  -malloc_debug - check for memory corruption at EVERY malloc or free
478 .  -fp_trap - Stops on floating point exceptions (Note that on the
479               IBM RS6000 this slows code by at least a factor of 10.)
480 .  -no_signal_handler - Indicates not to trap error signals
481 .  -shared_tmp - indicates /tmp directory is shared by all processors
482 .  -not_shared_tmp - each processor has own /tmp
483 .  -tmp - alternative name of /tmp directory
484 .  -get_total_flops - returns total flops done by all processors
485 -  -memory_info - Print memory usage at end of run
486 
487    Options Database Keys for Profiling:
488    See the Profiling chapter of the users manual for details.
489 +  -log_trace [filename] - Print traces of all PETSc calls
490         to the screen (useful to determine where a program
491         hangs without running in the debugger).  See PetscLogTraceBegin().
492 .  -info <optional filename> - Prints verbose information to the screen
493 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
494 
495    Environmental Variables:
496 +   PETSC_TMP - alternative tmp directory
497 .   PETSC_SHARED_TMP - tmp is shared by all processes
498 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
499 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
500 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
501 
502 
503    Level: beginner
504 
505    Notes:
506    If for some reason you must call MPI_Init() separately, call
507    it before PetscInitialize().
508 
509    Fortran Version:
510    In Fortran this routine has the format
511 $       call PetscInitialize(file,ierr)
512 
513 +   ierr - error return code
514 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
515           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
516 
517    Important Fortran Note:
518    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
519    null character string; you CANNOT just use PETSC_NULL as
520    in the C version.  See the users manual for details.
521 
522 
523    Concepts: initializing PETSc
524 
525 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs()
526 
527 @*/
528 PetscErrorCode PETSC_DLLEXPORT PetscInitialize(int *argc,char ***args,const char file[],const char help[])
529 {
530   PetscErrorCode ierr;
531   PetscMPIInt    flag, size;
532   PetscInt       nodesize;
533   PetscTruth     flg;
534   char           hostname[256];
535 
536   PetscFunctionBegin;
537   if (PetscInitializeCalled) PetscFunctionReturn(0);
538 
539   /* these must be initialized in a routine, not as a constant declaration*/
540   PETSC_STDOUT = stdout;
541   PETSC_STDERR = stderr;
542 
543   ierr = PetscOptionsCreate();CHKERRQ(ierr);
544 
545   /*
546      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
547      it that it sets args[0] on all processors to be args[0] on the first processor.
548   */
549   if (argc && *argc) {
550     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
551   } else {
552     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
553   }
554 
555   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
556   if (!flag) {
557     if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
558     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
559     PetscBeganMPI = PETSC_TRUE;
560   }
561   if (argc && args) {
562     PetscGlobalArgc = *argc;
563     PetscGlobalArgs = *args;
564   }
565   PetscInitializeCalled = PETSC_TRUE;
566   PetscFinalizeCalled   = PETSC_FALSE;
567 
568   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
569     PETSC_COMM_WORLD = MPI_COMM_WORLD;
570   }
571 
572   /* Done after init due to a bug in MPICH-GM? */
573   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
574 
575   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
576   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
577 
578 #if defined(PETSC_USE_COMPLEX)
579   /*
580      Initialized the global complex variable; this is because with
581      shared libraries the constructors for global variables
582      are not called; at least on IRIX.
583   */
584   {
585 #if defined(PETSC_CLANGUAGE_CXX)
586     PetscScalar ic(0.0,1.0);
587     PETSC_i = ic;
588 #else
589     PETSC_i = I;
590 #endif
591   }
592 
593 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
594   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
595   ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
596   ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPI_C_COMPLEX);CHKERRQ(ierr);
597   ierr = MPI_Type_commit(&MPI_C_COMPLEX);CHKERRQ(ierr);
598   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
599 #endif
600 #endif
601 
602   /*
603      Create the PETSc MPI reduction operator that sums of the first
604      half of the entries and maxes the second half.
605   */
606   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
607 
608   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
609   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
610   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
611   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
612 
613   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
614   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
615 
616   /*
617      Attributes to be set on PETSc communicators
618   */
619   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
620   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
621   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
622 
623   /*
624      Build the options database
625   */
626   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
627 
628 
629   /*
630      Print main application help message
631   */
632   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
633   if (help && flg) {
634     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
635   }
636   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
637 
638   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
639 #if defined(PETSC_USE_LOG)
640   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
641 #endif
642 
643   /*
644      Load the dynamic libraries (on machines that support them), this registers all
645      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
646   */
647   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
648 
649   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
650   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
651   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
652   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
653 
654   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
655   /* Check the options database for options related to the options database itself */
656   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
657 
658 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
659   /*
660       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
661 
662       Currently not used because it is not supported by MPICH.
663   */
664 #if !defined(PETSC_WORDS_BIGENDIAN)
665   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
666 #endif
667 #endif
668 
669   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
670   if (flg) {
671 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
672     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
673 #else
674     SETERRQ(PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
675 #endif
676   } else {
677     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
678     if (flg) {
679       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
680       if (PetscOpenMPWorker) { /* if worker then never enter user code */
681         ierr = PetscEnd();
682       }
683     }
684   }
685   flg  = PETSC_FALSE;
686   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg,PETSC_NULL);CHKERRQ(ierr);
687   if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
688 
689   PetscFunctionReturn(ierr);
690 }
691 
692 
693 #undef __FUNCT__
694 #define __FUNCT__ "PetscFinalize"
695 /*@C
696    PetscFinalize - Checks for options to be called at the conclusion
697    of the program. MPI_Finalize() is called only if the user had not
698    called MPI_Init() before calling PetscInitialize().
699 
700    Collective on PETSC_COMM_WORLD
701 
702    Options Database Keys:
703 +  -options_table - Calls PetscOptionsPrint()
704 .  -options_left - Prints unused options that remain in the database
705 .  -options_left no - Does not print unused options that remain in the database
706 .  -mpidump - Calls PetscMPIDump()
707 .  -malloc_dump - Calls PetscMallocDump()
708 .  -malloc_info - Prints total memory usage
709 -  -malloc_log - Prints summary of memory usage
710 
711    Options Database Keys for Profiling:
712    See the Profiling chapter of the users manual for details.
713 +  -log_summary [filename] - Prints summary of flop and timing
714         information to screen. If the filename is specified the
715         summary is written to the file. (for code compiled with
716         PETSC_USE_LOG).  See PetscLogPrintSummary().
717 .  -log_all [filename] - Logs extensive profiling information
718         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
719 .  -log [filename] - Logs basic profiline information (for
720         code compiled with PETSC_USE_LOG).  See PetscLogDump().
721 .  -log_sync - Log the synchronization in scatters, inner products
722         and norms
723 -  -log_mpe [filename] - Creates a logfile viewable by the
724       utility Upshot/Nupshot (in MPICH distribution)
725 
726    Level: beginner
727 
728    Note:
729    See PetscInitialize() for more general runtime options.
730 
731 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
732 @*/
733 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
734 {
735   PetscErrorCode ierr;
736   PetscMPIInt    rank;
737   int            nopt;
738   PetscTruth     flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
739   extern FILE   *PETSC_ZOPEFD;
740 
741   PetscFunctionBegin;
742 
743   if (!PetscInitializeCalled) {
744     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
745     PetscFunctionReturn(0);
746   }
747   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
748 
749   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
750 
751   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg1,PETSC_NULL);CHKERRQ(ierr);
752   if (flg1) {ierr = PetscPythonFinalize();CHKERRQ(ierr);}
753 
754   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
755   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
756   if (!flg2) {
757     flg2 = PETSC_FALSE;
758     ierr = PetscOptionsGetTruth(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
759   }
760   if (flg2) {
761     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
762   }
763 
764   /*
765      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
766   */
767   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
768 
769   /*
770        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
771   */
772   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
773 
774   /*
775      Destroy any packages that registered a finalize
776   */
777   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
778 
779   /*
780      Destroy all the function registration lists created
781   */
782   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
783 
784 #if defined(PETSC_USE_LOG)
785   flg1 = PETSC_FALSE;
786   ierr = PetscOptionsGetTruth(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
787   if (flg1) {
788     PetscLogDouble flops = 0;
789     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
790     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
791   }
792 #endif
793 
794 #if defined(PETSC_USE_DEBUG)
795   if (PetscStackActive) {
796     ierr = PetscStackDestroy();CHKERRQ(ierr);
797   }
798 #endif
799 
800 #if defined(PETSC_USE_LOG)
801   {
802     char mname[PETSC_MAX_PATH_LEN];
803 #if defined(PETSC_HAVE_MPE)
804     mname[0] = 0;
805     ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
806     if (flg1){
807       if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
808       else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
809     }
810 #endif
811     mname[0] = 0;
812     ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
813     if (flg1) {
814       if (mname[0])  {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
815       else           {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
816     }
817 
818     ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
819     if (flg1) {
820       if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
821       else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
822     }
823 
824     mname[0] = 0;
825     ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
826     ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
827     if (flg1 || flg2){
828       if (mname[0]) PetscLogDump(mname);
829       else          PetscLogDump(0);
830     }
831     ierr = PetscLogDestroy();CHKERRQ(ierr);
832   }
833 #endif
834   flg1 = PETSC_FALSE;
835   ierr = PetscOptionsGetTruth(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
836   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
837   flg1 = PETSC_FALSE;
838   ierr = PetscOptionsGetTruth(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
839   if (flg1) {
840     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
841   }
842   flg1 = PETSC_FALSE;
843   flg2 = PETSC_FALSE;
844   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
845   ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
846   if (flg2) {
847     if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);}
848   }
849 
850   /* to prevent PETSc -options_left from warning */
851   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr)
852   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
853 
854   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
855     flg3 = PETSC_FALSE; /* default value is required */
856     ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
857     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
858     if (flg3) {
859       if (!flg2) { /* have not yet printed the options */
860 	ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);
861       }
862       if (!nopt) {
863 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
864       } else if (nopt == 1) {
865 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
866       } else {
867 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
868       }
869     }
870 #if defined(PETSC_USE_DEBUG)
871     if (nopt && !flg3 && !flg1) {
872       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
873       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
874       ierr = PetscOptionsLeft();CHKERRQ(ierr);
875     } else if (nopt && flg3) {
876 #else
877     if (nopt && flg3) {
878 #endif
879       ierr = PetscOptionsLeft();CHKERRQ(ierr);
880     }
881   }
882 
883   flg1 = PETSC_FALSE;
884   ierr = PetscOptionsGetTruth(PETSC_NULL,"-log_history",&flg1,PETSC_NULL);CHKERRQ(ierr);
885   if (flg1) {
886     ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
887     petsc_history = 0;
888   }
889 
890   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
891 
892   flg1 = PETSC_FALSE;
893   flg3 = PETSC_FALSE;
894   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
895   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg3,PETSC_NULL);CHKERRQ(ierr);
896   if (flg1) {
897     char fname[PETSC_MAX_PATH_LEN];
898     FILE *fd;
899     int  err;
900 
901     fname[0] = 0;
902     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
903     if (flg1 && fname[0]) {
904       char sname[PETSC_MAX_PATH_LEN];
905 
906       sprintf(sname,"%s_%d",fname,rank);
907       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
908       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
909       err = fclose(fd);
910       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
911     } else {
912       MPI_Comm local_comm;
913 
914       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
915       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
916         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
917       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
918       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
919     }
920   }
921   if (flg3) {
922     char fname[PETSC_MAX_PATH_LEN];
923     FILE *fd;
924 
925     fname[0] = 0;
926     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
927     if (flg1 && fname[0]) {
928       char sname[PETSC_MAX_PATH_LEN];
929       int  err;
930 
931       sprintf(sname,"%s_%d",fname,rank);
932       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
933       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
934       err = fclose(fd);
935       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
936     } else {
937       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
938     }
939   }
940   /* Can be destroyed only after all the options are used */
941   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
942 
943   PetscGlobalArgc = 0;
944   PetscGlobalArgs = 0;
945 
946 #if defined(PETSC_USE_COMPLEX)
947 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
948   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
949   ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
950   ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr);
951 #endif
952 #endif
953   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
954   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
955   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
956   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
957   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
958 
959   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
960   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
961   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
962 
963   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
964   if (PetscBeganMPI) {
965 #if defined(PETSC_HAVE_MPI_FINALIZED)
966     PetscMPIInt flag;
967     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
968     if (flag) SETERRQ(PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
969 #endif
970     ierr = MPI_Finalize();CHKERRQ(ierr);
971   }
972 
973   if(PETSC_ZOPEFD != NULL){
974     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
975     else fprintf(PETSC_STDOUT, "<<<end>>>");}
976 
977 /*
978 
979      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
980    the communicator has some outstanding requests on it. Specifically if the
981    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
982    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
983    is never freed as it should be. Thus one may obtain messages of the form
984    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
985    memory was not freed.
986 
987 */
988   ierr = PetscMallocClear();CHKERRQ(ierr);
989   PetscInitializeCalled = PETSC_FALSE;
990   PetscFinalizeCalled   = PETSC_TRUE;
991   PetscFunctionReturn(ierr);
992 }
993 
994 /*
995      These may be used in code that ADIC is to be used on
996 */
997 
998 #undef __FUNCT__
999 #define __FUNCT__ "PetscGlobalMax"
1000 /*@
1001       PetscGlobalMax - Computes the maximum value over several processors
1002 
1003      Collective on MPI_Comm
1004 
1005    Input Parameters:
1006 +   local - the local value
1007 -   comm - the processors that find the maximum
1008 
1009    Output Parameter:
1010 .   result - the maximum value
1011 
1012    Level: intermediate
1013 
1014    Notes:
1015      These functions are to be used inside user functions that are to be processed with
1016    ADIC. PETSc will automatically provide differentiated versions of these functions
1017 
1018 .seealso: PetscGlobalMin(), PetscGlobalSum()
1019 @*/
1020 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal* local,PetscReal* result,MPI_Comm comm)
1021 {
1022   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MAX,comm);
1023 }
1024 
1025 #undef __FUNCT__
1026 #define __FUNCT__ "PetscGlobalMin"
1027 /*@
1028       PetscGlobalMin - Computes the minimum value over several processors
1029 
1030      Collective on MPI_Comm
1031 
1032    Input Parameters:
1033 +   local - the local value
1034 -   comm - the processors that find the minimum
1035 
1036    Output Parameter:
1037 .   result - the minimum value
1038 
1039    Level: intermediate
1040 
1041    Notes:
1042      These functions are to be used inside user functions that are to be processed with
1043    ADIC. PETSc will automatically provide differentiated versions of these functions
1044 
1045 .seealso: PetscGlobalMax(), PetscGlobalSum()
1046 @*/
1047 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal* local,PetscReal* result,MPI_Comm comm)
1048 {
1049   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MIN,comm);
1050 }
1051 
1052 #undef __FUNCT__
1053 #define __FUNCT__ "PetscGlobalSum"
1054 /*@
1055       PetscGlobalSum - Computes the sum over sever processors
1056 
1057      Collective on MPI_Comm
1058 
1059    Input Parameters:
1060 +   local - the local value
1061 -   comm - the processors that find the sum
1062 
1063    Output Parameter:
1064 .   result - the sum
1065 
1066    Level: intermediate
1067 
1068    Notes:
1069      These functions are to be used inside user functions that are to be processed with
1070    ADIC. PETSc will automatically provide differentiated versions of these functions
1071 
1072 .seealso: PetscGlobalMin(), PetscGlobalMax()
1073 @*/
1074 PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar* local,PetscScalar* result,MPI_Comm comm)
1075 {
1076   return MPI_Allreduce(local,result,1,MPIU_SCALAR,MPIU_SUM,comm);
1077 }
1078 
1079 
1080