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 Parameters: 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 name 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 Level: developer 274 275 .seealso: `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 PetscValidCharPointer(classname, 1); 284 PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID); 285 if (numClassID) PetscValidPointer(classIDs, 3); 286 PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL)); 287 /* -info_exclude is DEPRECATED */ 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 Level: advanced 324 325 .seealso: `PetscInfo()`, `PetscInfoGetInfo()` 326 @*/ 327 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag) 328 { 329 PetscFunctionBegin; 330 PetscInfoCommFilter = commSelfFlag; 331 PetscFunctionReturn(PETSC_SUCCESS); 332 } 333 334 /*@ 335 PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()` 336 337 Not Collective 338 339 Input Parameter: 340 . options - Options database, use `NULL` for default global database 341 342 Options Database Key: 343 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo(). 344 345 Level: advanced 346 347 Note: 348 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 349 350 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()` 351 @*/ 352 PetscErrorCode PetscInfoSetFromOptions(PetscOptions options) 353 { 354 char optstring[PETSC_MAX_PATH_LEN]; 355 PetscBool set; 356 357 PetscFunctionBegin; 358 PetscCall(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use -info instead")); 359 PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set)); 360 if (set) { 361 size_t size_loc0_, size_loc1_, size_loc2_; 362 char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL; 363 char **loc1_array = NULL; 364 PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE; 365 int nLoc1_ = 0; 366 PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL; 367 368 PetscInfoClassesSet = PETSC_TRUE; 369 PetscCall(PetscInfoAllow(PETSC_TRUE)); 370 PetscCall(PetscStrallocpy(optstring, &loc0_)); 371 PetscCall(PetscStrchr(loc0_, ':', &loc1_)); 372 if (loc1_) { 373 *loc1_++ = 0; 374 if (*loc1_ == '~') { 375 loc1_invert = PETSC_TRUE; 376 ++loc1_; 377 } 378 PetscCall(PetscStrchr(loc1_, ':', &loc2_)); 379 } 380 if (loc2_) { 381 *loc2_++ = 0; 382 if (*loc2_ == '~') { 383 loc2_invert = PETSC_TRUE; 384 ++loc2_; 385 } 386 } 387 PetscCall(PetscStrlen(loc0_, &size_loc0_)); 388 PetscCall(PetscStrlen(loc1_, &size_loc1_)); 389 PetscCall(PetscStrlen(loc2_, &size_loc2_)); 390 if (size_loc1_) { 391 PetscCall(PetscStrtolower(loc1_)); 392 PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array)); 393 } 394 if (size_loc2_) { 395 PetscBool foundSelf; 396 397 PetscCall(PetscStrtolower(loc2_)); 398 PetscCall(PetscStrcmp("self", loc2_, &foundSelf)); 399 if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF; 400 } 401 PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w")); 402 PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array)); 403 PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag)); 404 PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array)); 405 PetscCall(PetscFree(loc0_)); 406 } 407 PetscFunctionReturn(PETSC_SUCCESS); 408 } 409 410 /*@ 411 PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures. 412 413 Not Collective 414 415 Level: developer 416 417 Note: 418 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 419 `PetscInfo()` calls down the line. 420 421 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 422 @*/ 423 PetscErrorCode PetscInfoDestroy(void) 424 { 425 int err; 426 427 PetscFunctionBegin; 428 PetscCall(PetscInfoAllow(PETSC_FALSE)); 429 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 430 err = fflush(PetscInfoFile); 431 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 432 if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 433 PetscCall(PetscFree(PetscInfoFilename)); 434 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"); 435 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 436 PetscInfoFlags[i] = 1; 437 PetscCall(PetscFree(PetscInfoNames[i])); 438 } 439 440 PetscInfoClassesLocked = PETSC_FALSE; 441 PetscInfoInvertClasses = PETSC_FALSE; 442 PetscInfoClassesSet = PETSC_FALSE; 443 PetscInfoNumClasses = -1; 444 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 445 PetscFunctionReturn(PETSC_SUCCESS); 446 } 447 448 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 449 { 450 PetscFunctionBegin; 451 if (!classid) classid = PETSC_SMALLEST_CLASSID; 452 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 453 PetscFunctionReturn(PETSC_SUCCESS); 454 } 455 456 /*@ 457 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 458 459 Not Collective 460 461 Input Parameter: 462 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 463 464 Level: developer 465 466 Note: 467 One can pass 0 to deactivate all messages that are not associated with an object. 468 469 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 470 @*/ 471 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 472 { 473 PetscFunctionBegin; 474 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 475 PetscFunctionReturn(PETSC_SUCCESS); 476 } 477 478 /*@ 479 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 480 481 Not Collective 482 483 Input Parameter: 484 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 485 486 Level: developer 487 488 Note: 489 One can pass 0 to activate all messages that are not associated with an object. 490 491 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 492 @*/ 493 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 494 { 495 PetscFunctionBegin; 496 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 497 PetscFunctionReturn(PETSC_SUCCESS); 498 } 499 500 /* 501 If the option -history was used, then all printed PetscInfo() 502 messages are also printed to the history file, called by default 503 .petschistory in ones home directory. 504 */ 505 PETSC_INTERN FILE *petsc_history; 506 507 /*MC 508 PetscInfo - Logs informative data 509 510 Synopsis: 511 #include <petscsys.h> 512 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 513 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 514 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 515 ... 516 517 Collective 518 519 Input Parameters: 520 + obj - object most closely associated with the logging statement or `NULL` 521 . message - logging message 522 . formatmessage - logging message using standard "printf" format 523 - arg1, arg2, ... - arguments of the format 524 525 Level: intermediate 526 527 Notes: 528 `PetscInfo()` prints only from the first processor in the communicator of obj. 529 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 530 531 Extent of the printed messages can be controlled using the option database key -info as follows. 532 533 $ -info [filename][:[~]<list,of,classnames>[:[~]self]] 534 535 No filename means standard output `PETSC_STDOUT` is used. 536 537 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 538 If this list is not specified, all classes are enabled. 539 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 540 A special classname sys relates to PetscInfo() with obj being NULL. 541 542 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. 543 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. 544 545 All classname/self matching is case insensitive. Filename is case sensitive. 546 547 Example of Usage: 548 .vb 549 Mat A; 550 PetscInt alpha; 551 ... 552 PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 553 .ve 554 555 Options Examples: 556 Each call of the form 557 .vb 558 PetscInfo(obj, msg); 559 PetscInfo(obj, msg, arg1); 560 PetscInfo(obj, msg, arg1, arg2); 561 .ve 562 is evaluated as follows. 563 .vb 564 -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 565 -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 566 -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 567 -info :sys prints to PETSC_STDOUT only if obj is NULL 568 -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. 569 .ve 570 Fortran Note: 571 This function does not take the obj argument, there is only the `PetscInfo()` 572 version, not `PetscInfo()` etc. 573 574 .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 575 M*/ 576 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) 577 { 578 PetscClassId classid = PETSC_SMALLEST_CLASSID; 579 PetscBool enabled = PETSC_FALSE; 580 MPI_Comm comm = PETSC_COMM_SELF; 581 PetscMPIInt rank; 582 583 PetscFunctionBegin; 584 if (obj) { 585 PetscValidHeader(obj, 2); 586 classid = obj->classid; 587 } 588 PetscValidCharPointer(message, 3); 589 PetscCall(PetscInfoEnabled(classid, &enabled)); 590 if (!enabled) PetscFunctionReturn(PETSC_SUCCESS); 591 if (obj) PetscCall(PetscObjectGetComm(obj, &comm)); 592 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 593 /* rank > 0 always jumps out */ 594 if (rank) PetscFunctionReturn(PETSC_SUCCESS); 595 else { 596 PetscMPIInt size; 597 598 PetscCallMPI(MPI_Comm_size(comm, &size)); 599 /* If no self printing is allowed, and size too small, get out */ 600 if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(PETSC_SUCCESS); 601 /* If ONLY self printing, and size too big, get out */ 602 if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(PETSC_SUCCESS); 603 } 604 /* Mute info messages within this function */ 605 { 606 const PetscBool oldflag = PetscLogPrintInfo; 607 va_list Argp; 608 PetscMPIInt urank; 609 int err; 610 char string[8 * 1024]; 611 size_t fullLength, len; 612 613 PetscLogPrintInfo = PETSC_FALSE; 614 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank)); 615 va_start(Argp, message); 616 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func)); 617 PetscCall(PetscStrlen(string, &len)); 618 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 619 PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string)); 620 err = fflush(PetscInfoFile); 621 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 622 if (petsc_history) { 623 va_start(Argp, message); 624 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 625 } 626 va_end(Argp); 627 PetscLogPrintInfo = oldflag; 628 } 629 PetscFunctionReturn(PETSC_SUCCESS); 630 } 631