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 Parameters:
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: Note:
44: Use `PETSC_SMALLEST_CLASSID` to check if "sys" `PetscInfo()` calls are enabled. When PETSc is configured with debugging
45: support this function checks if classid >= `PETSC_SMALLEST_CLASSID`, otherwise it assumes valid classid.
47: Level: advanced
49: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()`
50: @*/
51: PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled)
52: {
55: *enabled = (PetscBool)(PetscLogPrintInfo && PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID]);
56: return 0;
57: }
59: /*@
60: PetscInfoAllow - Enables/disables `PetscInfo()` messages
62: Not Collective
64: Input Parameter:
65: . flag - `PETSC_TRUE` or `PETSC_FALSE`
67: Level: advanced
69: .seealso: `PetscInfo()`, `PetscInfoEnabled()`, `PetscInfoGetInfo()`, `PetscInfoSetFromOptions()`
70: @*/
71: PetscErrorCode PetscInfoAllow(PetscBool flag)
72: {
73: PetscLogPrintInfo = flag;
74: return 0;
75: }
77: /*@C
78: PetscInfoSetFile - Sets the printing destination for all `PetscInfo()` calls
80: Not Collective
82: Input Parameters:
83: + filename - Name of the file where `PetscInfo()` will print to
84: - mode - Write mode passed to PetscFOpen()`
86: Note:
87: Use filename = NULL to set `PetscInfo()` to write to `PETSC_STDOUT`.
89: Level: advanced
91: .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscFOpen()`
92: @*/
93: PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[])
94: {
95: if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT;
96: PetscFree(PetscInfoFilename);
97: if (filename) {
98: PetscMPIInt rank;
99: char fname[PETSC_MAX_PATH_LEN], tname[11];
103: PetscFixFilename(filename, fname);
104: PetscStrallocpy(fname, &PetscInfoFilename);
105: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
106: PetscSNPrintf(tname, PETSC_STATIC_ARRAY_LENGTH(tname), ".%d", rank);
107: PetscStrlcat(fname, tname, PETSC_STATIC_ARRAY_LENGTH(fname));
108: {
109: const PetscBool oldflag = PetscLogPrintInfo;
111: PetscLogPrintInfo = PETSC_FALSE;
112: 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: PetscInfo(NULL, "Opened PetscInfo file %s\n", fname);
120: }
121: return 0;
122: }
124: /*@C
125: PetscInfoGetFile - Gets the name and FILE pointer of the file where `PetscInfo()` prints to
127: Not Collective
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 afterwards.
139: Fortran Note:
140: This routine is not supported in Fortran.
142: .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()`
143: @*/
144: PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile)
145: {
148: PetscStrallocpy(PetscInfoFilename, filename);
149: *InfoFile = PetscInfoFile;
150: return 0;
151: }
153: /*@C
154: PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against
156: Not Collective
158: Input Parameters:
159: + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that
160: is NOT one of the classes specified
161: . n - Number of classes to filter for (size of classnames)
162: - classnames - String array containing the names of classes to filter for, e.g. "vec"
164: Notes:
165: This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called.
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: Fortran Note:
175: Not for use in Fortran
177: Level: developer
179: .seealso: `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()`
180: @*/
181: PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames)
182: {
184: PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);
185: PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames);
186: PetscInfoNumClasses = n;
187: PetscInfoInvertClasses = exclude;
188: /* Process sys class right away */
189: {
190: const PetscClassId id = PETSC_SMALLEST_CLASSID;
192: PetscInfoProcessClass("sys", 1, &id);
193: }
194: PetscInfoClassesSet = PETSC_TRUE;
195: return 0;
196: }
198: /*@C
199: PetscInfoGetClass - Indicates whether the provided classname is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()`
201: Not Collective
203: Input Parameter:
204: . classname - Name of the class to search for
206: Output Parameter:
207: . found - `PetscBool` indicating whether the classname was found
209: Note:
210: Use `PetscObjectGetName()` to retrieve an appropriate classname
212: Level: developer
214: .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()`
215: @*/
216: PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found)
217: {
218: PetscInt unused;
222: PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found);
223: PetscInfoClassesLocked = PETSC_TRUE;
224: return 0;
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: Note:
241: Initially commSelfFlag = `PETSC_INFO_COMM_ALL`
243: Level: developer
245: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()`
246: @*/
247: PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag)
248: {
254: if (infoEnabled) *infoEnabled = PetscLogPrintInfo;
255: if (classesSet) *classesSet = PetscInfoClassesSet;
256: if (exclude) *exclude = PetscInfoInvertClasses;
257: if (locked) *locked = PetscInfoClassesLocked;
258: if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter;
259: return 0;
260: }
262: /*@C
263: PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()`
265: Not Collective
267: Input Parameters:
268: + classname - Name of the class to activate/deactivate `PetscInfo()` for
269: . numClassID - Number of entries in classIDs
270: - classIDs - Array containing all of the PetscClassids associated with classname
272: Level: developer
274: .seealso: `PetscInfo()`, `PetscInfoActivateClass()`, `PetscInfoDeactivateClass()`, `PetscInfoSetFromOptions()`
275: @*/
276: PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, const PetscClassId classIDs[])
277: {
278: PetscBool enabled, exclude, found, opt;
279: char logList[256];
282: PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID);
284: PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL);
285: /* -info_exclude is DEPRECATED */
286: PetscOptionsGetString(NULL, NULL, "-info_exclude", logList, sizeof(logList), &opt);
287: if (opt) {
288: PetscBool pkg;
290: PetscStrInList(classname, logList, ',', &pkg);
291: if (pkg) {
292: for (PetscInt i = 0; i < numClassID; ++i) PetscInfoDeactivateClass(classIDs[i]);
293: }
294: }
295: for (PetscInt i = 0; i < numClassID; ++i) {
296: const PetscClassId idx = classIDs[i] - PETSC_SMALLEST_CLASSID;
298: PetscFree(PetscInfoNames[idx]);
299: PetscStrallocpy(classname, PetscInfoNames + idx);
300: }
301: PetscInfoGetClass(classname, &found);
302: if ((found && exclude) || (!found && !exclude)) {
303: if (PetscInfoNumClasses > 0) {
304: /* Check if -info was called empty */
305: for (PetscInt i = 0; i < numClassID; ++i) PetscInfoDeactivateClass(classIDs[i]);
306: }
307: } else {
308: for (PetscInt i = 0; i < numClassID; ++i) PetscInfoActivateClass(classIDs[i]);
309: }
310: return 0;
311: }
313: /*@
314: PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()`
316: Not Collective
318: Input Parameter:
319: . commSelfFlag - Enum value indicating method with which to filter `PetscInfo()` based on the size of the communicator of the object calling `PetscInfo()`
321: Level: advanced
323: .seealso: `PetscInfo()`, `PetscInfoGetInfo()`
324: @*/
325: PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag)
326: {
327: PetscInfoCommFilter = commSelfFlag;
328: return 0;
329: }
331: /*@
332: PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()`
334: Not Collective
336: Input Parameter:
337: . options - Options database, use NULL for default global database
339: Options Database Keys:
340: . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo().
342: Note:
343: This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves.
345: Level: advanced
347: .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()`
348: @*/
349: PetscErrorCode PetscInfoSetFromOptions(PetscOptions options)
350: {
351: char optstring[PETSC_MAX_PATH_LEN];
352: PetscBool set;
354: PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use -info instead");
355: PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set);
356: if (set) {
357: size_t size_loc0_, size_loc1_, size_loc2_;
358: char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL;
359: char **loc1_array = NULL;
360: PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE;
361: int nLoc1_ = 0;
362: PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL;
364: PetscInfoClassesSet = PETSC_TRUE;
365: PetscInfoAllow(PETSC_TRUE);
366: PetscStrallocpy(optstring, &loc0_);
367: PetscStrchr(loc0_, ':', &loc1_);
368: if (loc1_) {
369: *loc1_++ = 0;
370: if (*loc1_ == '~') {
371: loc1_invert = PETSC_TRUE;
372: ++loc1_;
373: }
374: PetscStrchr(loc1_, ':', &loc2_);
375: }
376: if (loc2_) {
377: *loc2_++ = 0;
378: if (*loc2_ == '~') {
379: loc2_invert = PETSC_TRUE;
380: ++loc2_;
381: }
382: }
383: PetscStrlen(loc0_, &size_loc0_);
384: PetscStrlen(loc1_, &size_loc1_);
385: PetscStrlen(loc2_, &size_loc2_);
386: if (size_loc1_) {
387: PetscStrtolower(loc1_);
388: PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array);
389: }
390: if (size_loc2_) {
391: PetscBool foundSelf;
393: PetscStrtolower(loc2_);
394: PetscStrcmp("self", loc2_, &foundSelf);
395: if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF;
396: }
397: PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w");
398: PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array);
399: PetscInfoSetFilterCommSelf(commSelfFlag);
400: PetscStrToArrayDestroy(nLoc1_, loc1_array);
401: PetscFree(loc0_);
402: }
403: return 0;
404: }
406: /*@
407: PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures.
409: Not Collective
411: Note:
412: This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent
413: `PetscInfo()` calls down the line.
415: Level: developer
417: .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()`
418: @*/
419: PetscErrorCode PetscInfoDestroy(void)
420: {
421: int err;
423: PetscInfoAllow(PETSC_FALSE);
424: PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames);
425: err = fflush(PetscInfoFile);
427: if (PetscInfoFilename) PetscFClose(PETSC_COMM_SELF, PetscInfoFile);
428: PetscFree(PetscInfoFilename);
429: 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");
430: for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) {
431: PetscInfoFlags[i] = 1;
432: PetscFree(PetscInfoNames[i]);
433: }
435: PetscInfoClassesLocked = PETSC_FALSE;
436: PetscInfoInvertClasses = PETSC_FALSE;
437: PetscInfoClassesSet = PETSC_FALSE;
438: PetscInfoNumClasses = -1;
439: PetscInfoCommFilter = PETSC_INFO_COMM_ALL;
440: return 0;
441: }
443: static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value)
444: {
445: if (!classid) classid = PETSC_SMALLEST_CLASSID;
446: PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value;
447: return 0;
448: }
450: /*@
451: PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class.
453: Not Collective
455: Input Parameter:
456: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
458: Note:
459: One can pass 0 to deactivate all messages that are not associated with an object.
461: Level: developer
463: .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
464: @*/
465: PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid)
466: {
467: PetscInfoSetClassActivation_Private(classid, 0);
468: return 0;
469: }
471: /*@
472: PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class.
474: Not Collective
476: Input Parameter:
477: . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc.
479: Note:
480: One can pass 0 to activate all messages that are not associated with an object.
482: Level: developer
484: .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
485: @*/
486: PetscErrorCode PetscInfoActivateClass(PetscClassId classid)
487: {
488: PetscInfoSetClassActivation_Private(classid, 1);
489: return 0;
490: }
492: /*
493: If the option -history was used, then all printed PetscInfo()
494: messages are also printed to the history file, called by default
495: .petschistory in ones home directory.
496: */
497: PETSC_INTERN FILE *petsc_history;
499: /*MC
500: PetscInfo - Logs informative data
502: Synopsis:
503: #include <petscsys.h>
504: PetscErrorCode PetscInfo(PetscObject obj, const char message[])
505: PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1)
506: PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2)
507: ...
509: Collective on obj
511: Input Parameters:
512: + obj - object most closely associated with the logging statement or NULL
513: . message - logging message
514: . formatmessage - logging message using standard "printf" format
515: - arg1, arg2, ... - arguments of the format
517: Notes:
518: `PetscInfo()` prints only from the first processor in the communicator of obj.
519: If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message.
521: Extent of the printed messages can be controlled using the option database key -info as follows.
523: $ -info [filename][:[~]<list,of,classnames>[:[~]self]]
525: No filename means standard output `PETSC_STDOUT` is used.
527: The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp.
528: If this list is not specified, all classes are enabled.
529: Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled.
530: A special classname sys relates to PetscInfo() with obj being NULL.
532: 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.
533: 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.
535: All classname/self matching is case insensitive. Filename is case sensitive.
537: Example of Usage:
538: $ Mat A;
539: $ PetscInt alpha;
540: $ ...
541: $ PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha);
543: Options Examples:
544: Each call of the form
545: $ PetscInfo(obj, msg);
546: $ PetscInfo(obj, msg, arg1);
547: $ PetscInfo(obj, msg, arg1, arg2);
548: is evaluated as follows.
549: $ -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator
550: $ -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1
551: $ -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
552: $ -info :sys prints to PETSC_STDOUT only if obj is NULL
553: Note that
554: $ -info :sys:~self
555: deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF.
557: Fortran Note:
558: This function does not take the obj argument, there is only the `PetscInfo()`
559: version, not `PetscInfo()` etc.
561: Level: intermediate
563: .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()`
564: M*/
565: PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...)
566: {
567: PetscClassId classid = PETSC_SMALLEST_CLASSID;
568: PetscBool enabled = PETSC_FALSE;
569: MPI_Comm comm = PETSC_COMM_SELF;
570: PetscMPIInt rank;
572: if (obj) {
574: classid = obj->classid;
575: }
577: PetscInfoEnabled(classid, &enabled);
578: if (!enabled) return 0;
579: if (obj) PetscObjectGetComm(obj, &comm);
580: MPI_Comm_rank(comm, &rank);
581: /* rank > 0 always jumps out */
582: if (rank) return 0;
583: else {
584: PetscMPIInt size;
586: MPI_Comm_size(comm, &size);
587: /* If no self printing is allowed, and size too small, get out */
588: if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) return 0;
589: /* If ONLY self printing, and size too big, get out */
590: if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) return 0;
591: }
592: /* Mute info messages within this function */
593: {
594: const PetscBool oldflag = PetscLogPrintInfo;
595: va_list Argp;
596: PetscMPIInt urank;
597: int err;
598: char string[8 * 1024];
599: size_t fullLength, len;
601: PetscLogPrintInfo = PETSC_FALSE;
602: MPI_Comm_rank(MPI_COMM_WORLD, &urank);
603: va_start(Argp, message);
604: PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func);
605: PetscStrlen(string, &len);
606: PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp);
607: PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string);
608: err = fflush(PetscInfoFile);
610: if (petsc_history) {
611: va_start(Argp, message);
612: (*PetscVFPrintf)(petsc_history, message, Argp);
613: }
614: va_end(Argp);
615: PetscLogPrintInfo = oldflag;
616: }
617: return 0;
618: }