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