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 OBJECT_CLASSID 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: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()` 50 @*/ 51 PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled) 52 { 53 PetscFunctionBegin; 54 PetscValidBoolPointer(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: `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 86 - mode - Write mode passed to `PetscFOpen()` 87 88 Level: advanced 89 90 Note: 91 Use `filename = NULL` to set `PetscInfo()` to write to `PETSC_STDOUT`. 92 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]; 103 104 PetscValidCharPointer(filename, 1); 105 PetscValidCharPointer(mode, 2); 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; 113 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 } 126 127 /*@C 128 PetscInfoGetFile - Gets the `filename` and `FILE` pointer of the file where `PetscInfo()` prints to 129 130 Not Collective; No Fortran Support 131 132 Output Parameters: 133 + filename - The name of the output file 134 - InfoFile - The `FILE` pointer for the output file 135 136 Level: advanced 137 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. 141 142 .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()` 143 @*/ 144 PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile) 145 { 146 PetscFunctionBegin; 147 PetscValidPointer(filename, 1); 148 PetscValidPointer(InfoFile, 2); 149 PetscCall(PetscStrallocpy(PetscInfoFilename, filename)); 150 *InfoFile = PetscInfoFile; 151 PetscFunctionReturn(PETSC_SUCCESS); 152 } 153 154 /*@C 155 PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against 156 157 Not Collective; No Fortran Support 158 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" 164 165 Level: developer 166 167 Notes: 168 This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called, unless the user calls `PetscInfoDestroy()` first. 169 170 Names in the `classnames` list should correspond to the names returned by `PetscObjectGetClassName()`. 171 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()`). 176 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, "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"); 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(PETSC_SUCCESS); 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 Level: developer 209 210 Note: 211 Use `PetscObjectGetName()` to retrieve an appropriate classname 212 213 .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()` 214 @*/ 215 PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found) 216 { 217 PetscInt unused; 218 219 PetscFunctionBegin; 220 PetscValidCharPointer(classname, 1); 221 PetscValidBoolPointer(found, 2); 222 PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found)); 223 PetscInfoClassesLocked = PETSC_TRUE; 224 PetscFunctionReturn(PETSC_SUCCESS); 225 } 226 227 /*@ 228 PetscInfoGetInfo - Returns the current state of several important flags for `PetscInfo()` 229 230 Not Collective 231 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 239 240 Level: developer 241 242 Note: 243 Initially commSelfFlag = `PETSC_INFO_COMM_ALL` 244 245 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()` 246 @*/ 247 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag) 248 { 249 PetscFunctionBegin; 250 if (infoEnabled) PetscValidBoolPointer(infoEnabled, 1); 251 if (classesSet) PetscValidBoolPointer(classesSet, 2); 252 if (exclude) PetscValidBoolPointer(exclude, 3); 253 if (locked) PetscValidBoolPointer(locked, 4); 254 if (commSelfFlag) PetscValidPointer(commSelfFlag, 5); 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 } 262 263 /*@C 264 PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()` 265 266 Not Collective 267 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` 272 273 Options Database Key: 274 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, see `PetscInfo()`. 275 276 Level: developer 277 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]; 284 285 PetscFunctionBegin; 286 PetscValidCharPointer(classname, 1); 287 PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID); 288 if (numClassID) PetscValidPointer(classIDs, 3); 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; 294 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; 302 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 } 317 318 /*@ 319 PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()` 320 321 Not Collective 322 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()` 325 326 Options Database Key: 327 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 328 329 Level: advanced 330 331 .seealso: `PetscInfo()`, `PetscInfoGetInfo()` 332 @*/ 333 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag) 334 { 335 PetscFunctionBegin; 336 PetscInfoCommFilter = commSelfFlag; 337 PetscFunctionReturn(PETSC_SUCCESS); 338 } 339 340 /*@ 341 PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()` 342 343 Not Collective 344 345 Input Parameter: 346 . options - Options database, use `NULL` for default global database 347 348 Options Database Key: 349 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 350 351 Level: advanced 352 353 Note: 354 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 355 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; 362 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; 372 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; 401 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 } 414 415 /*@ 416 PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures. 417 418 Not Collective 419 420 Level: developer 421 422 Notes: 423 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 424 `PetscInfo()` calls down the line. 425 426 Users calling this routine midway through a program should note that `PetscInfoDestroy()` 427 constitutes a full reset of `PetscInfo()`. It flushes, then closes, the current info file, 428 re-enables all classes, and resets all internal state. Finally -- and perhaps crucially -- it 429 disables `PetscInfo()` as-if-by `PetscInfoAllow(PETSC_FALSE)`. 430 431 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 432 @*/ 433 PetscErrorCode PetscInfoDestroy(void) 434 { 435 PetscFunctionBegin; 436 PetscCall(PetscInfoAllow(PETSC_FALSE)); 437 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 438 if (PetscInfoFile) PetscCall(PetscFFlush(PetscInfoFile)); 439 if (PetscInfoFilename) { 440 PetscAssert(PetscInfoFile, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Have non-null PetscInfo file '%s', but corresponding FILE handle is null!", PetscInfoFilename); 441 PetscCall(PetscFree(PetscInfoFilename)); 442 PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 443 } 444 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"); 445 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 446 PetscInfoFlags[i] = 1; 447 PetscCall(PetscFree(PetscInfoNames[i])); 448 } 449 450 PetscInfoFile = NULL; 451 PetscInfoClassesLocked = PETSC_FALSE; 452 PetscInfoInvertClasses = PETSC_FALSE; 453 PetscInfoClassesSet = PETSC_FALSE; 454 PetscInfoNumClasses = -1; 455 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 456 PetscFunctionReturn(PETSC_SUCCESS); 457 } 458 459 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 460 { 461 PetscFunctionBegin; 462 if (!classid) classid = PETSC_SMALLEST_CLASSID; 463 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 464 PetscFunctionReturn(PETSC_SUCCESS); 465 } 466 467 /*@ 468 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 469 470 Not Collective 471 472 Input Parameter: 473 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 474 475 Options Database Key: 476 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 477 478 Level: developer 479 480 Note: 481 One can pass 0 to deactivate all messages that are not associated with an object. 482 483 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 484 @*/ 485 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 486 { 487 PetscFunctionBegin; 488 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 489 PetscFunctionReturn(PETSC_SUCCESS); 490 } 491 492 /*@ 493 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 494 495 Not Collective 496 497 Input Parameter: 498 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 499 500 Options Database Key: 501 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 502 503 Level: developer 504 505 Note: 506 One can pass 0 to activate all messages that are not associated with an object. 507 508 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 509 @*/ 510 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 511 { 512 PetscFunctionBegin; 513 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 514 PetscFunctionReturn(PETSC_SUCCESS); 515 } 516 517 /* 518 If the option -history was used, then all printed PetscInfo() 519 messages are also printed to the history file, called by default 520 .petschistory in ones home directory. 521 */ 522 PETSC_INTERN FILE *petsc_history; 523 524 /*MC 525 PetscInfo - Logs informative data 526 527 Synopsis: 528 #include <petscsys.h> 529 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 530 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 531 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 532 ... 533 534 Collective 535 536 Input Parameters: 537 + obj - object most closely associated with the logging statement or `NULL` 538 . message - logging message 539 . formatmessage - logging message using standard "printf" format 540 - arg1, arg2, ... - arguments of the format 541 542 Options Database Key: 543 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 544 545 Level: intermediate 546 547 Notes: 548 `PetscInfo()` prints only from the first processor in the communicator of obj. 549 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 550 551 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 552 If this list is not specified, all classes are enabled. 553 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 554 A special classname `sys` relates to `PetscInfo()` with obj being `NULL`. 555 556 The optional keyword `self` specifies that `PetscInfo()` is enabled only for a communicator size of 1 (e.g. `PETSC_COMM_SELF`). 557 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. 558 559 All classname/self matching is case insensitive. Filename is case sensitive. 560 561 Example of Usage: 562 .vb 563 Mat A; 564 PetscInt alpha; 565 ... 566 PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 567 .ve 568 569 Options Examples: 570 Each call of the form 571 .vb 572 PetscInfo(obj, msg); 573 PetscInfo(obj, msg, arg1); 574 PetscInfo(obj, msg, arg1, arg2); 575 .ve 576 is evaluated as follows. 577 .vb 578 -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 579 -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 580 -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 581 -info :sys prints to PETSC_STDOUT only if obj is NULL 582 -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. 583 .ve 584 Fortran Note: 585 This function does not take the `obj` argument, there is only the `PetscInfo()` 586 version, not `PetscInfo()` etc. 587 588 .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 589 M*/ 590 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) 591 { 592 PetscClassId classid = PETSC_SMALLEST_CLASSID; 593 PetscBool enabled = PETSC_FALSE; 594 MPI_Comm comm = PETSC_COMM_SELF; 595 PetscMPIInt rank; 596 597 PetscFunctionBegin; 598 if (obj) { 599 PetscValidHeader(obj, 2); 600 classid = obj->classid; 601 } 602 PetscValidCharPointer(message, 3); 603 PetscCall(PetscInfoEnabled(classid, &enabled)); 604 if (!enabled) PetscFunctionReturn(PETSC_SUCCESS); 605 if (obj) PetscCall(PetscObjectGetComm(obj, &comm)); 606 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 607 /* rank > 0 always jumps out */ 608 if (rank) PetscFunctionReturn(PETSC_SUCCESS); 609 else { 610 PetscMPIInt size; 611 612 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 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func)); 629 PetscCall(PetscStrlen(string, &len)); 630 va_start(Argp, message); 631 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 632 va_end(Argp); 633 PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string)); 634 PetscCall(PetscFFlush(PetscInfoFile)); 635 if (petsc_history) { 636 va_start(Argp, message); 637 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 638 va_end(Argp); 639 } 640 PetscLogPrintInfo = oldflag; 641 } 642 PetscFunctionReturn(PETSC_SUCCESS); 643 } 644