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 `PetscClassid` 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: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()`
50: @*/
51: PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled)
52: {
53: PetscFunctionBegin;
54: PetscAssertPointer(enabled, 2);
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: [](sec_PetscInfo), `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, use `NULL` to write to `PETSC_STDOUT`.
86: - mode - Write mode passed to `PetscFOpen()`
88: Level: advanced
90: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetFile()`, `PetscInfoSetFromOptions()`, `PetscFOpen()`
91: @*/
92: PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[])
93: {
94: PetscFunctionBegin;
95: if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT;
96: PetscCall(PetscFree(PetscInfoFilename));
97: if (filename) {
98: PetscMPIInt rank;
99: char fname[PETSC_MAX_PATH_LEN], tname[11];
101: PetscAssertPointer(filename, 1);
102: PetscAssertPointer(mode, 2);
103: PetscCall(PetscFixFilename(filename, fname));
104: PetscCall(PetscStrallocpy(fname, &PetscInfoFilename));
105: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
106: PetscCall(PetscSNPrintf(tname, PETSC_STATIC_ARRAY_LENGTH(tname), ".%d", rank));
107: PetscCall(PetscStrlcat(fname, tname, PETSC_STATIC_ARRAY_LENGTH(fname)));
108: {
109: const PetscBool oldflag = PetscLogPrintInfo;
111: PetscLogPrintInfo = PETSC_FALSE;
112: PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, mode, &PetscInfoFile));
113: PetscLogPrintInfo = oldflag;
114: /*
115: PetscFOpen will write to PETSC_STDOUT and not PetscInfoFile here, so we disable the
116: PetscInfo call inside it, and call it afterwards so that it actually writes to file
117: */
118: }
119: PetscCall(PetscInfo(NULL, "Opened PetscInfo file %s\n", fname));
120: }
121: PetscFunctionReturn(PETSC_SUCCESS);
122: }
124: /*@C
125: PetscInfoGetFile - Gets the `filename` and `FILE` pointer of the file where `PetscInfo()` prints to
127: Not Collective; No Fortran Support
129: Output Parameters:
130: + filename - The name of the output file
131: - InfoFile - The `FILE` pointer for the output file
133: Level: advanced
135: Note:
136: This routine allocates and copies the `filename` so that the `filename` survives `PetscInfoDestroy()`. The user is
137: therefore responsible for freeing the allocated `filename` pointer with `PetscFree()`
139: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()`
140: @*/
141: PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile)
142: {
143: PetscFunctionBegin;
144: PetscAssertPointer(filename, 1);
145: PetscAssertPointer(InfoFile, 2);
146: PetscCall(PetscStrallocpy(PetscInfoFilename, filename));
147: *InfoFile = PetscInfoFile;
148: PetscFunctionReturn(PETSC_SUCCESS);
149: }
151: /*@C
152: PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against
154: Not Collective; No Fortran Support
156: Input Parameters:
157: + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that
158: is NOT one of the classes specified
159: . n - Number of classes to filter for (size of `classnames`)
160: - classnames - String array containing the names of classes to filter for, e.g. "vec"
162: Level: developer
164: Notes:
165: This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called, unless the user calls `PetscInfoDestroy()` first.
167: Names in the `classnames` list should correspond to the names returned by `PetscObjectGetClassName()`.
169: This function only sets the list of class names.
170: The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away.
171: The reason for this is that we need to set the list of included/excluded classes before their classids are known.
172: Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`).
174: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()`
175: @*/
176: PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames)
177: {
178: PetscFunctionBegin;
179: PetscCheck(!PetscInfoClassesLocked, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Trying to modify PetscInfo() configuration after it has been locked to a read-only state. Usually, this is an *error*! To re-enable modification, you must reset PetscInfo() by calling PetscInfoDestroy() first");
180: PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames));
181: PetscCall(PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames));
182: PetscInfoNumClasses = n;
183: PetscInfoInvertClasses = exclude;
184: /* Process sys class right away */
185: {
186: const PetscClassId id = PETSC_SMALLEST_CLASSID;
188: PetscCall(PetscInfoProcessClass("sys", 1, &id));
189: }
190: PetscInfoClassesSet = PETSC_TRUE;
191: PetscFunctionReturn(PETSC_SUCCESS);
192: }
194: /*@C
195: PetscInfoGetClass - Indicates whether the provided `classname` is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()`
197: Not Collective
199: Input Parameter:
200: . classname - Name of the class to search for
202: Output Parameter:
203: . found - `PetscBool` indicating whether the classname was found
205: Level: developer
207: Note:
208: Use `PetscObjectGetName()` to retrieve an appropriate classname
210: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()`
211: @*/
212: PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found)
213: {
214: PetscInt unused;
216: PetscFunctionBegin;
217: PetscAssertPointer(classname, 1);
218: PetscAssertPointer(found, 2);
219: PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found));
220: PetscInfoClassesLocked = PETSC_TRUE;
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: /*@
225: PetscInfoGetInfo - Returns the current state of several flags for `PetscInfo()`
227: Not Collective
229: Output Parameters:
230: + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called
231: . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set
232: . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted
233: . locked - `PETSC_TRUE` if the list of classes to filter for has been locked
234: - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all
235: communicators
237: Level: developer
239: Note:
240: Initially commSelfFlag = `PETSC_INFO_COMM_ALL`
242: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()`
243: @*/
244: PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag)
245: {
246: PetscFunctionBegin;
247: if (infoEnabled) PetscAssertPointer(infoEnabled, 1);
248: if (classesSet) PetscAssertPointer(classesSet, 2);
249: if (exclude) PetscAssertPointer(exclude, 3);
250: if (locked) PetscAssertPointer(locked, 4);
251: if (commSelfFlag) PetscAssertPointer(commSelfFlag, 5);
252: if (infoEnabled) *infoEnabled = PetscLogPrintInfo;
253: if (classesSet) *classesSet = PetscInfoClassesSet;
254: if (exclude) *exclude = PetscInfoInvertClasses;
255: if (locked) *locked = PetscInfoClassesLocked;
256: if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter;
257: PetscFunctionReturn(PETSC_SUCCESS);
258: }
260: /*@C
261: PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()`
263: Not Collective
265: Input Parameters:
266: + classname - Name of the class to activate/deactivate `PetscInfo()` for
267: . numClassID - Number of entries in `classIDs`
268: - classIDs - Array containing all of the `PetscClassId`s associated with `classname`
270: Options Database Key:
271: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, see `PetscInfo()`.
273: Level: developer
275: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoActivateClass()`, `PetscInfoDeactivateClass()`, `PetscInfoSetFromOptions()`
276: @*/
277: PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, const PetscClassId classIDs[])
278: {
279: PetscBool enabled, exclude, found, opt;
280: char logList[256];
282: PetscFunctionBegin;
283: PetscAssertPointer(classname, 1);
284: PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID);
285: if (numClassID) PetscAssertPointer(classIDs, 3);
286: PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL));
287: PetscCall(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use ~ with -info to indicate classes to exclude"));
288: PetscCall(PetscOptionsGetString(NULL, NULL, "-info_exclude", logList, sizeof(logList), &opt));
289: if (opt) {
290: PetscBool pkg;
292: PetscCall(PetscStrInList(classname, logList, ',', &pkg));
293: if (pkg) {
294: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i]));
295: }
296: }
297: for (PetscInt i = 0; i < numClassID; ++i) {
298: const PetscClassId idx = classIDs[i] - PETSC_SMALLEST_CLASSID;
300: PetscCall(PetscFree(PetscInfoNames[idx]));
301: PetscCall(PetscStrallocpy(classname, PetscInfoNames + idx));
302: }
303: PetscCall(PetscInfoGetClass(classname, &found));
304: if ((found && exclude) || (!found && !exclude)) {
305: if (PetscInfoNumClasses > 0) {
306: /* Check if -info was called empty */
307: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i]));
308: }
309: } else {
310: for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoActivateClass(classIDs[i]));
311: }
312: PetscFunctionReturn(PETSC_SUCCESS);
313: }
315: /*@
316: PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()`
318: Not Collective
320: Input Parameter:
321: . commSelfFlag - Enum value indicating method with which to filter `PetscInfo()` based on the size of the communicator of the object calling `PetscInfo()`
323: Options Database Key:
324: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
326: Level: advanced
328: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetInfo()`
329: @*/
330: PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag)
331: {
332: PetscFunctionBegin;
333: PetscInfoCommFilter = commSelfFlag;
334: PetscFunctionReturn(PETSC_SUCCESS);
335: }
337: /*@
338: PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()`
340: Not Collective
342: Input Parameter:
343: . options - Options database, use `NULL` for default global database
345: Options Database Key:
346: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
348: Level: advanced
350: Note:
351: This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves.
353: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()`
354: @*/
355: PetscErrorCode PetscInfoSetFromOptions(PetscOptions options)
356: {
357: char optstring[PETSC_MAX_PATH_LEN];
358: PetscBool set;
360: PetscFunctionBegin;
361: PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set));
362: if (set) {
363: size_t size_loc0_, size_loc1_, size_loc2_;
364: char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL;
365: char **loc1_array = NULL;
366: PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE;
367: int nLoc1_ = 0;
368: PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL;
370: PetscInfoClassesSet = PETSC_TRUE;
371: PetscCall(PetscInfoAllow(PETSC_TRUE));
372: PetscCall(PetscStrallocpy(optstring, &loc0_));
373: PetscCall(PetscStrchr(loc0_, ':', &loc1_));
374: if (loc1_) {
375: *loc1_++ = 0;
376: if (*loc1_ == '~') {
377: loc1_invert = PETSC_TRUE;
378: ++loc1_;
379: }
380: PetscCall(PetscStrchr(loc1_, ':', &loc2_));
381: }
382: if (loc2_) {
383: *loc2_++ = 0;
384: if (*loc2_ == '~') {
385: loc2_invert = PETSC_TRUE;
386: ++loc2_;
387: }
388: }
389: PetscCall(PetscStrlen(loc0_, &size_loc0_));
390: PetscCall(PetscStrlen(loc1_, &size_loc1_));
391: PetscCall(PetscStrlen(loc2_, &size_loc2_));
392: if (size_loc1_) {
393: PetscCall(PetscStrtolower(loc1_));
394: PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array));
395: }
396: if (size_loc2_) {
397: PetscBool foundSelf;
399: PetscCall(PetscStrtolower(loc2_));
400: PetscCall(PetscStrcmp("self", loc2_, &foundSelf));
401: if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF;
402: }
403: PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w"));
404: PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array));
405: PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag));
406: PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array));
407: PetscCall(PetscFree(loc0_));
408: }
409: PetscFunctionReturn(PETSC_SUCCESS);
410: }
412: /*@
413: PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures.
415: Not Collective
417: Level: developer
419: Notes:
420: This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent
421: `PetscInfo()` calls down the line.
423: Users calling this routine midway through a program should note that `PetscInfoDestroy()`
424: constitutes a full reset of `PetscInfo()`. It flushes, then closes, the current info file,
425: re-enables all classes, and resets all internal state. Finally -- and perhaps crucially -- it
426: disables `PetscInfo()` as-if-by `PetscInfoAllow(PETSC_FALSE)`.
428: .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetFromOptions()`
429: @*/
430: PetscErrorCode PetscInfoDestroy(void)
431: {
432: PetscFunctionBegin;
433: PetscCall(PetscInfoAllow(PETSC_FALSE));
434: PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames));
435: if (PetscInfoFile) PetscCall(PetscFFlush(PetscInfoFile));
436: if (PetscInfoFilename) {
437: PetscAssert(PetscInfoFile, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Have non-null PetscInfo file '%s', but corresponding FILE handle is null!", PetscInfoFilename);
438: PetscCall(PetscFree(PetscInfoFilename));
439: PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile));
440: }
441: 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");
442: for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) {
443: PetscInfoFlags[i] = 1;
444: PetscCall(PetscFree(PetscInfoNames[i]));
445: }
447: PetscInfoFile = NULL;
448: PetscInfoClassesLocked = PETSC_FALSE;
449: PetscInfoInvertClasses = PETSC_FALSE;
450: PetscInfoClassesSet = PETSC_FALSE;
451: PetscInfoNumClasses = -1;
452: PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
453: PetscFunctionReturn(PETSC_SUCCESS);
454: }
456: static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value)
457: {
458: PetscFunctionBegin;
459: if (!classid) classid = PETSC_SMALLEST_CLASSID;
460: PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value;
461: PetscFunctionReturn(PETSC_SUCCESS);
462: }
464: /*@
465: PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class.
467: Not Collective
469: Input Parameter:
470: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
472: Options Database Key:
473: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
475: Level: developer
477: Note:
478: One can pass 0 to deactivate all messages that are not associated with an object.
480: .seealso: [](sec_PetscInfo), `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
481: @*/
482: PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid)
483: {
484: PetscFunctionBegin;
485: PetscCall(PetscInfoSetClassActivation_Private(classid, 0));
486: PetscFunctionReturn(PETSC_SUCCESS);
487: }
489: /*@
490: PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class.
492: Not Collective
494: Input Parameter:
495: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
497: Options Database Key:
498: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`.
500: Level: developer
502: Note:
503: One can pass 0 to activate all messages that are not associated with an object.
505: .seealso: [](sec_PetscInfo), `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
506: @*/
507: PetscErrorCode PetscInfoActivateClass(PetscClassId classid)
508: {
509: PetscFunctionBegin;
510: PetscCall(PetscInfoSetClassActivation_Private(classid, 1));
511: PetscFunctionReturn(PETSC_SUCCESS);
512: }
514: /*
515: If the option -history was used, then all printed PetscInfo()
516: messages are also printed to the history file, called by default
517: .petschistory in ones home directory.
518: */
519: PETSC_INTERN FILE *petsc_history;
520: PETSC_INTERN PetscErrorCode PetscVFPrintf_Internal(FILE *, const char[], ...);
522: /*MC
523: PetscInfo - Logs informative data
525: Synopsis:
526: #include <petsclog.h>
527: PetscErrorCode PetscInfo(PetscObject obj, const char message[], ...)
529: Collective
531: Input Parameters:
532: + obj - object most closely associated with the logging statement or `NULL`
533: - message - logging message using standard "printf" format
535: Options Database Key:
536: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed
538: Level: intermediate
540: Notes:
541: `PetscInfo()` prints only from the first processor in the communicator of `obj`.
542: If `obj` is `NULL`, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message.
544: The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. `vec,mat,ksp`.
545: If this list is not specified, all classes are enabled.
546: Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled.
547: A special classname `sys` relates to `PetscInfo()` with `obj` being `NULL`.
549: The optional keyword `self` specifies that `PetscInfo()` is enabled only for a communicator size of 1 (e.g. `PETSC_COMM_SELF`).
550: 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.
552: All classname/self matching is case insensitive. Filename is case sensitive.
554: Example of Usage:
555: .vb
556: Mat A;
557: PetscInt alpha;
558: ...
559: PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha);
560: .ve
562: Examples using Options:
563: Each call of the form
564: .vb
565: PetscInfo(obj, msg);
566: PetscInfo(obj, msg, arg1);
567: PetscInfo(obj, msg, arg1, arg2);
568: .ve
569: is evaluated as follows.
570: .vb
571: -info or -info :: prints `msg` to `PETSC_STDOUT`, for any PETSc `obj` regardless class or communicator
572: -info :mat:self prints `msg` to `PETSC_STDOUT` only if class of `obj` is `Mat`, and its communicator has size = 1
573: -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
574: -info :sys prints to `PETSC_STDOUT` only if `obj` is `NULL`
575: -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`.
576: .ve
578: Fortran Notes:
579: This function does not take the `obj` argument, there is only the `PetscInfo()`
580: version, not `PetscInfo()` etc.
582: .seealso: [](sec_PetscInfo), `PetscInfoAllow()`, `PetscInfoSetFromOptions()`, `PetscInfoEnabled()`, `PetscInfoSetFile()`, `PetscInfoGetFile()`, `PetscInfoSetClasses()`,
583: `PetscInfoGetClass()`, `PetscInfoGetInfo()`, `PetscInfoProcessClass()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()`, `PetscInfoDeactivateClass()`,
584: `PetscInfoActivateClass()`
585: M*/
586: PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...)
587: {
588: PetscClassId classid = PETSC_SMALLEST_CLASSID;
589: PetscBool enabled = PETSC_FALSE;
590: MPI_Comm comm = MPI_COMM_NULL;
591: PetscMPIInt rank = 0;
592: const char *otype = NULL;
594: PetscFunctionBegin;
595: if (obj) {
597: classid = obj->classid;
598: }
599: PetscAssertPointer(message, 3);
600: PetscCall(PetscInfoEnabled(classid, &enabled));
601: if (!enabled) PetscFunctionReturn(PETSC_SUCCESS);
602: if (obj) {
603: PetscCall(PetscObjectGetComm(obj, &comm));
604: PetscCall(PetscObjectGetType(obj, &otype));
605: PetscCallMPI(MPI_Comm_rank(comm, &rank));
606: }
607: /* rank > 0 always jumps out */
608: if (rank) PetscFunctionReturn(PETSC_SUCCESS);
609: else {
610: PetscMPIInt size = 1;
612: if (comm != MPI_COMM_NULL) PetscCallMPI(MPI_Comm_size(comm, &size));
613: /* If no self printing is allowed, and size too small, get out */
614: if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(PETSC_SUCCESS);
615: /* If ONLY self printing, and size too big, get out */
616: if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(PETSC_SUCCESS);
617: }
618: /* Mute info messages within this function */
619: {
620: const PetscBool oldflag = PetscLogPrintInfo;
621: va_list Argp;
622: PetscMPIInt urank;
623: char string[8 * 1024];
624: size_t fullLength, len;
626: PetscLogPrintInfo = PETSC_FALSE;
627: PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank));
628: if (otype) {
629: PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s:%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], otype, func));
630: } else {
631: PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func));
632: }
633: PetscCall(PetscStrlen(string, &len));
634: va_start(Argp, message);
635: PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp));
636: va_end(Argp);
637: PetscCall(PetscVFPrintf_Internal(PetscInfoFile, "%s", string));
638: PetscCall(PetscFFlush(PetscInfoFile));
639: if (petsc_history) {
640: va_start(Argp, message);
641: PetscCall((*PetscVFPrintf)(petsc_history, message, Argp));
642: va_end(Argp);
643: }
644: PetscLogPrintInfo = oldflag;
645: }
646: PetscFunctionReturn(PETSC_SUCCESS);
647: }