xref: /petsc/src/sys/objects/pinit.c (revision 7319c6545cdf078a8212d19c3cdefe116c1a5fdd)
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 /*
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 
485   /* these must be initialized in a routine, not as a constant declaration*/
486   PETSC_STDOUT = stdout;
487   PETSC_STDERR = stderr;
488 
489   ierr = PetscOptionsCreate();CHKERRQ(ierr);
490 
491   /*
492      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
493      it that it sets args[0] on all processors to be args[0] on the first processor.
494   */
495   if (argc && *argc) {
496     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
497   } else {
498     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
499   }
500 
501   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
502   if (!flag) {
503     if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
504     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
505     PetscBeganMPI = PETSC_TRUE;
506   }
507   if (argc && args) {
508     PetscGlobalArgc = *argc;
509     PetscGlobalArgs = *args;
510   }
511   PetscInitializeCalled = PETSC_TRUE;
512   PetscFinalizeCalled   = PETSC_FALSE;
513 
514   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
515     PETSC_COMM_WORLD = MPI_COMM_WORLD;
516   }
517 
518   /* Done after init due to a bug in MPICH-GM? */
519   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
520 
521   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
522   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
523 
524 #if defined(PETSC_USE_COMPLEX)
525   /*
526      Initialized the global complex variable; this is because with
527      shared libraries the constructors for global variables
528      are not called; at least on IRIX.
529   */
530   {
531 #if defined(PETSC_CLANGUAGE_CXX)
532     PetscScalar ic(0.0,1.0);
533     PETSC_i = ic;
534 #else
535     PETSC_i = I;
536 #endif
537   }
538 
539   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_COMPLEX);CHKERRQ(ierr);
540   ierr = MPI_Type_commit(&MPIU_COMPLEX);CHKERRQ(ierr);
541   ierr = MPI_Op_create(PetscSum_Local,1,&PetscSum_Op);CHKERRQ(ierr);
542 #endif
543 
544   /*
545      Create the PETSc MPI reduction operator that sums of the first
546      half of the entries and maxes the second half.
547   */
548   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
549 
550   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
551   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
552   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
553   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
554 
555   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
556   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
557 
558   /*
559      Build the options database
560   */
561   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
562 
563 
564   /*
565      Print main application help message
566   */
567   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
568   if (help && flg) {
569     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
570   }
571   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
572 
573   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
574 #if defined(PETSC_USE_LOG)
575   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
576 #endif
577 
578   /*
579      Load the dynamic libraries (on machines that support them), this registers all
580      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
581   */
582   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
583 
584   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
585   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
586   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
587   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
588 
589   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
590   /* Check the options database for options related to the options database itself */
591   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
592 
593 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
594   /*
595       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
596 
597       Currently not used because it is not supported by MPICH.
598   */
599 #if !defined(PETSC_WORDS_BIGENDIAN)
600   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
601 #endif
602 #endif
603 
604   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
605   if (flg) {
606 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
607     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr);
608 #else
609     SETERRQ(PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
610 #endif
611   } else {
612     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
613     if (flg) {
614       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize);CHKERRQ(ierr);
615     }
616   }
617   flg  = PETSC_FALSE;
618   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg,PETSC_NULL);CHKERRQ(ierr);
619   if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
620 
621   PetscFunctionReturn(ierr);
622 }
623 
624 
625 #undef __FUNCT__
626 #define __FUNCT__ "PetscFinalize"
627 /*@C
628    PetscFinalize - Checks for options to be called at the conclusion
629    of the program. MPI_Finalize() is called only if the user had not
630    called MPI_Init() before calling PetscInitialize().
631 
632    Collective on PETSC_COMM_WORLD
633 
634    Options Database Keys:
635 +  -options_table - Calls PetscOptionsPrint()
636 .  -options_left - Prints unused options that remain in the database
637 .  -options_left no - Does not print unused options that remain in the database
638 .  -mpidump - Calls PetscMPIDump()
639 .  -malloc_dump - Calls PetscMallocDump()
640 .  -malloc_info - Prints total memory usage
641 -  -malloc_log - Prints summary of memory usage
642 
643    Options Database Keys for Profiling:
644    See the Profiling chapter of the users manual for details.
645 +  -log_summary [filename] - Prints summary of flop and timing
646         information to screen. If the filename is specified the
647         summary is written to the file. (for code compiled with
648         PETSC_USE_LOG).  See PetscLogPrintSummary().
649 .  -log_all [filename] - Logs extensive profiling information
650         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
651 .  -log [filename] - Logs basic profiline information (for
652         code compiled with PETSC_USE_LOG).  See PetscLogDump().
653 .  -log_sync - Log the synchronization in scatters, inner products
654         and norms
655 -  -log_mpe [filename] - Creates a logfile viewable by the
656       utility Upshot/Nupshot (in MPICH distribution)
657 
658    Level: beginner
659 
660    Note:
661    See PetscInitialize() for more general runtime options.
662 
663 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
664 @*/
665 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
666 {
667   PetscErrorCode ierr;
668   PetscMPIInt    rank;
669   int            nopt;
670   PetscTruth     flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
671   extern FILE   *PETSC_ZOPEFD;
672 
673   PetscFunctionBegin;
674 
675   if (!PetscInitializeCalled) {
676     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
677     PetscFunctionReturn(0);
678   }
679   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
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