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, 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, 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, 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 `PetscClassid` 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: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoGetInfo()`, `PetscObjectGetClassid()` 50 @*/ 51 PetscErrorCode PetscInfoEnabled(PetscClassId classid, PetscBool *enabled) 52 { 53 PetscFunctionBegin; 54 PetscAssertPointer(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: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoEnabled()`, `PetscInfoGetInfo()`, `PetscInfoSetFromOptions()` 71 @*/ 72 PetscErrorCode PetscInfoAllow(PetscBool flag) 73 { 74 PetscFunctionBegin; 75 PetscLogPrintInfo = flag; 76 PetscFunctionReturn(PETSC_SUCCESS); 77 } 78 79 /*@ 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, use `NULL` to write to `PETSC_STDOUT`. 86 - mode - Write mode passed to `PetscFOpen()` 87 88 Level: advanced 89 90 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetFile()`, `PetscInfoSetFromOptions()`, `PetscFOpen()` 91 @*/ 92 PetscErrorCode PetscInfoSetFile(const char filename[], const char mode[]) 93 { 94 PetscFunctionBegin; 95 if (!PetscInfoFile) PetscInfoFile = PETSC_STDOUT; 96 PetscCall(PetscFree(PetscInfoFilename)); 97 if (filename) { 98 PetscMPIInt rank; 99 char fname[PETSC_MAX_PATH_LEN], tname[11]; 100 101 PetscAssertPointer(filename, 1); 102 PetscAssertPointer(mode, 2); 103 PetscCall(PetscFixFilename(filename, fname)); 104 PetscCall(PetscStrallocpy(fname, &PetscInfoFilename)); 105 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 106 PetscCall(PetscSNPrintf(tname, PETSC_STATIC_ARRAY_LENGTH(tname), ".%d", rank)); 107 PetscCall(PetscStrlcat(fname, tname, PETSC_STATIC_ARRAY_LENGTH(fname))); 108 { 109 const PetscBool oldflag = PetscLogPrintInfo; 110 111 PetscLogPrintInfo = PETSC_FALSE; 112 PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, mode, &PetscInfoFile)); 113 PetscLogPrintInfo = oldflag; 114 /* 115 PetscFOpen will write to PETSC_STDOUT and not PetscInfoFile here, so we disable the 116 PetscInfo call inside it, and call it afterwards so that it actually writes to file 117 */ 118 } 119 PetscCall(PetscInfo(NULL, "Opened PetscInfo file %s\n", fname)); 120 } 121 PetscFunctionReturn(PETSC_SUCCESS); 122 } 123 124 /*@C 125 PetscInfoGetFile - Gets the `filename` and `FILE` pointer of the file where `PetscInfo()` prints to 126 127 Not Collective; No Fortran Support 128 129 Output Parameters: 130 + filename - The name of the output file 131 - InfoFile - The `FILE` pointer for the output file 132 133 Level: advanced 134 135 Note: 136 This routine allocates and copies the `filename` so that the `filename` survives `PetscInfoDestroy()`. The user is 137 therefore responsible for freeing the allocated `filename` pointer with `PetscFree()` 138 139 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetFile()`, `PetscInfoSetFromOptions()`, `PetscInfoDestroy()` 140 @*/ 141 PetscErrorCode PetscInfoGetFile(char *filename[], FILE **InfoFile) 142 { 143 PetscFunctionBegin; 144 PetscAssertPointer(filename, 1); 145 PetscAssertPointer(InfoFile, 2); 146 PetscCall(PetscStrallocpy(PetscInfoFilename, filename)); 147 *InfoFile = PetscInfoFile; 148 PetscFunctionReturn(PETSC_SUCCESS); 149 } 150 151 /*@C 152 PetscInfoSetClasses - Sets the classes which `PetscInfo()` is filtered for/against 153 154 Not Collective; No Fortran Support 155 156 Input Parameters: 157 + exclude - Whether or not to invert the filter, i.e. if exclude is true, `PetscInfo()` will print from every class that 158 is NOT one of the classes specified 159 . n - Number of classes to filter for (size of `classnames`) 160 - classnames - String array containing the names of classes to filter for, e.g. "vec" 161 162 Level: developer 163 164 Notes: 165 This function CANNOT be called after `PetscInfoGetClass()` or `PetscInfoProcessClass()` has been called, unless the user calls `PetscInfoDestroy()` first. 166 167 Names in the `classnames` list should correspond to the names returned by `PetscObjectGetClassName()`. 168 169 This function only sets the list of class names. 170 The actual filtering is deferred to `PetscInfoProcessClass()`, except of sys which is processed right away. 171 The reason for this is that we need to set the list of included/excluded classes before their classids are known. 172 Typically the classid is assigned and `PetscInfoProcessClass()` called in <Class>InitializePackage() (e.g. `VecInitializePackage()`). 173 174 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetClass()`, `PetscInfoProcessClass()`, `PetscInfoSetFromOptions()`, `PetscStrToArray()`, `PetscObjectGetName()` 175 @*/ 176 PetscErrorCode PetscInfoSetClasses(PetscBool exclude, PetscInt n, const char *const *classnames) 177 { 178 PetscFunctionBegin; 179 PetscCheck(!PetscInfoClassesLocked, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Trying to modify PetscInfo() configuration after it has been locked to a read-only state. Usually, this is an *error*! To re-enable modification, you must reset PetscInfo() by calling PetscInfoDestroy() first"); 180 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 181 PetscCall(PetscStrNArrayallocpy(n, classnames, &PetscInfoClassnames)); 182 PetscInfoNumClasses = n; 183 PetscInfoInvertClasses = exclude; 184 /* Process sys class right away */ 185 { 186 const PetscClassId id = PETSC_SMALLEST_CLASSID; 187 188 PetscCall(PetscInfoProcessClass("sys", 1, &id)); 189 } 190 PetscInfoClassesSet = PETSC_TRUE; 191 PetscFunctionReturn(PETSC_SUCCESS); 192 } 193 194 /*@ 195 PetscInfoGetClass - Indicates whether the provided `classname` is marked as a filter in `PetscInfo()` as set by `PetscInfoSetClasses()` 196 197 Not Collective 198 199 Input Parameter: 200 . classname - Name of the class to search for 201 202 Output Parameter: 203 . found - `PetscBool` indicating whether the classname was found 204 205 Level: developer 206 207 Note: 208 Use `PetscObjectGetName()` to retrieve an appropriate classname 209 210 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetClasses()`, `PetscInfoSetFromOptions()`, `PetscObjectGetName()` 211 @*/ 212 PetscErrorCode PetscInfoGetClass(const char classname[], PetscBool *found) 213 { 214 PetscInt unused; 215 216 PetscFunctionBegin; 217 PetscAssertPointer(classname, 1); 218 PetscAssertPointer(found, 2); 219 PetscCall(PetscEListFind(PetscInfoNumClasses, (const char *const *)PetscInfoClassnames, classname ? classname : "sys", &unused, found)); 220 PetscInfoClassesLocked = PETSC_TRUE; 221 PetscFunctionReturn(PETSC_SUCCESS); 222 } 223 224 /*@ 225 PetscInfoGetInfo - Returns the current state of several flags for `PetscInfo()` 226 227 Not Collective 228 229 Output Parameters: 230 + infoEnabled - `PETSC_TRUE` if `PetscInfoAllow`(`PETSC_TRUE`) has been called 231 . classesSet - `PETSC_TRUE` if the list of classes to filter for has been set 232 . exclude - `PETSC_TRUE` if the class filtering for `PetscInfo()` is inverted 233 . locked - `PETSC_TRUE` if the list of classes to filter for has been locked 234 - commSelfFlag - Enum indicating whether `PetscInfo()` will print for communicators of size 1, any size != 1, or all 235 communicators 236 237 Level: developer 238 239 Note: 240 Initially commSelfFlag = `PETSC_INFO_COMM_ALL` 241 242 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFilterCommSelf`, `PetscInfoSetFromOptions()` 243 @*/ 244 PetscErrorCode PetscInfoGetInfo(PetscBool *infoEnabled, PetscBool *classesSet, PetscBool *exclude, PetscBool *locked, PetscInfoCommFlag *commSelfFlag) 245 { 246 PetscFunctionBegin; 247 if (infoEnabled) PetscAssertPointer(infoEnabled, 1); 248 if (classesSet) PetscAssertPointer(classesSet, 2); 249 if (exclude) PetscAssertPointer(exclude, 3); 250 if (locked) PetscAssertPointer(locked, 4); 251 if (commSelfFlag) PetscAssertPointer(commSelfFlag, 5); 252 if (infoEnabled) *infoEnabled = PetscLogPrintInfo; 253 if (classesSet) *classesSet = PetscInfoClassesSet; 254 if (exclude) *exclude = PetscInfoInvertClasses; 255 if (locked) *locked = PetscInfoClassesLocked; 256 if (commSelfFlag) *commSelfFlag = PetscInfoCommFilter; 257 PetscFunctionReturn(PETSC_SUCCESS); 258 } 259 260 /*@ 261 PetscInfoProcessClass - Activates or deactivates a class based on the filtering status of `PetscInfo()` 262 263 Not Collective 264 265 Input Parameters: 266 + classname - Name of the class to activate/deactivate `PetscInfo()` for 267 . numClassID - Number of entries in `classIDs` 268 - classIDs - Array containing all of the `PetscClassId`s associated with `classname` 269 270 Options Database Key: 271 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, see `PetscInfo()`. 272 273 Level: developer 274 275 .seealso: [](sec_PetscInfo), `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 PetscAssertPointer(classname, 1); 284 PetscAssert(numClassID > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of classids %" PetscInt_FMT " <= 0", numClassID); 285 if (numClassID) PetscAssertPointer(classIDs, 3); 286 PetscCall(PetscInfoGetInfo(&enabled, NULL, &exclude, NULL, NULL)); 287 PetscCall(PetscOptionsDeprecated_Private(NULL, "-info_exclude", NULL, "3.13", "Use ~ with -info to indicate classes to exclude")); 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 PetscCheck(PETSC_LARGEST_CLASSID - PETSC_SMALLEST_CLASSID < (PetscInt)PETSC_STATIC_ARRAY_LENGTH(PetscInfoNames), PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscInfoNames array is too small for %s, need %" PetscInt_FMT " not %" PetscInt_FMT, classname, (PetscInt)(PETSC_LARGEST_CLASSID - PETSC_SMALLEST_CLASSID + 1), (PetscInt)PETSC_STATIC_ARRAY_LENGTH(PetscInfoNames)); 298 for (PetscInt i = 0; i < numClassID; ++i) { 299 const PetscClassId idx = classIDs[i] - PETSC_SMALLEST_CLASSID; 300 301 PetscCall(PetscFree(PetscInfoNames[idx])); 302 PetscCall(PetscStrallocpy(classname, PetscInfoNames + idx)); 303 } 304 PetscCall(PetscInfoGetClass(classname, &found)); 305 if ((found && exclude) || (!found && !exclude)) { 306 if (PetscInfoNumClasses > 0) { 307 /* Check if -info was called empty */ 308 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoDeactivateClass(classIDs[i])); 309 } 310 } else { 311 for (PetscInt i = 0; i < numClassID; ++i) PetscCall(PetscInfoActivateClass(classIDs[i])); 312 } 313 PetscFunctionReturn(PETSC_SUCCESS); 314 } 315 316 /*@ 317 PetscInfoSetFilterCommSelf - Sets `PetscInfoCommFlag` enum to determine communicator filtering for `PetscInfo()` 318 319 Not Collective 320 321 Input Parameter: 322 . commSelfFlag - Enum value indicating method with which to filter `PetscInfo()` based on the size of the communicator of the object calling `PetscInfo()` 323 324 Options Database Key: 325 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 326 327 Level: advanced 328 329 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoGetInfo()` 330 @*/ 331 PetscErrorCode PetscInfoSetFilterCommSelf(PetscInfoCommFlag commSelfFlag) 332 { 333 PetscFunctionBegin; 334 PetscInfoCommFilter = commSelfFlag; 335 PetscFunctionReturn(PETSC_SUCCESS); 336 } 337 338 /*@ 339 PetscInfoSetFromOptions - Configure `PetscInfo()` using command line options, enabling or disabling various calls to `PetscInfo()` 340 341 Not Collective 342 343 Input Parameter: 344 . options - Options database, use `NULL` for default global database 345 346 Options Database Key: 347 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 348 349 Level: advanced 350 351 Note: 352 This function is called automatically during `PetscInitialize()` so users usually do not need to call it themselves. 353 354 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFile()`, `PetscInfoSetClasses()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()` 355 @*/ 356 PetscErrorCode PetscInfoSetFromOptions(PetscOptions options) 357 { 358 char optstring[PETSC_MAX_PATH_LEN]; 359 PetscBool set; 360 361 PetscFunctionBegin; 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 Level: developer 419 420 Notes: 421 This is automatically called in `PetscFinalize()`. Useful for changing filters mid-program, or culling subsequent 422 `PetscInfo()` calls down the line. 423 424 Users calling this routine midway through a program should note that `PetscInfoDestroy()` 425 constitutes a full reset of `PetscInfo()`. It flushes, then closes, the current info file, 426 re-enables all classes, and resets all internal state. Finally -- and perhaps crucially -- it 427 disables `PetscInfo()` as-if-by `PetscInfoAllow(PETSC_FALSE)`. 428 429 .seealso: [](sec_PetscInfo), `PetscInfo()`, `PetscInfoSetFromOptions()` 430 @*/ 431 PetscErrorCode PetscInfoDestroy(void) 432 { 433 PetscFunctionBegin; 434 PetscCall(PetscInfoAllow(PETSC_FALSE)); 435 PetscCall(PetscStrNArrayDestroy(PetscInfoNumClasses, &PetscInfoClassnames)); 436 if (PetscInfoFile) PetscCall(PetscFFlush(PetscInfoFile)); 437 if (PetscInfoFilename) { 438 PetscAssert(PetscInfoFile, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Have non-null PetscInfo file '%s', but corresponding FILE handle is null!", PetscInfoFilename); 439 PetscCall(PetscFree(PetscInfoFilename)); 440 PetscCall(PetscFClose(PETSC_COMM_SELF, PetscInfoFile)); 441 } 442 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"); 443 for (size_t i = 0; i < PETSC_STATIC_ARRAY_LENGTH(PetscInfoFlags); ++i) { 444 PetscInfoFlags[i] = 1; 445 PetscCall(PetscFree(PetscInfoNames[i])); 446 } 447 448 PetscInfoFile = NULL; 449 PetscInfoClassesLocked = PETSC_FALSE; 450 PetscInfoInvertClasses = PETSC_FALSE; 451 PetscInfoClassesSet = PETSC_FALSE; 452 PetscInfoNumClasses = -1; 453 PetscInfoCommFilter = PETSC_INFO_COMM_ALL; 454 PetscFunctionReturn(PETSC_SUCCESS); 455 } 456 457 static PetscErrorCode PetscInfoSetClassActivation_Private(PetscClassId classid, int value) 458 { 459 PetscFunctionBegin; 460 if (!classid) classid = PETSC_SMALLEST_CLASSID; 461 PetscInfoFlags[classid - PETSC_SMALLEST_CLASSID] = value; 462 PetscFunctionReturn(PETSC_SUCCESS); 463 } 464 465 /*@ 466 PetscInfoDeactivateClass - Deactivates `PetscInfo()` messages for a PETSc object class. 467 468 Not Collective 469 470 Input Parameter: 471 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 472 473 Options Database Key: 474 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 475 476 Level: developer 477 478 Note: 479 One can pass 0 to deactivate all messages that are not associated with an object. 480 481 .seealso: [](sec_PetscInfo), `PetscInfoActivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 482 @*/ 483 PetscErrorCode PetscInfoDeactivateClass(PetscClassId classid) 484 { 485 PetscFunctionBegin; 486 PetscCall(PetscInfoSetClassActivation_Private(classid, 0)); 487 PetscFunctionReturn(PETSC_SUCCESS); 488 } 489 490 /*@ 491 PetscInfoActivateClass - Activates `PetscInfo()` messages for a PETSc object class. 492 493 Not Collective 494 495 Input Parameter: 496 . classid - The object class, e.g., `MAT_CLASSID`, `SNES_CLASSID`, etc. 497 498 Options Database Key: 499 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed, See `PetscInfo()`. 500 501 Level: developer 502 503 Note: 504 One can pass 0 to activate all messages that are not associated with an object. 505 506 .seealso: [](sec_PetscInfo), `PetscInfoDeactivateClass()`, `PetscInfo()`, `PetscInfoAllow()`, `PetscInfoSetFromOptions()` 507 @*/ 508 PetscErrorCode PetscInfoActivateClass(PetscClassId classid) 509 { 510 PetscFunctionBegin; 511 PetscCall(PetscInfoSetClassActivation_Private(classid, 1)); 512 PetscFunctionReturn(PETSC_SUCCESS); 513 } 514 515 /* 516 If the option -history was used, then all printed PetscInfo() 517 messages are also printed to the history file, called by default 518 .petschistory in ones home directory. 519 */ 520 PETSC_INTERN FILE *petsc_history; 521 PETSC_INTERN PetscErrorCode PetscVFPrintf_Internal(FILE *, const char[], ...); 522 523 /*MC 524 PetscInfo - Logs informative data 525 526 Synopsis: 527 #include <petsclog.h> 528 PetscErrorCode PetscInfo(PetscObject obj, const char message[], ...) 529 530 Collective 531 532 Input Parameters: 533 + obj - object most closely associated with the logging statement or `NULL` 534 - message - logging message using standard "printf" format 535 536 Options Database Key: 537 . -info [filename][:[~]<list,of,classnames>[:[~]self]] - specify which informative messages are printed 538 539 Level: intermediate 540 541 Notes: 542 `PetscInfo()` prints only from the first processor in the communicator of `obj`. 543 If `obj` is `NULL`, the `PETSC_COMM_SELF` communicator is used, i.e. every rank of `PETSC_COMM_WORLD` prints the message. 544 545 The optional <list,of,classnames> is a comma separated list of enabled classes, e.g. `vec,mat,ksp`. 546 If this list is not specified, all classes are enabled. 547 Prepending the list with ~ means inverted selection, i.e. all classes except the listed are enabled. 548 A special classname `sys` relates to `PetscInfo()` with `obj` being `NULL`. 549 550 The optional keyword `self` specifies that `PetscInfo()` is enabled only for a communicator size of 1 (e.g. `PETSC_COMM_SELF`). 551 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. 552 553 All classname/self matching is case insensitive. Filename is case sensitive. 554 555 Example of Usage: 556 .vb 557 Mat A; 558 PetscInt alpha; 559 ... 560 PetscInfo(A,"Matrix uses parameter alpha=%" PetscInt_FMT "\n",alpha); 561 .ve 562 563 Examples using Options: 564 Each call of the form 565 .vb 566 PetscInfo(obj, msg); 567 PetscInfo(obj, msg, arg1); 568 PetscInfo(obj, msg, arg1, arg2); 569 .ve 570 is evaluated as follows. 571 .vb 572 -info or -info :: prints `msg` to `PETSC_STDOUT`, for any PETSc `obj` regardless class or communicator 573 -info :mat:self prints `msg` to `PETSC_STDOUT` only if class of `obj` is `Mat`, and its communicator has size = 1 574 -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 575 -info :sys prints to `PETSC_STDOUT` only if `obj` is `NULL` 576 -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`. 577 .ve 578 579 Fortran Notes: 580 This function does not take the `obj` argument, there is only the `PetscInfo()` 581 version, not `PetscInfo()` etc. 582 583 .seealso: [](sec_PetscInfo), `PetscInfoAllow()`, `PetscInfoSetFromOptions()`, `PetscInfoEnabled()`, `PetscInfoSetFile()`, `PetscInfoGetFile()`, `PetscInfoSetClasses()`, 584 `PetscInfoGetClass()`, `PetscInfoGetInfo()`, `PetscInfoProcessClass()`, `PetscInfoSetFilterCommSelf()`, `PetscInfoDestroy()`, `PetscInfoDeactivateClass()`, 585 `PetscInfoActivateClass()` 586 M*/ 587 PetscErrorCode PetscInfo_Private(const char func[], PetscObject obj, const char message[], ...) 588 { 589 PetscClassId classid = PETSC_SMALLEST_CLASSID; 590 PetscBool enabled = PETSC_FALSE; 591 MPI_Comm comm = MPI_COMM_NULL; 592 PetscMPIInt rank = 0; 593 const char *otype = NULL; 594 595 PetscFunctionBegin; 596 if (obj) { 597 PetscValidHeader(obj, 2); 598 classid = obj->classid; 599 } 600 PetscAssertPointer(message, 3); 601 PetscCall(PetscInfoEnabled(classid, &enabled)); 602 if (!enabled) PetscFunctionReturn(PETSC_SUCCESS); 603 if (obj) { 604 PetscCall(PetscObjectGetComm(obj, &comm)); 605 PetscCall(PetscObjectGetType(obj, &otype)); 606 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 607 } 608 /* rank > 0 always jumps out */ 609 if (rank) PetscFunctionReturn(PETSC_SUCCESS); 610 else { 611 PetscMPIInt size = 1; 612 613 if (comm != MPI_COMM_NULL) PetscCallMPI(MPI_Comm_size(comm, &size)); 614 /* If no self printing is allowed, and size too small, get out */ 615 if ((PetscInfoCommFilter == PETSC_INFO_COMM_NO_SELF) && (size < 2)) PetscFunctionReturn(PETSC_SUCCESS); 616 /* If ONLY self printing, and size too big, get out */ 617 if ((PetscInfoCommFilter == PETSC_INFO_COMM_ONLY_SELF) && (size > 1)) PetscFunctionReturn(PETSC_SUCCESS); 618 } 619 /* Mute info messages within this function */ 620 { 621 const PetscBool oldflag = PetscLogPrintInfo; 622 va_list Argp; 623 PetscMPIInt urank; 624 char string[8 * 1024]; 625 size_t fullLength, len; 626 627 PetscLogPrintInfo = PETSC_FALSE; 628 PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &urank)); 629 if (otype) { 630 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s:%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], otype, func)); 631 } else { 632 PetscCall(PetscSNPrintf(string, PETSC_STATIC_ARRAY_LENGTH(string), "[%d] <%s> %s(): ", urank, PetscInfoNames[classid - PETSC_SMALLEST_CLASSID], func)); 633 } 634 PetscCall(PetscStrlen(string, &len)); 635 va_start(Argp, message); 636 PetscCall(PetscVSNPrintf(string + len, 8 * 1024 - len, message, &fullLength, Argp)); 637 va_end(Argp); 638 PetscCall(PetscVFPrintf_Internal(PetscInfoFile, "%s", string)); 639 PetscCall(PetscFFlush(PetscInfoFile)); 640 if (petsc_history) { 641 va_start(Argp, message); 642 PetscCall((*PetscVFPrintf)(petsc_history, message, Argp)); 643 va_end(Argp); 644 } 645 PetscLogPrintInfo = oldflag; 646 } 647 PetscFunctionReturn(PETSC_SUCCESS); 648 } 649