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(0); 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(0); 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(0); 125 } 126 127 /*@C 128 PetscInfoGetFile - Gets the name and FILE pointer of the file where `PetscInfo()` prints to 129 130 Not Collective 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 Fortran Note: 143 This routine is not supported in Fortran. 144 145 .seealso: `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()` 146 @*/ 147 PetscErrorCode PetscInfoGetFile(char **filename, FILE **InfoFile) 148 { 149 PetscFunctionBegin; 150 PetscValidPointer(filename, 1); 151 PetscValidPointer(InfoFile, 2); 152 PetscCall(PetscStrallocpy(PetscInfoFilename, filename)); 153 *InfoFile = PetscInfoFile; 154 PetscFunctionReturn(0); 155 } 156 157 /*@C 158 PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against 159 160 Not Collective 161 162 Input Parameters: 163 + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that 164 is NOT one of the classes specified 165 . n - Number of classes to filter for (size of classnames) 166 - classnames - String array containing the names of classes to filter for, e.g. "vec" 167 168 Notes: 169 This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called. 170 171 Names in the classnames list should correspond to the names returned by `PetscObjectGetClassName()`. 172 173 This function only sets the list of class names. 174 The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away. 175 The reason for this is that we need to set the list of included/excluded classes before their classids are known. 176 Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`). 177 178 Fortran Note: 179 Not for use in Fortran 180 181 Level: developer 182 183 .seealso: `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()` 184 @*/ 185 PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames) 186 { 187 PetscFunctionBegin; 188 PetscCheck(!PetscInfoClassesLocked, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscInfoSetClasses() cannot be called after PetscInfoGetClass() or PetscInfoProcessClass()"); 189 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 190 PetscCall(PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames)); 191 PetscInfoNumClasses = n; 192 PetscInfoInvertClasses = exclude; 193 /* Process sys class right away */ 194 { 195 const PetscClassId id = PETSC_SMALLEST_CLASSID; 196 197 PetscCall(PetscInfoProcessClass("sys", 1, &id)); 198 } 199 PetscInfoClassesSet = PETSC_TRUE; 200 PetscFunctionReturn(0); 201 } 202 203 /*@C 204 PetscInfoGetClass - Indicates whether the provided classname is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()` 205 206 Not Collective 207 208 Input Parameter: 209 . classname - Name of the class to search for 210 211 Output Parameter: 212 . found - `PetscBool` indicating whether the classname was found 213 214 Note: 215 Use `PetscObjectGetName()` to retrieve an appropriate classname 216 217 Level: developer 218 219 .seealso: `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()` 220 @*/ 221 PetscErrorCode PetscInfoGetClass(const char *classname, PetscBool *found) 222 { 223 PetscInt unused; 224 225 PetscFunctionBegin; 226 PetscValidCharPointer(classname, 1); 227 PetscValidBoolPointer(found, 2); 228 PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found)); 229 PetscInfoClassesLocked = PETSC_TRUE; 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 PetscInfoGetInfo - Returns the current state of several important flags for `PetscInfo()` 235 236 Not Collective 237 238 Output Parameters: 239 + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called 240 . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set 241 . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted 242 . locked - `PETSC_TRUE` if the list of classes to filter for has been locked 243 - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all 244 communicators 245 246 Note: 247 Initially commSelfFlag = `PETSC_INFO_COMM_ALL` 248 249 Level: developer 250 251 .seealso: `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()` 252 @*/ 253 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag) 254 { 255 PetscFunctionBegin; 256 if (infoEnabled) PetscValidBoolPointer(infoEnabled, 1); 257 if (classesSet) PetscValidBoolPointer(classesSet, 2); 258 if (exclude) PetscValidBoolPointer(exclude, 3); 259 if (locked) PetscValidBoolPointer(locked, 4); 260 if (commSelfFlag) PetscValidPointer(commSelfFlag, 5); 261 if (infoEnabled) *infoEnabled = PetscLogPrintInfo; 262 if (classesSet) *classesSet = PetscInfoClassesSet; 263 if (exclude) *exclude = PetscInfoInvertClasses; 264 if (locked) *locked = PetscInfoClassesLocked; 265 if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter; 266 PetscFunctionReturn(0); 267 } 268 269 /*@C 270 PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()` 271 272 Not Collective 273 274 Input Parameters: 275 + classname - Name of the class to activate/deactivate `PetscInfo()` for 276 . numClassID - Number of entries in classIDs 277 - classIDs - Array containing all of the PetscClassids associated with classname 278 279 Level: developer 280 281 .seealso: `PetscInfo()`, `PetscInfoActivateClass()`, `PetscInfoDeactivateClass()`, `PetscInfoSetFromOptions()` 282 @*/ 283 PetscErrorCode PetscInfoProcessClass(const char classname[], PetscInt numClassID, const PetscClassId classIDs[]) 284 { 285 PetscBool enabled, exclude, found, opt; 286 char logList[256]; 287 288 PetscFunctionBegin; 289 PetscValidCharPointer(classname, 1); 290 PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID); 291 if (numClassID) PetscValidPointer(classIDs, 3); 292 PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL)); 293 /* -info_exclude is DEPRECATED */ 294 PetscCall(PetscOptionsGetString(NULL, NULL, "-info_exclude", logList, sizeof(logList), &opt)); 295 if (opt) { 296 PetscBool pkg; 297 298 PetscCall(PetscStrInList(classname, logList, ',', &pkg)); 299 if (pkg) { 300 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i])); 301 } 302 } 303 for (PetscInt i = 0; i < numClassID; ++i) { 304 const PetscClassId idx = classIDs[i] - PETSC_SMALLEST_CLASSID; 305 306 PetscCall(PetscFree(PetscInfoNames[idx])); 307 PetscCall(PetscStrallocpy(classname, PetscInfoNames + idx)); 308 } 309 PetscCall(PetscInfoGetClass(classname, &found)); 310 if ((found && exclude) || (!found && !exclude)) { 311 if (PetscInfoNumClasses > 0) { 312 /* Check if -info was called empty */ 313 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i])); 314 } 315 } else { 316 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoActivateClass(classIDs[i])); 317 } 318 PetscFunctionReturn(0); 319 } 320 321 /*@ 322 PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()` 323 324 Not Collective 325 326 Input Parameter: 327 . commSelfFlag - Enum value indicating method with which to filter `PetscInfo()` based on the size of the communicator of the object calling `PetscInfo()` 328 329 Level: advanced 330 331 .seealso: `PetscInfo()`, `PetscInfoGetInfo()` 332 @*/ 333 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag) 334 { 335 PetscFunctionBegin; 336 PetscInfoCommFilter = commSelfFlag; 337 PetscFunctionReturn(0); 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 Keys: 349 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See PetscInfo(). 350 351 Note: 352 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 353 354 Level: advanced 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(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use -info instead")); 365 PetscCall(PetscOptionsGetString(options, NULL, "-info", optstring, PETSC_STATIC_ARRAY_LENGTH(optstring), &set)); 366 if (set) { 367 size_t size_loc0_, size_loc1_, size_loc2_; 368 char *loc0_ = NULL, *loc1_ = NULL, *loc2_ = NULL; 369 char **loc1_array = NULL; 370 PetscBool loc1_invert = PETSC_FALSE, loc2_invert = PETSC_FALSE; 371 int nLoc1_ = 0; 372 PetscInfoCommFlag commSelfFlag = PETSC_INFO_COMM_ALL; 373 374 PetscInfoClassesSet = PETSC_TRUE; 375 PetscCall(PetscInfoAllow(PETSC_TRUE)); 376 PetscCall(PetscStrallocpy(optstring, &loc0_)); 377 PetscCall(PetscStrchr(loc0_, ':', &loc1_)); 378 if (loc1_) { 379 *loc1_++ = 0; 380 if (*loc1_ == '~') { 381 loc1_invert = PETSC_TRUE; 382 ++loc1_; 383 } 384 PetscCall(PetscStrchr(loc1_, ':', &loc2_)); 385 } 386 if (loc2_) { 387 *loc2_++ = 0; 388 if (*loc2_ == '~') { 389 loc2_invert = PETSC_TRUE; 390 ++loc2_; 391 } 392 } 393 PetscCall(PetscStrlen(loc0_, &size_loc0_)); 394 PetscCall(PetscStrlen(loc1_, &size_loc1_)); 395 PetscCall(PetscStrlen(loc2_, &size_loc2_)); 396 if (size_loc1_) { 397 PetscCall(PetscStrtolower(loc1_)); 398 PetscCall(PetscStrToArray(loc1_, ',', &nLoc1_, &loc1_array)); 399 } 400 if (size_loc2_) { 401 PetscBool foundSelf; 402 403 PetscCall(PetscStrtolower(loc2_)); 404 PetscCall(PetscStrcmp("self", loc2_, &foundSelf)); 405 if (foundSelf) commSelfFlag = loc2_invert ? PETSC_INFO_COMM_NO_SELF : PETSC_INFO_COMM_ONLY_SELF; 406 } 407 PetscCall(PetscInfoSetFile(size_loc0_ ? loc0_ : NULL, "w")); 408 PetscCall(PetscInfoSetClasses(loc1_invert, (PetscInt)nLoc1_, (const char *const *)loc1_array)); 409 PetscCall(PetscInfoSetFilterCommSelf(commSelfFlag)); 410 PetscCall(PetscStrToArrayDestroy(nLoc1_, loc1_array)); 411 PetscCall(PetscFree(loc0_)); 412 } 413 PetscFunctionReturn(0); 414 } 415 416 /*@ 417 PetscInfoDestroy - Destroys and resets internal `PetscInfo()` data structures. 418 419 Not Collective 420 421 Note: 422 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 423 `PetscInfo()` calls down the line. 424 425 Level: developer 426 427 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()` 428 @*/ 429 PetscErrorCode PetscInfoDestroy(void) 430 { 431 int err; 432 433 PetscFunctionBegin; 434 PetscCall(PetscInfoAllow(PETSC_FALSE)); 435 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 436 err = fflush(PetscInfoFile); 437 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 438 if (PetscInfoFilename) PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 439 PetscCall(PetscFree(PetscInfoFilename)); 440 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"); 441 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 442 PetscInfoFlags[i] = 1; 443 PetscCall(PetscFree(PetscInfoNames[i])); 444 } 445 446 PetscInfoClassesLocked = PETSC_FALSE; 447 PetscInfoInvertClasses = PETSC_FALSE; 448 PetscInfoClassesSet = PETSC_FALSE; 449 PetscInfoNumClasses = -1; 450 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 451 PetscFunctionReturn(0); 452 } 453 454 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 455 { 456 PetscFunctionBegin; 457 if (!classid) classid = PETSC_SMALLEST_CLASSID; 458 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 459 PetscFunctionReturn(0); 460 } 461 462 /*@ 463 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 464 465 Not Collective 466 467 Input Parameter: 468 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 469 470 Note: 471 One can pass 0 to deactivate all messages that are not associated with an object. 472 473 Level: developer 474 475 .seealso: `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 476 @*/ 477 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 478 { 479 PetscFunctionBegin; 480 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 481 PetscFunctionReturn(0); 482 } 483 484 /*@ 485 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 486 487 Not Collective 488 489 Input Parameter: 490 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 491 492 Note: 493 One can pass 0 to activate all messages that are not associated with an object. 494 495 Level: developer 496 497 .seealso: `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 498 @*/ 499 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 500 { 501 PetscFunctionBegin; 502 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 503 PetscFunctionReturn(0); 504 } 505 506 /* 507 If the option -history was used, then all printed PetscInfo() 508 messages are also printed to the history file, called by default 509 .petschistory in ones home directory. 510 */ 511 PETSC_INTERN FILE *petsc_history; 512 513 /*MC 514 PetscInfo - Logs informative data 515 516 Synopsis: 517 #include <petscsys.h> 518 PetscErrorCode PetscInfo(PetscObject obj, const char message[]) 519 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1) 520 PetscErrorCode PetscInfo(PetscObject obj, const char formatmessage[],arg1,arg2) 521 ... 522 523 Collective on obj 524 525 Input Parameters: 526 + obj - object most closely associated with the logging statement or NULL 527 . message - logging message 528 . formatmessage - logging message using standard "printf" format 529 - arg1, arg2, ... - arguments of the format 530 531 Notes: 532 `PetscInfo()` prints only from the first processor in the communicator of obj. 533 If obj is NULL, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 534 535 Extent of the printed messages can be controlled using the option database key -info as follows. 536 537 $ -info [filename][:[~]<list,of,classnames>[:[~]self]] 538 539 No filename means standard output `PETSC_STDOUT` is used. 540 541 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. vec,mat,ksp. 542 If this list is not specified, all classes are enabled. 543 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 544 A special classname sys relates to PetscInfo() with obj being NULL. 545 546 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. 547 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. 548 549 All classname/self matching is case insensitive. Filename is case sensitive. 550 551 Example of Usage: 552 $ Mat A; 553 $ PetscInt alpha; 554 $ ... 555 $ PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 556 557 Options Examples: 558 Each call of the form 559 $ PetscInfo(obj, msg); 560 $ PetscInfo(obj, msg, arg1); 561 $ PetscInfo(obj, msg, arg1, arg2); 562 is evaluated as follows. 563 $ -info or -info :: prints msg to PETSC_STDOUT, for any obj regardless class or communicator 564 $ -info :mat:self prints msg to PETSC_STDOUT only if class of obj is Mat, and its communicator has size = 1 565 $ -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 566 $ -info :sys prints to PETSC_STDOUT only if obj is NULL 567 Note that 568 $ -info :sys:~self 569 deactivates all info messages because sys means obj = NULL which implies PETSC_COMM_SELF but ~self filters out everything on PETSC_COMM_SELF. 570 571 Fortran Note: 572 This function does not take the obj argument, there is only the `PetscInfo()` 573 version, not `PetscInfo()` etc. 574 575 Level: intermediate 576 577 .seealso: `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 578 M*/ 579 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) 580 { 581 PetscClassId classid = PETSC_SMALLEST_CLASSID; 582 PetscBool enabled = PETSC_FALSE; 583 MPI_Comm comm = PETSC_COMM_SELF; 584 PetscMPIInt rank; 585 586 PetscFunctionBegin; 587 if (obj) { 588 PetscValidHeader(obj, 2); 589 classid = obj->classid; 590 } 591 PetscValidCharPointer(message, 3); 592 PetscCall(PetscInfoEnabled(classid, &enabled)); 593 if (!enabled) PetscFunctionReturn(0); 594 if (obj) PetscCall(PetscObjectGetComm(obj, &comm)); 595 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 596 /* rank > 0 always jumps out */ 597 if (rank) PetscFunctionReturn(0); 598 else { 599 PetscMPIInt size; 600 601 PetscCallMPI(MPI_Comm_size(comm, &size)); 602 /* If no self printing is allowed, and size too small, get out */ 603 if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(0); 604 /* If ONLY self printing, and size too big, get out */ 605 if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(0); 606 } 607 /* Mute info messages within this function */ 608 { 609 const PetscBool oldflag = PetscLogPrintInfo; 610 va_list Argp; 611 PetscMPIInt urank; 612 int err; 613 char string[8 * 1024]; 614 size_t fullLength, len; 615 616 PetscLogPrintInfo = PETSC_FALSE; 617 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank)); 618 va_start(Argp, message); 619 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func)); 620 PetscCall(PetscStrlen(string, &len)); 621 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 622 PetscCall(PetscFPrintf(PETSC_COMM_SELF, PetscInfoFile, "%s", string)); 623 err = fflush(PetscInfoFile); 624 PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fflush() failed on file"); 625 if (petsc_history) { 626 va_start(Argp, message); 627 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 628 } 629 va_end(Argp); 630 PetscLogPrintInfo = oldflag; 631 } 632 PetscFunctionReturn(0); 633 } 634