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: }