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> /*I "petscsys.h" I*/ 6 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. 10 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. 15 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 PetscBool PetscLogPrintInfo = PETSC_FALSE; 29 FILE *PetscInfoFile = NULL; 30 31 /*@ 32 PetscInfoEnabled - Checks whether a given OBJECT_CLASSID is allowed to print using `PetscInfo()` 33 34 Not Collective 35 36 Input Parameters: 37 . classid - `PetscClassid` retrieved from a `PetscObject` e.g. `VEC_CLASSID` 38 39 Output Parameter: 40 . enabled - `PetscBool` indicating whether this classid is allowed to print 41 42 Note: 43 Use `PETSC_SMALLEST_CLASSID` to check if "sys" `PetscInfo()` calls are enabled. When PETSc is configured with debugging 44 support this function checks if classid >= `PETSC_SMALLEST_CLASSID`, otherwise it assumes valid classid. 45 46 Level: advanced 47 48 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()` 49 @*/ 50 PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled) { 51 PetscFunctionBegin; 52 PetscValidBoolPointer(enabled, 2); 53 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); 54 *enabled = (PetscBool)(PetscLogPrintInfo && PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID]); 55 PetscFunctionReturn(0); 56 } 57 58 /*@ 59 PetscInfoAllow - Enables/disables `PetscInfo()` messages 60 61 Not Collective 62 63 Input Parameter: 64 . flag - `PETSC_TRUE` or `PETSC_FALSE` 65 66 Level: advanced 67 68 .seealso: `PetscInfo()`, `PetscInfoEnabled()`, `PetscInfoGetInfo()`, `PetscInfoSetFromOptions()` 69 @*/ 70 PetscErrorCode PetscInfoAllow(PetscBool flag) { 71 PetscFunctionBegin; 72 PetscLogPrintInfo = flag; 73 PetscFunctionReturn(0); 74 } 75 76 /*@C 77 PetscInfoSetFile - Sets the printing destination for all `PetscInfo()` calls 78 79 Not Collective 80 81 Input Parameters: 82 + filename - Name of the file where `PetscInfo()` will print to 83 - mode - Write mode passed to PetscFOpen()` 84 85 Note: 86 Use filename = NULL to set `PetscInfo()` to write to `PETSC_STDOUT`. 87 88 Level: advanced 89 90 .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscFOpen()` 91 @*/ 92 PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[]) { 93 PetscFunctionBegin; 94 if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT; 95 PetscCall(PetscFree(PetscInfoFilename)); 96 if (filename) { 97 PetscMPIInt rank; 98 char fname[PETSC_MAX_PATH_LEN], tname[11]; 99 100 PetscValidCharPointer(filename, 1); 101 PetscValidCharPointer(mode, 2); 102 PetscCall(PetscFixFilename(filename, fname)); 103 PetscCall(PetscStrallocpy(fname, &PetscInfoFilename)); 104 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 105 PetscCall(PetscSNPrintf(tname, PETSC_STATIC_ARRAY_LENGTH(tname), ".%d", rank)); 106 PetscCall(PetscStrlcat(fname, tname, PETSC_STATIC_ARRAY_LENGTH(fname))); 107 { 108 const PetscBool oldflag = PetscLogPrintInfo; 109 110 PetscLogPrintInfo = PETSC_FALSE; 111 PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, mode, &PetscInfoFile)); 112 PetscLogPrintInfo = oldflag; 113 /* 114 PetscFOpen will write to PETSC_STDOUT and not PetscInfoFile here, so we disable the 115 PetscInfo call inside it, and call it afterwards so that it actually writes to file 116 */ 117 } 118 PetscCall(PetscInfo(NULL, "Opened PetscInfo file %s\n", fname)); 119 } 120 PetscFunctionReturn(0); 121 } 122 123 /*@C 124 PetscInfoGetFile - Gets the name and FILE pointer of the file where `PetscInfo()` prints to 125 126 Not Collective 127 128 Output Parameters: 129 + filename - The name of the output file 130 - InfoFile - The FILE pointer for the output file 131 132 Level: advanced 133 134 Note: 135 This routine allocates and copies the filename so that the filename survives `PetscInfoDestroy()`. The user is 136 therefore responsible for freeing the allocated filename pointer afterwards. 137 138 Fortran Note: 139 This routine is not supported in Fortran. 140 141 .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()` 142 @*/ 143 PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile) { 144 PetscFunctionBegin; 145 PetscValidPointer(filename, 1); 146 PetscValidPointer(InfoFile, 2); 147 PetscCall(PetscStrallocpy(PetscInfoFilename, filename)); 148 *InfoFile = PetscInfoFile; 149 PetscFunctionReturn(0); 150 } 151 152 /*@C 153 PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against 154 155 Not Collective 156 157 Input Parameters: 158 + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that 159 is NOT one of the classes specified 160 . n - Number of classes to filter for (size of classnames) 161 - classnames - String array containing the names of classes to filter for, e.g. "vec" 162 163 Notes: 164 This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called. 165 166 Names in the classnames list should correspond to the names returned by `PetscObjectGetClassName()`. 167 168 This function only sets the list of class names. 169 The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away. 170 The reason for this is that we need to set the list of included/excluded classes before their classids are known. 171 Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`). 172 173 Fortran Note: 174 Not for use in Fortran 175 176 Level: developer 177 178 .seealso: `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()` 179 @*/ 180 PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames) { 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; 190 191 PetscCall(PetscInfoProcessClass("sys", 1, &id)); 192 } 193 PetscInfoClassesSet = PETSC_TRUE; 194 PetscFunctionReturn(0); 195 } 196 197 /*@C 198 PetscInfoGetClass - Indicates whether the provided classname is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()` 199 200 Not Collective 201 202 Input Parameter: 203 . classname - Name of the class to search for 204 205 Output Parameter: 206 . found - `PetscBool` indicating whether the classname was found 207 208 Note: 209 Use `PetscObjectGetName()` to retrieve an appropriate classname 210 211 Level: developer 212 213 .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()` 214 @*/ 215 PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found) { 216 PetscInt unused; 217 218 PetscFunctionBegin; 219 PetscValidCharPointer(classname, 1); 220 PetscValidBoolPointer(found, 2); 221 PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found)); 222 PetscInfoClassesLocked = PETSC_TRUE; 223 PetscFunctionReturn(0); 224 } 225 226 /*@ 227 PetscInfoGetInfo - Returns the current state of several important flags for `PetscInfo()` 228 229 Not Collective 230 231 Output Parameters: 232 + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called 233 . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set 234 . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted 235 . locked - `PETSC_TRUE` if the list of classes to filter for has been locked 236 - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all 237 communicators 238 239 Note: 240 Initially commSelfFlag = `PETSC_INFO_COMM_ALL` 241 242 Level: developer 243 244 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()` 245 @*/ 246 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag) { 247 PetscFunctionBegin; 248 if (infoEnabled) PetscValidBoolPointer(infoEnabled, 1); 249 if (classesSet) PetscValidBoolPointer(classesSet, 2); 250 if (exclude) PetscValidBoolPointer(exclude, 3); 251 if (locked) PetscValidBoolPointer(locked, 4); 252 if (commSelfFlag) PetscValidPointer(commSelfFlag, 5); 253 if (infoEnabled) *infoEnabled = PetscLogPrintInfo; 254 if (classesSet) *classesSet = PetscInfoClassesSet; 255 if (exclude) *exclude = PetscInfoInvertClasses; 256 if (locked) *locked = PetscInfoClassesLocked; 257 if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter; 258 PetscFunctionReturn(0); 259 } 260 261 /*@C 262 PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()` 263 264 Not Collective 265 266 Input Parameters: 267 + classname - Name of the class to activate/deactivate `PetscInfo()` for 268 . numClassID - Number of entries in classIDs 269 - classIDs - Array containing all of the PetscClassids associated with classname 270 271 Level: developer 272 273 .seealso: `PetscInfo()`, `PetscInfoActivateClass()`, `PetscInfoDeactivateClass()`, `PetscInfoSetFromOptions()` 274 @*/ 275 PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, const PetscClassId classIDs[]) { 276 PetscBool enabled, exclude, found, opt; 277 char logList[256]; 278 279 PetscFunctionBegin; 280 PetscValidCharPointer(classname, 1); 281 PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID); 282 if (numClassID) PetscValidPointer(classIDs, 3); 283 PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL)); 284 /* -info_exclude is DEPRECATED */ 285 PetscCall(PetscOptionsGetString(NULL, NULL, "-info_exclude", logList, sizeof(logList), &opt)); 286 if (opt) { 287 PetscBool pkg; 288 289 PetscCall(PetscStrInList(classname, logList, ',', &pkg)); 290 if (pkg) { 291 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i])); 292 } 293 } 294 PetscCall(PetscInfoGetClass(classname, &found)); 295 if ((found && exclude) || (!found && !exclude)) { 296 if (PetscInfoNumClasses > 0) { 297 /* Check if -info was called empty */ 298 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i])); 299 } 300 } else { 301 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoActivateClass(classIDs[i])); 302 } 303 PetscFunctionReturn(0); 304 } 305 306 /*@ 307 PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()` 308 309 Not Collective 310 311 Input Parameter: 312 . commSelfFlag - Enum value indicating method with which to filter `PetscInfo()` based on the size of the communicator of the object calling `PetscInfo()` 313 314 Level: advanced 315 316 .seealso: `PetscInfo()`, `PetscInfoGetInfo()` 317 @*/ 318 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag) { 319 PetscFunctionBegin; 320 PetscInfoCommFilter = commSelfFlag; 321 PetscFunctionReturn(0); 322 } 323 324 /*@ 325 PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()` 326 327 Not Collective 328 329 Input Parameter: 330 . options - Options database, use NULL for default global database 331 332 Options Database Keys: 333 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo(). 334 335 Note: 336 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 337 338 Level: advanced 339 340 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()` 341 @*/ 342 PetscErrorCode PetscInfoSetFromOptions(PetscOptions options) { 343 char optstring[PETSC_MAX_PATH_LEN]; 344 PetscBool set; 345 346 PetscFunctionBegin; 347 PetscCall(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use -info instead")); 348 PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set)); 349 if (set) { 350 size_t size_loc0_, size_loc1_, size_loc2_; 351 char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL; 352 char **loc1_array = NULL; 353 PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE; 354 int nLoc1_ = 0; 355 PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL; 356 357 PetscInfoClassesSet = PETSC_TRUE; 358 PetscCall(PetscInfoAllow(PETSC_TRUE)); 359 PetscCall(PetscStrallocpy(optstring, &loc0_)); 360 PetscCall(PetscStrchr(loc0_, ':', &loc1_)); 361 if (loc1_) { 362 *loc1_++ = 0; 363 if (*loc1_ == '~') { 364 loc1_invert = PETSC_TRUE; 365 ++loc1_; 366 } 367 PetscCall(PetscStrchr(loc1_, ':', &loc2_)); 368 } 369 if (loc2_) { 370 *loc2_++ = 0; 371 if (*loc2_ == '~') { 372 loc2_invert = PETSC_TRUE; 373 ++loc2_; 374 } 375 } 376 PetscCall(PetscStrlen(loc0_, &size_loc0_)); 377 PetscCall(PetscStrlen(loc1_, &size_loc1_)); 378 PetscCall(PetscStrlen(loc2_, &size_loc2_)); 379 if (size_loc1_) { 380 PetscCall(PetscStrtolower(loc1_)); 381 PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array)); 382 } 383 if (size_loc2_) { 384 PetscBool foundSelf; 385 386 PetscCall(PetscStrtolower(loc2_)); 387 PetscCall(PetscStrcmp("self", loc2_, &foundSelf)); 388 if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF; 389 } 390 PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w")); 391 PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array)); 392 PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag)); 393 PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array)); 394 PetscCall(PetscFree(loc0_)); 395 } 396 PetscFunctionReturn(0); 397 } 398 399 /*@ 400 PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures. 401 402 Not Collective 403 404 Note: 405 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 406 `PetscInfo()` calls down the line. 407 408 Level: developer 409 410 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 411 @*/ 412 PetscErrorCode PetscInfoDestroy(void) { 413 int err; 414 415 PetscFunctionBegin; 416 PetscCall(PetscInfoAllow(PETSC_FALSE)); 417 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 418 err = fflush(PetscInfoFile); 419 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 420 if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 421 PetscCall(PetscFree(PetscInfoFilename)); 422 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) PetscInfoFlags[i] = 1; 423 PetscInfoClassesLocked = PETSC_FALSE; 424 PetscInfoInvertClasses = PETSC_FALSE; 425 PetscInfoClassesSet = PETSC_FALSE; 426 PetscInfoNumClasses = -1; 427 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 428 PetscFunctionReturn(0); 429 } 430 431 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) { 432 PetscFunctionBegin; 433 if (!classid) classid = PETSC_SMALLEST_CLASSID; 434 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 435 PetscFunctionReturn(0); 436 } 437 438 /*@ 439 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 440 441 Not Collective 442 443 Input Parameter: 444 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 445 446 Note: 447 One can pass 0 to deactivate all messages that are not associated with an object. 448 449 Level: developer 450 451 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 452 @*/ 453 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) { 454 PetscFunctionBegin; 455 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 456 PetscFunctionReturn(0); 457 } 458 459 /*@ 460 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 461 462 Not Collective 463 464 Input Parameter: 465 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 466 467 Note: 468 One can pass 0 to activate all messages that are not associated with an object. 469 470 Level: developer 471 472 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 473 @*/ 474 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) { 475 PetscFunctionBegin; 476 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 477 PetscFunctionReturn(0); 478 } 479 480 /* 481 If the option -history was used, then all printed PetscInfo() 482 messages are also printed to the history file, called by default 483 .petschistory in ones home directory. 484 */ 485 PETSC_INTERN FILE *petsc_history; 486 487 /*MC 488 PetscInfo - Logs informative data 489 490 Synopsis: 491 #include <petscsys.h> 492 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 493 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 494 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 495 ... 496 497 Collective on obj 498 499 Input Parameters: 500 + obj - object most closely associated with the logging statement or NULL 501 . message - logging message 502 . formatmessage - logging message using standard "printf" format 503 - arg1, arg2, ... - arguments of the format 504 505 Notes: 506 `PetscInfo()` prints only from the first processor in the communicator of obj. 507 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 508 509 Extent of the printed messages can be controlled using the option database key -info as follows. 510 511 $ -info [filename][:[~]<list,of,classnames>[:[~]self]] 512 513 No filename means standard output `PETSC_STDOUT` is used. 514 515 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 516 If this list is not specified, all classes are enabled. 517 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 518 A special classname sys relates to PetscInfo() with obj being NULL. 519 520 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. 521 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. 522 523 All classname/self matching is case insensitive. Filename is case sensitive. 524 525 Example of Usage: 526 $ Mat A; 527 $ PetscInt alpha; 528 $ ... 529 $ PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 530 531 Options Examples: 532 Each call of the form 533 $ PetscInfo(obj, msg); 534 $ PetscInfo(obj, msg, arg1); 535 $ PetscInfo(obj, msg, arg1, arg2); 536 is evaluated as follows. 537 $ -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 538 $ -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 539 $ -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 540 $ -info :sys prints to PETSC_STDOUT only if obj is NULL 541 Note that 542 $ -info :sys:~self 543 deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF. 544 545 Fortran Note: 546 This function does not take the obj argument, there is only the `PetscInfo()` 547 version, not `PetscInfo()` etc. 548 549 Level: intermediate 550 551 .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 552 M*/ 553 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) { 554 PetscClassId classid = PETSC_SMALLEST_CLASSID; 555 PetscBool enabled = PETSC_FALSE; 556 MPI_Comm comm = PETSC_COMM_SELF; 557 PetscMPIInt rank; 558 559 PetscFunctionBegin; 560 if (obj) { 561 PetscValidHeader(obj, 2); 562 classid = obj->classid; 563 } 564 PetscValidCharPointer(message, 3); 565 PetscCall(PetscInfoEnabled(classid, &enabled)); 566 if (!enabled) PetscFunctionReturn(0); 567 if (obj) PetscCall(PetscObjectGetComm(obj, &comm)); 568 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 569 /* rank > 0 always jumps out */ 570 if (rank) PetscFunctionReturn(0); 571 else { 572 PetscMPIInt size; 573 574 PetscCallMPI(MPI_Comm_size(comm, &size)); 575 /* If no self printing is allowed, and size too small, get out */ 576 if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(0); 577 /* If ONLY self printing, and size too big, get out */ 578 if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(0); 579 } 580 /* Mute info messages within this function */ 581 { 582 const PetscBool oldflag = PetscLogPrintInfo; 583 va_list Argp; 584 PetscMPIInt urank; 585 int err; 586 char string[8 * 1024]; 587 size_t fullLength, len; 588 589 PetscLogPrintInfo = PETSC_FALSE; 590 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank)); 591 va_start(Argp, message); 592 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] %s(): ", urank, func)); 593 PetscCall(PetscStrlen(string, &len)); 594 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 595 PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string)); 596 err = fflush(PetscInfoFile); 597 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 598 if (petsc_history) { 599 va_start(Argp, message); 600 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 601 } 602 va_end(Argp); 603 PetscLogPrintInfo = oldflag; 604 } 605 PetscFunctionReturn(0); 606 } 607