xref: /petsc/src/sys/objects/pinit.c (revision b3b5d266a9a22787e7e02b6a7b014debf5b06993)
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 EXTERN PetscErrorCode PetscOptionsHelpDestroyList(void);
25 
26 /* this is used by the _, __, and ___ macros (see include/petscerror.h) */
27 PetscErrorCode __gierr = 0;
28 
29 /* user may set this BEFORE calling PetscInitialize() */
30 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;
31 
32 PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
33 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
34 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
35 
36 /*
37      Declare and set all the string names of the PETSc enums
38 */
39 const char *PetscTruths[]    = {"FALSE","TRUE","PetscTruth","PETSC_",0};
40 const char *PetscDataTypes[] = {"INT", "DOUBLE", "COMPLEX",
41                                 "LONG","SHORT",  "FLOAT",
42                                 "CHAR","LOGICAL","ENUM","TRUTH","LONGDOUBLE","PetscDataType","PETSC_",0};
43 
44 PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
45 PetscTruth PetscPreLoadingOn   = PETSC_FALSE;
46 
47 /*
48        Checks the options database for initializations related to the
49     PETSc components
50 */
51 #undef __FUNCT__
52 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
53 PetscErrorCode PETSC_DLLEXPORT PetscOptionsCheckInitial_Components(void)
54 {
55   PetscTruth flg1;
56   PetscErrorCode ierr;
57 
58   PetscFunctionBegin;
59   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr);
60   if (flg1) {
61 #if defined (PETSC_USE_LOG)
62     MPI_Comm   comm = PETSC_COMM_WORLD;
63     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
64     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
65     ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
66     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
67 #endif
68   }
69   PetscFunctionReturn(0);
70 }
71 
72 #undef __FUNCT__
73 #define __FUNCT__ "PetscInitializeNoArguments"
74 /*@C
75       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
76         the command line arguments.
77 
78    Collective
79 
80    Level: advanced
81 
82 .seealso: PetscInitialize(), PetscInitializeFortran()
83 @*/
84 PetscErrorCode PETSC_DLLEXPORT PetscInitializeNoArguments(void)
85 {
86   PetscErrorCode ierr;
87   int            argc = 0;
88   char           **args = 0;
89 
90   PetscFunctionBegin;
91   ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
92   PetscFunctionReturn(ierr);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "PetscInitialized"
97 /*@
98       PetscInitialized - Determine whether PETSc is initialized.
99 
100 7   Level: beginner
101 
102 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
103 @*/
104 PetscErrorCode PETSC_DLLEXPORT PetscInitialized(PetscTruth *isInitialized)
105 {
106   PetscFunctionBegin;
107   PetscValidPointer(isInitialized, 1);
108   *isInitialized = PetscInitializeCalled;
109   PetscFunctionReturn(0);
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PetscFinalized"
114 /*@
115       PetscFinalized - Determine whether PetscFinalize() has been called yet
116 
117    Level: developer
118 
119 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
120 @*/
121 PetscErrorCode PETSC_DLLEXPORT PetscFinalized(PetscTruth *isFinalized)
122 {
123   PetscFunctionBegin;
124   PetscValidPointer(isFinalized, 1);
125   *isFinalized = PetscFinalizeCalled;
126   PetscFunctionReturn(0);
127 }
128 
129 EXTERN PetscErrorCode        PetscOptionsCheckInitial_Private(void);
130 extern PetscTruth PetscBeganMPI;
131 
132 /*
133        This function is the MPI reduction operation used to compute the sum of the
134    first half of the datatype and the max of the second half.
135 */
136 MPI_Op PetscMaxSum_Op = 0;
137 
138 EXTERN_C_BEGIN
139 #undef __FUNCT__
140 #define __FUNCT__ "PetscMaxSum_Local"
141 void PETSC_DLLEXPORT MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
142 {
143   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
144 
145   PetscFunctionBegin;
146   if (*datatype != MPIU_2INT) {
147     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
148     MPI_Abort(MPI_COMM_WORLD,1);
149   }
150 
151   for (i=0; i<count; i++) {
152     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
153     xout[2*i+1] += xin[2*i+1];
154   }
155   PetscStackPop;
156   return;
157 }
158 EXTERN_C_END
159 
160 /*
161     Returns the max of the first entry owned by this processor and the
162 sum of the second entry.
163 
164     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
165 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
166 there would be no place to store the both needed results.
167 */
168 #undef __FUNCT__
169 #define __FUNCT__ "PetscMaxSum"
170 PetscErrorCode PETSC_DLLEXPORT PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
171 {
172   PetscMPIInt    size,rank;
173   PetscInt       *work;
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
178   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
179   ierr   = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
180   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
181   *max   = work[2*rank];
182   *sum   = work[2*rank+1];
183   ierr   = PetscFree(work);CHKERRQ(ierr);
184   PetscFunctionReturn(0);
185 }
186 
187 /* ----------------------------------------------------------------------------*/
188 MPI_Op PETSC_DLLEXPORT PetscADMax_Op = 0;
189 
190 EXTERN_C_BEGIN
191 #undef __FUNCT__
192 #define __FUNCT__ "PetscADMax_Local"
193 void PETSC_DLLEXPORT MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
194 {
195   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
196   PetscInt    i,count = *cnt;
197 
198   PetscFunctionBegin;
199   if (*datatype != MPIU_2SCALAR) {
200     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
201     MPI_Abort(MPI_COMM_WORLD,1);
202   }
203 
204   for (i=0; i<count; i++) {
205     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
206       xout[2*i]   = xin[2*i];
207       xout[2*i+1] = xin[2*i+1];
208     }
209   }
210 
211   PetscStackPop;
212   return;
213 }
214 EXTERN_C_END
215 
216 MPI_Op PETSC_DLLEXPORT PetscADMin_Op = 0;
217 
218 EXTERN_C_BEGIN
219 #undef __FUNCT__
220 #define __FUNCT__ "PetscADMin_Local"
221 void PETSC_DLLEXPORT MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
222 {
223   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
224   PetscInt    i,count = *cnt;
225 
226   PetscFunctionBegin;
227   if (*datatype != MPIU_2SCALAR) {
228     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
229     MPI_Abort(MPI_COMM_WORLD,1);
230   }
231 
232   for (i=0; i<count; i++) {
233     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
234       xout[2*i]   = xin[2*i];
235       xout[2*i+1] = xin[2*i+1];
236     }
237   }
238 
239   PetscStackPop;
240   return;
241 }
242 EXTERN_C_END
243 /* ---------------------------------------------------------------------------------------*/
244 
245 #if defined(PETSC_USE_COMPLEX)
246 
247 /*
248     This operation is only needed when using complex numbers with older MPI that does not support complex numbers
249 */
250 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
251 MPI_Op MPIU_SUM = 0;
252 
253 EXTERN_C_BEGIN
254 #undef __FUNCT__
255 #define __FUNCT__ "PetscSum_Local"
256 void PETSC_DLLEXPORT PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
257 {
258   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
259   PetscInt    i,count = *cnt;
260 
261   PetscFunctionBegin;
262   if (*datatype != MPIU_SCALAR) {
263     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
264     MPI_Abort(MPI_COMM_WORLD,1);
265   }
266 
267   for (i=0; i<count; i++) {
268     xout[i] += xin[i];
269   }
270 
271   PetscStackPop;
272   return;
273 }
274 EXTERN_C_END
275 #endif
276 #endif
277 
278 EXTERN_C_BEGIN
279 #undef __FUNCT__
280 #define __FUNCT__ "Petsc_DelCounter"
281 /*
282    Private routine to delete internal tag/name counter storage when a communicator is freed.
283 
284    This is called by MPI, not by users.
285 
286    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
287 
288 */
289 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
290 {
291   PetscErrorCode ierr;
292 
293   PetscFunctionBegin;
294   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
295   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
296   PetscFunctionReturn(MPI_SUCCESS);
297 }
298 EXTERN_C_END
299 
300 EXTERN_C_BEGIN
301 #undef __FUNCT__
302 #define __FUNCT__ "Petsc_DelComm"
303 /*
304   This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the
305   the external MPI_Comm drops its reference to the internal MPI_Comm
306 
307   This is called by MPI, not by users.
308 
309   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
310 
311 */
312 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
313 {
314   PetscErrorCode ierr;
315 
316   PetscFunctionBegin;
317   ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
318   /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */
319   PetscFunctionReturn(MPI_SUCCESS);
320 }
321 EXTERN_C_END
322 
323 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
324 #if !defined(PETSC_WORDS_BIGENDIAN)
325 EXTERN_C_BEGIN
326 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
327 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
328 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
329 EXTERN_C_END
330 #endif
331 #endif
332 
333 int  PetscGlobalArgc   = 0;
334 char **PetscGlobalArgs = 0;
335 
336 #undef __FUNCT__
337 #define __FUNCT__ "PetscGetArgs"
338 /*@C
339    PetscGetArgs - Allows you to access the raw command line arguments anywhere
340      after PetscInitialize() is called but before PetscFinalize().
341 
342    Not Collective
343 
344    Output Parameters:
345 +  argc - count of number of command line arguments
346 -  args - the command line arguments
347 
348    Level: intermediate
349 
350    Notes:
351       This is usually used to pass the command line arguments into other libraries
352    that are called internally deep in PETSc or the application.
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 
524    Concepts: initializing PETSc
525 
526 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs()
527 
528 @*/
529 PetscErrorCode PETSC_DLLEXPORT PetscInitialize(int *argc,char ***args,const char file[],const char help[])
530 {
531   PetscErrorCode ierr;
532   PetscMPIInt    flag, size;
533   PetscInt       nodesize;
534   PetscTruth     flg;
535   char           hostname[256];
536 
537   PetscFunctionBegin;
538   if (PetscInitializeCalled) PetscFunctionReturn(0);
539 
540   /* these must be initialized in a routine, not as a constant declaration*/
541   PETSC_STDOUT = stdout;
542   PETSC_STDERR = stderr;
543 
544   ierr = PetscOptionsCreate();CHKERRQ(ierr);
545 
546   /*
547      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
548      it that it sets args[0] on all processors to be args[0] on the first processor.
549   */
550   if (argc && *argc) {
551     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
552   } else {
553     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
554   }
555 
556   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
557   if (!flag) {
558     if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
559     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
560     PetscBeganMPI = PETSC_TRUE;
561   }
562   if (argc && args) {
563     PetscGlobalArgc = *argc;
564     PetscGlobalArgs = *args;
565   }
566   PetscInitializeCalled = PETSC_TRUE;
567   PetscFinalizeCalled   = PETSC_FALSE;
568 
569   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
570     PETSC_COMM_WORLD = MPI_COMM_WORLD;
571   }
572 
573   /* Done after init due to a bug in MPICH-GM? */
574   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
575 
576   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
577   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
578 
579 #if defined(PETSC_USE_COMPLEX)
580   /*
581      Initialized the global complex variable; this is because with
582      shared libraries the constructors for global variables
583      are not called; at least on IRIX.
584   */
585   {
586 #if defined(PETSC_CLANGUAGE_CXX)
587     PetscScalar ic(0.0,1.0);
588     PETSC_i = ic;
589 #else
590     PETSC_i = I;
591 #endif
592   }
593 
594 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
595   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
596   ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr);
597   ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr);
598 #endif
599 #endif
600 
601   /*
602      Create the PETSc MPI reduction operator that sums of the first
603      half of the entries and maxes the second half.
604   */
605   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
606 
607   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
608   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
609   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
610   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
611 
612   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
613   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
614 
615   /*
616      Attributes to be set on PETSc communicators
617   */
618   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
619   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
620   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
621 
622   /*
623      Build the options database
624   */
625   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
626 
627 
628   /*
629      Print main application help message
630   */
631   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
632   if (help && flg) {
633     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
634   }
635   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
636 
637   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
638 #if defined(PETSC_USE_LOG)
639   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
640 #endif
641 
642   /*
643      Load the dynamic libraries (on machines that support them), this registers all
644      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
645   */
646   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
647 
648   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
649   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
650   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
651   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
652 
653   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
654   /* Check the options database for options related to the options database itself */
655   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
656 
657 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
658   /*
659       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
660 
661       Currently not used because it is not supported by MPICH.
662   */
663 #if !defined(PETSC_WORDS_BIGENDIAN)
664   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
665 #endif
666 #endif
667 
668   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
669   if (flg) {
670 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
671     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */
672 #else
673     SETERRQ(PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
674 #endif
675   } else {
676     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
677     if (flg) {
678       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
679       if (PetscOpenMPWorker) { /* if worker then never enter user code */
680         ierr = PetscEnd();
681       }
682     }
683   }
684   flg  = PETSC_FALSE;
685   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg,PETSC_NULL);CHKERRQ(ierr);
686   if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
687 
688   PetscFunctionReturn(ierr);
689 }
690 
691 
692 #undef __FUNCT__
693 #define __FUNCT__ "PetscFinalize"
694 /*@C
695    PetscFinalize - Checks for options to be called at the conclusion
696    of the program. MPI_Finalize() is called only if the user had not
697    called MPI_Init() before calling PetscInitialize().
698 
699    Collective on PETSC_COMM_WORLD
700 
701    Options Database Keys:
702 +  -options_table - Calls PetscOptionsPrint()
703 .  -options_left - Prints unused options that remain in the database
704 .  -options_left no - Does not print unused options that remain in the database
705 .  -mpidump - Calls PetscMPIDump()
706 .  -malloc_dump - Calls PetscMallocDump()
707 .  -malloc_info - Prints total memory usage
708 -  -malloc_log - Prints summary of memory usage
709 
710    Options Database Keys for Profiling:
711    See the Profiling chapter of the users manual for details.
712 +  -log_summary [filename] - Prints summary of flop and timing
713         information to screen. If the filename is specified the
714         summary is written to the file. (for code compiled with
715         PETSC_USE_LOG).  See PetscLogPrintSummary().
716 .  -log_all [filename] - Logs extensive profiling information
717         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
718 .  -log [filename] - Logs basic profiline information (for
719         code compiled with PETSC_USE_LOG).  See PetscLogDump().
720 .  -log_sync - Log the synchronization in scatters, inner products
721         and norms
722 -  -log_mpe [filename] - Creates a logfile viewable by the
723       utility Upshot/Nupshot (in MPICH distribution)
724 
725    Level: beginner
726 
727    Note:
728    See PetscInitialize() for more general runtime options.
729 
730 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
731 @*/
732 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
733 {
734   PetscErrorCode ierr;
735   PetscMPIInt    rank;
736   int            nopt;
737   PetscTruth     flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
738   extern FILE   *PETSC_ZOPEFD;
739 
740   PetscFunctionBegin;
741 
742   if (!PetscInitializeCalled) {
743     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
744     PetscFunctionReturn(0);
745   }
746   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
747 
748   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
749 
750   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg1,PETSC_NULL);CHKERRQ(ierr);
751   if (flg1) {ierr = PetscPythonFinalize();CHKERRQ(ierr);}
752 
753   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
754   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
755   if (!flg2) {
756     flg2 = PETSC_FALSE;
757     ierr = PetscOptionsGetTruth(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
758   }
759   if (flg2) {
760     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
761   }
762 
763   /*
764      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
765   */
766   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
767 
768   /*
769        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
770   */
771   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
772 
773   /*
774      Destroy any packages that registered a finalize
775   */
776   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
777 
778   /*
779      Destroy all the function registration lists created
780   */
781   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
782 
783 #if defined(PETSC_USE_LOG)
784   flg1 = PETSC_FALSE;
785   ierr = PetscOptionsGetTruth(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
786   if (flg1) {
787     PetscLogDouble flops = 0;
788     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
789     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
790   }
791 #endif
792 
793   ierr = PetscOptionsHelpDestroyList();CHKERRQ(ierr);
794 
795 #if defined(PETSC_USE_DEBUG)
796   if (PetscStackActive) {
797     ierr = PetscStackDestroy();CHKERRQ(ierr);
798   }
799 #endif
800 
801 #if defined(PETSC_USE_LOG)
802   {
803     char mname[PETSC_MAX_PATH_LEN];
804 #if defined(PETSC_HAVE_MPE)
805     mname[0] = 0;
806     ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
807     if (flg1){
808       if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
809       else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
810     }
811 #endif
812     mname[0] = 0;
813     ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
814     if (flg1) {
815       if (mname[0])  {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
816       else           {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
817     }
818 
819     ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
820     if (flg1) {
821       if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
822       else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
823     }
824 
825     mname[0] = 0;
826     ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
827     ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
828     if (flg1 || flg2){
829       if (mname[0]) PetscLogDump(mname);
830       else          PetscLogDump(0);
831     }
832     ierr = PetscLogDestroy();CHKERRQ(ierr);
833   }
834 #endif
835   flg1 = PETSC_FALSE;
836   ierr = PetscOptionsGetTruth(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
837   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
838   flg1 = PETSC_FALSE;
839   ierr = PetscOptionsGetTruth(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
840   if (flg1) {
841     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
842   }
843   flg1 = PETSC_FALSE;
844   flg2 = PETSC_FALSE;
845   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
846   ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
847   if (flg2) {
848     if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);}
849   }
850 
851   /* to prevent PETSc -options_left from warning */
852   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr)
853   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
854 
855   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
856     flg3 = PETSC_FALSE; /* default value is required */
857     ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
858     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
859     if (flg3) {
860       if (!flg2) { /* have not yet printed the options */
861 	ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);
862       }
863       if (!nopt) {
864 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
865       } else if (nopt == 1) {
866 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
867       } else {
868 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
869       }
870     }
871 #if defined(PETSC_USE_DEBUG)
872     if (nopt && !flg3 && !flg1) {
873       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
874       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
875       ierr = PetscOptionsLeft();CHKERRQ(ierr);
876     } else if (nopt && flg3) {
877 #else
878     if (nopt && flg3) {
879 #endif
880       ierr = PetscOptionsLeft();CHKERRQ(ierr);
881     }
882   }
883 
884   flg1 = PETSC_FALSE;
885   ierr = PetscOptionsGetTruth(PETSC_NULL,"-log_history",&flg1,PETSC_NULL);CHKERRQ(ierr);
886   if (flg1) {
887     ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
888     petsc_history = 0;
889   }
890 
891   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
892 
893   flg1 = PETSC_FALSE;
894   flg3 = PETSC_FALSE;
895   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
896   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg3,PETSC_NULL);CHKERRQ(ierr);
897   if (flg1) {
898     char fname[PETSC_MAX_PATH_LEN];
899     FILE *fd;
900     int  err;
901 
902     fname[0] = 0;
903     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
904     if (flg1 && fname[0]) {
905       char sname[PETSC_MAX_PATH_LEN];
906 
907       sprintf(sname,"%s_%d",fname,rank);
908       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
909       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
910       err = fclose(fd);
911       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
912     } else {
913       MPI_Comm local_comm;
914 
915       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
916       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
917         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
918       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
919       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
920     }
921   }
922   if (flg3) {
923     char fname[PETSC_MAX_PATH_LEN];
924     FILE *fd;
925 
926     fname[0] = 0;
927     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
928     if (flg1 && fname[0]) {
929       char sname[PETSC_MAX_PATH_LEN];
930       int  err;
931 
932       sprintf(sname,"%s_%d",fname,rank);
933       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
934       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
935       err = fclose(fd);
936       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
937     } else {
938       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
939     }
940   }
941   /* Can be destroyed only after all the options are used */
942   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
943 
944   PetscGlobalArgc = 0;
945   PetscGlobalArgs = 0;
946 
947 #if defined(PETSC_USE_COMPLEX)
948 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
949   ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr);
950   ierr = MPI_Type_free(&MPI_C_DOUBLE_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