Actual source code: verboseinfo.c
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>
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.
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.
16: PetscInfoFilename determines where PetscInfo() output is piped.
17: PetscInfoClassnames holds a char array of classes which are filtered out/for in PetscInfo() calls.
18: */
19: const char *const PetscInfoCommFlags[] = {"all", "no_self", "only_self", "PetscInfoCommFlag", "PETSC_INFO_COMM_", NULL};
20: static PetscBool PetscInfoClassesLocked = PETSC_FALSE, PetscInfoInvertClasses = PETSC_FALSE, PetscInfoClassesSet = PETSC_FALSE;
21: static char **PetscInfoClassnames = NULL;
22: static char *PetscInfoFilename = NULL;
23: static PetscInt PetscInfoNumClasses = -1;
24: static PetscInfoCommFlag PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
25: static int PetscInfoFlags[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
26: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
27: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
28: static char *PetscInfoNames[PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags)] = {NULL};
29: PetscBool PetscLogPrintInfo = PETSC_FALSE;
30: FILE *PetscInfoFile = NULL;
32: /*@
33: PetscInfoEnabled - Checks whether a given OBJECT_CLASSID is allowed to print using `PetscInfo()`
35: Not Collective
37: Input Parameter:
38: . classid - `PetscClassid` retrieved from a `PetscObject` e.g. `VEC_CLASSID`
40: Output Parameter:
41: . enabled - `PetscBool` indicating whether this classid is allowed to print
43: Level: advanced
45: Note:
46: Use `PETSC_SMALLEST_CLASSID` to check if "sys" `PetscInfo()` calls are enabled. When PETSc is configured with debugging
47: support this function checks if classid >= `PETSC_SMALLEST_CLASSID`, otherwise it assumes valid classid.
49: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()`
50: @*/
51: PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled)
52: {
53: PetscFunctionBegin;
55: PetscCheck(classid >= PETSC_SMALLEST_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Classid (current: %d) must be equal to or greater than PETSC_SMALLEST_CLASSID", classid);
56: *enabled = (PetscBool)(PetscLogPrintInfo && PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID]);
57: PetscFunctionReturn(PETSC_SUCCESS);
58: }
60: /*@
61: PetscInfoAllow - Enables/disables `PetscInfo()` messages
63: Not Collective
65: Input Parameter:
66: . flag - `PETSC_TRUE` or `PETSC_FALSE`
68: Level: advanced
70: .seealso: `PetscInfo()`, `PetscInfoEnabled()`, `PetscInfoGetInfo()`, `PetscInfoSetFromOptions()`
71: @*/
72: PetscErrorCode PetscInfoAllow(PetscBool flag)
73: {
74: PetscFunctionBegin;
75: PetscLogPrintInfo = flag;
76: PetscFunctionReturn(PETSC_SUCCESS);
77: }
79: /*@C
80: PetscInfoSetFile - Sets the printing destination for all `PetscInfo()` calls
82: Not Collective
84: Input Parameters:
85: + filename - Name of the file where `PetscInfo()` will print to
86: - mode - Write mode passed to `PetscFOpen()`
88: Level: advanced
90: Note:
91: Use `filename = NULL` to set `PetscInfo()` to write to `PETSC_STDOUT`.
93: .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscFOpen()`
94: @*/
95: PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[])
96: {
97: PetscFunctionBegin;
98: if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT;
99: PetscCall(PetscFree(PetscInfoFilename));
100: if (filename) {
101: PetscMPIInt rank;
102: char fname[PETSC_MAX_PATH_LEN], tname[11];
106: PetscCall(PetscFixFilename(filename, fname));
107: PetscCall(PetscStrallocpy(fname, &PetscInfoFilename));
108: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
109: PetscCall(PetscSNPrintf(tname, PETSC_STATIC_ARRAY_LENGTH(tname), ".%d", rank));
110: PetscCall(PetscStrlcat(fname, tname, PETSC_STATIC_ARRAY_LENGTH(fname)));
111: {
112: const PetscBool oldflag = PetscLogPrintInfo;
114: PetscLogPrintInfo = PETSC_FALSE;
115: PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, mode, &PetscInfoFile));
116: PetscLogPrintInfo = oldflag;
117: /*
118: PetscFOpen will write to PETSC_STDOUT and not PetscInfoFile here, so we disable the
119: PetscInfo call inside it, and call it afterwards so that it actually writes to file
120: */
121: }
122: PetscCall(PetscInfo(NULL, "Opened PetscInfo file %s\n", fname));
123: }
124: PetscFunctionReturn(PETSC_SUCCESS);
125: }
127: /*@C
128: PetscInfoGetFile - Gets the `filename` and `FILE` pointer of the file where `PetscInfo()` prints to
130: Not Collective; No Fortran Support
132: Output Parameters:
133: + filename - The name of the output file
134: - InfoFile - The `FILE` pointer for the output file
136: Level: advanced
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.
142: .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()`
143: @*/
144: PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile)
145: {
146: PetscFunctionBegin;
149: PetscCall(PetscStrallocpy(PetscInfoFilename, filename));
150: *InfoFile = PetscInfoFile;
151: PetscFunctionReturn(PETSC_SUCCESS);
152: }
154: /*@C
155: PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against
157: Not Collective; No Fortran Support
159: Input Parameters:
160: + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that
161: is NOT one of the classes specified
162: . n - Number of classes to filter for (size of `classnames`)
163: - classnames - String array containing the names of classes to filter for, e.g. "vec"
165: Level: developer
167: Notes:
168: This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called.
170: Names in the `classnames` list should correspond to the names returned by `PetscObjectGetClassName()`.
172: This function only sets the list of class names.
173: The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away.
174: The reason for this is that we need to set the list of included/excluded classes before their classids are known.
175: Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`).
177: .seealso: `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()`
178: @*/
179: PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames)
180: {
181: PetscFunctionBegin;
182: PetscCheck(!PetscInfoClassesLocked, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscInfoSetClasses() cannot be called after PetscInfoGetClass() or PetscInfoProcessClass()");
183: PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames));
184: PetscCall(PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames));
185: PetscInfoNumClasses = n;
186: PetscInfoInvertClasses = exclude;
187: /* Process sys class right away */
188: {
189: const PetscClassId id = PETSC_SMALLEST_CLASSID;
191: PetscCall(PetscInfoProcessClass("sys", 1, &id));
192: }
193: PetscInfoClassesSet = PETSC_TRUE;
194: PetscFunctionReturn(PETSC_SUCCESS);
195: }
197: /*@C
198: PetscInfoGetClass - Indicates whether the provided `classname` is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()`
200: Not Collective
202: Input Parameter:
203: . classname - Name of the class to search for
205: Output Parameter:
206: . found - `PetscBool` indicating whether the classname was found
208: Level: developer
210: Note:
211: Use `PetscObjectGetName()` to retrieve an appropriate classname
213: .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()`
214: @*/
215: PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found)
216: {
217: PetscInt unused;
219: PetscFunctionBegin;
222: PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found));
223: PetscInfoClassesLocked = PETSC_TRUE;
224: PetscFunctionReturn(PETSC_SUCCESS);
225: }
227: /*@
228: PetscInfoGetInfo - Returns the current state of several important flags for `PetscInfo()`
230: Not Collective
232: Output Parameters:
233: + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called
234: . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set
235: . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted
236: . locked - `PETSC_TRUE` if the list of classes to filter for has been locked
237: - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all
238: communicators
240: Level: developer
242: Note:
243: Initially commSelfFlag = `PETSC_INFO_COMM_ALL`
245: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()`
246: @*/
247: PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag)
248: {
249: PetscFunctionBegin;
255: if (infoEnabled) *infoEnabled = PetscLogPrintInfo;
256: if (classesSet) *classesSet = PetscInfoClassesSet;
257: if (exclude) *exclude = PetscInfoInvertClasses;
258: if (locked) *locked = PetscInfoClassesLocked;
259: if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter;
260: PetscFunctionReturn(PETSC_SUCCESS);
261: }
263: /*@C
264: PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()`
266: Not Collective
268: Input Parameters:
269: + classname - Name of the class to activate/deactivate `PetscInfo()` for
270: . numClassID - Number of entries in `classIDs`
271: - classIDs - Array containing all of the `PetscClassId`s associated with `classname`
273: Options Database Key:
274: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, see `PetscInfo()`.
276: Level: developer
278: .seealso: `PetscInfo()`, `PetscInfoActivateClass()`, `PetscInfoDeactivateClass()`, `PetscInfoSetFromOptions()`
279: @*/
280: PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, const PetscClassId classIDs[])
281: {
282: PetscBool enabled, exclude, found, opt;
283: char logList[256];
285: PetscFunctionBegin;
287: PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID);
289: PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL));
290: PetscCall(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use ~ with -info to indicate classes to exclude"));
291: PetscCall(PetscOptionsGetString(NULL, NULL, "-info_exclude", logList, sizeof(logList), &opt));
292: if (opt) {
293: PetscBool pkg;
295: PetscCall(PetscStrInList(classname, logList, ',', &pkg));
296: if (pkg) {
297: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i]));
298: }
299: }
300: for (PetscInt i = 0; i < numClassID; ++i) {
301: const PetscClassId idx = classIDs[i] - PETSC_SMALLEST_CLASSID;
303: PetscCall(PetscFree(PetscInfoNames[idx]));
304: PetscCall(PetscStrallocpy(classname, PetscInfoNames + idx));
305: }
306: PetscCall(PetscInfoGetClass(classname, &found));
307: if ((found && exclude) || (!found && !exclude)) {
308: if (PetscInfoNumClasses > 0) {
309: /* Check if -info was called empty */
310: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i]));
311: }
312: } else {
313: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoActivateClass(classIDs[i]));
314: }
315: PetscFunctionReturn(PETSC_SUCCESS);
316: }
318: /*@
319: PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()`
321: Not Collective
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()`
326: Options Database Key:
327: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
329: Level: advanced
331: .seealso: `PetscInfo()`, `PetscInfoGetInfo()`
332: @*/
333: PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag)
334: {
335: PetscFunctionBegin;
336: PetscInfoCommFilter = commSelfFlag;
337: PetscFunctionReturn(PETSC_SUCCESS);
338: }
340: /*@
341: PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()`
343: Not Collective
345: Input Parameter:
346: . options - Options database, use `NULL` for default global database
348: Options Database Key:
349: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
351: Level: advanced
353: Note:
354: This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves.
356: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()`
357: @*/
358: PetscErrorCode PetscInfoSetFromOptions(PetscOptions options)
359: {
360: char optstring[PETSC_MAX_PATH_LEN];
361: PetscBool set;
363: PetscFunctionBegin;
364: PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set));
365: if (set) {
366: size_t size_loc0_, size_loc1_, size_loc2_;
367: char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL;
368: char **loc1_array = NULL;
369: PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE;
370: int nLoc1_ = 0;
371: PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL;
373: PetscInfoClassesSet = PETSC_TRUE;
374: PetscCall(PetscInfoAllow(PETSC_TRUE));
375: PetscCall(PetscStrallocpy(optstring, &loc0_));
376: PetscCall(PetscStrchr(loc0_, ':', &loc1_));
377: if (loc1_) {
378: *loc1_++ = 0;
379: if (*loc1_ == '~') {
380: loc1_invert = PETSC_TRUE;
381: ++loc1_;
382: }
383: PetscCall(PetscStrchr(loc1_, ':', &loc2_));
384: }
385: if (loc2_) {
386: *loc2_++ = 0;
387: if (*loc2_ == '~') {
388: loc2_invert = PETSC_TRUE;
389: ++loc2_;
390: }
391: }
392: PetscCall(PetscStrlen(loc0_, &size_loc0_));
393: PetscCall(PetscStrlen(loc1_, &size_loc1_));
394: PetscCall(PetscStrlen(loc2_, &size_loc2_));
395: if (size_loc1_) {
396: PetscCall(PetscStrtolower(loc1_));
397: PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array));
398: }
399: if (size_loc2_) {
400: PetscBool foundSelf;
402: PetscCall(PetscStrtolower(loc2_));
403: PetscCall(PetscStrcmp("self", loc2_, &foundSelf));
404: if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF;
405: }
406: PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w"));
407: PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array));
408: PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag));
409: PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array));
410: PetscCall(PetscFree(loc0_));
411: }
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }
415: /*@
416: PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures.
418: Not Collective
420: Level: developer
422: Note:
423: This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent
424: `PetscInfo()` calls down the line.
426: .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()`
427: @*/
428: PetscErrorCode PetscInfoDestroy(void)
429: {
430: PetscFunctionBegin;
431: PetscCall(PetscInfoAllow(PETSC_FALSE));
432: PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames));
433: PetscCall(PetscFFlush(PetscInfoFile));
434: if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile));
435: PetscCall(PetscFree(PetscInfoFilename));
436: PetscAssert(PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags) == PETSC_STATIC_ARRAY_LENGTH(PetscInfoNames), PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscInfoFlags and PetscInfoNames must be the same size");
437: for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) {
438: PetscInfoFlags[i] = 1;
439: PetscCall(PetscFree(PetscInfoNames[i]));
440: }
442: PetscInfoClassesLocked = PETSC_FALSE;
443: PetscInfoInvertClasses = PETSC_FALSE;
444: PetscInfoClassesSet = PETSC_FALSE;
445: PetscInfoNumClasses = -1;
446: PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
447: PetscFunctionReturn(PETSC_SUCCESS);
448: }
450: static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value)
451: {
452: PetscFunctionBegin;
453: if (!classid) classid = PETSC_SMALLEST_CLASSID;
454: PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value;
455: PetscFunctionReturn(PETSC_SUCCESS);
456: }
458: /*@
459: PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class.
461: Not Collective
463: Input Parameter:
464: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
466: Options Database Key:
467: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
469: Level: developer
471: Note:
472: One can pass 0 to deactivate all messages that are not associated with an object.
474: .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
475: @*/
476: PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid)
477: {
478: PetscFunctionBegin;
479: PetscCall(PetscInfoSetClassActivation_Private(classid, 0));
480: PetscFunctionReturn(PETSC_SUCCESS);
481: }
483: /*@
484: PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class.
486: Not Collective
488: Input Parameter:
489: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
491: Options Database Key:
492: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
494: Level: developer
496: Note:
497: One can pass 0 to activate all messages that are not associated with an object.
499: .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
500: @*/
501: PetscErrorCode PetscInfoActivateClass(PetscClassId classid)
502: {
503: PetscFunctionBegin;
504: PetscCall(PetscInfoSetClassActivation_Private(classid, 1));
505: PetscFunctionReturn(PETSC_SUCCESS);
506: }
508: /*
509: If the option -history was used, then all printed PetscInfo()
510: messages are also printed to the history file, called by default
511: .petschistory in ones home directory.
512: */
513: PETSC_INTERN FILE *petsc_history;
515: /*MC
516: PetscInfo - Logs informative data
518: Synopsis:
519: #include <petscsys.h>
520: PetscErrorCode PetscInfo(PetscObject obj, const char message[])
521: PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1)
522: PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2)
523: ...
525: Collective
527: Input Parameters:
528: + obj - object most closely associated with the logging statement or `NULL`
529: . message - logging message
530: . formatmessage - logging message using standard "printf" format
531: - arg1, arg2, ... - arguments of the format
533: Options Database Key:
534: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
536: Level: intermediate
538: Notes:
539: `PetscInfo()` prints only from the first processor in the communicator of obj.
540: If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message.
542: The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp.
543: If this list is not specified, all classes are enabled.
544: Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled.
545: A special classname `sys` relates to `PetscInfo()` with obj being `NULL`.
547: The optional keyword `self` specifies that `PetscInfo()` is enabled only for a communicator size of 1 (e.g. `PETSC_COMM_SELF`).
548: 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.
550: All classname/self matching is case insensitive. Filename is case sensitive.
552: Example of Usage:
553: .vb
554: Mat A;
555: PetscInt alpha;
556: ...
557: PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha);
558: .ve
560: Options Examples:
561: Each call of the form
562: .vb
563: PetscInfo(obj, msg);
564: PetscInfo(obj, msg, arg1);
565: PetscInfo(obj, msg, arg1, arg2);
566: .ve
567: is evaluated as follows.
568: .vb
569: -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator
570: -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1
571: -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
572: -info :sys prints to PETSC_STDOUT only if obj is NULL
573: -info :sys:~self deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF.
574: .ve
575: Fortran Note:
576: This function does not take the `obj` argument, there is only the `PetscInfo()`
577: version, not `PetscInfo()` etc.
579: .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
580: M*/
581: PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...)
582: {
583: PetscClassId classid = PETSC_SMALLEST_CLASSID;
584: PetscBool enabled = PETSC_FALSE;
585: MPI_Comm comm = PETSC_COMM_SELF;
586: PetscMPIInt rank;
588: PetscFunctionBegin;
589: if (obj) {
591: classid = obj->classid;
592: }
594: PetscCall(PetscInfoEnabled(classid, &enabled));
595: if (!enabled) PetscFunctionReturn(PETSC_SUCCESS);
596: if (obj) PetscCall(PetscObjectGetComm(obj, &comm));
597: PetscCallMPI(MPI_Comm_rank(comm, &rank));
598: /* rank > 0 always jumps out */
599: if (rank) PetscFunctionReturn(PETSC_SUCCESS);
600: else {
601: PetscMPIInt size;
603: PetscCallMPI(MPI_Comm_size(comm, &size));
604: /* If no self printing is allowed, and size too small, get out */
605: if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(PETSC_SUCCESS);
606: /* If ONLY self printing, and size too big, get out */
607: if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(PETSC_SUCCESS);
608: }
609: /* Mute info messages within this function */
610: {
611: const PetscBool oldflag = PetscLogPrintInfo;
612: va_list Argp;
613: PetscMPIInt urank;
614: char string[8 * 1024];
615: size_t fullLength, len;
617: PetscLogPrintInfo = PETSC_FALSE;
618: PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank));
619: PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func));
620: PetscCall(PetscStrlen(string, &len));
621: va_start(Argp, message);
622: PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp));
623: va_end(Argp);
624: PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string));
625: PetscCall(PetscFFlush(PetscInfoFile));
626: if (petsc_history) {
627: va_start(Argp, message);
628: PetscCall((*PetscVFPrintf)(petsc_history, message, Argp));
629: va_end(Argp);
630: }
631: PetscLogPrintInfo = oldflag;
632: }
633: PetscFunctionReturn(PETSC_SUCCESS);
634: }