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