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