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 Note: 44 Use `PETSC_SMALLEST_CLASSID` to check if "sys" `PetscInfo()` calls are enabled. When PETSc is configured with debugging 45 support this function checks if classid >= `PETSC_SMALLEST_CLASSID`, otherwise it assumes valid classid. 46 47 Level: advanced 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 Note: 89 Use filename = NULL to set `PetscInfo()` to write to `PETSC_STDOUT`. 90 91 Level: advanced 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 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 Notes: 166 This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called. 167 168 Names in the classnames list should correspond to the names returned by `PetscObjectGetClassName()`. 169 170 This function only sets the list of class names. 171 The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away. 172 The reason for this is that we need to set the list of included/excluded classes before their classids are known. 173 Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`). 174 175 Fortran Note: 176 Not for use in Fortran 177 178 Level: developer 179 180 .seealso: `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()` 181 @*/ 182 PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames) 183 { 184 PetscFunctionBegin; 185 PetscCheck(!PetscInfoClassesLocked, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscInfoSetClasses() cannot be called after PetscInfoGetClass() or PetscInfoProcessClass()"); 186 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 187 PetscCall(PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames)); 188 PetscInfoNumClasses = n; 189 PetscInfoInvertClasses = exclude; 190 /* Process sys class right away */ 191 { 192 const PetscClassId id = PETSC_SMALLEST_CLASSID; 193 194 PetscCall(PetscInfoProcessClass("sys", 1, &id)); 195 } 196 PetscInfoClassesSet = PETSC_TRUE; 197 PetscFunctionReturn(PETSC_SUCCESS); 198 } 199 200 /*@C 201 PetscInfoGetClass - Indicates whether the provided classname is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()` 202 203 Not Collective 204 205 Input Parameter: 206 . classname - Name of the class to search for 207 208 Output Parameter: 209 . found - `PetscBool` indicating whether the classname was found 210 211 Note: 212 Use `PetscObjectGetName()` to retrieve an appropriate classname 213 214 Level: developer 215 216 .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()` 217 @*/ 218 PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found) 219 { 220 PetscInt unused; 221 222 PetscFunctionBegin; 223 PetscValidCharPointer(classname, 1); 224 PetscValidBoolPointer(found, 2); 225 PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found)); 226 PetscInfoClassesLocked = PETSC_TRUE; 227 PetscFunctionReturn(PETSC_SUCCESS); 228 } 229 230 /*@ 231 PetscInfoGetInfo - Returns the current state of several important flags for `PetscInfo()` 232 233 Not Collective 234 235 Output Parameters: 236 + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called 237 . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set 238 . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted 239 . locked - `PETSC_TRUE` if the list of classes to filter for has been locked 240 - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all 241 communicators 242 243 Note: 244 Initially commSelfFlag = `PETSC_INFO_COMM_ALL` 245 246 Level: developer 247 248 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()` 249 @*/ 250 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag) 251 { 252 PetscFunctionBegin; 253 if (infoEnabled) PetscValidBoolPointer(infoEnabled, 1); 254 if (classesSet) PetscValidBoolPointer(classesSet, 2); 255 if (exclude) PetscValidBoolPointer(exclude, 3); 256 if (locked) PetscValidBoolPointer(locked, 4); 257 if (commSelfFlag) PetscValidPointer(commSelfFlag, 5); 258 if (infoEnabled) *infoEnabled = PetscLogPrintInfo; 259 if (classesSet) *classesSet = PetscInfoClassesSet; 260 if (exclude) *exclude = PetscInfoInvertClasses; 261 if (locked) *locked = PetscInfoClassesLocked; 262 if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter; 263 PetscFunctionReturn(PETSC_SUCCESS); 264 } 265 266 /*@C 267 PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()` 268 269 Not Collective 270 271 Input Parameters: 272 + classname - Name of the class to activate/deactivate `PetscInfo()` for 273 . numClassID - Number of entries in classIDs 274 - classIDs - Array containing all of the PetscClassids associated with classname 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 /* -info_exclude is DEPRECATED */ 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 Level: advanced 327 328 .seealso: `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 Keys: 346 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo(). 347 348 Note: 349 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 350 351 Level: advanced 352 353 .seealso: `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(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use -info instead")); 362 PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set)); 363 if (set) { 364 size_t size_loc0_, size_loc1_, size_loc2_; 365 char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL; 366 char **loc1_array = NULL; 367 PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE; 368 int nLoc1_ = 0; 369 PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL; 370 371 PetscInfoClassesSet = PETSC_TRUE; 372 PetscCall(PetscInfoAllow(PETSC_TRUE)); 373 PetscCall(PetscStrallocpy(optstring, &loc0_)); 374 PetscCall(PetscStrchr(loc0_, ':', &loc1_)); 375 if (loc1_) { 376 *loc1_++ = 0; 377 if (*loc1_ == '~') { 378 loc1_invert = PETSC_TRUE; 379 ++loc1_; 380 } 381 PetscCall(PetscStrchr(loc1_, ':', &loc2_)); 382 } 383 if (loc2_) { 384 *loc2_++ = 0; 385 if (*loc2_ == '~') { 386 loc2_invert = PETSC_TRUE; 387 ++loc2_; 388 } 389 } 390 PetscCall(PetscStrlen(loc0_, &size_loc0_)); 391 PetscCall(PetscStrlen(loc1_, &size_loc1_)); 392 PetscCall(PetscStrlen(loc2_, &size_loc2_)); 393 if (size_loc1_) { 394 PetscCall(PetscStrtolower(loc1_)); 395 PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array)); 396 } 397 if (size_loc2_) { 398 PetscBool foundSelf; 399 400 PetscCall(PetscStrtolower(loc2_)); 401 PetscCall(PetscStrcmp("self", loc2_, &foundSelf)); 402 if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF; 403 } 404 PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w")); 405 PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array)); 406 PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag)); 407 PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array)); 408 PetscCall(PetscFree(loc0_)); 409 } 410 PetscFunctionReturn(PETSC_SUCCESS); 411 } 412 413 /*@ 414 PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures. 415 416 Not Collective 417 418 Note: 419 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 420 `PetscInfo()` calls down the line. 421 422 Level: developer 423 424 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 425 @*/ 426 PetscErrorCode PetscInfoDestroy(void) 427 { 428 int err; 429 430 PetscFunctionBegin; 431 PetscCall(PetscInfoAllow(PETSC_FALSE)); 432 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 433 err = fflush(PetscInfoFile); 434 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 435 if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 436 PetscCall(PetscFree(PetscInfoFilename)); 437 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"); 438 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 439 PetscInfoFlags[i] = 1; 440 PetscCall(PetscFree(PetscInfoNames[i])); 441 } 442 443 PetscInfoClassesLocked = PETSC_FALSE; 444 PetscInfoInvertClasses = PETSC_FALSE; 445 PetscInfoClassesSet = PETSC_FALSE; 446 PetscInfoNumClasses = -1; 447 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 448 PetscFunctionReturn(PETSC_SUCCESS); 449 } 450 451 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 452 { 453 PetscFunctionBegin; 454 if (!classid) classid = PETSC_SMALLEST_CLASSID; 455 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 456 PetscFunctionReturn(PETSC_SUCCESS); 457 } 458 459 /*@ 460 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 461 462 Not Collective 463 464 Input Parameter: 465 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 466 467 Note: 468 One can pass 0 to deactivate all messages that are not associated with an object. 469 470 Level: developer 471 472 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 473 @*/ 474 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 475 { 476 PetscFunctionBegin; 477 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 478 PetscFunctionReturn(PETSC_SUCCESS); 479 } 480 481 /*@ 482 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 483 484 Not Collective 485 486 Input Parameter: 487 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 488 489 Note: 490 One can pass 0 to activate all messages that are not associated with an object. 491 492 Level: developer 493 494 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 495 @*/ 496 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 497 { 498 PetscFunctionBegin; 499 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 500 PetscFunctionReturn(PETSC_SUCCESS); 501 } 502 503 /* 504 If the option -history was used, then all printed PetscInfo() 505 messages are also printed to the history file, called by default 506 .petschistory in ones home directory. 507 */ 508 PETSC_INTERN FILE *petsc_history; 509 510 /*MC 511 PetscInfo - Logs informative data 512 513 Synopsis: 514 #include <petscsys.h> 515 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 516 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 517 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 518 ... 519 520 Collective 521 522 Input Parameters: 523 + obj - object most closely associated with the logging statement or `NULL` 524 . message - logging message 525 . formatmessage - logging message using standard "printf" format 526 - arg1, arg2, ... - arguments of the format 527 528 Notes: 529 `PetscInfo()` prints only from the first processor in the communicator of obj. 530 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 531 532 Extent of the printed messages can be controlled using the option database key -info as follows. 533 534 $ -info [filename][:[~]<list,of,classnames>[:[~]self]] 535 536 No filename means standard output `PETSC_STDOUT` is used. 537 538 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 539 If this list is not specified, all classes are enabled. 540 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 541 A special classname sys relates to PetscInfo() with obj being NULL. 542 543 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. 544 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. 545 546 All classname/self matching is case insensitive. Filename is case sensitive. 547 548 Example of Usage: 549 $ Mat A; 550 $ PetscInt alpha; 551 $ ... 552 $ PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 553 554 Options Examples: 555 Each call of the form 556 $ PetscInfo(obj, msg); 557 $ PetscInfo(obj, msg, arg1); 558 $ PetscInfo(obj, msg, arg1, arg2); 559 is evaluated as follows. 560 $ -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 561 $ -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 562 $ -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 563 $ -info :sys prints to PETSC_STDOUT only if obj is NULL 564 Note that 565 $ -info :sys:~self 566 deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF. 567 568 Fortran Note: 569 This function does not take the obj argument, there is only the `PetscInfo()` 570 version, not `PetscInfo()` etc. 571 572 Level: intermediate 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