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