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