Actual source code: pinit.c

  1: /*$Id: pinit.c,v 1.58 2001/08/10 03:28:54 bsmith Exp $*/
  2: /*
  3:    This file defines the initialization of PETSc, including PetscInitialize()
  4: */

 6:  #include petsc.h
 7:  #include petscsys.h

  9: EXTERN int PetscLogBegin_Private(void);

 11: /* -----------------------------------------------------------------------------------------*/

 13: extern FILE *petsc_history;

 15: EXTERN int PetscInitialize_DynamicLibraries(void);
 16: EXTERN int PetscFinalize_DynamicLibraries(void);
 17: EXTERN int PetscFListDestroyAll(void);
 18: EXTERN int PetscSequentialPhaseBegin_Private(MPI_Comm,int);
 19: EXTERN int PetscSequentialPhaseEnd_Private(MPI_Comm,int);
 20: EXTERN int PetscLogCloseHistoryFile(FILE **);

 22: /* this is used by the _, __, and ___ macros (see include/petscerror.h) */
 23: int __g0;

 25: /*
 26:        Checks the options database for initializations related to the 
 27:     PETSc components
 28: */
 29: int PetscOptionsCheckInitial_Components(void)
 30: {
 31:   MPI_Comm   comm = PETSC_COMM_WORLD;
 32:   PetscTruth flg1;
 33:   int        ierr;

 36:   /*
 37:      Publishing to the AMS
 38:   */
 39: #if defined(PETSC_HAVE_AMS)
 40:   PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg1);
 41:   if (flg1) {
 42:     PetscAMSPublishAll = PETSC_TRUE;
 43:   }
 44:   PetscOptionsHasName(PETSC_NULL,"-ams_publish_stack",&flg1);
 45:   if (flg1) {
 46:     PetscStackPublish();
 47:   }
 48: #endif

 50:   PetscOptionsHasName(PETSC_NULL,"-help",&flg1);
 51:   if (flg1) {
 52: #if defined (PETSC_USE_LOG)
 53:     (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------n");
 54:     (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,sles,snes>n");
 55:     (*PetscHelpPrintf)(comm," -log_info_exclude: <null,vec,mat,sles,snes,ts>n");
 56:     (*PetscHelpPrintf)(comm,"-----------------------------------------------n");
 57: #endif
 58:   }
 59:   return(0);
 60: }

 62: /*@C
 63:       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
 64:         the command line arguments.

 66:    Collective
 67:   
 68:    Level: advanced

 70: .seealso: PetscInitialize(), PetscInitializeFortran()
 71: @*/
 72: int PetscInitializeNoArguments(void)
 73: {
 74:   int ierr,argc = 0;
 75:   char **args = 0;

 78:   PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
 79:   PetscFunctionReturn(ierr);
 80: }

 82: EXTERN int        PetscOptionsCheckInitial(void);
 83: extern PetscTruth PetscBeganMPI;

 85: /*
 86:        This function is the MPI reduction operation used to compute the sum of the 
 87:    first half of the entries and the max of the second half.
 88: */
 89: MPI_Op PetscMaxSum_Op = 0;

 91: EXTERN_C_BEGIN
 92: void PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
 93: {
 94:   int *xin = (int *)in,*xout = (int*)out,i,count = *cnt;

 97:   if (*datatype != MPI_INT) {
 98:     (*PetscErrorPrintf)("Can only handle MPI_INT data types");
 99:     MPI_Abort(MPI_COMM_WORLD,1);
100:   }
101:   if (count % 2) {
102:     (*PetscErrorPrintf)("Count must be divisible by 2");
103:     MPI_Abort(MPI_COMM_WORLD,1);
104:   }

106:   count = count/2;
107:   for (i=0; i<count; i++) {
108:     xout[i] = PetscMax(xout[i],xin[i]);
109:   }
110:   for (i=count; i<2*count; i++) {
111:     xout[i] += xin[i];
112:   }

114:   PetscStackPop;
115:   return;
116: }
117: EXTERN_C_END

119: /* ----------------------------------------------------------------------------*/
120: MPI_Op PetscADMax_Op = 0;

122: EXTERN_C_BEGIN
123: void PetscADMax_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
124: {
125:   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
126:   int         i,count = *cnt;

129:   if (*datatype != MPIU_SCALAR) {
130:     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
131:     MPI_Abort(MPI_COMM_WORLD,1);
132:   }

134:   for (i=0; i<count/2; i++) {
135:     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
136:       xout[2*i]   = xin[2*i];
137:       xout[2*i+1] = xin[2*i+1];
138:     }
139:   }

141:   PetscStackPop;
142:   return;
143: }
144: EXTERN_C_END

146: MPI_Op PetscADMin_Op = 0;

148: EXTERN_C_BEGIN
149: void PetscADMin_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
150: {
151:   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
152:   int         i,count = *cnt;

155:   if (*datatype != MPIU_SCALAR) {
156:     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
157:     MPI_Abort(MPI_COMM_WORLD,1);
158:   }

160:   for (i=0; i<count/2; i++) {
161:     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
162:       xout[2*i]   = xin[2*i];
163:       xout[2*i+1] = xin[2*i+1];
164:     }
165:   }

167:   PetscStackPop;
168:   return;
169: }
170: EXTERN_C_END
171: /* ---------------------------------------------------------------------------------------*/

173: #if defined(PETSC_USE_COMPLEX)
174: MPI_Op PetscSum_Op = 0;

176: EXTERN_C_BEGIN
177: void PetscSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
178: {
179:   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
180:   int         i,count = *cnt;

183:   if (*datatype != MPIU_SCALAR) {
184:     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
185:     MPI_Abort(MPI_COMM_WORLD,1);
186:   }

188:   for (i=0; i<count; i++) {
189:     xout[i] += xin[i];
190:   }

192:   PetscStackPop;
193:   return;
194: }
195: EXTERN_C_END
196: #endif

198: static int  PetscGlobalArgc   = 0;
199: static char **PetscGlobalArgs = 0;

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

205:    Not Collective

207:    Output Parameters:
208: +  argc - count of number of command line arguments
209: -  args - the command line arguments

211:    Level: intermediate

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

217:    Concepts: command line arguments
218:    
219: .seealso: PetscFinalize(), PetscInitializeFortran()

221: @*/
222: int PetscGetArgs(int *argc,char ***args)
223: {
225:   if (!PetscGlobalArgs) {
226:     SETERRQ(1,"You must call after PetscInitialize() but before PetscFinalize()");
227:   }
228:   *argc = PetscGlobalArgc;
229:   *args = PetscGlobalArgs;
230:   return(0);
231: }

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

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

241:    Input Parameters:
242: +  argc - count of number of command line arguments
243: .  args - the command line arguments
244: .  file - [optional] PETSc database file, defaults to ~username/.petscrc
245:           (use PETSC_NULL for default)
246: -  help - [optional] Help message to print, use PETSC_NULL for no message

248:    Options Database Keys:
249: +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
250: .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
251: .  -on_error_emacs <machinename> causes emacsclient to jump to error file
252: .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
253: .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
254: .  -stop_for_debugger - Print message on how to attach debugger manually to 
255:                         process and wait (-debugger_pause) seconds for attachment
256: .  -trmalloc - Indicates use of PETSc error-checking malloc
257: .  -trmalloc_off - Indicates not to use error-checking malloc
258: .  -fp_trap - Stops on floating point exceptions (Note that on the
259:               IBM RS6000 this slows code by at least a factor of 10.)
260: .  -no_signal_handler - Indicates not to trap error signals
261: .  -shared_tmp - indicates /tmp directory is shared by all processors
262: .  -not_shared_tmp - each processor has own /tmp
263: .  -tmp - alternative name of /tmp directory
264: .  -get_total_flops - returns total flops done by all processors
265: -  -get_resident_set_size - Print memory usage at end of run

267:    Options Database Keys for Profiling:
268:    See the Profiling chapter of the users manual for details.
269: +  -log_trace [filename] - Print traces of all PETSc calls
270:         to the screen (useful to determine where a program
271:         hangs without running in the debugger).  See PetscLogTraceBegin().
272: .  -log_info <optional filename> - Prints verbose information to the screen
273: -  -log_info_exclude <null,vec,mat,sles,snes,ts> - Excludes some of the verbose messages

275:    Environmental Variables:
276: +   PETSC_TMP - alternative tmp directory
277: .   PETSC_SHARED_TMP - tmp is shared by all processes
278: .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
279: .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
280: -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to


283:    Level: beginner

285:    Notes:
286:    If for some reason you must call MPI_Init() separately, call
287:    it before PetscInitialize().

289:    Fortran Version:
290:    In Fortran this routine has the format
291: $       call PetscInitialize(file,ierr)

293: +   ierr - error return code
294: -   file - [optional] PETSc database file name, defaults to 
295:            ~username/.petscrc (use PETSC_NULL_CHARACTER for default)
296:            
297:    Important Fortran Note:
298:    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
299:    null character string; you CANNOT just use PETSC_NULL as 
300:    in the C version.  See the users manual for details.


303:    Concepts: initializing PETSc
304:    
305: .seealso: PetscFinalize(), PetscInitializeFortran(), PetescGetArgs()

307: @*/
308: int PetscInitialize(int *argc,char ***args,char file[],const char help[])
309: {
310:   int        ierr,flag,dummy_tag,size;
311:   PetscTruth flg;
312:   char       hostname[64];

315:   if (PetscInitializeCalled) return(0);
316:   if (argc && args) {
317:     PetscGlobalArgc = *argc;
318:     PetscGlobalArgs = *args;
319:   }

321:   PetscOptionsCreate();

323:   /*
324:      We initialize the program name here (before MPI_Init()) because MPICH has a bug in 
325:      it that it sets args[0] on all processors to be args[0] on the first processor.
326:   */
327:   if (argc && *argc) {
328:     PetscSetProgramName(**args);
329:   } else {
330:     PetscSetProgramName("Unknown Name");
331:   }

333:   /* Also initialize the initial datestamp */
334:   PetscSetInitialDate();

336:   MPI_Initialized(&flag);
337:   if (!flag) {
338:     ierr          = MPI_Init(argc,args);
339:     PetscBeganMPI = PETSC_TRUE;
340:   }
341:   PetscInitializeCalled = PETSC_TRUE;

343:   if (!PETSC_COMM_WORLD) {
344:     PETSC_COMM_WORLD = MPI_COMM_WORLD;
345:   }

347:   MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);
348:   MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);

350: #if defined(PETSC_USE_COMPLEX)
351:   /* 
352:      Initialized the global complex variable; this is because with 
353:      shared libraries the constructors for global variables
354:      are not called; at least on IRIX.
355:   */
356:   {
357:     PetscScalar ic(0.0,1.0);
358:     PETSC_i = ic;
359:   }
360:   MPI_Type_contiguous(2,MPIU_REAL,&MPIU_COMPLEX);
361:   MPI_Type_commit(&MPIU_COMPLEX);
362:   MPI_Op_create(PetscSum_Local,1,&PetscSum_Op);
363: #endif

365:   /*
366:      Create the PETSc MPI reduction operator that sums of the first
367:      half of the entries and maxes the second half.
368:   */
369:   MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);

371:   MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);
372:   MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);

374:   /*
375:      Build the options database and check for user setup requests
376:   */
377:   PetscOptionsInsert(argc,args,file);

379:   /*
380:      Print main application help message
381:   */
382:   PetscOptionsHasName(PETSC_NULL,"-help",&flg);
383:   if (help && flg) {
384:     PetscPrintf(PETSC_COMM_WORLD,help);
385:   }
386:   PetscOptionsCheckInitial();

388:   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we od not print it out */
389:   PetscLogBegin_Private();

391:   /*
392:      Initialize PETSC_COMM_SELF and WORLD as a MPI_Comm with the PETSc attribute.
393:     
394:      We delay until here to do it, since PetscMalloc() may not have been
395:      setup before this.
396:   */
397:   PetscCommDuplicate_Private(MPI_COMM_SELF,&PETSC_COMM_SELF,&dummy_tag);
398:   PetscCommDuplicate_Private(PETSC_COMM_WORLD,&PETSC_COMM_WORLD,&dummy_tag);

400:   /*
401:      Load the dynamic libraries (on machines that support them), this registers all
402:      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
403:   */
404:   PetscInitialize_DynamicLibraries();

406:   /*
407:      Initialize all the default viewers
408:   */
409:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
410:   PetscLogInfo(0,"PetscInitialize:PETSc successfully started: number of processors = %dn",size);
411:   PetscGetHostName(hostname,64);
412:   PetscLogInfo(0,"PetscInitialize:Running on machine: %sn",hostname);

414:   PetscOptionsCheckInitial_Components();

416:   PetscFunctionReturn(ierr);
417: }


420: /*@C 
421:    PetscFinalize - Checks for options to be called at the conclusion
422:    of the program and calls MPI_Finalize().

424:    Collective on PETSC_COMM_WORLD

426:    Options Database Keys:
427: +  -options_table - Calls OptionsPrint()
428: .  -options_left - Prints unused options that remain in the database
429: .  -options_left no - Does not print unused options that remain in the database
430: .  -mpidump - Calls PetscMPIDump()
431: .  -trdump - Calls PetscTrDump()
432: .  -trinfo - Prints total memory usage
433: .  -trdebug - Calls malloc_debug(2) to activate memory
434:         allocation diagnostics (used by PETSC_ARCH=sun4, 
435:         BOPT=[g,g_c++,g_complex] only!)
436: -  -trmalloc_log - Prints summary of memory usage

438:    Options Database Keys for Profiling:
439:    See the Profiling chapter of the users manual for details.
440: +  -log_summary [filename] - Prints summary of flop and timing
441:         information to screen. If the filename is specified the
442:         summary is written to the file. (for code compiled with 
443:         PETSC_USE_LOG).  See PetscLogPrintSummary().
444: .  -log_all [filename] - Logs extensive profiling information
445:         (for code compiled with PETSC_USE_LOG). See PetscLogDump(). 
446: .  -log [filename] - Logs basic profiline information (for
447:         code compiled with PETSC_USE_LOG).  See PetscLogDump().
448: .  -log_sync - Log the synchronization in scatters, inner products
449:         and norms
450: -  -log_mpe [filename] - Creates a logfile viewable by the 
451:       utility Upshot/Nupshot (in MPICH distribution)

453:    Level: beginner

455:    Note:
456:    See PetscInitialize() for more general runtime options.

458: .seealso: PetscInitialize(), PetscOptionsPrint(), PetscTrDump(), PetscMPIDump(), PetscEnd()
459: @*/
460: int PetscFinalize(void)
461: {
462:   int            ierr,rank,nopt;
463:   PetscLogDouble rss;
464:   PetscTruth     flg1,flg2,flg3;
465: 

468:   if (!PetscInitializeCalled) {
469:     (*PetscErrorPrintf)("PETSc ERROR: PetscInitialize() must be called before PetscFinalize()n");
470:     return(0);
471:   }
472:   /* Destroy auxiliary packages */
473:   PetscViewerMathematicaFinalizePackage();
474:   PetscPLAPACKFinalizePackage();

476:   /*
477:      Destroy all the function registration lists created
478:   */
479:   PetscFinalize_DynamicLibraries();


482:   PetscOptionsHasName(PETSC_NULL,"-get_resident_set_size",&flg1);
483:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
484:   if (flg1) {
485:     PetscGetResidentSetSize(&rss);
486:     PetscPrintf(PETSC_COMM_SELF,"[%d] Size of entire process memory %dn",rank,(int)rss);
487:   }

489: #if defined(PETSC_USE_LOG)
490:   PetscOptionsHasName(PETSC_NULL,"-get_total_flops",&flg1);
491:   if (flg1) {
492:     PetscLogDouble flops = 0;
493:     MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);
494:     PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %gn",flops);
495:   }
496: #endif

498:   /*
499:      Free all objects registered with PetscObjectRegisterDestroy() such ast
500:     PETSC_VIEWER_XXX_().
501:   */
502:   PetscObjectRegisterDestroyAll();

504: #if defined(PETSC_USE_STACK)
505:   if (PetscStackActive) {
506:     PetscStackDestroy();
507:   }
508: #endif

510: #if defined(PETSC_USE_LOG)
511:   {
512:     char mname[64];
513: #if defined(PETSC_HAVE_MPE)
514:     mname[0] = 0;
515:     PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,64,&flg1);
516:     if (flg1){
517:       if (mname[0]) {PetscLogMPEDump(mname);}
518:       else          {PetscLogMPEDump(0);}
519:     }
520: #endif
521:     mname[0] = 0;
522:     PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,64,&flg1);
523:     if (flg1) {
524:       if (mname[0])  {PetscLogPrintSummary(PETSC_COMM_WORLD,mname);}
525:       else           {PetscLogPrintSummary(PETSC_COMM_WORLD,0);}
526:     }

528:     mname[0] = 0;
529:     PetscOptionsGetString(PETSC_NULL,"-log_all",mname,64,&flg1);
530:     PetscOptionsGetString(PETSC_NULL,"-log",mname,64,&flg2);
531:     if (flg1 || flg2){
532:       if (mname[0]) PetscLogDump(mname);
533:       else          PetscLogDump(0);
534:     }
535:     PetscLogDestroy();
536:   }
537: #endif
538:   PetscOptionsHasName(PETSC_NULL,"-no_signal_handler",&flg1);
539:   if (!flg1) { PetscPopSignalHandler();}
540:   PetscOptionsHasName(PETSC_NULL,"-mpidump",&flg1);
541:   if (flg1) {
542:     PetscMPIDump(stdout);
543:   }
544:   PetscOptionsHasName(PETSC_NULL,"-trdump",&flg1);
545:   PetscOptionsHasName(PETSC_NULL,"-optionstable",&flg1);
546:   PetscOptionsHasName(PETSC_NULL,"-options_table",&flg2);
547:   if (flg1 && flg2) {
548:     if (!rank) {PetscOptionsPrint(stdout);}
549:   }

551:   /* to prevent PETSc -options_left from warning */
552:   PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
553:   PetscOptionsHasName(PETSC_NULL,"-error_output_stderr",&flg1);

555:   PetscOptionsGetLogical(PETSC_NULL,"-options_left",&flg2,&flg1);
556:   PetscOptionsAllUsed(&nopt);
557:   if (flg2) {
558:     PetscOptionsPrint(stdout);
559:     if (!nopt) {
560:       PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.n");
561:     } else if (nopt == 1) {
562:       PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:n");
563:     } else {
564:       PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:n",nopt);
565:     }
566:   }
567: #if defined(PETSC_USE_BOPT_g)
568:   if (nopt && !flg1 && !flg2) {
569:     PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!n");
570:     PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!n");
571:     PetscOptionsLeft();
572:   } else if (nopt && flg2) {
573: #else 
574:   if (nopt && flg2) {
575: #endif
576:     PetscOptionsLeft();
577:   }

579:   PetscOptionsHasName(PETSC_NULL,"-log_history",&flg1);
580:   if (flg1) {
581:     PetscLogCloseHistoryFile(&petsc_history);
582:     petsc_history = 0;
583:   }


586:   /*
587:        Destroy PETSC_COMM_SELF/WORLD as a MPI_Comm with the PETSc 
588:      attribute.
589:   */
590:   PetscCommDestroy_Private(&PETSC_COMM_SELF);
591:   PetscCommDestroy_Private(&PETSC_COMM_WORLD);

593:   /*
594:        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
595:   */
596:   PetscFListDestroyAll();

598:   PetscOptionsHasName(PETSC_NULL,"-trdump",&flg1);
599:   PetscOptionsHasName(PETSC_NULL,"-trinfo",&flg2);
600:   PetscOptionsHasName(PETSC_NULL,"-trmalloc_log",&flg3);
601:   if (flg1) {
602:     char fname[256];
603:     FILE *fd;
604: 
605:     fname[0] = 0;
606:     PetscOptionsGetString(PETSC_NULL,"-trdump",fname,250,&flg1);
607:     if (flg1 && fname[0]) {
608:       char sname[256];

610:       sprintf(sname,"%s_%d",fname,rank);
611:       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(1,"Cannot open log file: %s",sname);
612:       PetscTrDump(fd);
613:       fclose(fd);
614:     } else {
615:       MPI_Comm local_comm;

617:       MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
618:       PetscSequentialPhaseBegin_Private(local_comm,1);
619:         PetscTrDump(stdout);
620:       PetscSequentialPhaseEnd_Private(local_comm,1);
621:       MPI_Comm_free(&local_comm);
622:     }
623:   } else if (flg2) {
624:     MPI_Comm       local_comm;
625:     PetscLogDouble maxm;

627:     MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
628:     PetscTrSpace(PETSC_NULL,PETSC_NULL,&maxm);
629:     PetscSequentialPhaseBegin_Private(local_comm,1);
630:       printf("[%d] Maximum memory used %gn",rank,maxm);
631:     PetscSequentialPhaseEnd_Private(local_comm,1);
632:     MPI_Comm_free(&local_comm);
633:   }
634:   if (flg3) {
635:     char fname[256];
636:     FILE *fd;
637: 
638:     fname[0] = 0;
639:     PetscOptionsGetString(PETSC_NULL,"-trmalloc_log",fname,250,&flg1);
640:     if (flg1 && fname[0]) {
641:       char sname[256];

643:       sprintf(sname,"%s_%d",fname,rank);
644:       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(1,"Cannot open log file: %s",sname);
645:       PetscTrLogDump(fd);
646:       fclose(fd);
647:     } else {
648:       PetscTrLogDump(stdout);
649:     }
650:   }
651:   /* Can be destroyed only after all the options are used */
652:   PetscOptionsDestroy();

654:   PetscGlobalArgc = 0;
655:   PetscGlobalArgs = 0;

657:   PetscLogInfo(0,"PetscFinalize:PETSc successfully ended!n");
658:   if (PetscBeganMPI) {
659:     MPI_Finalize();
660:   }

662: /*

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

672: */
673:   PetscClearMalloc();
674:   PetscInitializeCalled = PETSC_FALSE;
675:   PetscFunctionReturn(ierr);
676: }

678: /*
679:      These may be used in code that ADIC is to be used on
680: */

682: /*@C
683:       PetscGlobalMax - Computes the maximum value over several processors

685:      Collective on MPI_Comm

687:    Input Parameters:
688: +   local - the local value
689: -   comm - the processors that find the maximum

691:    Output Parameter:
692: .   result - the maximum value
693:   
694:    Level: intermediate

696:    Notes:
697:      These functions are to be used inside user functions that are to be processed with 
698:    ADIC. PETSc will automatically provide differentiated versions of these functions

700: .seealso: PetscGlobalMin(), PetscGlobalSum()
701: @*/
702: int PetscGlobalMax(double* local,double* result,MPI_Comm comm)
703: {
704:   return MPI_Allreduce(local,result,1,MPI_DOUBLE,MPI_MAX,comm);
705: }

707: /*@C
708:       PetscGlobalMin - Computes the minimum value over several processors

710:      Collective on MPI_Comm

712:    Input Parameters:
713: +   local - the local value
714: -   comm - the processors that find the minimum

716:    Output Parameter:
717: .   result - the minimum value
718:   
719:    Level: intermediate

721:    Notes:
722:      These functions are to be used inside user functions that are to be processed with 
723:    ADIC. PETSc will automatically provide differentiated versions of these functions

725: .seealso: PetscGlobalMax(), PetscGlobalSum()
726: @*/
727: int PetscGlobalMin(double* local,double* result,MPI_Comm comm)
728: {
729:   return MPI_Allreduce(local,result,1,MPI_DOUBLE,MPI_MIN,comm);
730: }

732: /*@C
733:       PetscGlobalSum - Computes the sum over sever processors

735:      Collective on MPI_Comm

737:    Input Parameters:
738: +   local - the local value
739: -   comm - the processors that find the sum

741:    Output Parameter:
742: .   result - the sum
743:   
744:    Level: intermediate

746:    Notes:
747:      These functions are to be used inside user functions that are to be processed with 
748:    ADIC. PETSc will automatically provide differentiated versions of these functions

750: .seealso: PetscGlobalMin(), PetscGlobalMax()
751: @*/
752: int PetscGlobalSum(PetscScalar* local,PetscScalar* result,MPI_Comm comm)
753: {
754:   return MPI_Allreduce(local,result,1,MPIU_SCALAR,PetscSum_Op,comm);
755: }