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