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