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