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