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