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