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