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