xref: /petsc/src/sys/info/verboseinfo.c (revision 61bb57ed3979a08b29eaff0911e2dad60879110d)
1 /*
2       PetscInfo() is contained in a different file from the other profiling to
3    allow it to be replaced at link time by an alternative routine.
4 */
5 #include <petsc/private/petscimpl.h>        /*I    "petscsys.h"   I*/
6 
7 /*
8   The next set of variables determine which, if any, PetscInfo() calls are used.
9   If PetscLogPrintInfo is false, no info messages are printed.
10 
11   If PetscInfoFlags[OBJECT_CLASSID - PETSC_SMALLEST_CLASSID] is zero, no messages related
12   to that object are printed. OBJECT_CLASSID is, for example, MAT_CLASSID.
13   Note for developers: the PetscInfoFlags array is currently 160 entries large, to ensure headroom. Perhaps it is worth
14   dynamically allocating this array intelligently rather than just some big number.
15 
16   PetscInfoFilename determines where PetscInfo() output is piped.
17   PetscInfoClassnames holds a char array of classes which are filtered out/for in PetscInfo() calls.
18 */
19 const char * const        PetscInfoCommFlags[] = {"all", "no_self", "only_self", "PetscInfoCommFlag", "PETSC_INFO_COMM_", 0};
20 static PetscBool          PetscInfoClassnamesLocked = PETSC_FALSE, PetscInfoInvertClasses = PETSC_FALSE;
21 static char               **PetscInfoClassnames = NULL;
22 static char               *PetscInfoFilename = NULL;
23 static PetscInt           PetscInfoNumClasses = -1;
24 static PetscInfoCommFlag  PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
25 static int                PetscInfoFlags[]  = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
26                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
27                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
28                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
29                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
30                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
31                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
32                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
33                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
34                                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
35 PetscBool                 PetscLogPrintInfo = PETSC_FALSE, PetscInfoSetUp = PETSC_FALSE;
36 FILE                      *PetscInfoFile = NULL;
37 
38 /*@
39     PetscInfoEnabled - Checks whether a given OBJECT_CLASSID is allowed to print using PetscInfo()
40 
41     Not Collective
42 
43     Input Parameters:
44 .   classid - PetscClassid retrieved from a PetscObject e.g. VEC_CLASSID
45 
46     Output Parameter:
47 .   enabled - PetscBool indicating whether this classid is allowed to print
48 
49     Notes:
50     Use PETSC_SMALLEST_CLASSID to check if "sys" PetscInfo() calls are enabled. When PETSc is configured with debugging
51     support this function checks if classid >= PETSC_SMALLEST_CLASSID, otherwise it assumes valid classid.
52 
53     Level: beginner
54 
55 .seealso: PetscInfo(), PetscInfoAllow(), PetscInfoGetInfo(), PetscObjectGetClassid()
56 @*/
57 PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled)
58 {
59   PetscFunctionBegin;
60 #if defined(PETSC_USE_DEBUG)
61   if (classid < PETSC_SMALLEST_CLASSID) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Classid (current: %d) must be equal to or greater than PETSC_SMALLEST_CLASSID", classid);
62 #endif
63   *enabled = (PetscBool) (PetscLogPrintInfo && PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID]);
64   PetscFunctionReturn(0);
65 }
66 
67 /*@
68     PetscInfoAllow - Causes PetscInfo() messages to be printed to PetscInfoFile
69 
70     Not Collective, each processor may call this separately, but printing is only
71     turned on if the lowest processor number associated with the PetscObject associated
72     with the call to PetscInfo() has called this routine.
73 
74     Input Parameter:
75 .   flag - PETSC_TRUE or PETSC_FALSE
76 
77     Level: advanced
78 
79 .seealso: PetscInfo(), PetscInfoEnabled(), PetscInfoGetInfo(), PetscInfoSetFromOptions()
80 @*/
81 PetscErrorCode PetscInfoAllow(PetscBool flag)
82 {
83   PetscFunctionBegin;
84   PetscLogPrintInfo = flag;
85   PetscFunctionReturn(0);
86 }
87 
88 /*@C
89     PetscInfoSetFile - Sets the printing destination for all PetscInfo() calls (i.e. set PetscInfoFile)
90 
91     Not Collective, any processor which has not called this routine will print to PETSC_SDOUT.
92 
93     Input Parameter:
94 +   filename - Name of the file where PetscInfo() will print to
95 -   mode - Write mode passed to PetscFOpen()
96 
97     Notes:
98     By default PetscInfo() writes to PETSC_STDOUT. Use "stdout" or NULL to set PetscInfo() to write to stdout
99 
100     Level: advanced
101 
102 .seealso: PetscInfo(), PetscInfoSetFile(), PetscInfoSetFromOptions(), PetscFOpen()
103 @*/
104 PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[])
105 {
106   char            fname[PETSC_MAX_PATH_LEN], tname[11];
107   PetscMPIInt     rank;
108   PetscErrorCode  ierr;
109 
110   PetscFunctionBegin;
111   if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT;
112   ierr = PetscFree(PetscInfoFilename);CHKERRQ(ierr);
113   if (filename) {
114     PetscBool  oldflag;
115     PetscValidCharPointer(filename, 1);
116     ierr = PetscFixFilename(filename, fname);CHKERRQ(ierr);
117     ierr = PetscStrallocpy(fname, &PetscInfoFilename);CHKERRQ(ierr);
118     ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);CHKERRQ(ierr);
119     sprintf(tname, ".%d", rank);
120     ierr = PetscStrcat(fname, tname);CHKERRQ(ierr);
121     oldflag = PetscLogPrintInfo; PetscLogPrintInfo = PETSC_FALSE;
122     ierr = PetscFOpen(MPI_COMM_SELF, fname, mode, &PetscInfoFile);CHKERRQ(ierr);
123     PetscLogPrintInfo = oldflag;
124     /* PetscFOpen will write to PETSC_STDOUT and not PetscInfoFile here, so we disable the PetscInfo call inside it, and
125      call it afterwards so that it actually writes to file */
126     ierr = PetscInfo1(NULL, "Opened PetscInfo file %s\n", fname);CHKERRQ(ierr);
127   }
128   PetscFunctionReturn(0);
129 }
130 
131 /*@C
132     PetscInfoGetFile - Gets the name and FILE pointer of the file where PetscInfo() prints to
133 
134     Not Collective
135 
136     Output Parameters:
137 +   filename - The name of the output file
138 -   InfoFile - The FILE pointer for the output file
139 
140     Level: advanced
141 
142     Note:
143     This routine allocates and copies the filename so that the filename survives PetscInfoDestroy(). The user is
144     therefore responsible for freeing the allocated filename pointer afterwards.
145 
146     Fortran Note:
147     This routine is not supported in Fortran.
148 
149 .seealso: PetscInfo(), PetscInfoSetFile(), PetscInfoSetFromOptions(), PetscInfoDestroy()
150 @*/
151 PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile)
152 {
153   PetscErrorCode  ierr;
154 
155   PetscFunctionBegin;
156   PetscValidPointer(filename, 1);
157   PetscValidPointer(InfoFile, 2);
158   ierr = PetscStrallocpy(PetscInfoFilename, filename);CHKERRQ(ierr);
159   *InfoFile = PetscInfoFile;
160   PetscFunctionReturn(0);
161 }
162 
163 /*@C
164     PetscInfoSetClasses - Sets the classes which PetscInfo() is filtered for/against
165 
166     Not Collective
167 
168     Input Parameters:
169 +   exclude - Whether or not to invert the filter, i.e. if exclude is true, PetscInfo() will print from every class that
170     is NOT one of the classes specified
171 .   N - Number of classes to filter for (size of classnames)
172 -   classnames - String array containing the names of classes to filter for, e.g. "vec"
173 
174     Notes:
175     Not for use in Fortran
176 
177     This function CANNOT be called after PetscInfoGetClass() or PetscInfoProcessClass() has been called.
178 
179     Names in the classnames list should correspond to the names returned by PetscObjectGetClassName().
180 
181     This function only sets the list of class names.
182     The actual filtering is deferred to PetscInfoProcessClass(), except of sys which is processed right away.
183     The reason for this is that we need to set the list of included/excluded classes before their classids are known.
184     Typically the classid is assigned and PetscInfoProcessClass() called in <Class>InitializePackage() (e.g. VecInitializePackage()).
185 
186     Level: developer
187 
188 .seealso: PetscInfo(), PetscInfoGetClass(), PetscInfoProcessClass(), PetscInfoSetFromOptions(), PetscStrToArray(), PetscObjectGetName()
189 @*/
190 PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt N, const char *const *classnames)
191 {
192   PetscErrorCode  ierr;
193 
194   PetscFunctionBegin;
195   if (PetscInfoClassnamesLocked) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscInfoSetClasses() cannot be called after PetscInfoGetClass() or PetscInfoProcessClass()");
196   ierr = PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);CHKERRQ(ierr);
197   ierr = PetscStrNArrayallocpy(N, classnames, &PetscInfoClassnames);CHKERRQ(ierr);
198   PetscInfoNumClasses = N;
199   PetscInfoInvertClasses = exclude;
200   {
201     /* Process sys class right away */
202     PetscClassId  sysclassid = PETSC_SMALLEST_CLASSID;
203     ierr = PetscInfoProcessClass("sys", 1, &sysclassid);CHKERRQ(ierr);
204   }
205   PetscInfoSetUp = PETSC_TRUE;
206   PetscFunctionReturn(0);
207 }
208 
209 /*@C
210     PetscInfoGetClass - Indicates whether the provided classname is marked as a filter in PetscInfo() as set by PetscInfoSetClasses()
211 
212     Not Collective
213 
214     Input Paramater:
215 .   classname - Name of the class to search for
216 
217     Output Parameter:
218 .   found - PetscBool indicating whether the classname was found
219 
220     Notes:
221     Use PetscObjectGetName() to retrieve an appropriate classname
222 
223     Level: developer
224 
225 .seealso: PetscInfo(), PetscInfoSetClasses(), PetscInfoSetFromOptions(), PetscObjectGetName()
226 @*/
227 PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found)
228 {
229   PetscInt        idx;
230   PetscErrorCode  ierr;
231 
232   PetscFunctionBegin;
233   PetscValidCharPointer(classname,1);
234   ierr = PetscEListFind(PetscInfoNumClasses, (const char *const *) PetscInfoClassnames, classname ? classname : "sys", &idx, found);CHKERRQ(ierr);
235   PetscInfoClassnamesLocked = PETSC_TRUE;
236   PetscFunctionReturn(0);
237 }
238 
239 /*@
240     PetscInfoGetInfo - Returns the current state of several important flags for PetscInfo()
241 
242     Not Collective
243 
244     Output Parameters:
245 +   infoEnabled - PETSC_TRUE if PetscInfoAllow(PETSC_TRUE) has been called
246 .   exclude - PETSC_TRUE if the class filtering for PetscInfo() is inverted
247 .   locked - PETSC_TRUE if the list of classes to filter for has been locked
248 -   commSelfFlag - Enum indicating whether PetscInfo() will print for communicators of size 1, any size != 1, or all
249     communicators
250 
251     Notes:
252     Initially commSelfFlag = PETSC_INFO_COMM_ALL
253 
254     Level: beginner
255 
256 .seealso: PetscInfo(), PetscInfoAllow(), PetscInfoSetFilterCommSelf, PetscInfoSetFromOptions()
257 @*/
258 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *setup, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag)
259 {
260   PetscFunctionBegin;
261   if (infoEnabled)  *infoEnabled  = PetscLogPrintInfo;
262   if (setup)        *setup        = PetscInfoSetUp;
263   if (exclude)      *exclude      = PetscInfoInvertClasses;
264   if (locked)       *locked       = PetscInfoClassnamesLocked;
265   if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter;
266   PetscFunctionReturn(0);
267 }
268 
269 /*@C
270     PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of PetscInfo()
271 
272     Not Collective
273 
274     Input Parameters:
275 +   classname - Name of the class to activate/deactivate PetscInfo() for
276 .   numClassID - Number of entries in classIDs
277 -   classIDs - Array containing all of the PetscClassids associated with classname
278 
279     Note: This function contains the deprecation warning for -info_exclude
280 
281     Level: developer
282 
283 .seealso: PetscInfo(), PetscInfoActivateClass(), PetscInfoDeactivateClass(), PetscInfoSetFromOptions()
284 @*/
285 PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, PetscClassId classIDs[])
286 {
287   PetscInt        i;
288   PetscBool       enabled, exclude, found, opt, pkg;
289   char            logList[256];
290   PetscErrorCode  ierr;
291 
292   PetscFunctionBegin;
293   PetscValidCharPointer(classname, 1);
294   ierr = PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL);CHKERRQ(ierr);
295   /* -info_exclude is DEPRECATED */
296   ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",logList,sizeof(logList),&opt);CHKERRQ(ierr);
297   if (opt) {
298     ierr = PetscStrInList(classname,logList,',',&pkg);CHKERRQ(ierr);
299     if (pkg) {
300       for (i = 0; i < numClassID; ++i) {
301         ierr = PetscInfoDeactivateClass(classIDs[i]);CHKERRQ(ierr);
302       }
303     }
304   }
305   ierr = PetscInfoGetClass(classname, &found);CHKERRQ(ierr);
306   if ((found && exclude) || (!found && !exclude)) {
307     if (PetscInfoNumClasses > 0) {
308       /* Check if -info was called empty */
309       for (i = 0; i < numClassID; ++i) {
310         ierr = PetscInfoDeactivateClass(classIDs[i]);CHKERRQ(ierr);
311       }
312     }
313   } else {
314     for (i = 0; i < numClassID; ++i) {
315       ierr = PetscInfoActivateClass(classIDs[i]);CHKERRQ(ierr);
316     }
317   }
318   PetscFunctionReturn(0);
319 }
320 
321 /*@
322     PetscInfoSetFilterCommSelf - Sets PetscInfoCommFlag enum to determine communicator filtering for PetscInfo()
323 
324     Not Collective
325 
326     Input Parameter:
327 .   commSelfFlag - Enum value indicating method with which to filter PetscInfo() based on the size of the communicator
328 of the object calling PetscInfo()
329 
330     Level: developer
331 
332 .seealso: PetscInfo(), PetscInfoGetInfo()
333 @*/
334 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag)
335 {
336   PetscFunctionBegin;
337   PetscInfoCommFilter = commSelfFlag;
338   PetscFunctionReturn(0);
339 }
340 
341 /*@
342     PetscInfoSetFromOptions - Configure PetscInfo() using command line options, enabling or disabling various calls to
343     PetscInfo()
344 
345     Not Collective
346 
347     Input Parameter:
348 .   options - Options database, use NULL for default global database
349 
350     Options Database Key:
351 $   -info [optional filename][:[~]optional list,of,classnames][:[~]optional "self"]
352 
353     Notes:
354     PetscInfo() defaults:
355 $   [optional filename] defaults to write output to PETSC_STDOUT
356 $   [optional list,of,classnames] defaults to enabling all classes
357 $   [optional "self"] default is that any communicator is allowed to print (albeit with the caveat that only the first rank on that communicator will print).
358 
359     Prepend `~` to first classname or "self" to invert either selection, i.e. -info :~ts,snes:~self will activate
360     every PetscInfo() call on a communicator with size > 1, associated with TS or SNES objects. Note that command line options
361     will also silence any user-written calls to PetscInfo() if an object which is filtered for is passed as the PetscObject
362     argument to PetscInfo(). To filter for PetscInfo() calls not directly associated with an object (i.e. where *vobj ==
363  NULL), use "sys".
364 
365     All classname/self matching is case insensitive. Filename IS case sensitive.
366 
367     Example:
368 $   -info :: OR -info will print to PETSC_STDOUT, print for ALL classes, and print for ALL communicator sizes
369 $   -info :mat:self will print to PETSC_STDOUT, print ONLY PetscInfo() calls associated to Mat objects, whose communicators are of
370 size = 1
371 $   -info myInfoFileName:~vec:~self will create and print to ./myInfoFileName, print all PetscInfo() calls NOT associated
372 with Vec Objects, whose communicators are of size > 1
373 
374     Level: beginner
375 
376 .seealso: PetscInfo(), PetscInfoAllow(), PetscInfoSetFile(), PetscInfoSetClasses(), PetscInfoSetFilterCommSelf(), PetscInfoDestroy()
377 @*/
378 PetscErrorCode PetscInfoSetFromOptions(PetscOptions options)
379 {
380   PetscToken         tok;
381   char               optstring[PETSC_MAX_PATH_LEN], *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL;
382   char               **loc1_array = NULL;
383   PetscBool          set, loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE, foundSelf = PETSC_FALSE;
384   size_t             size_loc0_ = 0, size_loc1_ = 0, size_loc2_ = 0;
385   int                nLoc1_ = 0;
386   PetscInfoCommFlag  commSelfFlag = PETSC_INFO_COMM_ALL;
387   PetscErrorCode     ierr;
388 
389   PetscFunctionBegin;
390   ierr = PetscOptionsDeprecated_Private(NULL,"-info_exclude", NULL, "3.13", "Use -info instead");CHKERRQ(ierr);
391   ierr = PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_MAX_PATH_LEN, &set);CHKERRQ(ierr);
392   if (set) {
393     /* Allow sys class to be processed as part of setup */
394     PetscInfoSetUp = PETSC_TRUE;
395     ierr = PetscInfoAllow(PETSC_TRUE);CHKERRQ(ierr);
396     ierr = PetscTokenCreate(optstring, ':', &tok);CHKERRQ(ierr);
397     ierr = PetscTokenFind(tok, &loc0_);CHKERRQ(ierr);
398     ierr = PetscTokenFind(tok, &loc1_);CHKERRQ(ierr);
399     ierr = PetscTokenFind(tok, &loc2_);CHKERRQ(ierr);
400     if (loc1_) {
401       ierr = PetscStrcmp("self", (const char *) loc1_, &foundSelf);CHKERRQ(ierr);
402       if (foundSelf) {
403         /* side effect of PetscTokenFind() if tokens are next to each other, i.e. str="foo::bar", instead of "foo" "" "bar", returns "foo" "bar" "NULL" */
404         loc2_ = loc1_;
405         loc1_ = NULL;
406       } else {
407         if (*loc1_ == '~') {
408           loc1_invert = PETSC_TRUE;
409           ++loc1_;
410         }
411       }
412     }
413     if (loc2_) {
414       if (*loc2_ == '~') {
415         loc2_invert = PETSC_TRUE;
416         ++loc2_;
417       }
418     }
419     ierr = PetscStrlen(loc0_, &size_loc0_);CHKERRQ(ierr);
420     ierr = PetscStrlen(loc1_, &size_loc1_);CHKERRQ(ierr);
421     ierr = PetscStrlen(loc2_, &size_loc2_);CHKERRQ(ierr);
422     if (size_loc1_) {
423       ierr = PetscStrtolower(loc1_);CHKERRQ(ierr);
424       ierr = PetscStrToArray((const char *) loc1_, ',',(int *) &nLoc1_, &loc1_array);CHKERRQ(ierr);
425     }
426     if (size_loc2_) {
427       ierr = PetscStrtolower(loc2_);CHKERRQ(ierr);
428       ierr = PetscStrcmp("self", (const char *) loc2_, &foundSelf);CHKERRQ(ierr);
429       if (foundSelf) {
430         if (loc2_invert) {
431           commSelfFlag = PETSC_INFO_COMM_NO_SELF;
432         } else {
433           commSelfFlag = PETSC_INFO_COMM_ONLY_SELF;
434         }
435       }
436     }
437     ierr = PetscInfoSetFile((const char *) size_loc0_ ? loc0_ : NULL, "w");CHKERRQ(ierr);
438     ierr = PetscInfoSetClasses(loc1_invert,(PetscInt) nLoc1_, (const char *const *) loc1_array);CHKERRQ(ierr);
439     ierr = PetscInfoSetFilterCommSelf(commSelfFlag);CHKERRQ(ierr);
440     ierr = PetscStrToArrayDestroy(nLoc1_, loc1_array);CHKERRQ(ierr);
441     ierr = PetscTokenDestroy(&tok);CHKERRQ(ierr);
442   }
443   PetscFunctionReturn(0);
444 }
445 
446 /*@
447   PetscInfoDestroy - Destroys and resets internal PetscInfo() data structures.
448 
449   Not Collective
450 
451   Notes:
452   This is automatically called in PetscFinalize(). Useful for changing filters mid-program, or culling subsequent
453   PetscInfo() calls down the line.
454 
455   Level: intermediate
456 
457 .seealso: PetscInfo(), PetscInfoSetFromOptions()
458 @*/
459 PetscErrorCode PetscInfoDestroy(void)
460 {
461   PetscErrorCode  ierr;
462   int             err;
463 
464   PetscFunctionBegin;
465   ierr = PetscInfoAllow(PETSC_FALSE);CHKERRQ(ierr);
466   ierr = PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);CHKERRQ(ierr);
467   err  = fflush(PetscInfoFile);
468   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
469   if (PetscInfoFilename) {
470     ierr  = PetscFClose(MPI_COMM_SELF, PetscInfoFile);CHKERRQ(ierr);
471   }
472   ierr = PetscFree(PetscInfoFilename);CHKERRQ(ierr);
473   memset(PetscInfoFlags, 1, (size_t) 160*sizeof(PetscInfoFlags[0]));
474   PetscInfoClassnamesLocked = PETSC_FALSE;
475   PetscInfoInvertClasses = PETSC_FALSE;
476   PetscInfoNumClasses = -1;
477   PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
478   PetscInfoSetUp = PETSC_FALSE;
479   PetscFunctionReturn(0);
480 }
481 
482 /*@
483   PetscInfoDeactivateClass - Deactivates PetscInfo() messages for a PETSc object class.
484 
485   Not Collective
486 
487   Input Parameter:
488 . classid - The object class,  e.g., MAT_CLASSID, SNES_CLASSID, etc.
489 
490   Notes:
491   One can pass 0 to deactivate all messages that are not associated with an object.
492 
493   Level: developer
494 
495 .seealso: PetscInfoActivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
496 @*/
497 PetscErrorCode  PetscInfoDeactivateClass(PetscClassId classid)
498 {
499   PetscFunctionBegin;
500   if (!classid) classid = PETSC_SMALLEST_CLASSID;
501   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 0;
502   PetscFunctionReturn(0);
503 }
504 
505 /*@
506   PetscInfoActivateClass - Activates PetscInfo() messages for a PETSc object class.
507 
508   Not Collective
509 
510   Input Parameter:
511 . classid - The object class, e.g., MAT_CLASSID, SNES_CLASSID, etc.
512 
513   Notes:
514   One can pass 0 to activate all messages that are not associated with an object.
515 
516   Level: developer
517 
518 .seealso: PetscInfoDeactivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
519 @*/
520 PetscErrorCode  PetscInfoActivateClass(PetscClassId classid)
521 {
522   PetscFunctionBegin;
523   if (!classid) classid = PETSC_SMALLEST_CLASSID;
524   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 1;
525   PetscFunctionReturn(0);
526 }
527 
528 /*
529    If the option -history was used, then all printed PetscInfo()
530   messages are also printed to the history file, called by default
531   .petschistory in ones home directory.
532 */
533 PETSC_INTERN FILE *petsc_history;
534 
535 /*MC
536     PetscInfo - Logs informative data
537 
538    Synopsis:
539        #include <petscsys.h>
540        PetscErrorCode PetscInfo(void *vobj, const char message[])
541        PetscErrorCode PetscInfo1(void *vobj, const char formatmessage[],arg1)
542        PetscErrorCode PetscInfo2(void *vobj, const char formatmessage[],arg1,arg2)
543        etc
544 
545     Collective over PetscObject argument
546 
547     Input Parameter:
548 +   vobj - object most closely associated with the logging statement or NULL
549 .   message - logging message
550 -   formatmessage - logging message using standard "printf" format
551 
552     Options Database Key:
553 $   -info [optional filename][:[~]optional list,of,classnames][:[~]optional "self"]
554 
555     Notes:
556     For complete explanation of options database keys see PetscInfoSetFromOptions().
557 
558     Level: intermediate
559 
560     Fortran Note: This function does not take the vobj argument, there is only the PetscInfo()
561      version, not PetscInfo1() etc.
562 
563     Example of Usage:
564 $
565 $     Mat A
566 $     double alpha
567 $     PetscInfo1(A,"Matrix uses parameter alpha=%g\n",alpha);
568 $
569 
570 .seealso: PetscInfoAllow(), PetscInfoSetFromOptions()
571 M*/
572 PetscErrorCode  PetscInfo_Private(const char func[],void *vobj, const char message[], ...)
573 {
574   va_list        Argp;
575   PetscMPIInt    rank = 0,urank,size = 1;
576   PetscObject    obj = (PetscObject)vobj;
577   PetscClassId   classid;
578   PetscBool      enabled = PETSC_FALSE, oldflag;
579   char           string[8*1024];
580   PetscErrorCode ierr;
581   size_t         fullLength,len;
582   int            err;
583 
584   PetscFunctionBegin;
585   if (obj) PetscValidHeader(obj,2);
586   classid = obj ? obj->classid : PETSC_SMALLEST_CLASSID;
587   ierr = PetscInfoEnabled(classid, &enabled);CHKERRQ(ierr);
588   if (!enabled) PetscFunctionReturn(0);
589   PetscValidCharPointer(message,3);
590   if (obj) {
591     ierr = MPI_Comm_rank(obj->comm, &rank);CHKERRQ(ierr);
592     ierr = MPI_Comm_size(obj->comm, &size);CHKERRQ(ierr);
593   }
594   /* rank > 0 always jumps out */
595   if (rank) PetscFunctionReturn(0);
596   if (!PetscInfoCommFilter && (size < 2)) {
597     /* If no self printing is allowed, and size too small get out */
598     PetscFunctionReturn(0);
599   } else if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) {
600     /* If ONLY self printing, and size too big, get out */
601     PetscFunctionReturn(0);
602   }
603   /* Mute info messages within this function */
604   oldflag = PetscLogPrintInfo; PetscLogPrintInfo = PETSC_FALSE;
605   ierr = MPI_Comm_rank(MPI_COMM_WORLD, &urank);CHKERRQ(ierr);
606   va_start(Argp, message);
607   sprintf(string, "[%d] %s(): ",urank,func);
608   ierr = PetscStrlen(string, &len);CHKERRQ(ierr);
609   ierr = PetscVSNPrintf(string+len, 8*1024-len,message,&fullLength, Argp);CHKERRQ(ierr);
610   ierr = PetscFPrintf(PETSC_COMM_SELF,PetscInfoFile, "%s", string);CHKERRQ(ierr);
611   err  = fflush(PetscInfoFile);
612   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
613   if (petsc_history) {
614     va_start(Argp, message);
615     ierr = (*PetscVFPrintf)(petsc_history, message, Argp);CHKERRQ(ierr);
616   }
617   va_end(Argp);
618   PetscLogPrintInfo = oldflag;
619   PetscFunctionReturn(0);
620 }
621