1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #include <petsc/private/hashtable.h> 4 #if defined(PETSC_HAVE_SAWS) 5 #include <petscviewersaws.h> 6 #endif 7 8 PetscFunctionList PetscViewerList = NULL; 9 10 PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL; 11 KHASH_SET_INIT_STR(HTPrinted) 12 struct _n_PetscOptionsHelpPrinted{ 13 khash_t(HTPrinted) *printed; 14 PetscSegBuffer strings; 15 }; 16 17 PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp) 18 { 19 PetscFunctionBegin; 20 if (!*hp) PetscFunctionReturn(0); 21 kh_destroy(HTPrinted,(*hp)->printed); 22 PetscCall(PetscSegBufferDestroy(&(*hp)->strings)); 23 PetscCall(PetscFree(*hp)); 24 PetscFunctionReturn(0); 25 } 26 27 /*@C 28 PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have 29 been printed so they will not be printed again. 30 31 Not collective 32 33 Level: developer 34 35 .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()` 36 @*/ 37 PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp) 38 { 39 PetscFunctionBegin; 40 PetscCall(PetscNew(hp)); 41 (*hp)->printed = kh_init(HTPrinted); 42 PetscCall(PetscSegBufferCreate(sizeof(char),10000,&(*hp)->strings)); 43 PetscFunctionReturn(0); 44 } 45 46 /*@C 47 PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed) 48 49 Not collective 50 51 Input Parameters: 52 + hp - the object used to manage tracking what help messages have been printed 53 . pre - the prefix part of the string, many be NULL 54 - name - the string to look for (cannot be NULL) 55 56 Output Parameter: 57 . found - PETSC_TRUE if the string was already set 58 59 Level: intermediate 60 61 .seealso: `PetscOptionsHelpPrintedCreate()` 62 @*/ 63 PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char *pre,const char* name,PetscBool *found) 64 { 65 size_t l1,l2; 66 #if !defined(PETSC_HAVE_THREADSAFETY) 67 char *both; 68 int newitem; 69 #endif 70 71 PetscFunctionBegin; 72 PetscCall(PetscStrlen(pre,&l1)); 73 PetscCall(PetscStrlen(name,&l2)); 74 if (l1+l2 == 0) { 75 *found = PETSC_FALSE; 76 PetscFunctionReturn(0); 77 } 78 #if !defined(PETSC_HAVE_THREADSAFETY) 79 PetscCall(PetscSegBufferGet(hp->strings,l1+l2+1,&both)); 80 PetscCall(PetscStrcpy(both,pre)); 81 PetscCall(PetscStrcat(both,name)); 82 kh_put(HTPrinted,hp->printed,both,&newitem); 83 if (!newitem) { 84 PetscCall(PetscSegBufferUnuse(hp->strings,l1+l2+1)); 85 } 86 *found = newitem ? PETSC_FALSE : PETSC_TRUE; 87 #else 88 *found = PETSC_FALSE; 89 #endif 90 PetscFunctionReturn(0); 91 } 92 93 static PetscBool noviewer = PETSC_FALSE; 94 static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX]; 95 static PetscInt inoviewers = 0; 96 97 /*@ 98 PetscOptionsPushGetViewerOff - control whether PetscOptionsGetViewer returns a viewer. 99 100 Logically Collective 101 102 Input Parameter: 103 . flg - PETSC_TRUE to turn off viewer creation, PETSC_FALSE to turn it on. 104 105 Level: developer 106 107 Notes: 108 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 109 many small subsolves. Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls. 110 111 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()` 112 @*/ 113 PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg) 114 { 115 PetscFunctionBegin; 116 PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?"); 117 118 noviewers[inoviewers++] = noviewer; 119 noviewer = flg; 120 PetscFunctionReturn(0); 121 } 122 123 /*@ 124 PetscOptionsPopGetViewerOff - reset whether PetscOptionsGetViewer returns a viewer. 125 126 Logically Collective 127 128 Level: developer 129 130 Notes: 131 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 132 many small subsolves. Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls. 133 134 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()` 135 @*/ 136 PetscErrorCode PetscOptionsPopGetViewerOff(void) 137 { 138 PetscFunctionBegin; 139 PetscCheck(inoviewers,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?"); 140 noviewer = noviewers[--inoviewers]; 141 PetscFunctionReturn(0); 142 } 143 144 /*@ 145 PetscOptionsGetViewerOff - does PetscOptionsGetViewer return a viewer? 146 147 Logically Collective 148 149 Output Parameter: 150 . flg - whether viewers are returned. 151 152 Level: developer 153 154 Notes: 155 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 156 many small subsolves. 157 158 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()` 159 @*/ 160 PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg) 161 { 162 PetscFunctionBegin; 163 PetscValidBoolPointer(flg,1); 164 *flg = noviewer; 165 PetscFunctionReturn(0); 166 } 167 168 /*@C 169 PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user 170 171 Collective 172 173 Input Parameters: 174 + comm - the communicator to own the viewer 175 . options - options database, use NULL for default global database 176 . pre - the string to prepend to the name or NULL 177 - name - the option one is seeking 178 179 Output Parameters: 180 + viewer - the viewer, pass NULL if not needed 181 . format - the PetscViewerFormat requested by the user, pass NULL if not needed 182 - set - PETSC_TRUE if found, else PETSC_FALSE 183 184 Level: intermediate 185 186 Notes: 187 If no value is provided ascii:stdout is used 188 $ ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 189 for example ascii::ascii_info prints just the information about the object not all details 190 unless :append is given filename opens in write mode, overwriting what was already there 191 $ binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 192 $ draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 193 $ socket[:port] defaults to the standard output port 194 $ saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 195 196 Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur 197 198 You can control whether calls to this function create a viewer (or return early with *set of PETSC_FALSE) with 199 PetscOptionsPushGetViewerOff. This is useful if calling many small subsolves, in which case XXXViewFromOptions can take 200 an appreciable fraction of the runtime. 201 202 If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE 203 204 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 205 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 206 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 207 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 208 `PetscOptionsStringArray(),PetscOptionsRealArray()`, `PetscOptionsScalar()`, 209 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 210 `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`, 211 `PetscOptionsGetViewerOff()` 212 @*/ 213 PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set) 214 { 215 const char *value; 216 PetscBool flag,hashelp; 217 218 PetscFunctionBegin; 219 PetscValidCharPointer(name,4); 220 221 if (viewer) *viewer = NULL; 222 if (format) *format = PETSC_VIEWER_DEFAULT; 223 if (set) *set = PETSC_FALSE; 224 PetscCall(PetscOptionsGetViewerOff(&flag)); 225 if (flag) PetscFunctionReturn(0); 226 227 PetscCall(PetscOptionsHasHelp(NULL,&hashelp)); 228 if (hashelp) { 229 PetscBool found; 230 231 if (!PetscOptionsHelpPrintedSingleton) { 232 PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton)); 233 } 234 PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,pre,name,&found)); 235 if (!found && viewer) { 236 PetscCall((*PetscHelpPrintf)(comm,"----------------------------------------\nViewer (-%s%s) options:\n",pre ? pre : "",name+1)); 237 PetscCall((*PetscHelpPrintf)(comm," -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer")); 238 PetscCall((*PetscHelpPrintf)(comm," -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer")); 239 PetscCall((*PetscHelpPrintf)(comm," -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer")); 240 PetscCall((*PetscHelpPrintf)(comm," -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer")); 241 PetscCall((*PetscHelpPrintf)(comm," -%s%s saws[:communicatorname]: %s (%s)\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer")); 242 } 243 } 244 245 if (format) *format = PETSC_VIEWER_DEFAULT; 246 PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag)); 247 if (flag) { 248 if (set) *set = PETSC_TRUE; 249 if (!value) { 250 if (viewer) { 251 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 252 PetscCall(PetscObjectReference((PetscObject)*viewer)); 253 } 254 } else { 255 char *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL; 256 PetscInt cnt; 257 const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,PETSCVIEWERGLVIS,PETSCVIEWEREXODUSII,NULL}; 258 259 PetscCall(PetscStrallocpy(value,&loc0_vtype)); 260 PetscCall(PetscStrchr(loc0_vtype,':',&loc1_fname)); 261 if (loc1_fname) { 262 *loc1_fname++ = 0; 263 PetscCall(PetscStrchr(loc1_fname,':',&loc2_fmt)); 264 } 265 if (loc2_fmt) { 266 *loc2_fmt++ = 0; 267 PetscCall(PetscStrchr(loc2_fmt,':',&loc3_fmode)); 268 } 269 if (loc3_fmode) *loc3_fmode++ = 0; 270 PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt)); 271 PetscCheck(cnt <= (PetscInt) sizeof(viewers)-1,comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype); 272 if (viewer) { 273 if (!loc1_fname) { 274 switch (cnt) { 275 case 0: 276 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 277 break; 278 case 1: 279 if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB); 280 break; 281 case 2: 282 if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB); 283 break; 284 #if defined(PETSC_USE_SOCKET_VIEWER) 285 case 3: 286 if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB); 287 break; 288 #endif 289 #if defined(PETSC_HAVE_MATLAB_ENGINE) 290 case 4: 291 if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB); 292 break; 293 #endif 294 #if defined(PETSC_HAVE_SAWS) 295 case 5: 296 if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB); 297 break; 298 #endif 299 #if defined(PETSC_HAVE_HDF5) 300 case 7: 301 if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB); 302 break; 303 #endif 304 case 8: 305 if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB); 306 break; 307 #if defined(PETSC_HAVE_EXODUSII) 308 case 9: 309 if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB); 310 break; 311 #endif 312 default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype); 313 } 314 PetscCall(PetscObjectReference((PetscObject)*viewer)); 315 } else { 316 if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */ 317 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 318 PetscCall(PetscObjectReference((PetscObject)*viewer)); 319 } else { 320 PetscFileMode fmode; 321 PetscCall(PetscViewerCreate(comm,viewer)); 322 PetscCall(PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii")); 323 fmode = FILE_MODE_WRITE; 324 if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */ 325 PetscCall(PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag)); 326 PetscCheck(flag,comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode); 327 } 328 if (loc2_fmt) { 329 PetscBool tk,im; 330 PetscCall(PetscStrcmp(loc1_fname,"tikz",&tk)); 331 PetscCall(PetscStrcmp(loc1_fname,"image",&im)); 332 if (tk || im) { 333 PetscCall(PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE)); 334 *loc2_fmt = 0; 335 } 336 } 337 PetscCall(PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE)); 338 PetscCall(PetscViewerFileSetName(*viewer,loc1_fname)); 339 if (*loc1_fname) { 340 PetscCall(PetscViewerDrawSetDrawType(*viewer,loc1_fname)); 341 } 342 PetscCall(PetscViewerSetFromOptions(*viewer)); 343 } 344 } 345 } 346 if (viewer) { 347 PetscCall(PetscViewerSetUp(*viewer)); 348 } 349 if (loc2_fmt && *loc2_fmt) { 350 PetscViewerFormat tfmt; 351 352 PetscCall(PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)&tfmt,&flag)); 353 if (format) *format = tfmt; 354 PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt); 355 } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */ 356 PetscCall(PetscViewerGetFormat(*viewer,format)); 357 } 358 PetscCall(PetscFree(loc0_vtype)); 359 } 360 } 361 PetscFunctionReturn(0); 362 } 363 364 /*@ 365 PetscViewerCreate - Creates a viewing context 366 367 Collective 368 369 Input Parameter: 370 . comm - MPI communicator 371 372 Output Parameter: 373 . inviewer - location to put the PetscViewer context 374 375 Level: advanced 376 377 .seealso: `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType` 378 379 @*/ 380 PetscErrorCode PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer) 381 { 382 PetscViewer viewer; 383 384 PetscFunctionBegin; 385 *inviewer = NULL; 386 PetscCall(PetscViewerInitializePackage()); 387 PetscCall(PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,PetscViewerView)); 388 *inviewer = viewer; 389 viewer->data = NULL; 390 PetscFunctionReturn(0); 391 } 392 393 /*@C 394 PetscViewerSetType - Builds PetscViewer for a particular implementation. 395 396 Collective on PetscViewer 397 398 Input Parameters: 399 + viewer - the PetscViewer context 400 - type - for example, PETSCVIEWERASCII 401 402 Options Database Command: 403 . -viewer_type <type> - Sets the type; use -help for a list 404 of available methods (for instance, ascii) 405 406 Level: advanced 407 408 Notes: 409 See "include/petscviewer.h" for available methods (for instance, 410 PETSCVIEWERSOCKET) 411 412 .seealso: `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()` 413 @*/ 414 PetscErrorCode PetscViewerSetType(PetscViewer viewer,PetscViewerType type) 415 { 416 PetscBool match; 417 PetscErrorCode (*r)(PetscViewer); 418 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 421 PetscValidCharPointer(type,2); 422 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,type,&match)); 423 if (match) PetscFunctionReturn(0); 424 425 /* cleanup any old type that may be there */ 426 if (viewer->data) { 427 PetscCall((*viewer->ops->destroy)(viewer)); 428 429 viewer->ops->destroy = NULL; 430 viewer->data = NULL; 431 } 432 PetscCall(PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps))); 433 434 PetscCall(PetscFunctionListFind(PetscViewerList,type,&r)); 435 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type); 436 437 PetscCall(PetscObjectChangeTypeName((PetscObject)viewer,type)); 438 PetscCall((*r)(viewer)); 439 PetscFunctionReturn(0); 440 } 441 442 /*@C 443 PetscViewerRegister - Adds a viewer 444 445 Not Collective 446 447 Input Parameters: 448 + name_solver - name of a new user-defined viewer 449 - routine_create - routine to create method context 450 451 Level: developer 452 Notes: 453 PetscViewerRegister() may be called multiple times to add several user-defined viewers. 454 455 Sample usage: 456 .vb 457 PetscViewerRegister("my_viewer_type",MyViewerCreate); 458 .ve 459 460 Then, your solver can be chosen with the procedural interface via 461 $ PetscViewerSetType(viewer,"my_viewer_type") 462 or at runtime via the option 463 $ -viewer_type my_viewer_type 464 465 .seealso: `PetscViewerRegisterAll()` 466 @*/ 467 PetscErrorCode PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer)) 468 { 469 PetscFunctionBegin; 470 PetscCall(PetscViewerInitializePackage()); 471 PetscCall(PetscFunctionListAdd(&PetscViewerList,sname,function)); 472 PetscFunctionReturn(0); 473 } 474 475 /*@C 476 PetscViewerSetFromOptions - Sets the graphics type from the options database. 477 Defaults to a PETSc X windows graphics. 478 479 Collective on PetscViewer 480 481 Input Parameter: 482 . PetscViewer - the graphics context 483 484 Level: intermediate 485 486 Notes: 487 Must be called after PetscViewerCreate() before the PetscViewer is used. 488 489 .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType` 490 491 @*/ 492 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer) 493 { 494 char vtype[256]; 495 PetscBool flg; 496 497 PetscFunctionBegin; 498 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 499 500 if (!PetscViewerList) { 501 PetscCall(PetscViewerRegisterAll()); 502 } 503 PetscObjectOptionsBegin((PetscObject)viewer); 504 PetscCall(PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg)); 505 if (flg) { 506 PetscCall(PetscViewerSetType(viewer,vtype)); 507 } 508 /* type has not been set? */ 509 if (!((PetscObject)viewer)->type_name) { 510 PetscCall(PetscViewerSetType(viewer,PETSCVIEWERASCII)); 511 } 512 if (viewer->ops->setfromoptions) { 513 PetscCall((*viewer->ops->setfromoptions)(PetscOptionsObject,viewer)); 514 } 515 516 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 517 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer)); 518 PetscCall(PetscViewerViewFromOptions(viewer,NULL,"-viewer_view")); 519 PetscOptionsEnd(); 520 PetscFunctionReturn(0); 521 } 522 523 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt) 524 { 525 PetscFunctionBegin; 526 PetscCall(PetscViewerBinaryGetFlowControl(viewer,mcnt)); 527 PetscCall(PetscViewerBinaryGetFlowControl(viewer,cnt)); 528 PetscFunctionReturn(0); 529 } 530 531 PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt) 532 { 533 MPI_Comm comm; 534 535 PetscFunctionBegin; 536 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 537 if (i >= *mcnt) { 538 *mcnt += cnt; 539 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 540 } 541 PetscFunctionReturn(0); 542 } 543 544 PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer,PetscInt *mcnt) 545 { 546 MPI_Comm comm; 547 PetscFunctionBegin; 548 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 549 *mcnt = 0; 550 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 551 PetscFunctionReturn(0); 552 } 553 554 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt) 555 { 556 MPI_Comm comm; 557 PetscFunctionBegin; 558 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 559 while (PETSC_TRUE) { 560 if (rank < *mcnt) break; 561 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 562 } 563 PetscFunctionReturn(0); 564 } 565 566 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt) 567 { 568 MPI_Comm comm; 569 PetscFunctionBegin; 570 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 571 while (PETSC_TRUE) { 572 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 573 if (!*mcnt) break; 574 } 575 PetscFunctionReturn(0); 576 } 577