xref: /petsc/src/sys/info/verboseinfo.c (revision 8d76b567012869fc44a72bfbee2ffc0c796c6d4b)
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 .   exclude - PETSC_TRUE if the class filtering for PetscInfo() is inverted
245 .   locked - PETSC_TRUE if the list of classes to filter for has been locked
246 -   commSelfFlag - Enum indicating whether PetscInfo() will print for communicators of size 1, any size != 1, or all
247     communicators
248 
249     Notes:
250     Initially commSelfFlag = PETSC_INFO_COMM_ALL
251 
252     Level: developer
253 
254 .seealso: PetscInfo(), PetscInfoAllow(), PetscInfoSetFilterCommSelf, PetscInfoSetFromOptions()
255 @*/
256 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *setup, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag)
257 {
258   PetscFunctionBegin;
259   if (infoEnabled)  *infoEnabled  = PetscLogPrintInfo;
260   if (setup)        *setup        = PetscInfoSetUp;
261   if (exclude)      *exclude      = PetscInfoInvertClasses;
262   if (locked)       *locked       = PetscInfoClassnamesLocked;
263   if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter;
264   PetscFunctionReturn(0);
265 }
266 
267 /*@C
268     PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of PetscInfo()
269 
270     Not Collective
271 
272     Input Parameters:
273 +   classname - Name of the class to activate/deactivate PetscInfo() for
274 .   numClassID - Number of entries in classIDs
275 -   classIDs - Array containing all of the PetscClassids associated with classname
276 
277     Level: developer
278 
279 .seealso: PetscInfo(), PetscInfoActivateClass(), PetscInfoDeactivateClass(), PetscInfoSetFromOptions()
280 @*/
281 PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, PetscClassId classIDs[])
282 {
283   PetscInt        i;
284   PetscBool       enabled, exclude, found, opt, pkg;
285   char            logList[256];
286   PetscErrorCode  ierr;
287 
288   PetscFunctionBegin;
289   PetscValidCharPointer(classname, 1);
290   ierr = PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL);CHKERRQ(ierr);
291   /* -info_exclude is DEPRECATED */
292   ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",logList,sizeof(logList),&opt);CHKERRQ(ierr);
293   if (opt) {
294     ierr = PetscStrInList(classname,logList,',',&pkg);CHKERRQ(ierr);
295     if (pkg) {
296       for (i = 0; i < numClassID; ++i) {
297         ierr = PetscInfoDeactivateClass(classIDs[i]);CHKERRQ(ierr);
298       }
299     }
300   }
301   ierr = PetscInfoGetClass(classname, &found);CHKERRQ(ierr);
302   if ((found && exclude) || (!found && !exclude)) {
303     if (PetscInfoNumClasses > 0) {
304       /* Check if -info was called empty */
305       for (i = 0; i < numClassID; ++i) {
306         ierr = PetscInfoDeactivateClass(classIDs[i]);CHKERRQ(ierr);
307       }
308     }
309   } else {
310     for (i = 0; i < numClassID; ++i) {
311       ierr = PetscInfoActivateClass(classIDs[i]);CHKERRQ(ierr);
312     }
313   }
314   PetscFunctionReturn(0);
315 }
316 
317 /*@
318     PetscInfoSetFilterCommSelf - Sets PetscInfoCommFlag enum to determine communicator filtering for PetscInfo()
319 
320     Not Collective
321 
322     Input Parameter:
323 .   commSelfFlag - Enum value indicating method with which to filter PetscInfo() based on the size of the communicator of the object calling PetscInfo()
324 
325     Level: advanced
326 
327 .seealso: PetscInfo(), PetscInfoGetInfo()
328 @*/
329 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag)
330 {
331   PetscFunctionBegin;
332   PetscInfoCommFilter = commSelfFlag;
333   PetscFunctionReturn(0);
334 }
335 
336 /*@
337     PetscInfoSetFromOptions - Configure PetscInfo() using command line options, enabling or disabling various calls to PetscInfo()
338 
339     Not Collective
340 
341     Input Parameter:
342 .   options - Options database, use NULL for default global database
343 
344     Options Database Keys:
345 .   -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo().
346 
347     Notes:
348     This function is called automatically during PetscInitialize() so users usually do not need to call it themselves.
349 
350     Level: advanced
351 
352 .seealso: PetscInfo(), PetscInfoAllow(), PetscInfoSetFile(), PetscInfoSetClasses(), PetscInfoSetFilterCommSelf(), PetscInfoDestroy()
353 @*/
354 PetscErrorCode PetscInfoSetFromOptions(PetscOptions options)
355 {
356   PetscToken         tok;
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     /* Allow sys class to be processed as part of setup */
370     PetscInfoSetUp = PETSC_TRUE;
371     ierr = PetscInfoAllow(PETSC_TRUE);CHKERRQ(ierr);
372     ierr = PetscTokenCreate(optstring, ':', &tok);CHKERRQ(ierr);
373     ierr = PetscTokenFind(tok, &loc0_);CHKERRQ(ierr);
374     ierr = PetscTokenFind(tok, &loc1_);CHKERRQ(ierr);
375     ierr = PetscTokenFind(tok, &loc2_);CHKERRQ(ierr);
376     if (loc1_) {
377       ierr = PetscStrcmp("self", (const char *) loc1_, &foundSelf);CHKERRQ(ierr);
378       if (foundSelf) {
379         /* side effect of PetscTokenFind() if tokens are next to each other, i.e. str="foo::bar", instead of "foo" "" "bar", returns "foo" "bar" "NULL" */
380         loc2_ = loc1_;
381         loc1_ = NULL;
382       } else {
383         if (*loc1_ == '~') {
384           loc1_invert = PETSC_TRUE;
385           ++loc1_;
386         }
387       }
388     }
389     if (loc2_) {
390       if (*loc2_ == '~') {
391         loc2_invert = PETSC_TRUE;
392         ++loc2_;
393       }
394     }
395     ierr = PetscStrlen(loc0_, &size_loc0_);CHKERRQ(ierr);
396     ierr = PetscStrlen(loc1_, &size_loc1_);CHKERRQ(ierr);
397     ierr = PetscStrlen(loc2_, &size_loc2_);CHKERRQ(ierr);
398     if (size_loc1_) {
399       ierr = PetscStrtolower(loc1_);CHKERRQ(ierr);
400       ierr = PetscStrToArray((const char *) loc1_, ',',(int *) &nLoc1_, &loc1_array);CHKERRQ(ierr);
401     }
402     if (size_loc2_) {
403       ierr = PetscStrtolower(loc2_);CHKERRQ(ierr);
404       ierr = PetscStrcmp("self", (const char *) loc2_, &foundSelf);CHKERRQ(ierr);
405       if (foundSelf) {
406         if (loc2_invert) {
407           commSelfFlag = PETSC_INFO_COMM_NO_SELF;
408         } else {
409           commSelfFlag = PETSC_INFO_COMM_ONLY_SELF;
410         }
411       }
412     }
413     ierr = PetscInfoSetFile((const char *) size_loc0_ ? loc0_ : NULL, "w");CHKERRQ(ierr);
414     ierr = PetscInfoSetClasses(loc1_invert,(PetscInt) nLoc1_, (const char *const *) loc1_array);CHKERRQ(ierr);
415     ierr = PetscInfoSetFilterCommSelf(commSelfFlag);CHKERRQ(ierr);
416     ierr = PetscStrToArrayDestroy(nLoc1_, loc1_array);CHKERRQ(ierr);
417     ierr = PetscTokenDestroy(&tok);CHKERRQ(ierr);
418   }
419   PetscFunctionReturn(0);
420 }
421 
422 /*@
423   PetscInfoDestroy - Destroys and resets internal PetscInfo() data structures.
424 
425   Not Collective
426 
427   Notes:
428   This is automatically called in PetscFinalize(). Useful for changing filters mid-program, or culling subsequent
429   PetscInfo() calls down the line.
430 
431   Level: developer
432 
433 .seealso: PetscInfo(), PetscInfoSetFromOptions()
434 @*/
435 PetscErrorCode PetscInfoDestroy(void)
436 {
437   PetscErrorCode  ierr;
438   int             err;
439 
440   PetscFunctionBegin;
441   ierr = PetscInfoAllow(PETSC_FALSE);CHKERRQ(ierr);
442   ierr = PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);CHKERRQ(ierr);
443   err  = fflush(PetscInfoFile);
444   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
445   if (PetscInfoFilename) {
446     ierr  = PetscFClose(MPI_COMM_SELF, PetscInfoFile);CHKERRQ(ierr);
447   }
448   ierr = PetscFree(PetscInfoFilename);CHKERRQ(ierr);
449   memset(PetscInfoFlags, 1, (size_t) 160*sizeof(PetscInfoFlags[0]));
450   PetscInfoClassnamesLocked = PETSC_FALSE;
451   PetscInfoInvertClasses = PETSC_FALSE;
452   PetscInfoNumClasses = -1;
453   PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
454   PetscInfoSetUp = PETSC_FALSE;
455   PetscFunctionReturn(0);
456 }
457 
458 /*@
459   PetscInfoDeactivateClass - Deactivates PetscInfo() messages for a PETSc object class.
460 
461   Not Collective
462 
463   Input Parameter:
464 . classid - The object class,  e.g., MAT_CLASSID, SNES_CLASSID, etc.
465 
466   Notes:
467   One can pass 0 to deactivate all messages that are not associated with an object.
468 
469   Level: developer
470 
471 .seealso: PetscInfoActivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
472 @*/
473 PetscErrorCode  PetscInfoDeactivateClass(PetscClassId classid)
474 {
475   PetscFunctionBegin;
476   if (!classid) classid = PETSC_SMALLEST_CLASSID;
477   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 0;
478   PetscFunctionReturn(0);
479 }
480 
481 /*@
482   PetscInfoActivateClass - Activates PetscInfo() messages for a PETSc object class.
483 
484   Not Collective
485 
486   Input Parameter:
487 . classid - The object class, e.g., MAT_CLASSID, SNES_CLASSID, etc.
488 
489   Notes:
490   One can pass 0 to activate all messages that are not associated with an object.
491 
492   Level: developer
493 
494 .seealso: PetscInfoDeactivateClass(), PetscInfo(), PetscInfoAllow(), PetscInfoSetFromOptions()
495 @*/
496 PetscErrorCode  PetscInfoActivateClass(PetscClassId classid)
497 {
498   PetscFunctionBegin;
499   if (!classid) classid = PETSC_SMALLEST_CLASSID;
500   PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = 1;
501   PetscFunctionReturn(0);
502 }
503 
504 /*
505    If the option -history was used, then all printed PetscInfo()
506   messages are also printed to the history file, called by default
507   .petschistory in ones home directory.
508 */
509 PETSC_INTERN FILE *petsc_history;
510 
511 /*MC
512     PetscInfo - Logs informative data
513 
514    Synopsis:
515        #include <petscsys.h>
516        PetscErrorCode PetscInfo(PetscObject obj, const char message[])
517        PetscErrorCode PetscInfo1(PetscObject obj, const char formatmessage[],arg1)
518        PetscErrorCode PetscInfo2(PetscObject obj, const char formatmessage[],arg1,arg2)
519        ...
520 
521     Collective on obj
522 
523     Input Parameter:
524 +   obj - object most closely associated with the logging statement or NULL
525 .   message - logging message
526 .   formatmessage - logging message using standard "printf" format
527 -   arg1, arg2, ... - arguments of the format
528 
529     Notes:
530     PetscInfo() prints only from the first processor in the communicator of obj.
531     If obj is NULL, the PETSC_COMM_SELF communicator is used, i.e. every rank of PETSC_COMM_WORLD prints the message.
532 
533     Extent of the printed messages can be controlled using the option database key -info as follows.
534 
535 $   -info [filename][:[~]<list,of,classnames>[:[~]self]]
536 
537     No filename means standard output PETSC_STDOUT is used.
538 
539     The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp.
540     If this list is not specified, all classes are enabled.
541     Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled.
542     A special classname sys relates to PetscInfo() with obj being NULL.
543 
544     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.
545     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.
546 
547     All classname/self matching is case insensitive. Filename is case sensitive.
548 
549     Example of Usage:
550 $     Mat A;
551 $     PetscInt alpha;
552 $     ...
553 $     PetscInfo1(A,"Matrix uses parameter alpha=%D\n",alpha);
554 
555     Options Examples:
556     Each call of the form
557 $     PetscInfo(obj, msg);
558 $     PetscInfo1(obj, msg, arg1);
559 $     PetscInfo2(obj, msg, arg1, arg2);
560     is evaluated as follows.
561 $     -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator
562 $     -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1
563 $     -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
564 $     -info :sys prints to PETSC_STDOUT only if obj is NULL
565     Note that
566 $     -info :sys:~self
567     deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF.
568 
569     Fortran Note:
570     This function does not take the obj argument, there is only the PetscInfo()
571      version, not PetscInfo1() etc.
572 
573     Level: intermediate
574 
575 .seealso: PetscInfoAllow(), PetscInfoSetFromOptions()
576 M*/
577 PetscErrorCode  PetscInfo_Private(const char func[],PetscObject obj, const char message[], ...)
578 {
579   va_list        Argp;
580   PetscMPIInt    rank = 0,urank,size = 1;
581   PetscClassId   classid;
582   PetscBool      enabled = PETSC_FALSE, oldflag;
583   char           string[8*1024];
584   PetscErrorCode ierr;
585   size_t         fullLength,len;
586   int            err;
587 
588   PetscFunctionBegin;
589   if (obj) PetscValidHeader(obj,2);
590   classid = obj ? obj->classid : PETSC_SMALLEST_CLASSID;
591   ierr = PetscInfoEnabled(classid, &enabled);CHKERRQ(ierr);
592   if (!enabled) PetscFunctionReturn(0);
593   PetscValidCharPointer(message,3);
594   if (obj) {
595     ierr = MPI_Comm_rank(obj->comm, &rank);CHKERRQ(ierr);
596     ierr = MPI_Comm_size(obj->comm, &size);CHKERRQ(ierr);
597   }
598   /* rank > 0 always jumps out */
599   if (rank) PetscFunctionReturn(0);
600   if (!PetscInfoCommFilter && (size < 2)) {
601     /* If no self printing is allowed, and size too small get out */
602     PetscFunctionReturn(0);
603   } else if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) {
604     /* If ONLY self printing, and size too big, get out */
605     PetscFunctionReturn(0);
606   }
607   /* Mute info messages within this function */
608   oldflag = PetscLogPrintInfo; PetscLogPrintInfo = PETSC_FALSE;
609   ierr = MPI_Comm_rank(MPI_COMM_WORLD, &urank);CHKERRQ(ierr);
610   va_start(Argp, message);
611   sprintf(string, "[%d] %s(): ",urank,func);
612   ierr = PetscStrlen(string, &len);CHKERRQ(ierr);
613   ierr = PetscVSNPrintf(string+len, 8*1024-len,message,&fullLength, Argp);CHKERRQ(ierr);
614   ierr = PetscFPrintf(PETSC_COMM_SELF,PetscInfoFile, "%s", string);CHKERRQ(ierr);
615   err  = fflush(PetscInfoFile);
616   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
617   if (petsc_history) {
618     va_start(Argp, message);
619     ierr = (*PetscVFPrintf)(petsc_history, message, Argp);CHKERRQ(ierr);
620   }
621   va_end(Argp);
622   PetscLogPrintInfo = oldflag;
623   PetscFunctionReturn(0);
624 }
625