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