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