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