xref: /petsc/src/sys/objects/pinit.c (revision f963788bda91a1d728e4d3144eba9dd2a8083b3a)
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   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr);
620   if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
621 
622   PetscFunctionReturn(ierr);
623 }
624 
625 
626 #undef __FUNCT__
627 #define __FUNCT__ "PetscFinalize"
628 /*@C
629    PetscFinalize - Checks for options to be called at the conclusion
630    of the program. MPI_Finalize() is called only if the user had not
631    called MPI_Init() before calling PetscInitialize().
632 
633    Collective on PETSC_COMM_WORLD
634 
635    Options Database Keys:
636 +  -options_table - Calls PetscOptionsPrint()
637 .  -options_left - Prints unused options that remain in the database
638 .  -options_left no - Does not print unused options that remain in the database
639 .  -mpidump - Calls PetscMPIDump()
640 .  -malloc_dump - Calls PetscMallocDump()
641 .  -malloc_info - Prints total memory usage
642 -  -malloc_log - Prints summary of memory usage
643 
644    Options Database Keys for Profiling:
645    See the Profiling chapter of the users manual for details.
646 +  -log_summary [filename] - Prints summary of flop and timing
647         information to screen. If the filename is specified the
648         summary is written to the file. (for code compiled with
649         PETSC_USE_LOG).  See PetscLogPrintSummary().
650 .  -log_all [filename] - Logs extensive profiling information
651         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
652 .  -log [filename] - Logs basic profiline information (for
653         code compiled with PETSC_USE_LOG).  See PetscLogDump().
654 .  -log_sync - Log the synchronization in scatters, inner products
655         and norms
656 -  -log_mpe [filename] - Creates a logfile viewable by the
657       utility Upshot/Nupshot (in MPICH distribution)
658 
659    Level: beginner
660 
661    Note:
662    See PetscInitialize() for more general runtime options.
663 
664 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
665 @*/
666 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
667 {
668   PetscErrorCode ierr;
669   PetscMPIInt    rank;
670   int            nopt;
671   PetscTruth     flg1,flg2,flg3;
672   extern FILE   *PETSC_ZOPEFD;
673 
674   PetscFunctionBegin;
675 
676   if (!PetscInitializeCalled) {
677     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
678     PetscFunctionReturn(0);
679   }
680   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
681 
682   ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg1);CHKERRQ(ierr);
683   if (flg1) {ierr = PetscPythonFinalize();CHKERRQ(ierr);}
684 
685   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
686   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_info",&flg2);CHKERRQ(ierr);
687   if (!flg2) {
688     ierr = PetscOptionsHasName(PETSC_NULL,"-memory_info",&flg2);CHKERRQ(ierr);
689   }
690   if (flg2) {
691     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
692   }
693 
694   /*
695      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
696   */
697   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
698 
699   /*
700        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
701   */
702   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
703 
704   /*
705      Destroy any packages that registered a finalize
706   */
707   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
708 
709   /*
710      Destroy all the function registration lists created
711   */
712   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
713 
714 #if defined(PETSC_USE_LOG)
715   ierr = PetscOptionsHasName(PETSC_NULL,"-get_total_flops",&flg1);CHKERRQ(ierr);
716   if (flg1) {
717     PetscLogDouble flops = 0;
718     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
719     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
720   }
721 #endif
722 
723   ierr = PetscOptionsHelpDestroyList();CHKERRQ(ierr);
724 
725 #if defined(PETSC_USE_DEBUG)
726   if (PetscStackActive) {
727     ierr = PetscStackDestroy();CHKERRQ(ierr);
728   }
729 #endif
730 
731 #if defined(PETSC_USE_LOG)
732   {
733     char mname[PETSC_MAX_PATH_LEN];
734 #if defined(PETSC_HAVE_MPE)
735     mname[0] = 0;
736     ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
737     if (flg1){
738       if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
739       else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
740     }
741 #endif
742     mname[0] = 0;
743     ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
744     if (flg1) {
745       if (mname[0])  {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
746       else           {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
747     }
748 
749     ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
750     if (flg1) {
751       if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
752       else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
753     }
754 
755     mname[0] = 0;
756     ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
757     ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
758     if (flg1 || flg2){
759       if (mname[0]) PetscLogDump(mname);
760       else          PetscLogDump(0);
761     }
762     ierr = PetscLogDestroy();CHKERRQ(ierr);
763   }
764 #endif
765   ierr = PetscOptionsHasName(PETSC_NULL,"-no_signal_handler",&flg1);CHKERRQ(ierr);
766   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
767   ierr = PetscOptionsHasName(PETSC_NULL,"-mpidump",&flg1);CHKERRQ(ierr);
768   if (flg1) {
769     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
770   }
771   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
772   ierr = PetscOptionsHasName(PETSC_NULL,"-options_table",&flg2);CHKERRQ(ierr);
773   if (flg2) {
774     if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);}
775   }
776 
777   /* to prevent PETSc -options_left from warning */
778   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr)
779   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
780 
781   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
782     flg3 = PETSC_FALSE; /* default value is required */
783     ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
784     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
785     if (flg3) {
786       if (!flg2) { /* have not yet printed the options */
787 	ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);
788       }
789       if (!nopt) {
790 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
791       } else if (nopt == 1) {
792 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
793       } else {
794 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
795       }
796     }
797 #if defined(PETSC_USE_DEBUG)
798     if (nopt && !flg3 && !flg1) {
799       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
800       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
801       ierr = PetscOptionsLeft();CHKERRQ(ierr);
802     } else if (nopt && flg3) {
803 #else
804     if (nopt && flg3) {
805 #endif
806       ierr = PetscOptionsLeft();CHKERRQ(ierr);
807     }
808   }
809 
810   ierr = PetscOptionsHasName(PETSC_NULL,"-log_history",&flg1);CHKERRQ(ierr);
811   if (flg1) {
812     ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
813     petsc_history = 0;
814   }
815 
816   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
817 
818   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr);
819   ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log",&flg3);CHKERRQ(ierr);
820   if (flg1) {
821     char fname[PETSC_MAX_PATH_LEN];
822     FILE *fd;
823     int  err;
824 
825     fname[0] = 0;
826     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
827     if (flg1 && fname[0]) {
828       char sname[PETSC_MAX_PATH_LEN];
829 
830       sprintf(sname,"%s_%d",fname,rank);
831       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
832       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
833       err = fclose(fd);
834       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
835     } else {
836       MPI_Comm local_comm;
837 
838       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
839       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
840         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
841       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
842       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
843     }
844   }
845   if (flg3) {
846     char fname[PETSC_MAX_PATH_LEN];
847     FILE *fd;
848 
849     fname[0] = 0;
850     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
851     if (flg1 && fname[0]) {
852       char sname[PETSC_MAX_PATH_LEN];
853       int  err;
854 
855       sprintf(sname,"%s_%d",fname,rank);
856       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
857       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
858       err = fclose(fd);
859       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
860     } else {
861       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
862     }
863   }
864   /* Can be destroyed only after all the options are used */
865   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
866 
867   PetscGlobalArgc = 0;
868   PetscGlobalArgs = 0;
869 
870 #if defined(PETSC_USE_COMPLEX)
871   ierr = MPI_Op_free(&PetscSum_Op);CHKERRQ(ierr);
872   ierr = MPI_Type_free(&MPIU_COMPLEX);CHKERRQ(ierr);
873 #endif
874   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
875   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
876   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
877   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
878   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
879 
880   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
881   if (PetscBeganMPI) {
882 #if defined(PETSC_HAVE_MPI_FINALIZED)
883     PetscMPIInt flag;
884     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
885     if (flag) SETERRQ(PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
886 #endif
887     ierr = MPI_Finalize();CHKERRQ(ierr);
888   }
889 
890   if(PETSC_ZOPEFD != NULL){
891     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
892     else fprintf(PETSC_STDOUT, "<<<end>>>");}
893 
894 /*
895 
896      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
897    the communicator has some outstanding requests on it. Specifically if the
898    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
899    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
900    is never freed as it should be. Thus one may obtain messages of the form
901    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
902    memory was not freed.
903 
904 */
905   ierr = PetscMallocClear();CHKERRQ(ierr);
906   PetscInitializeCalled = PETSC_FALSE;
907   PetscFinalizeCalled   = PETSC_TRUE;
908   PetscFunctionReturn(ierr);
909 }
910 
911 /*
912      These may be used in code that ADIC is to be used on
913 */
914 
915 #undef __FUNCT__
916 #define __FUNCT__ "PetscGlobalMax"
917 /*@
918       PetscGlobalMax - Computes the maximum value over several processors
919 
920      Collective on MPI_Comm
921 
922    Input Parameters:
923 +   local - the local value
924 -   comm - the processors that find the maximum
925 
926    Output Parameter:
927 .   result - the maximum value
928 
929    Level: intermediate
930 
931    Notes:
932      These functions are to be used inside user functions that are to be processed with
933    ADIC. PETSc will automatically provide differentiated versions of these functions
934 
935 .seealso: PetscGlobalMin(), PetscGlobalSum()
936 @*/
937 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal* local,PetscReal* result,MPI_Comm comm)
938 {
939   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MAX,comm);
940 }
941 
942 #undef __FUNCT__
943 #define __FUNCT__ "PetscGlobalMin"
944 /*@
945       PetscGlobalMin - Computes the minimum value over several processors
946 
947      Collective on MPI_Comm
948 
949    Input Parameters:
950 +   local - the local value
951 -   comm - the processors that find the minimum
952 
953    Output Parameter:
954 .   result - the minimum value
955 
956    Level: intermediate
957 
958    Notes:
959      These functions are to be used inside user functions that are to be processed with
960    ADIC. PETSc will automatically provide differentiated versions of these functions
961 
962 .seealso: PetscGlobalMax(), PetscGlobalSum()
963 @*/
964 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal* local,PetscReal* result,MPI_Comm comm)
965 {
966   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MIN,comm);
967 }
968 
969 #undef __FUNCT__
970 #define __FUNCT__ "PetscGlobalSum"
971 /*@
972       PetscGlobalSum - Computes the sum over sever processors
973 
974      Collective on MPI_Comm
975 
976    Input Parameters:
977 +   local - the local value
978 -   comm - the processors that find the sum
979 
980    Output Parameter:
981 .   result - the sum
982 
983    Level: intermediate
984 
985    Notes:
986      These functions are to be used inside user functions that are to be processed with
987    ADIC. PETSc will automatically provide differentiated versions of these functions
988 
989 .seealso: PetscGlobalMin(), PetscGlobalMax()
990 @*/
991 PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar* local,PetscScalar* result,MPI_Comm comm)
992 {
993   return MPI_Allreduce(local,result,1,MPIU_SCALAR,PetscSum_Op,comm);
994 }
995 
996 
997