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: #if defined(PETSC_USE_COMPLEX)
120: MPI_Op PetscSum_Op = 0;

122: EXTERN_C_BEGIN
123: void PetscSum_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; i++) {
135:     xout[i] += xin[i];
136:   }

138:   PetscStackPop;
139:   return;
140: }
141: EXTERN_C_END
142: #endif

144: static int  PetscGlobalArgc   = 0;
145: static char **PetscGlobalArgs = 0;

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

151:    Not Collective

153:    Output Parameters:
154: +  argc - count of number of command line arguments
155: -  args - the command line arguments

157:    Level: intermediate

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

163:    Concepts: command line arguments
164:    
165: .seealso: PetscFinalize(), PetscInitializeFortran()

167: @*/
168: int PetscGetArgs(int *argc,char ***args)
169: {
171:   if (!PetscGlobalArgs) {
172:     SETERRQ(1,"You must call after PetscInitialize() but before PetscFinalize()");
173:   }
174:   *argc = PetscGlobalArgc;
175:   *args = PetscGlobalArgs;
176:   return(0);
177: }

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

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

187:    Input Parameters:
188: +  argc - count of number of command line arguments
189: .  args - the command line arguments
190: .  file - [optional] PETSc database file, defaults to ~username/.petscrc
191:           (use PETSC_NULL for default)
192: -  help - [optional] Help message to print, use PETSC_NULL for no message

194:    Options Database Keys:
195: +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
196: .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
197: .  -on_error_emacs <machinename> causes emacsclient to jump to error file
198: .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
199: .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
200: .  -stop_for_debugger - Print message on how to attach debugger manually to 
201:                         process and wait (-debugger_pause) seconds for attachment
202: .  -trmalloc - Indicates use of PETSc error-checking malloc
203: .  -trmalloc_off - Indicates not to use error-checking malloc
204: .  -fp_trap - Stops on floating point exceptions (Note that on the
205:               IBM RS6000 this slows code by at least a factor of 10.)
206: .  -no_signal_handler - Indicates not to trap error signals
207: .  -shared_tmp - indicates /tmp directory is shared by all processors
208: .  -not_shared_tmp - each processor has own /tmp
209: .  -tmp - alternative name of /tmp directory
210: .  -get_total_flops - returns total flops done by all processors
211: -  -get_resident_set_size - Print memory usage at end of run

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

221:    Environmental Variables:
222: +   PETSC_TMP - alternative tmp directory
223: .   PETSC_SHARED_TMP - tmp is shared by all processes
224: .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
225: .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
226: -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to


229:    Level: beginner

231:    Notes:
232:    If for some reason you must call MPI_Init() separately, call
233:    it before PetscInitialize().

235:    Fortran Version:
236:    In Fortran this routine has the format
237: $       call PetscInitialize(file,ierr)

239: +   ierr - error return code
240: -   file - [optional] PETSc database file name, defaults to 
241:            ~username/.petscrc (use PETSC_NULL_CHARACTER for default)
242:            
243:    Important Fortran Note:
244:    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
245:    null character string; you CANNOT just use PETSC_NULL as 
246:    in the C version.  See the users manual for details.


249:    Concepts: initializing PETSc
250:    
251: .seealso: PetscFinalize(), PetscInitializeFortran(), PetescGetArgs()

253: @*/
254: int PetscInitialize(int *argc,char ***args,char file[],const char help[])
255: {
256:   int        ierr,flag,dummy_tag,size;
257:   PetscTruth flg;
258:   char       hostname[64];

261:   if (PetscInitializeCalled) return(0);
262:   if (argc && args) {
263:     PetscGlobalArgc = *argc;
264:     PetscGlobalArgs = *args;
265:   }

267:   PetscOptionsCreate();

269:   /*
270:      We initialize the program name here (before MPI_Init()) because MPICH has a bug in 
271:      it that it sets args[0] on all processors to be args[0] on the first processor.
272:   */
273:   if (argc && *argc) {
274:     PetscSetProgramName(**args);
275:   } else {
276:     PetscSetProgramName("Unknown Name");
277:   }

279:   /* Also initialize the initial datestamp */
280:   PetscSetInitialDate();

282:   MPI_Initialized(&flag);
283:   if (!flag) {
284:     ierr          = MPI_Init(argc,args);
285:     PetscBeganMPI = PETSC_TRUE;
286:   }
287:   PetscInitializeCalled = PETSC_TRUE;

289:   if (!PETSC_COMM_WORLD) {
290:     PETSC_COMM_WORLD = MPI_COMM_WORLD;
291:   }

293:   MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);
294:   MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);

296: #if defined(PETSC_USE_COMPLEX)
297:   /* 
298:      Initialized the global complex variable; this is because with 
299:      shared libraries the constructors for global variables
300:      are not called; at least on IRIX.
301:   */
302:   {
303:     PetscScalar ic(0.0,1.0);
304:     PETSC_i = ic;
305:   }
306:   MPI_Type_contiguous(2,MPIU_REAL,&MPIU_COMPLEX);
307:   MPI_Type_commit(&MPIU_COMPLEX);
308:   MPI_Op_create(PetscSum_Local,1,&PetscSum_Op);
309: #endif

311:   /*
312:      Create the PETSc MPI reduction operator that sums of the first
313:      half of the entries and maxes the second half.
314:   */
315:   MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);
316:   /*
317:      Build the options database and check for user setup requests
318:   */
319:   PetscOptionsInsert(argc,args,file);

321:   /*
322:      Print main application help message
323:   */
324:   PetscOptionsHasName(PETSC_NULL,"-help",&flg);
325:   if (help && flg) {
326:     PetscPrintf(PETSC_COMM_WORLD,help);
327:   }
328:   PetscOptionsCheckInitial();

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

333:   /*
334:      Initialize PETSC_COMM_SELF and WORLD as a MPI_Comm with the PETSc attribute.
335:     
336:      We delay until here to do it, since PetscMalloc() may not have been
337:      setup before this.
338:   */
339:   PetscCommDuplicate_Private(MPI_COMM_SELF,&PETSC_COMM_SELF,&dummy_tag);
340:   PetscCommDuplicate_Private(PETSC_COMM_WORLD,&PETSC_COMM_WORLD,&dummy_tag);

342:   /*
343:      Load the dynamic libraries (on machines that support them), this registers all
344:      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
345:   */
346:   PetscInitialize_DynamicLibraries();

348:   /*
349:      Initialize all the default viewers
350:   */
351:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
352:   PetscLogInfo(0,"PetscInitialize:PETSc successfully started: number of processors = %dn",size);
353:   PetscGetHostName(hostname,64);
354:   PetscLogInfo(0,"PetscInitialize:Running on machine: %sn",hostname);

356:   PetscOptionsCheckInitial_Components();

358:   PetscFunctionReturn(ierr);
359: }


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

366:    Collective on PETSC_COMM_WORLD

368:    Options Database Keys:
369: +  -options_table - Calls OptionsPrint()
370: .  -options_left - Prints unused options that remain in the database
371: .  -options_left no - Does not print unused options that remain in the database
372: .  -mpidump - Calls PetscMPIDump()
373: .  -trdump - Calls PetscTrDump()
374: .  -trinfo - Prints total memory usage
375: .  -trdebug - Calls malloc_debug(2) to activate memory
376:         allocation diagnostics (used by PETSC_ARCH=sun4, 
377:         BOPT=[g,g_c++,g_complex] only!)
378: -  -trmalloc_log - Prints summary of memory usage

380:    Options Database Keys for Profiling:
381:    See the Profiling chapter of the users manual for details.
382: +  -log_summary [filename] - Prints summary of flop and timing
383:         information to screen. If the filename is specified the
384:         summary is written to the file. (for code compiled with 
385:         PETSC_USE_LOG).  See PetscLogPrintSummary().
386: .  -log_all [filename] - Logs extensive profiling information
387:         (for code compiled with PETSC_USE_LOG). See PetscLogDump(). 
388: .  -log [filename] - Logs basic profiline information (for
389:         code compiled with PETSC_USE_LOG).  See PetscLogDump().
390: .  -log_sync - Log the synchronization in scatters, inner products
391:         and norms
392: -  -log_mpe [filename] - Creates a logfile viewable by the 
393:       utility Upshot/Nupshot (in MPICH distribution)

395:    Level: beginner

397:    Note:
398:    See PetscInitialize() for more general runtime options.

400: .seealso: PetscInitialize(), PetscOptionsPrint(), PetscTrDump(), PetscMPIDump(), PetscEnd()
401: @*/
402: int PetscFinalize(void)
403: {
404:   int            ierr,rank,nopt;
405:   PetscLogDouble rss;
406:   PetscTruth     flg1,flg2,flg3;
407: 

410:   if (!PetscInitializeCalled) {
411:     (*PetscErrorPrintf)("PETSc ERROR: PetscInitialize() must be called before PetscFinalize()n");
412:     return(0);
413:   }
414:   /* Destroy auxiliary packages */
415:   PetscViewerMathematicaFinalizePackage();
416:   PetscPLAPACKFinalizePackage();

418:   /*
419:      Destroy all the function registration lists created
420:   */
421:   PetscFinalize_DynamicLibraries();


424:   PetscOptionsHasName(PETSC_NULL,"-get_resident_set_size",&flg1);
425:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
426:   if (flg1) {
427:     PetscGetResidentSetSize(&rss);
428:     PetscPrintf(PETSC_COMM_SELF,"[%d] Size of entire process memory %dn",rank,(int)rss);
429:   }

431: #if defined(PETSC_USE_LOG)
432:   PetscOptionsHasName(PETSC_NULL,"-get_total_flops",&flg1);
433:   if (flg1) {
434:     PetscLogDouble flops = 0;
435:     MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);
436:     PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %gn",flops);
437:   }
438: #endif

440:   /*
441:      Free all objects registered with PetscObjectRegisterDestroy() such ast
442:     PETSC_VIEWER_XXX_().
443:   */
444:   PetscObjectRegisterDestroyAll();

446: #if defined(PETSC_USE_STACK)
447:   if (PetscStackActive) {
448:     PetscStackDestroy();
449:   }
450: #endif

452: #if defined(PETSC_USE_LOG)
453:   {
454:     char mname[64];
455: #if defined(PETSC_HAVE_MPE)
456:     mname[0] = 0;
457:     PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,64,&flg1);
458:     if (flg1){
459:       if (mname[0]) {PetscLogMPEDump(mname);}
460:       else          {PetscLogMPEDump(0);}
461:     }
462: #endif
463:     mname[0] = 0;
464:     PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,64,&flg1);
465:     if (flg1) {
466:       if (mname[0])  {PetscLogPrintSummary(PETSC_COMM_WORLD,mname);}
467:       else           {PetscLogPrintSummary(PETSC_COMM_WORLD,0);}
468:     }

470:     mname[0] = 0;
471:     PetscOptionsGetString(PETSC_NULL,"-log_all",mname,64,&flg1);
472:     PetscOptionsGetString(PETSC_NULL,"-log",mname,64,&flg2);
473:     if (flg1 || flg2){
474:       if (mname[0]) PetscLogDump(mname);
475:       else          PetscLogDump(0);
476:     }
477:     PetscLogDestroy();
478:   }
479: #endif
480:   PetscOptionsHasName(PETSC_NULL,"-no_signal_handler",&flg1);
481:   if (!flg1) { PetscPopSignalHandler();}
482:   PetscOptionsHasName(PETSC_NULL,"-mpidump",&flg1);
483:   if (flg1) {
484:     PetscMPIDump(stdout);
485:   }
486:   PetscOptionsHasName(PETSC_NULL,"-trdump",&flg1);
487:   PetscOptionsHasName(PETSC_NULL,"-optionstable",&flg1);
488:   PetscOptionsHasName(PETSC_NULL,"-options_table",&flg2);
489:   if (flg1 && flg2) {
490:     if (!rank) {PetscOptionsPrint(stdout);}
491:   }

493:   /* to prevent PETSc -options_left from warning */
494:   PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
495:   PetscOptionsHasName(PETSC_NULL,"-error_output_stderr",&flg1);

497:   PetscOptionsGetLogical(PETSC_NULL,"-options_left",&flg2,&flg1);
498:   PetscOptionsAllUsed(&nopt);
499:   if (flg2) {
500:     PetscOptionsPrint(stdout);
501:     if (!nopt) {
502:       PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.n");
503:     } else if (nopt == 1) {
504:       PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:n");
505:     } else {
506:       PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:n",nopt);
507:     }
508:   }
509: #if defined(PETSC_USE_BOPT_g)
510:   if (nopt && !flg1 && !flg2) {
511:     PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!n");
512:     PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!n");
513: #else 
514:   if (nopt && flg2) {
515: #endif
516:     PetscOptionsLeft();
517:   }

519:   PetscOptionsHasName(PETSC_NULL,"-log_history",&flg1);
520:   if (flg1) {
521:     PetscLogCloseHistoryFile(&petsc_history);
522:     petsc_history = 0;
523:   }


526:   /*
527:        Destroy PETSC_COMM_SELF/WORLD as a MPI_Comm with the PETSc 
528:      attribute.
529:   */
530:   PetscCommDestroy_Private(&PETSC_COMM_SELF);
531:   PetscCommDestroy_Private(&PETSC_COMM_WORLD);

533:   /*
534:        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
535:   */
536:   PetscFListDestroyAll();

538:   PetscOptionsHasName(PETSC_NULL,"-trdump",&flg1);
539:   PetscOptionsHasName(PETSC_NULL,"-trinfo",&flg2);
540:   PetscOptionsHasName(PETSC_NULL,"-trmalloc_log",&flg3);
541:   if (flg1) {
542:     char fname[256];
543:     FILE *fd;
544: 
545:     fname[0] = 0;
546:     PetscOptionsGetString(PETSC_NULL,"-trdump",fname,250,&flg1);
547:     if (flg1 && fname[0]) {
548:       char sname[256];

550:       sprintf(sname,"%s_%d",fname,rank);
551:       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(1,"Cannot open log file: %s",sname);
552:       PetscTrDump(fd);
553:       fclose(fd);
554:     } else {
555:       MPI_Comm local_comm;

557:       MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
558:       PetscSequentialPhaseBegin_Private(local_comm,1);
559:         PetscTrDump(stdout);
560:       PetscSequentialPhaseEnd_Private(local_comm,1);
561:       MPI_Comm_free(&local_comm);
562:     }
563:   } else if (flg2) {
564:     MPI_Comm       local_comm;
565:     PetscLogDouble maxm;

567:     MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
568:     PetscTrSpace(PETSC_NULL,PETSC_NULL,&maxm);
569:     PetscSequentialPhaseBegin_Private(local_comm,1);
570:       printf("[%d] Maximum memory used %gn",rank,maxm);
571:     PetscSequentialPhaseEnd_Private(local_comm,1);
572:     MPI_Comm_free(&local_comm);
573:   }
574:   if (flg3) {
575:     char fname[256];
576:     FILE *fd;
577: 
578:     fname[0] = 0;
579:     PetscOptionsGetString(PETSC_NULL,"-trmalloc_log",fname,250,&flg1);
580:     if (flg1 && fname[0]) {
581:       char sname[256];

583:       sprintf(sname,"%s_%d",fname,rank);
584:       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(1,"Cannot open log file: %s",sname);
585:       PetscTrLogDump(fd);
586:       fclose(fd);
587:     } else {
588:       PetscTrLogDump(stdout);
589:     }
590:   }
591:   /* Can be destroyed only after all the options are used */
592:   PetscOptionsDestroy();

594:   PetscGlobalArgc = 0;
595:   PetscGlobalArgs = 0;

597:   PetscLogInfo(0,"PetscFinalize:PETSc successfully ended!n");
598:   if (PetscBeganMPI) {
599:     MPI_Finalize();
600:   }

602: /*

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

612: */
613:   PetscClearMalloc();
614:   PetscInitializeCalled = PETSC_FALSE;
615:   PetscFunctionReturn(ierr);
616: }