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. 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, "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(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 Note: 423 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 424 `PetscInfo()` calls down the line. 425 426 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 427 @*/ 428 PetscErrorCode PetscInfoDestroy(void) 429 { 430 PetscFunctionBegin; 431 PetscCall(PetscInfoAllow(PETSC_FALSE)); 432 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 433 PetscCall(PetscFFlush(PetscInfoFile)); 434 if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 435 PetscCall(PetscFree(PetscInfoFilename)); 436 PetscAssert(PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags) == PETSC_STATIC_ARRAY_LENGTH(PetscInfoNames), PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscInfoFlags and PetscInfoNames must be the same size"); 437 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 438 PetscInfoFlags[i] = 1; 439 PetscCall(PetscFree(PetscInfoNames[i])); 440 } 441 442 PetscInfoClassesLocked = PETSC_FALSE; 443 PetscInfoInvertClasses = PETSC_FALSE; 444 PetscInfoClassesSet = PETSC_FALSE; 445 PetscInfoNumClasses = -1; 446 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 447 PetscFunctionReturn(PETSC_SUCCESS); 448 } 449 450 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 451 { 452 PetscFunctionBegin; 453 if (!classid) classid = PETSC_SMALLEST_CLASSID; 454 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 455 PetscFunctionReturn(PETSC_SUCCESS); 456 } 457 458 /*@ 459 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 460 461 Not Collective 462 463 Input Parameter: 464 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 465 466 Options Database Key: 467 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 468 469 Level: developer 470 471 Note: 472 One can pass 0 to deactivate all messages that are not associated with an object. 473 474 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 475 @*/ 476 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 477 { 478 PetscFunctionBegin; 479 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 480 PetscFunctionReturn(PETSC_SUCCESS); 481 } 482 483 /*@ 484 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 485 486 Not Collective 487 488 Input Parameter: 489 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 490 491 Options Database Key: 492 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 493 494 Level: developer 495 496 Note: 497 One can pass 0 to activate all messages that are not associated with an object. 498 499 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 500 @*/ 501 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 502 { 503 PetscFunctionBegin; 504 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 505 PetscFunctionReturn(PETSC_SUCCESS); 506 } 507 508 /* 509 If the option -history was used, then all printed PetscInfo() 510 messages are also printed to the history file, called by default 511 .petschistory in ones home directory. 512 */ 513 PETSC_INTERN FILE *petsc_history; 514 515 /*MC 516 PetscInfo - Logs informative data 517 518 Synopsis: 519 #include <petscsys.h> 520 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 521 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 522 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 523 ... 524 525 Collective 526 527 Input Parameters: 528 + obj - object most closely associated with the logging statement or `NULL` 529 . message - logging message 530 . formatmessage - logging message using standard "printf" format 531 - arg1, arg2, ... - arguments of the format 532 533 Options Database Key: 534 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 535 536 Level: intermediate 537 538 Notes: 539 `PetscInfo()` prints only from the first processor in the communicator of obj. 540 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 541 542 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 543 If this list is not specified, all classes are enabled. 544 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 545 A special classname `sys` relates to `PetscInfo()` with obj being `NULL`. 546 547 The optional keyword `self` specifies that `PetscInfo()` is enabled only for a communicator size of 1 (e.g. `PETSC_COMM_SELF`). 548 By contrast, ~self means that `PetscInfo()` is enabled only for communicator size > 1 (e.g. `PETSC_COMM_WORLD`), i.e. those `PetscInfo()` calls which print from every rank of `PETSC_COMM_WORLD` are disabled. 549 550 All classname/self matching is case insensitive. Filename is case sensitive. 551 552 Example of Usage: 553 .vb 554 Mat A; 555 PetscInt alpha; 556 ... 557 PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 558 .ve 559 560 Options Examples: 561 Each call of the form 562 .vb 563 PetscInfo(obj, msg); 564 PetscInfo(obj, msg, arg1); 565 PetscInfo(obj, msg, arg1, arg2); 566 .ve 567 is evaluated as follows. 568 .vb 569 -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 570 -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 571 -info myInfoFileName:~vec:~self prints msg to file named myInfoFileName, only if the obj's class is NULL or other than Vec, and obj's communicator has size > 1 572 -info :sys prints to PETSC_STDOUT only if obj is NULL 573 -info :sys:~self deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF. 574 .ve 575 Fortran Note: 576 This function does not take the `obj` argument, there is only the `PetscInfo()` 577 version, not `PetscInfo()` etc. 578 579 .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 580 M*/ 581 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) 582 { 583 PetscClassId classid = PETSC_SMALLEST_CLASSID; 584 PetscBool enabled = PETSC_FALSE; 585 MPI_Comm comm = PETSC_COMM_SELF; 586 PetscMPIInt rank; 587 const char *otype = NULL; 588 589 PetscFunctionBegin; 590 if (obj) { 591 PetscValidHeader(obj, 2); 592 classid = obj->classid; 593 } 594 PetscValidCharPointer(message, 3); 595 PetscCall(PetscInfoEnabled(classid, &enabled)); 596 if (!enabled) PetscFunctionReturn(PETSC_SUCCESS); 597 if (obj) { 598 PetscCall(PetscObjectGetComm(obj, &comm)); 599 PetscCall(PetscObjectGetType(obj, &otype)); 600 } 601 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 602 /* rank > 0 always jumps out */ 603 if (rank) PetscFunctionReturn(PETSC_SUCCESS); 604 else { 605 PetscMPIInt size; 606 607 PetscCallMPI(MPI_Comm_size(comm, &size)); 608 /* If no self printing is allowed, and size too small, get out */ 609 if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(PETSC_SUCCESS); 610 /* If ONLY self printing, and size too big, get out */ 611 if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(PETSC_SUCCESS); 612 } 613 /* Mute info messages within this function */ 614 { 615 const PetscBool oldflag = PetscLogPrintInfo; 616 va_list Argp; 617 PetscMPIInt urank; 618 char string[8 * 1024]; 619 size_t fullLength, len; 620 621 PetscLogPrintInfo = PETSC_FALSE; 622 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank)); 623 if (otype) { 624 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s:%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], otype, func)); 625 } else { 626 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func)); 627 } 628 PetscCall(PetscStrlen(string, &len)); 629 va_start(Argp, message); 630 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 631 va_end(Argp); 632 PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string)); 633 PetscCall(PetscFFlush(PetscInfoFile)); 634 if (petsc_history) { 635 va_start(Argp, message); 636 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 637 va_end(Argp); 638 } 639 PetscLogPrintInfo = oldflag; 640 } 641 PetscFunctionReturn(PETSC_SUCCESS); 642 } 643