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: }