xref: /petsc/src/sys/info/verboseinfo.c (revision c87ba875e4007ad659b117ea274f03d5f4cd5ea7)
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: 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 (PetscInfoClassnamesLocked) 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   PetscInfoSetUp = 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   PetscInfoClassnamesLocked = 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   = PetscInfoSetUp;
262   if (exclude)      *exclude      = PetscInfoInvertClasses;
263   if (locked)       *locked       = PetscInfoClassnamesLocked;
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     PetscInfoSetUp = 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((const char *) loc1_, ',',(int *) &nLoc1_, &loc1_array);CHKERRQ(ierr);
394     }
395     if (size_loc2_) {
396       ierr = PetscStrtolower(loc2_);CHKERRQ(ierr);
397       ierr = PetscStrcmp("self", (const char *) 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((const char *) 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, i;
432 
433   PetscFunctionBegin;
434   ierr = PetscInfoAllow(PETSC_FALSE);CHKERRQ(ierr);
435   ierr = PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);CHKERRQ(ierr);
436   err  = fflush(PetscInfoFile);
437   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
438   if (PetscInfoFilename) {
439     ierr  = PetscFClose(MPI_COMM_SELF, PetscInfoFile);CHKERRQ(ierr);
440   }
441   ierr = PetscFree(PetscInfoFilename);CHKERRQ(ierr);
442   for (i=0; i<160; i++) PetscInfoFlags[i] = 1;
443   PetscInfoClassnamesLocked = PETSC_FALSE;
444   PetscInfoInvertClasses = PETSC_FALSE;
445   PetscInfoNumClasses = -1;
446   PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
447   PetscInfoSetUp = PETSC_FALSE;
448   PetscFunctionReturn(0);
449 }
450 
451 /*@
452   PetscInfoDeactivateClass - Deactivates PetscInfo() messages for a PETSc object class.
453 
454   Not Collective
455 
456   Input Parameter:
457 . classid - The object class,  e.g., MAT_CLASSID, SNES_CLASSID, etc.
458 
459   Notes:
460   One can pass 0 to deactivate all messages that are not associated with an object.
461 
462   Level: developer
463 
464 .seealso: PetscInfoActivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
465 @*/
466 PetscErrorCode  PetscInfoDeactivateClass(PetscClassId classid)
467 {
468   PetscFunctionBegin;
469   if (!classid) classid = PETSC_SMALLEST_CLASSID;
470   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 0;
471   PetscFunctionReturn(0);
472 }
473 
474 /*@
475   PetscInfoActivateClass - Activates PetscInfo() messages for a PETSc object class.
476 
477   Not Collective
478 
479   Input Parameter:
480 . classid - The object class, e.g., MAT_CLASSID, SNES_CLASSID, etc.
481 
482   Notes:
483   One can pass 0 to activate all messages that are not associated with an object.
484 
485   Level: developer
486 
487 .seealso: PetscInfoDeactivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
488 @*/
489 PetscErrorCode  PetscInfoActivateClass(PetscClassId classid)
490 {
491   PetscFunctionBegin;
492   if (!classid) classid = PETSC_SMALLEST_CLASSID;
493   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 1;
494   PetscFunctionReturn(0);
495 }
496 
497 /*
498    If the option -history was used, then all printed PetscInfo()
499   messages are also printed to the history file, called by default
500   .petschistory in ones home directory.
501 */
502 PETSC_INTERN FILE *petsc_history;
503 
504 /*MC
505     PetscInfo - Logs informative data
506 
507    Synopsis:
508        #include <petscsys.h>
509        PetscErrorCode PetscInfo(PetscObject obj, const char message[])
510        PetscErrorCode PetscInfo1(PetscObject obj, const char formatmessage[],arg1)
511        PetscErrorCode PetscInfo2(PetscObject obj, const char formatmessage[],arg1,arg2)
512        ...
513 
514     Collective on obj
515 
516     Input Parameter:
517 +   obj - object most closely associated with the logging statement or NULL
518 .   message - logging message
519 .   formatmessage - logging message using standard "printf" format
520 -   arg1, arg2, ... - arguments of the format
521 
522     Notes:
523     PetscInfo() prints only from the first processor in the communicator of obj.
524     If obj is NULL, the PETSC_COMM_SELF communicator is used, i.e. every rank of PETSC_COMM_WORLD prints the message.
525 
526     Extent of the printed messages can be controlled using the option database key -info as follows.
527 
528 $   -info [filename][:[~]<list,of,classnames>[:[~]self]]
529 
530     No filename means standard output PETSC_STDOUT is used.
531 
532     The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp.
533     If this list is not specified, all classes are enabled.
534     Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled.
535     A special classname sys relates to PetscInfo() with obj being NULL.
536 
537     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.
538     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.
539 
540     All classname/self matching is case insensitive. Filename is case sensitive.
541 
542     Example of Usage:
543 $     Mat A;
544 $     PetscInt alpha;
545 $     ...
546 $     PetscInfo1(A,"Matrix uses parameter alpha=%D\n",alpha);
547 
548     Options Examples:
549     Each call of the form
550 $     PetscInfo(obj, msg);
551 $     PetscInfo1(obj, msg, arg1);
552 $     PetscInfo2(obj, msg, arg1, arg2);
553     is evaluated as follows.
554 $     -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator
555 $     -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1
556 $     -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
557 $     -info :sys prints to PETSC_STDOUT only if obj is NULL
558     Note that
559 $     -info :sys:~self
560     deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF.
561 
562     Fortran Note:
563     This function does not take the obj argument, there is only the PetscInfo()
564      version, not PetscInfo1() etc.
565 
566     Level: intermediate
567 
568 .seealso: PetscInfoAllow(), PetscInfoSetFromOptions()
569 M*/
570 PetscErrorCode  PetscInfo_Private(const char func[],PetscObject obj, const char message[], ...)
571 {
572   va_list        Argp;
573   PetscMPIInt    rank = 0,urank,size = 1;
574   PetscClassId   classid;
575   PetscBool      enabled = PETSC_FALSE, oldflag;
576   char           string[8*1024];
577   PetscErrorCode ierr;
578   size_t         fullLength,len;
579   int            err;
580 
581   PetscFunctionBegin;
582   if (obj) PetscValidHeader(obj,2);
583   classid = obj ? obj->classid : PETSC_SMALLEST_CLASSID;
584   ierr = PetscInfoEnabled(classid, &enabled);CHKERRQ(ierr);
585   if (!enabled) PetscFunctionReturn(0);
586   PetscValidCharPointer(message,3);
587   if (obj) {
588     ierr = MPI_Comm_rank(obj->comm, &rank);CHKERRQ(ierr);
589     ierr = MPI_Comm_size(obj->comm, &size);CHKERRQ(ierr);
590   }
591   /* rank > 0 always jumps out */
592   if (rank) PetscFunctionReturn(0);
593   if (!PetscInfoCommFilter && (size < 2)) {
594     /* If no self printing is allowed, and size too small get out */
595     PetscFunctionReturn(0);
596   } else if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) {
597     /* If ONLY self printing, and size too big, get out */
598     PetscFunctionReturn(0);
599   }
600   /* Mute info messages within this function */
601   oldflag = PetscLogPrintInfo; PetscLogPrintInfo = PETSC_FALSE;
602   ierr = MPI_Comm_rank(MPI_COMM_WORLD, &urank);CHKERRQ(ierr);
603   va_start(Argp, message);
604   sprintf(string, "[%d] %s(): ",urank,func);
605   ierr = PetscStrlen(string, &len);CHKERRQ(ierr);
606   ierr = PetscVSNPrintf(string+len, 8*1024-len,message,&fullLength, Argp);CHKERRQ(ierr);
607   ierr = PetscFPrintf(PETSC_COMM_SELF,PetscInfoFile, "%s", string);CHKERRQ(ierr);
608   err  = fflush(PetscInfoFile);
609   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
610   if (petsc_history) {
611     va_start(Argp, message);
612     ierr = (*PetscVFPrintf)(petsc_history, message, Argp);CHKERRQ(ierr);
613   }
614   va_end(Argp);
615   PetscLogPrintInfo = oldflag;
616   PetscFunctionReturn(0);
617 }
618