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