Actual source code: pinit.c

petsc-3.4.2 2013-07-02
  2: /*
  3:    This file defines the initialization of PETSc, including PetscInitialize()
  4: */
  5: #define PETSC_DESIRE_COMPLEX
  6: #include <petsc-private/petscimpl.h>        /*I  "petscsys.h"   I*/
  7: #include <petscviewer.h>

  9: #if defined(PETSC_HAVE_CUDA)
 10: #include <cublas.h>
 11: #endif

 13: #include <petscthreadcomm.h>

 15: #if defined(PETSC_USE_LOG)
 16: extern PetscErrorCode PetscLogBegin_Private(void);
 17: #endif
 18: extern PetscBool PetscHMPIWorker;


 21: #if defined(PETSC_SERIALIZE_FUNCTIONS)
 22: PetscFPT PetscFPTData = 0;
 23: #endif

 25: /* -----------------------------------------------------------------------------------------*/

 27: extern FILE *petsc_history;

 29: extern PetscErrorCode PetscInitialize_DynamicLibraries(void);
 30: extern PetscErrorCode PetscFinalize_DynamicLibraries(void);
 31: extern PetscErrorCode PetscFunctionListPrintAll(void);
 32: extern PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
 33: extern PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
 34: extern PetscErrorCode PetscCloseHistoryFile(FILE**);

 36: /* user may set this BEFORE calling PetscInitialize() */
 37: MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;

 39: PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
 40: PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
 41: PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;

 43: /*
 44:      Declare and set all the string names of the PETSc enums
 45: */
 46: const char *const PetscBools[]     = {"FALSE","TRUE","PetscBool","PETSC_",0};
 47: const char *const PetscCopyModes[] = {"COPY_VALUES","OWN_POINTER","USE_POINTER","PetscCopyMode","PETSC_",0};
 48: const char *const PetscDataTypes[] = {"INT","DOUBLE","COMPLEX","LONG","SHORT","FLOAT",
 49:                                       "CHAR","LOGICAL","ENUM","BOOL","LONGDOUBLE","OBJECT","FUNCTION","PetscDataType","PETSC_",0};

 51: PetscBool PetscPreLoadingUsed = PETSC_FALSE;
 52: PetscBool PetscPreLoadingOn   = PETSC_FALSE;

 54: /* pthread_key for PetscStack */
 55: #if defined(PETSC_HAVE_PTHREADCLASSES) && !defined(PETSC_PTHREAD_LOCAL)
 56: pthread_key_t petscstack;
 57: #endif

 59: /*
 60:        Checks the options database for initializations related to the
 61:     PETSc components
 62: */
 65: PetscErrorCode  PetscOptionsCheckInitial_Components(void)
 66: {
 67:   PetscBool      flg1;

 71:   PetscOptionsHasName(NULL,"-help",&flg1);
 72:   if (flg1) {
 73: #if defined(PETSC_USE_LOG)
 74:     MPI_Comm comm = PETSC_COMM_WORLD;
 75:     (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");
 76:     (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");
 77:     (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");
 78:     (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");
 79: #endif
 80:   }
 81:   return(0);
 82: }

 86: /*
 87:       PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args

 89:    Collective

 91:    Level: advanced

 93:     Notes: this is called only by the PETSc MATLAB and Julia interface. Even though it might start MPI it sets the flag to
 94:      indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to
 95:      be called multiple times from MATLAB and Julia without the problem of trying to initialize MPI more than once.

 97:      Turns off PETSc signal handling because that can interact with MATLAB's signal handling causing random crashes.

 99: .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments()
100: */
101: PetscErrorCode  PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help)
102: {
104:   int            myargc   = argc;
105:   char           **myargs = args;

108:   PetscInitialize(&myargc,&myargs,filename,help);
109:   PetscPopSignalHandler();
110:   PetscBeganMPI = PETSC_FALSE;
111:   PetscFunctionReturn(ierr);
112: }

116: /*
117:       Used by MATLAB and Julia interface to get communicator
118: */
119: PetscErrorCode  PetscGetPETSC_COMM_SELF(MPI_Comm *comm)
120: {
122:   *comm = PETSC_COMM_SELF;
123:   return(0);
124: }

128: /*@C
129:       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
130:         the command line arguments.

132:    Collective

134:    Level: advanced

136: .seealso: PetscInitialize(), PetscInitializeFortran()
137: @*/
138: PetscErrorCode  PetscInitializeNoArguments(void)
139: {
141:   int            argc   = 0;
142:   char           **args = 0;

145:   PetscInitialize(&argc,&args,NULL,NULL);
146:   PetscFunctionReturn(ierr);
147: }

151: /*@
152:       PetscInitialized - Determine whether PETSc is initialized.

154:    Level: beginner

156: .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
157: @*/
158: PetscErrorCode PetscInitialized(PetscBool  *isInitialized)
159: {
160:   *isInitialized = PetscInitializeCalled;
161:   return 0;
162: }

166: /*@
167:       PetscFinalized - Determine whether PetscFinalize() has been called yet

169:    Level: developer

171: .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
172: @*/
173: PetscErrorCode  PetscFinalized(PetscBool  *isFinalized)
174: {
175:   *isFinalized = PetscFinalizeCalled;
176:   return 0;
177: }

179: extern PetscErrorCode PetscOptionsCheckInitial_Private(void);

181: /*
182:        This function is the MPI reduction operation used to compute the sum of the
183:    first half of the datatype and the max of the second half.
184: */
185: MPI_Op PetscMaxSum_Op = 0;

189: PETSC_EXTERN void MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
190: {
191:   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;

194:   if (*datatype != MPIU_2INT) {
195:     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
196:     MPI_Abort(MPI_COMM_WORLD,1);
197:   }

199:   for (i=0; i<count; i++) {
200:     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
201:     xout[2*i+1] += xin[2*i+1];
202:   }
203:   PetscFunctionReturnVoid();
204: }

206: /*
207:     Returns the max of the first entry owned by this processor and the
208: sum of the second entry.

210:     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
211: is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
212: there would be no place to store the both needed results.
213: */
216: PetscErrorCode  PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
217: {
218:   PetscMPIInt    size,rank;
219:   struct {PetscInt max,sum;} *work;

223:   MPI_Comm_size(comm,&size);
224:   MPI_Comm_rank(comm,&rank);
225:   PetscMalloc(size*sizeof(*work),&work);
226:   MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);
227:   *max = work[rank].max;
228:   *sum = work[rank].sum;
229:   PetscFree(work);
230:   return(0);
231: }

233: /* ----------------------------------------------------------------------------*/
234: MPI_Op  PetscADMax_Op = 0;

238: PETSC_EXTERN void MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
239: {
240:   PetscScalar *xin = (PetscScalar*)in,*xout = (PetscScalar*)out;
241:   PetscInt    i,count = *cnt;

244:   if (*datatype != MPIU_2SCALAR) {
245:     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
246:     MPI_Abort(MPI_COMM_WORLD,1);
247:   }

249:   for (i=0; i<count; i++) {
250:     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
251:       xout[2*i]   = xin[2*i];
252:       xout[2*i+1] = xin[2*i+1];
253:     }
254:   }
255:   PetscFunctionReturnVoid();
256: }

258: MPI_Op PetscADMin_Op = 0;

262: PETSC_EXTERN void MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
263: {
264:   PetscScalar *xin = (PetscScalar*)in,*xout = (PetscScalar*)out;
265:   PetscInt    i,count = *cnt;

268:   if (*datatype != MPIU_2SCALAR) {
269:     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
270:     MPI_Abort(MPI_COMM_WORLD,1);
271:   }

273:   for (i=0; i<count; i++) {
274:     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
275:       xout[2*i]   = xin[2*i];
276:       xout[2*i+1] = xin[2*i+1];
277:     }
278:   }
279:   PetscFunctionReturnVoid();
280: }
281: /* ---------------------------------------------------------------------------------------*/

283: #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
284: MPI_Op MPIU_SUM = 0;

288: PETSC_EXTERN void PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
289: {
290:   PetscInt i,count = *cnt;

293:   if (*datatype == MPIU_REAL) {
294:     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
295:     for (i=0; i<count; i++) xout[i] += xin[i];
296:   }
297: #if defined(PETSC_HAVE_COMPLEX)
298:   else if (*datatype == MPIU_COMPLEX) {
299:     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
300:     for (i=0; i<count; i++) xout[i] += xin[i];
301:   }
302: #endif
303:   else {
304:     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
305:     MPI_Abort(MPI_COMM_WORLD,1);
306:   }
307:   PetscFunctionReturnVoid();
308: }
309: #endif

311: #if defined(PETSC_USE_REAL___FLOAT128)
312: MPI_Op MPIU_MAX = 0;
313: MPI_Op MPIU_MIN = 0;

317: PETSC_EXTERN void PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
318: {
319:   PetscInt i,count = *cnt;

322:   if (*datatype == MPIU_REAL) {
323:     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
324:     for (i=0; i<count; i++) xout[i] = PetscMax(xout[i],xin[i]);
325:   }
326: #if defined(PETSC_HAVE_COMPLEX)
327:   else if (*datatype == MPIU_COMPLEX) {
328:     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
329:     for (i=0; i<count; i++) {
330:       xout[i] = PetscRealPartComplex(xout[i])<PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
331:     }
332:   }
333: #endif
334:   else {
335:     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
336:     MPI_Abort(MPI_COMM_WORLD,1);
337:   }
338:   PetscFunctionReturnVoid();
339: }

343: PETSC_EXTERN void PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
344: {
345:   PetscInt    i,count = *cnt;

348:   if (*datatype == MPIU_REAL) {
349:     PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
350:     for (i=0; i<count; i++) xout[i] = PetscMin(xout[i],xin[i]);
351:   }
352: #if defined(PETSC_HAVE_COMPLEX)
353:   else if (*datatype == MPIU_COMPLEX) {
354:     PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
355:     for (i=0; i<count; i++) {
356:       xout[i] = PetscRealPartComplex(xout[i])>PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
357:     }
358:   }
359: #endif
360:   else {
361:     (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types");
362:     MPI_Abort(MPI_COMM_WORLD,1);
363:   }
364:   PetscFunctionReturnVoid();
365: }
366: #endif

370: /*
371:    Private routine to delete internal tag/name counter storage when a communicator is freed.

373:    This is called by MPI, not by users. This is called by MPI_Comm_free() when the communicator that has this  data as an attribute is freed.

375:    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()

377: */
378: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
379: {

383:   PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
384:   PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
385:   PetscFunctionReturn(MPI_SUCCESS);
386: }

390: /*
391:   This is invoked on the outer comm as a result of either PetscCommDestroy() (via MPI_Attr_delete) or when the user
392:   calls MPI_Comm_free().

394:   This is the only entry point for breaking the links between inner and outer comms.

396:   This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator.

398:   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()

400: */
401: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Outer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
402: {
404:   PetscMPIInt    flg;
405:   union {MPI_Comm comm; void *ptr;} icomm,ocomm;

408:   if (keyval != Petsc_InnerComm_keyval) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Unexpected keyval");
409:   icomm.ptr = attr_val;

411:   MPI_Attr_get(icomm.comm,Petsc_OuterComm_keyval,&ocomm,&flg);
412:   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected reference to outer comm");
413:   if (ocomm.comm != comm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm has reference to non-matching outer comm");
414:   MPI_Attr_delete(icomm.comm,Petsc_OuterComm_keyval); /* Calls Petsc_DelComm_Inner */
415:   PetscInfo1(0,"User MPI_Comm %ld is being freed after removing reference from inner PETSc comm to this outer comm\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
416:   PetscFunctionReturn(MPI_SUCCESS);
417: }

421: /*
422:  * This is invoked on the inner comm when Petsc_DelComm_Outer calls MPI_Attr_delete.  It should not be reached any other way.
423:  */
424: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelComm_Inner(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
425: {

429:   PetscInfo1(0,"Removing reference to PETSc communicator embedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
430:   PetscFunctionReturn(MPI_SUCCESS);
431: }

433: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
434: #if !defined(PETSC_WORDS_BIGENDIAN)
435: PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
436: PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
437: PETSC_EXTERN PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
438: #endif
439: #endif

441: int  PetscGlobalArgc   = 0;
442: char **PetscGlobalArgs = 0;

446: /*@C
447:    PetscGetArgs - Allows you to access the raw command line arguments anywhere
448:      after PetscInitialize() is called but before PetscFinalize().

450:    Not Collective

452:    Output Parameters:
453: +  argc - count of number of command line arguments
454: -  args - the command line arguments

456:    Level: intermediate

458:    Notes:
459:       This is usually used to pass the command line arguments into other libraries
460:    that are called internally deep in PETSc or the application.

462:       The first argument contains the program name as is normal for C arguments.

464:    Concepts: command line arguments

466: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()

468: @*/
469: PetscErrorCode  PetscGetArgs(int *argc,char ***args)
470: {
472:   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
473:   *argc = PetscGlobalArgc;
474:   *args = PetscGlobalArgs;
475:   return(0);
476: }

480: /*@C
481:    PetscGetArguments - Allows you to access the  command line arguments anywhere
482:      after PetscInitialize() is called but before PetscFinalize().

484:    Not Collective

486:    Output Parameters:
487: .  args - the command line arguments

489:    Level: intermediate

491:    Notes:
492:       This does NOT start with the program name and IS null terminated (final arg is void)

494:    Concepts: command line arguments

496: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()

498: @*/
499: PetscErrorCode  PetscGetArguments(char ***args)
500: {
501:   PetscInt       i,argc = PetscGlobalArgc;

505:   if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
506:   if (!argc) {*args = 0; return(0);}
507:   PetscMalloc(argc*sizeof(char*),args);
508:   for (i=0; i<argc-1; i++) {
509:     PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);
510:   }
511:   (*args)[argc-1] = 0;
512:   return(0);
513: }

517: /*@C
518:    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()

520:    Not Collective

522:    Output Parameters:
523: .  args - the command line arguments

525:    Level: intermediate

527:    Concepts: command line arguments

529: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()

531: @*/
532: PetscErrorCode  PetscFreeArguments(char **args)
533: {
534:   PetscInt       i = 0;

538:   if (!args) return(0);
539:   while (args[i]) {
540:     PetscFree(args[i]);
541:     i++;
542:   }
543:   PetscFree(args);
544:   return(0);
545: }

549: /*@C
550:    PetscInitialize - Initializes the PETSc database and MPI.
551:    PetscInitialize() calls MPI_Init() if that has yet to be called,
552:    so this routine should always be called near the beginning of
553:    your program -- usually the very first line!

555:    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set

557:    Input Parameters:
558: +  argc - count of number of command line arguments
559: .  args - the command line arguments
560: .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL to not check for
561:           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
562: -  help - [optional] Help message to print, use NULL for no message

564:    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
565:    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
566:    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
567:    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
568:    if different subcommunicators of the job are doing different things with PETSc.

570:    Options Database Keys:
571: +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
572: .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
573: .  -on_error_emacs <machinename> causes emacsclient to jump to error file
574: .  -on_error_abort calls abort() when error detected (no traceback)
575: .  -on_error_mpiabort calls MPI_abort() when error detected
576: .  -error_output_stderr prints error messages to stderr instead of the default stdout
577: .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
578: .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
579: .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
580: .  -stop_for_debugger - Print message on how to attach debugger manually to
581:                         process and wait (-debugger_pause) seconds for attachment
582: .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
583: .  -malloc no - Indicates not to use error-checking malloc
584: .  -malloc_debug - check for memory corruption at EVERY malloc or free
585: .  -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds
586: .  -fp_trap - Stops on floating point exceptions (Note that on the
587:               IBM RS6000 this slows code by at least a factor of 10.)
588: .  -no_signal_handler - Indicates not to trap error signals
589: .  -shared_tmp - indicates /tmp directory is shared by all processors
590: .  -not_shared_tmp - each processor has own /tmp
591: .  -tmp - alternative name of /tmp directory
592: .  -get_total_flops - returns total flops done by all processors
593: .  -memory_info - Print memory usage at end of run
594: -  -server <port> - start PETSc webserver (default port is 8080)

596:    Options Database Keys for Profiling:
597:    See the <a href="../../docs/manual.pdf#nameddest=Chapter 10 Profiling">profiling chapter of the users manual</a> for details.
598: +  -info <optional filename> - Prints verbose information to the screen
599: .  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
600: .  -log_sync - Log the synchronization in scatters, inner products and norms
601: .  -log_trace [filename] - Print traces of all PETSc calls to the screen (useful to determine where a program
602:         hangs without running in the debugger).  See PetscLogTraceBegin().
603: .  -log_summary [filename] - Prints summary of flop and timing information to screen. If the filename is specified the
604:         summary is written to the file.  See PetscLogView().
605: .  -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen. See PetscLogPrintSViewPython().
606: .  -log_all [filename] - Logs extensive profiling information  See PetscLogDump().
607: .  -log [filename] - Logs basic profiline information  See PetscLogDump().
608: -  -log_mpe [filename] - Creates a logfile viewable by the utility Jumpshot (in MPICH distribution)

610:     Only one of -log_trace, -log_summary, -log_all, -log, or -log_mpe may be used at a time

612:    Environmental Variables:
613: +   PETSC_TMP - alternative tmp directory
614: .   PETSC_SHARED_TMP - tmp is shared by all processes
615: .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
616: .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
617: -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to


620:    Level: beginner

622:    Notes:
623:    If for some reason you must call MPI_Init() separately, call
624:    it before PetscInitialize().

626:    Fortran Version:
627:    In Fortran this routine has the format
628: $       call PetscInitialize(file,ierr)

630: +   ierr - error return code
631: -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use NULL_CHARACTER to not check for
632:           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files

634:    Important Fortran Note:
635:    In Fortran, you MUST use NULL_CHARACTER to indicate a
636:    null character string; you CANNOT just use NULL as
637:    in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details.

639:    If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
640:    calling PetscInitialize().

642:    Concepts: initializing PETSc

644: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()

646: @*/
647: PetscErrorCode  PetscInitialize(int *argc,char ***args,const char file[],const char help[])
648: {
650:   PetscMPIInt    flag, size;
651:   PetscInt       nodesize;
652:   PetscBool      flg;
653:   char           hostname[256];

656:   if (PetscInitializeCalled) return(0);

658:   /* these must be initialized in a routine, not as a constant declaration*/
659:   PETSC_STDOUT = stdout;
660:   PETSC_STDERR = stderr;

662:   PetscOptionsCreate();

664:   /*
665:      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
666:      it that it sets args[0] on all processors to be args[0] on the first processor.
667:   */
668:   if (argc && *argc) {
669:     PetscSetProgramName(**args);
670:   } else {
671:     PetscSetProgramName("Unknown Name");
672:   }

674:   MPI_Initialized(&flag);
675:   if (!flag) {
676:     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");
677: #if defined(PETSC_HAVE_MPI_INIT_THREAD)
678:     {
679:       PetscMPIInt provided;
680:       MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);
681:     }
682: #else
683:     MPI_Init(argc,args);
684: #endif
685:     PetscBeganMPI = PETSC_TRUE;
686:   }
687:   if (argc && args) {
688:     PetscGlobalArgc = *argc;
689:     PetscGlobalArgs = *args;
690:   }
691:   PetscFinalizeCalled = PETSC_FALSE;

693:   if (PETSC_COMM_WORLD == MPI_COMM_NULL) PETSC_COMM_WORLD = MPI_COMM_WORLD;
694:   MPI_Comm_set_errhandler(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);

696:   /* Done after init due to a bug in MPICH-GM? */
697:   PetscErrorPrintfInitialize();

699:   MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);
700:   MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);

702:   MPIU_BOOL = MPI_INT;
703:   MPIU_ENUM = MPI_INT;

705:   /*
706:      Initialized the global complex variable; this is because with
707:      shared libraries the constructors for global variables
708:      are not called; at least on IRIX.
709:   */
710: #if defined(PETSC_HAVE_COMPLEX)
711:   {
712: #if defined(PETSC_CLANGUAGE_CXX)
713:     PetscComplex ic(0.0,1.0);
714:     PETSC_i = ic;
715: #elif defined(PETSC_CLANGUAGE_C)
716:     PETSC_i = _Complex_I;
717: #endif
718:   }

720: #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
721:   MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU_C_DOUBLE_COMPLEX);
722:   MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);
723:   MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);
724:   MPI_Type_commit(&MPIU_C_COMPLEX);
725: #endif
726: #endif /* PETSC_HAVE_COMPLEX */

728:   /*
729:      Create the PETSc MPI reduction operator that sums of the first
730:      half of the entries and maxes the second half.
731:   */
732:   MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);

734: #if defined(PETSC_USE_REAL___FLOAT128)
735:   MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);
736:   MPI_Type_commit(&MPIU___FLOAT128);
737: #if defined(PETSC_HAVE_COMPLEX)
738:   MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);
739:   MPI_Type_commit(&MPIU___COMPLEX128);
740: #endif
741:   MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);
742:   MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);
743: #endif

745: #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
746:   MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);
747: #endif

749:   MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);
750:   MPI_Type_commit(&MPIU_2SCALAR);
751:   MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);
752:   MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);

754: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
755:   MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);
756:   MPI_Type_commit(&MPIU_2INT);
757: #endif

759:   /*
760:      Attributes to be set on PETSc communicators
761:   */
762:   MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);
763:   MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Outer,&Petsc_InnerComm_keyval,(void*)0);
764:   MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm_Inner,&Petsc_OuterComm_keyval,(void*)0);

766:   /*
767:      Build the options database
768:   */
769:   PetscOptionsInsert(argc,args,file);


772:   /*
773:      Print main application help message
774:   */
775:   PetscOptionsHasName(NULL,"-help",&flg);
776:   if (help && flg) {
777:     PetscPrintf(PETSC_COMM_WORLD,help);
778:   }
779:   PetscOptionsCheckInitial_Private();

781:   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
782: #if defined(PETSC_USE_LOG)
783:   PetscLogBegin_Private();
784: #endif

786:   /*
787:      Load the dynamic libraries (on machines that support them), this registers all
788:      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
789:   */
790:   PetscInitialize_DynamicLibraries();

792:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
793:   PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);
794:   PetscGetHostName(hostname,256);
795:   PetscInfo1(0,"Running on machine: %s\n",hostname);

797:   PetscOptionsCheckInitial_Components();
798:   /* Check the options database for options related to the options database itself */
799:   PetscOptionsSetFromOptions();

801: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
802:   /*
803:       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI

805:       Currently not used because it is not supported by MPICH.
806:   */
807: #if !defined(PETSC_WORDS_BIGENDIAN)
808:   MPI_Register_datarep((char*)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,NULL);
809: #endif
810: #endif

812:   PetscOptionsGetInt(NULL,"-hmpi_spawn_size",&nodesize,&flg);
813:   if (flg) {
814: #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
815:     PetscHMPISpawn((PetscMPIInt) nodesize); /* worker nodes never return from here; they go directly to PetscEnd() */
816: #else
817:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead");
818: #endif
819:   } else {
820:     PetscOptionsGetInt(NULL,"-hmpi_merge_size",&nodesize,&flg);
821:     if (flg) {
822:       PetscHMPIMerge((PetscMPIInt) nodesize,NULL,NULL);
823:       if (PetscHMPIWorker) { /* if worker then never enter user code */
824:         PetscInitializeCalled = PETSC_TRUE;
825:         PetscEnd();
826:       }
827:     }
828:   }

830: #if defined(PETSC_HAVE_CUDA)
831:   {
832:     PetscMPIInt p;
833:     for (p = 0; p < PetscGlobalSize; ++p) {
834:       if (p == PetscGlobalRank) cublasInit();
835:       MPI_Barrier(PETSC_COMM_WORLD);
836:     }
837:   }
838: #endif

840:   PetscOptionsHasName(NULL,"-python",&flg);
841:   if (flg) {
842:     PetscInitializeCalled = PETSC_TRUE;
843:     PetscPythonInitialize(NULL,NULL);
844:   }

846:   PetscThreadCommInitializePackage();

848:   /*
849:       Setup building of stack frames for all function calls
850:   */
851: #if defined(PETSC_USE_DEBUG)
852:   PetscThreadLocalRegister((PetscThreadKey*)&petscstack); /* Creates petscstack_key if needed */
853:   PetscStackCreate();
854: #endif

856: #if defined(PETSC_SERIALIZE_FUNCTIONS)
857:   PetscFPTCreate(10000);
858: #endif

860:   /*
861:       Once we are completedly initialized then we can set this variables
862:   */
863:   PetscInitializeCalled = PETSC_TRUE;
864:   return(0);
865: }

867: extern PetscObject *PetscObjects;
868: extern PetscInt    PetscObjectsCounts, PetscObjectsMaxCounts;

872: /*@C
873:    PetscFinalize - Checks for options to be called at the conclusion
874:    of the program. MPI_Finalize() is called only if the user had not
875:    called MPI_Init() before calling PetscInitialize().

877:    Collective on PETSC_COMM_WORLD

879:    Options Database Keys:
880: +  -options_table - Calls PetscOptionsView()
881: .  -options_left - Prints unused options that remain in the database
882: .  -objects_dump [all] - Prints list of objects allocated by the user that have not been freed, the option all cause all outstanding objects to be listed
883: .  -mpidump - Calls PetscMPIDump()
884: .  -malloc_dump - Calls PetscMallocDump()
885: .  -malloc_info - Prints total memory usage
886: -  -malloc_log - Prints summary of memory usage

888:    Level: beginner

890:    Note:
891:    See PetscInitialize() for more general runtime options.

893: .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
894: @*/
895: PetscErrorCode  PetscFinalize(void)
896: {
898:   PetscMPIInt    rank;
899:   PetscInt       nopt;
900:   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
901: #if defined(PETSC_HAVE_AMS)
902:   PetscBool      flg = PETSC_FALSE;
903: #endif
904: #if defined(PETSC_USE_LOG)
905:   char           mname[PETSC_MAX_PATH_LEN];
906: #endif

909:   if (!PetscInitializeCalled) {
910:     printf("PetscInitialize() must be called before PetscFinalize()\n");
911:     PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE);
912:   }
913:   PetscInfo(NULL,"PetscFinalize() called\n");

915: #if defined(PETSC_SERIALIZE_FUNCTIONS)
916:   PetscFPTDestroy();
917: #endif


920: #if defined(PETSC_HAVE_AMS)
921:   PetscOptionsGetBool(NULL,"-options_gui",&flg,NULL);
922:   if (flg) {
923:     PetscOptionsAMSDestroy();
924:   }
925: #endif

927: #if defined(PETSC_HAVE_SERVER)
928:   flg1 = PETSC_FALSE;
929:   PetscOptionsGetBool(NULL,"-server",&flg1,NULL);
930:   if (flg1) {
931:     /*  this is a crude hack, but better than nothing */
932:     PetscPOpen(PETSC_COMM_WORLD,NULL,"pkill -9 petscwebserver","r",NULL);
933:   }
934: #endif

936:   PetscHMPIFinalize();

938:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
939:   PetscOptionsGetBool(NULL,"-malloc_info",&flg2,NULL);
940:   if (!flg2) {
941:     flg2 = PETSC_FALSE;
942:     PetscOptionsGetBool(NULL,"-memory_info",&flg2,NULL);
943:   }
944:   if (flg2) {
945:     PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");
946:   }

948: #if defined(PETSC_USE_LOG)
949:   flg1 = PETSC_FALSE;
950:   PetscOptionsGetBool(NULL,"-get_total_flops",&flg1,NULL);
951:   if (flg1) {
952:     PetscLogDouble flops = 0;
953:     MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);
954:     PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);
955:   }
956: #endif


959: #if defined(PETSC_USE_LOG)
960: #if defined(PETSC_HAVE_MPE)
961:   mname[0] = 0;

963:   PetscOptionsGetString(NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);
964:   if (flg1) {
965:     if (mname[0]) {PetscLogMPEDump(mname);}
966:     else          {PetscLogMPEDump(0);}
967:   }
968: #endif
969:   mname[0] = 0;

971:   PetscOptionsGetString(NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);
972:   if (flg1) {
973:     PetscViewer viewer;
974:     if (mname[0]) {
975:       PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);
976:       PetscLogView(viewer);
977:       PetscViewerDestroy(&viewer);
978:     } else {
979:       viewer = PETSC_VIEWER_STDOUT_WORLD;
980:       PetscLogView(viewer);
981:     }
982:   }

984:   mname[0] = 0;

986:   PetscOptionsGetString(NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);
987:   if (flg1) {
988:     PetscViewer viewer;
989:     if (mname[0]) {
990:       PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);
991:       PetscLogViewPython(viewer);
992:       PetscViewerDestroy(&viewer);
993:     } else {
994:       viewer = PETSC_VIEWER_STDOUT_WORLD;
995:       PetscLogViewPython(viewer);
996:     }
997:   }

999:   PetscOptionsGetString(NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);
1000:   if (flg1) {
1001:     if (mname[0])  {PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);}
1002:     else           {PetscLogPrintDetailed(PETSC_COMM_WORLD,0);}
1003:   }

1005:   mname[0] = 0;

1007:   PetscOptionsGetString(NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);
1008:   PetscOptionsGetString(NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);
1009:   if (flg1 || flg2) {
1010:     if (mname[0]) PetscLogDump(mname);
1011:     else          PetscLogDump(0);
1012:   }
1013: #endif

1015:   /*
1016:      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1017:   */
1018:   PetscObjectRegisterDestroyAll();

1020:   PetscStackDestroy();

1022:   flg1 = PETSC_FALSE;
1023:   PetscOptionsGetBool(NULL,"-no_signal_handler",&flg1,NULL);
1024:   if (!flg1) { PetscPopSignalHandler();}
1025:   flg1 = PETSC_FALSE;
1026:   PetscOptionsGetBool(NULL,"-mpidump",&flg1,NULL);
1027:   if (flg1) {
1028:     PetscMPIDump(stdout);
1029:   }
1030:   flg1 = PETSC_FALSE;
1031:   flg2 = PETSC_FALSE;
1032:   /* preemptive call to avoid listing this option in options table as unused */
1033:   PetscOptionsHasName(NULL,"-malloc_dump",&flg1);
1034:   PetscOptionsHasName(NULL,"-objects_dump",&flg1);
1035:   PetscOptionsGetBool(NULL,"-options_table",&flg2,NULL);

1037:   if (flg2) {
1038:     PetscViewer viewer;
1039:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
1040:     PetscOptionsView(viewer);
1041:     PetscViewerDestroy(&viewer);
1042:   }

1044:   /* to prevent PETSc -options_left from warning */
1045:   PetscOptionsHasName(NULL,"-nox",&flg1);
1046:   PetscOptionsHasName(NULL,"-nox_warning",&flg1);

1048:   if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */
1049:     flg3 = PETSC_FALSE; /* default value is required */
1050:     PetscOptionsGetBool(NULL,"-options_left",&flg3,&flg1);
1051:     PetscOptionsAllUsed(&nopt);
1052:     if (flg3) {
1053:       if (!flg2) { /* have not yet printed the options */
1054:         PetscViewer viewer;
1055:         PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
1056:         PetscOptionsView(viewer);
1057:         PetscViewerDestroy(&viewer);
1058:       }
1059:       if (!nopt) {
1060:         PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");
1061:       } else if (nopt == 1) {
1062:         PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");
1063:       } else {
1064:         PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);
1065:       }
1066:     }
1067: #if defined(PETSC_USE_DEBUG)
1068:     if (nopt && !flg3 && !flg1) {
1069:       PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");
1070:       PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");
1071:       PetscOptionsLeft();
1072:     } else if (nopt && flg3) {
1073: #else
1074:     if (nopt && flg3) {
1075: #endif
1076:       PetscOptionsLeft();
1077:     }
1078:   }

1080:   {
1081:     PetscThreadComm tcomm_world;
1082:     PetscGetThreadCommWorld(&tcomm_world);
1083:     /* Free global thread communicator */
1084:     PetscThreadCommDestroy(&tcomm_world);
1085:   }

1087:   /*
1088:        List all objects the user may have forgot to free
1089:   */
1090:   PetscOptionsHasName(NULL,"-objects_dump",&flg1);
1091:   if (flg1) {
1092:     MPI_Comm local_comm;
1093:     char     string[64];

1095:     PetscOptionsGetString(NULL,"-objects_dump",string,64,NULL);
1096:     MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
1097:     PetscSequentialPhaseBegin_Private(local_comm,1);
1098:     PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);
1099:     PetscSequentialPhaseEnd_Private(local_comm,1);
1100:     MPI_Comm_free(&local_comm);
1101:   }
1102:   PetscObjectsCounts    = 0;
1103:   PetscObjectsMaxCounts = 0;

1105:   PetscFree(PetscObjects);

1107: #if defined(PETSC_USE_LOG)
1108:   PetscLogDestroy();
1109: #endif

1111:   /*
1112:      Destroy any packages that registered a finalize
1113:   */
1114:   PetscRegisterFinalizeAll();

1116:   /*
1117:      Destroy all the function registration lists created
1118:   */
1119:   PetscFinalize_DynamicLibraries();

1121:   /*
1122:      Print PetscFunctionLists that have not been properly freed

1124:   PetscFunctionListPrintAll();
1125:   */

1127:   if (petsc_history) {
1128:     PetscCloseHistoryFile(&petsc_history);
1129:     petsc_history = 0;
1130:   }

1132:   PetscInfoAllow(PETSC_FALSE,NULL);

1134:   {
1135:     char fname[PETSC_MAX_PATH_LEN];
1136:     FILE *fd;
1137:     int  err;

1139:     fname[0] = 0;

1141:     PetscOptionsGetString(NULL,"-malloc_dump",fname,250,&flg1);
1142:     flg2 = PETSC_FALSE;
1143:     PetscOptionsGetBool(NULL,"-malloc_test",&flg2,NULL);
1144: #if defined(PETSC_USE_DEBUG)
1145:     if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE;
1146: #else
1147:     flg2 = PETSC_FALSE;         /* Skip reporting for optimized builds regardless of -malloc_test */
1148: #endif
1149:     if (flg1 && fname[0]) {
1150:       char sname[PETSC_MAX_PATH_LEN];

1152:       sprintf(sname,"%s_%d",fname,rank);
1153:       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
1154:       PetscMallocDump(fd);
1155:       err  = fclose(fd);
1156:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1157:     } else if (flg1 || flg2) {
1158:       MPI_Comm local_comm;

1160:       MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
1161:       PetscSequentialPhaseBegin_Private(local_comm,1);
1162:       PetscMallocDump(stdout);
1163:       PetscSequentialPhaseEnd_Private(local_comm,1);
1164:       MPI_Comm_free(&local_comm);
1165:     }
1166:   }

1168:   {
1169:     char fname[PETSC_MAX_PATH_LEN];
1170:     FILE *fd = NULL;

1172:     fname[0] = 0;

1174:     PetscOptionsGetString(NULL,"-malloc_log",fname,250,&flg1);
1175:     PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg2);
1176:     if (flg1 && fname[0]) {
1177:       int err;

1179:       if (!rank) {
1180:         fd = fopen(fname,"w");
1181:         if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname);
1182:       }
1183:       PetscMallocDumpLog(fd);
1184:       if (fd) {
1185:         err = fclose(fd);
1186:         if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
1187:       }
1188:     } else if (flg1 || flg2) {
1189:       PetscMallocDumpLog(stdout);
1190:     }
1191:   }
1192:   /* Can be destroyed only after all the options are used */
1193:   PetscOptionsDestroy();

1195:   PetscGlobalArgc = 0;
1196:   PetscGlobalArgs = 0;

1198: #if defined(PETSC_USE_REAL___FLOAT128)
1199:   MPI_Type_free(&MPIU___FLOAT128);
1200: #if defined(PETSC_HAVE_COMPLEX)
1201:   MPI_Type_free(&MPIU___COMPLEX128);
1202: #endif
1203:   MPI_Op_free(&MPIU_MAX);
1204:   MPI_Op_free(&MPIU_MIN);
1205: #endif

1207: #if defined(PETSC_HAVE_COMPLEX)
1208: #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)
1209:   MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);
1210:   MPI_Type_free(&MPIU_C_COMPLEX);
1211: #endif
1212: #endif

1214: #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128)
1215:   MPI_Op_free(&MPIU_SUM);
1216: #endif

1218:   MPI_Type_free(&MPIU_2SCALAR);
1219: #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT)
1220:   MPI_Type_free(&MPIU_2INT);
1221: #endif
1222:   MPI_Op_free(&PetscMaxSum_Op);
1223:   MPI_Op_free(&PetscADMax_Op);
1224:   MPI_Op_free(&PetscADMin_Op);

1226:   /*
1227:      Destroy any known inner MPI_Comm's and attributes pointing to them
1228:      Note this will not destroy any new communicators the user has created.

1230:      If all PETSc objects were not destroyed those left over objects will have hanging references to
1231:      the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1232:  */
1233:   {
1234:     PetscCommCounter *counter;
1235:     PetscMPIInt      flg;
1236:     MPI_Comm         icomm;
1237:     union {MPI_Comm comm; void *ptr;} ucomm;
1238:     MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ucomm,&flg);
1239:     if (flg) {
1240:       icomm = ucomm.comm;
1241:       MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);
1242:       if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");

1244:       MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);
1245:       MPI_Attr_delete(icomm,Petsc_Counter_keyval);
1246:       MPI_Comm_free(&icomm);
1247:     }
1248:     MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ucomm,&flg);
1249:     if (flg) {
1250:       icomm = ucomm.comm;
1251:       MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);
1252:       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory");

1254:       MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);
1255:       MPI_Attr_delete(icomm,Petsc_Counter_keyval);
1256:       MPI_Comm_free(&icomm);
1257:     }
1258:   }

1260:   MPI_Keyval_free(&Petsc_Counter_keyval);
1261:   MPI_Keyval_free(&Petsc_InnerComm_keyval);
1262:   MPI_Keyval_free(&Petsc_OuterComm_keyval);

1264: #if defined(PETSC_HAVE_CUDA)
1265:   {
1266:     PetscInt p;
1267:     for (p = 0; p < PetscGlobalSize; ++p) {
1268:       if (p == PetscGlobalRank) cublasShutdown();
1269:       MPI_Barrier(PETSC_COMM_WORLD);
1270:     }
1271:   }
1272: #endif

1274:   if (PetscBeganMPI) {
1275: #if defined(PETSC_HAVE_MPI_FINALIZED)
1276:     PetscMPIInt flag;
1277:     MPI_Finalized(&flag);
1278:     if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
1279: #endif
1280:     MPI_Finalize();
1281:   }
1282: /*

1284:      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1285:    the communicator has some outstanding requests on it. Specifically if the
1286:    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1287:    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1288:    is never freed as it should be. Thus one may obtain messages of the form
1289:    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1290:    memory was not freed.

1292: */
1293:   PetscMallocClear();

1295:   PetscInitializeCalled = PETSC_FALSE;
1296:   PetscFinalizeCalled   = PETSC_TRUE;
1297:   PetscFunctionReturn(ierr);
1298: }

1300: #if defined(PETSC_MISSING_LAPACK_lsame_)
1301: PETSC_EXTERN int lsame_(char *a,char *b)
1302: {
1303:   if (*a == *b) return 1;
1304:   if (*a + 32 == *b) return 1;
1305:   if (*a - 32 == *b) return 1;
1306:   return 0;
1307: }
1308: #endif

1310: #if defined(PETSC_MISSING_LAPACK_lsame)
1311: PETSC_EXTERN int lsame(char *a,char *b)
1312: {
1313:   if (*a == *b) return 1;
1314:   if (*a + 32 == *b) return 1;
1315:   if (*a - 32 == *b) return 1;
1316:   return 0;
1317: }
1318: #endif