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