1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #include <fcntl.h> 4 #if defined(PETSC_HAVE_UNISTD_H) 5 #include <unistd.h> 6 #endif 7 #if defined(PETSC_HAVE_IO_H) 8 #include <io.h> 9 #endif 10 11 typedef struct { 12 int fdes; /* file descriptor, ignored if using MPI IO */ 13 #if defined(PETSC_HAVE_MPIIO) 14 PetscBool usempiio; 15 MPI_File mfdes; /* ignored unless using MPI IO */ 16 MPI_Offset moff; 17 #endif 18 PetscFileMode btype; /* read or write? */ 19 FILE *fdes_info; /* optional file containing info on binary file*/ 20 PetscBool storecompressed; /* gzip the write binary file when closing it*/ 21 char *filename; 22 char *ogzfilename; /* gzip can be run after the filename has been updated */ 23 PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */ 24 PetscBool skipoptions; /* don't use PETSc options database when loading */ 25 PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */ 26 PetscBool skipheader; /* don't write header, only raw data */ 27 PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */ 28 PetscBool setfromoptionscalled; 29 } PetscViewer_Binary; 30 31 static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 32 { 33 int rank; 34 PetscErrorCode ierr; 35 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary; 36 37 PetscFunctionBegin; 38 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 39 #if defined(PETSC_HAVE_MPIIO) 40 if (vbinary->usempiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Not yet implemented for binary viewers using MPI I/O"); 41 #endif 42 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 43 if (!rank) { 44 ierr = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr); 45 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);CHKERRQ(ierr); 46 obinary = (PetscViewer_Binary*)(*outviewer)->data; 47 ierr = PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));CHKERRQ(ierr); 48 (*outviewer)->setupcalled = PETSC_TRUE; 49 } else { 50 *outviewer = NULL; 51 } 52 PetscFunctionReturn(0); 53 } 54 55 static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 56 { 57 PetscErrorCode ierr; 58 PetscErrorCode rank; 59 60 PetscFunctionBegin; 61 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 62 if (!rank) { 63 ierr = PetscFree((*outviewer)->data);CHKERRQ(ierr); 64 ierr = PetscHeaderDestroy(outviewer);CHKERRQ(ierr); 65 } 66 PetscFunctionReturn(0); 67 } 68 69 #if defined(PETSC_HAVE_MPIIO) 70 /*@C 71 PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view() 72 73 Not Collective 74 75 Input Parameter: 76 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 77 78 Output Parameter: 79 . off - the current offset 80 81 Level: advanced 82 83 Fortran Note: 84 This routine is not supported in Fortran. 85 86 Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view. 87 88 Concepts: file descriptor^getting 89 Concepts: PetscViewerBinary^accessing file descriptor 90 91 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset() 92 @*/ 93 PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off) 94 { 95 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 96 97 PetscFunctionBegin; 98 *off = vbinary->moff; 99 PetscFunctionReturn(0); 100 } 101 102 /*@C 103 PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view() 104 105 Not Collective 106 107 Input Parameters: 108 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 109 - off - the addition to the offset 110 111 Level: advanced 112 113 Fortran Note: 114 This routine is not supported in Fortran. 115 116 Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() 117 118 Concepts: file descriptor^getting 119 Concepts: PetscViewerBinary^accessing file descriptor 120 121 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 122 @*/ 123 PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off) 124 { 125 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 126 127 PetscFunctionBegin; 128 vbinary->moff += off; 129 PetscFunctionReturn(0); 130 } 131 132 /*@C 133 PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer. 134 135 Not Collective 136 137 Input Parameter: 138 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 139 140 Output Parameter: 141 . fdes - file descriptor 142 143 Level: advanced 144 145 Fortran Note: 146 This routine is not supported in Fortran. 147 148 Concepts: file descriptor^getting 149 Concepts: PetscViewerBinary^accessing file descriptor 150 151 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 152 @*/ 153 PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes) 154 { 155 PetscErrorCode ierr; 156 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 157 158 PetscFunctionBegin; 159 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 160 *fdes = vbinary->mfdes; 161 PetscFunctionReturn(0); 162 } 163 164 static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg) 165 { 166 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 167 168 PetscFunctionBegin; 169 *flg = vbinary->usempiio; 170 PetscFunctionReturn(0); 171 } 172 #endif 173 174 175 /*@C 176 PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO. 177 178 Not Collective 179 180 Input Parameter: 181 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 182 183 Output Parameter: 184 - flg - PETSC_TRUE if MPI-IO is being used 185 186 Options Database: 187 -viewer_binary_mpiio : Flag for using MPI-IO 188 189 Level: advanced 190 191 Note: 192 If MPI-IO is not available, this function will always return PETSC_FALSE 193 194 Fortran Note: 195 This routine is not supported in Fortran. 196 197 Concepts: file descriptor^getting 198 Concepts: PetscViewerBinary^accessing file descriptor 199 200 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 201 @*/ 202 PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg) 203 { 204 PetscErrorCode ierr; 205 206 PetscFunctionBegin; 207 *flg = PETSC_FALSE; 208 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));CHKERRQ(ierr); 209 PetscFunctionReturn(0); 210 } 211 212 static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc) 213 { 214 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 215 216 PetscFunctionBegin; 217 *fc = vbinary->flowcontrol; 218 PetscFunctionReturn(0); 219 } 220 221 /*@C 222 PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes 223 224 Not Collective 225 226 Input Parameter: 227 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 228 229 Output Parameter: 230 . fc - the number of messages 231 232 Level: advanced 233 234 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl() 235 236 @*/ 237 PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc) 238 { 239 PetscErrorCode ierr; 240 241 PetscFunctionBegin; 242 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr); 243 PetscFunctionReturn(0); 244 } 245 246 static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc) 247 { 248 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 249 250 PetscFunctionBegin; 251 if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc); 252 vbinary->flowcontrol = fc; 253 PetscFunctionReturn(0); 254 } 255 256 /*@C 257 PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes 258 259 Not Collective 260 261 Input Parameter: 262 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 263 - fc - the number of messages, defaults to 256 if this function was not called 264 265 Level: advanced 266 267 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl() 268 269 @*/ 270 PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc) 271 { 272 PetscErrorCode ierr; 273 274 PetscFunctionBegin; 275 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr); 276 PetscFunctionReturn(0); 277 } 278 279 /*@C 280 PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer. 281 282 Collective On PetscViewer 283 284 Input Parameter: 285 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 286 287 Output Parameter: 288 . fdes - file descriptor 289 290 Level: advanced 291 292 Notes: 293 For writable binary PetscViewers, the descriptor will only be valid for the 294 first processor in the communicator that shares the PetscViewer. For readable 295 files it will only be valid on nodes that have the file. If node 0 does not 296 have the file it generates an error even if another node does have the file. 297 298 Fortran Note: 299 This routine is not supported in Fortran. 300 301 Developer Notes: This must be called on all processes because Dave May changed 302 the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered. 303 304 305 Concepts: file descriptor^getting 306 Concepts: PetscViewerBinary^accessing file descriptor 307 308 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer() 309 @*/ 310 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes) 311 { 312 PetscErrorCode ierr; 313 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 314 315 PetscFunctionBegin; 316 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 317 *fdes = vbinary->fdes; 318 PetscFunctionReturn(0); 319 } 320 321 /*@ 322 PetscViewerBinarySkipInfo - Binary file will not have .info file created with it 323 324 Not Collective 325 326 Input Paramter: 327 . viewer - PetscViewer context, obtained from PetscViewerCreate() 328 329 Options Database Key: 330 . -viewer_binary_skip_info 331 332 Level: advanced 333 334 Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then 335 you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the 336 viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo(). 337 338 The .info contains meta information about the data in the binary file, for example the block size if it was 339 set for a vector or matrix. 340 341 Concepts: PetscViewerBinary^accessing info file 342 343 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 344 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo() 345 @*/ 346 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer) 347 { 348 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 349 350 PetscFunctionBegin; 351 vbinary->skipinfo = PETSC_TRUE; 352 PetscFunctionReturn(0); 353 } 354 355 static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip) 356 { 357 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 358 359 PetscFunctionBegin; 360 vbinary->skipinfo = skip; 361 PetscFunctionReturn(0); 362 } 363 364 /*@ 365 PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it 366 367 Not Collective 368 369 Input Paramter: 370 . viewer - PetscViewer context, obtained from PetscViewerCreate() 371 372 Options Database Key: 373 . -viewer_binary_skip_info 374 375 Level: advanced 376 377 Concepts: PetscViewerBinary^accessing info file 378 379 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 380 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo() 381 @*/ 382 PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip) 383 { 384 PetscErrorCode ierr; 385 386 PetscFunctionBegin; 387 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 388 PetscFunctionReturn(0); 389 } 390 391 static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip) 392 { 393 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 394 395 PetscFunctionBegin; 396 *skip = vbinary->skipinfo; 397 PetscFunctionReturn(0); 398 } 399 400 /*@ 401 PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file 402 403 Not Collective 404 405 Input Parameter: 406 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 407 408 Output Parameter: 409 . skip - PETSC_TRUE implies the .info file was not generated 410 411 Level: advanced 412 413 Notes: This must be called after PetscViewerSetType() 414 415 Concepts: PetscViewerBinary^accessing info file 416 417 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 418 PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo() 419 @*/ 420 PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip) 421 { 422 PetscErrorCode ierr; 423 424 PetscFunctionBegin; 425 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 426 PetscFunctionReturn(0); 427 } 428 429 static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip) 430 { 431 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 432 433 PetscFunctionBegin; 434 vbinary->skipoptions = skip; 435 PetscFunctionReturn(0); 436 } 437 438 /*@ 439 PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects 440 441 Not Collective 442 443 Input Parameters: 444 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 445 - skip - PETSC_TRUE means do not use 446 447 Options Database Key: 448 . -viewer_binary_skip_options 449 450 Level: advanced 451 452 Notes: This must be called after PetscViewerSetType() 453 454 Concepts: PetscViewerBinary^accessing info file 455 456 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 457 PetscViewerBinaryGetSkipOptions() 458 @*/ 459 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip) 460 { 461 PetscErrorCode ierr; 462 463 PetscFunctionBegin; 464 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 465 PetscFunctionReturn(0); 466 } 467 468 static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip) 469 { 470 PetscViewer_Binary *vbinary; 471 472 PetscFunctionBegin; 473 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 474 vbinary = (PetscViewer_Binary*)viewer->data; 475 *skip = vbinary->skipoptions; 476 PetscFunctionReturn(0); 477 } 478 479 /*@ 480 PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects 481 482 Not Collective 483 484 Input Parameter: 485 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 486 487 Output Parameter: 488 . skip - PETSC_TRUE means do not use 489 490 Level: advanced 491 492 Notes: This must be called after PetscViewerSetType() 493 494 Concepts: PetscViewerBinary^accessing info file 495 496 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 497 PetscViewerBinarySetSkipOptions() 498 @*/ 499 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip) 500 { 501 PetscErrorCode ierr; 502 503 PetscFunctionBegin; 504 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 505 PetscFunctionReturn(0); 506 } 507 508 static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip) 509 { 510 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 511 512 PetscFunctionBegin; 513 vbinary->skipheader = skip; 514 PetscFunctionReturn(0); 515 } 516 517 /*@ 518 PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data 519 520 Not Collective 521 522 Input Parameters: 523 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 524 - skip - PETSC_TRUE means do not write header 525 526 Options Database Key: 527 . -viewer_binary_skip_header 528 529 Level: advanced 530 531 Notes: This must be called after PetscViewerSetType() 532 533 Can ONLY be called on a binary viewer 534 535 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 536 PetscViewerBinaryGetSkipHeader() 537 @*/ 538 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip) 539 { 540 PetscErrorCode ierr; 541 542 PetscFunctionBegin; 543 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 544 PetscFunctionReturn(0); 545 } 546 547 static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip) 548 { 549 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 550 551 PetscFunctionBegin; 552 *skip = vbinary->skipheader; 553 PetscFunctionReturn(0); 554 } 555 556 /*@ 557 PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data 558 559 Not Collective 560 561 Input Parameter: 562 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 563 564 Output Parameter: 565 . skip - PETSC_TRUE means do not write header 566 567 Level: advanced 568 569 Notes: This must be called after PetscViewerSetType() 570 571 Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it. 572 573 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 574 PetscViewerBinarySetSkipHeader() 575 @*/ 576 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip) 577 { 578 PetscErrorCode ierr; 579 580 PetscFunctionBegin; 581 *skip = PETSC_FALSE; 582 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 583 PetscFunctionReturn(0); 584 } 585 586 static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file) 587 { 588 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 589 PetscErrorCode ierr; 590 MPI_Comm comm; 591 592 PetscFunctionBegin; 593 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 594 *file = vbinary->fdes_info; 595 if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) { 596 vbinary->matlabheaderwritten = PETSC_TRUE; 597 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 598 ierr = PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 599 ierr = PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr); 600 ierr = PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr); 601 ierr = PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 602 } 603 PetscFunctionReturn(0); 604 } 605 606 /*@C 607 PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII 608 info file associated with a binary file. 609 610 Not Collective 611 612 Input Parameter: 613 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 614 615 Output Parameter: 616 . file - file pointer Always returns NULL if not a binary viewer 617 618 Level: advanced 619 620 Notes: 621 For writable binary PetscViewers, the descriptor will only be valid for the 622 first processor in the communicator that shares the PetscViewer. 623 624 Fortran Note: 625 This routine is not supported in Fortran. 626 627 Concepts: PetscViewerBinary^accessing info file 628 629 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor() 630 @*/ 631 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file) 632 { 633 PetscErrorCode ierr; 634 635 PetscFunctionBegin; 636 *file = NULL; 637 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr); 638 PetscFunctionReturn(0); 639 } 640 641 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v) 642 { 643 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 644 PetscErrorCode ierr; 645 PetscMPIInt rank; 646 int err; 647 648 PetscFunctionBegin; 649 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr); 650 if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) { 651 close(vbinary->fdes); 652 if (!rank && vbinary->storecompressed) { 653 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 654 FILE *fp; 655 /* compress the file */ 656 ierr = PetscStrncpy(par,"gzip -f ",sizeof(par));CHKERRQ(ierr); 657 ierr = PetscStrlcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename,sizeof(par));CHKERRQ(ierr); 658 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 659 #if defined(PETSC_HAVE_POPEN) 660 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 661 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf); 662 ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 663 #else 664 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 665 #endif 666 } 667 } 668 if (vbinary->fdes_info) { 669 err = fclose(vbinary->fdes_info); 670 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 671 } 672 PetscFunctionReturn(0); 673 } 674 675 #if defined(PETSC_HAVE_MPIIO) 676 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v) 677 { 678 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 679 int err; 680 PetscErrorCode ierr; 681 682 PetscFunctionBegin; 683 if (vbinary->mfdes) { 684 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr); 685 } 686 if (vbinary->fdes_info) { 687 err = fclose(vbinary->fdes_info); 688 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 689 } 690 PetscFunctionReturn(0); 691 } 692 #endif 693 694 static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v) 695 { 696 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 697 PetscErrorCode ierr; 698 699 PetscFunctionBegin; 700 if (v->format == PETSC_VIEWER_BINARY_MATLAB) { 701 MPI_Comm comm; 702 FILE *info; 703 704 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 705 ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr); 706 ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 707 ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr); 708 ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 709 } 710 #if defined(PETSC_HAVE_MPIIO) 711 if (vbinary->usempiio) { 712 ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr); 713 } else { 714 #endif 715 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr); 716 #if defined(PETSC_HAVE_MPIIO) 717 } 718 #endif 719 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 720 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 721 ierr = PetscFree(vbinary);CHKERRQ(ierr); 722 PetscFunctionReturn(0); 723 } 724 725 /*@C 726 PetscViewerBinaryOpen - Opens a file for binary input/output. 727 728 Collective on MPI_Comm 729 730 Input Parameters: 731 + comm - MPI communicator 732 . name - name of file 733 - type - type of file 734 $ FILE_MODE_WRITE - create new file for binary output 735 $ FILE_MODE_READ - open existing file for binary input 736 $ FILE_MODE_APPEND - open existing file for binary output 737 738 Output Parameter: 739 . binv - PetscViewer for binary input/output to use with the specified file 740 741 Options Database Keys: 742 + -viewer_binary_filename <name> 743 . -viewer_binary_skip_info 744 . -viewer_binary_skip_options 745 . -viewer_binary_skip_header 746 - -viewer_binary_mpiio 747 748 Level: beginner 749 750 Note: 751 This PetscViewer should be destroyed with PetscViewerDestroy(). 752 753 For reading files, the filename may begin with ftp:// or http:// and/or 754 end with .gz; in this case file is brought over and uncompressed. 755 756 For creating files, if the file name ends with .gz it is automatically 757 compressed when closed. 758 759 For writing files it only opens the file on processor 0 in the communicator. 760 For readable files it opens the file on all nodes that have the file. If 761 node 0 does not have the file it generates an error even if other nodes 762 do have the file. 763 764 Concepts: binary files 765 Concepts: PetscViewerBinary^creating 766 Concepts: gzip 767 Concepts: accessing remote file 768 Concepts: remote file 769 770 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 771 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 772 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(), 773 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 774 @*/ 775 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 776 { 777 PetscErrorCode ierr; 778 779 PetscFunctionBegin; 780 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 781 ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr); 782 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 783 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 784 ierr = PetscViewerSetFromOptions(*binv);CHKERRQ(ierr); 785 PetscFunctionReturn(0); 786 } 787 788 #if defined(PETSC_HAVE_MPIIO) 789 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write) 790 { 791 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 792 PetscErrorCode ierr; 793 MPI_Datatype mdtype; 794 PetscMPIInt cnt; 795 MPI_Status status; 796 MPI_Aint ul,dsize; 797 798 PetscFunctionBegin; 799 ierr = PetscMPIIntCast(num,&cnt);CHKERRQ(ierr); 800 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 801 ierr = MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 802 if (write) { 803 ierr = MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 804 } else { 805 ierr = MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 806 } 807 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 808 809 vbinary->moff += dsize*cnt; 810 if (count) *count = num; 811 PetscFunctionReturn(0); 812 } 813 #endif 814 815 /*@C 816 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 817 818 Collective on MPI_Comm 819 820 Input Parameters: 821 + viewer - the binary viewer 822 . data - location of the data to be written 823 . num - number of items of data to read 824 - dtype - type of data to read 825 826 Output Parameters: 827 . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num. 828 829 Level: beginner 830 831 Concepts: binary files 832 833 Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves. 834 835 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 836 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 837 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 838 @*/ 839 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 840 { 841 PetscErrorCode ierr; 842 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 843 844 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 845 #if defined(PETSC_HAVE_MPIIO) 846 if (vbinary->usempiio) { 847 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 848 } else { 849 #endif 850 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);CHKERRQ(ierr); 851 if (count) *count = num; 852 #if defined(PETSC_HAVE_MPIIO) 853 } 854 #endif 855 PetscFunctionReturn(0); 856 } 857 858 /*@C 859 PetscViewerBinaryWrite - writes to a binary file, only from the first process 860 861 Collective on MPI_Comm 862 863 Input Parameters: 864 + viewer - the binary viewer 865 . data - location of data 866 . count - number of items of data to write 867 . dtype - type of data to write 868 - istemp - data may be overwritten 869 870 Level: beginner 871 872 Notes: because byte-swapping may be done on the values in data it cannot be declared const 873 874 Concepts: binary files 875 876 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 877 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 878 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 879 @*/ 880 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 881 { 882 PetscErrorCode ierr; 883 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 884 885 PetscFunctionBegin; 886 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 887 #if defined(PETSC_HAVE_MPIIO) 888 if (vbinary->usempiio) { 889 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr); 890 } else { 891 #endif 892 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 893 #if defined(PETSC_HAVE_MPIIO) 894 } 895 #endif 896 PetscFunctionReturn(0); 897 } 898 899 /*@C 900 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 901 902 Collective on MPI_Comm 903 904 Input Parameters: 905 + viewer - the binary viewer 906 - data - location of the array of strings 907 908 909 Level: intermediate 910 911 Concepts: binary files 912 913 Notes: array of strings is null terminated 914 915 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 916 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 917 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 918 @*/ 919 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 920 { 921 PetscErrorCode ierr; 922 PetscInt i,n = 0,*sizes; 923 924 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 925 /* count number of strings */ 926 while (data[n++]) ; 927 n--; 928 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 929 sizes[0] = n; 930 for (i=0; i<n; i++) { 931 size_t tmp; 932 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 933 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 934 } 935 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 936 for (i=0; i<n; i++) { 937 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 938 } 939 ierr = PetscFree(sizes);CHKERRQ(ierr); 940 PetscFunctionReturn(0); 941 } 942 943 /*@C 944 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 945 946 Collective on MPI_Comm 947 948 Input Parameter: 949 . viewer - the binary viewer 950 951 Output Parameter: 952 . data - location of the array of strings 953 954 Level: intermediate 955 956 Concepts: binary files 957 958 Notes: array of strings is null terminated 959 960 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 961 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 962 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 963 @*/ 964 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 965 { 966 PetscErrorCode ierr; 967 PetscInt i,n,*sizes,N = 0; 968 969 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 970 /* count number of strings */ 971 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 972 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 973 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 974 for (i=0; i<n; i++) N += sizes[i]; 975 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 976 (*data)[0] = (char*)((*data) + n + 1); 977 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 978 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 979 980 (*data)[n] = 0; 981 982 ierr = PetscFree(sizes);CHKERRQ(ierr); 983 PetscFunctionReturn(0); 984 } 985 986 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 987 { 988 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 989 990 PetscFunctionBegin; 991 *name = vbinary->filename; 992 PetscFunctionReturn(0); 993 } 994 995 /*@C 996 PetscViewerFileGetMode - Gets the type of file to be open 997 998 Not Collective 999 1000 Input Parameter: 1001 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1002 1003 Output Parameter: 1004 . type - type of file 1005 $ FILE_MODE_WRITE - create new file for binary output 1006 $ FILE_MODE_READ - open existing file for binary input 1007 $ FILE_MODE_APPEND - open existing file for binary output 1008 1009 Level: advanced 1010 1011 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1012 1013 @*/ 1014 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 1015 { 1016 PetscErrorCode ierr; 1017 1018 PetscFunctionBegin; 1019 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1020 PetscValidPointer(type,2); 1021 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 1022 PetscFunctionReturn(0); 1023 } 1024 1025 /*@ 1026 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called 1027 before PetscViewerFileSetName() 1028 1029 Logically Collective on PetscViewer 1030 1031 Input Parameters: 1032 + viewer - the PetscViewer; must be a binary 1033 - flg - PETSC_TRUE means MPI-IO will be used 1034 1035 Options Database: 1036 -viewer_binary_mpiio : Flag for using MPI-IO 1037 1038 Level: advanced 1039 1040 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(), 1041 PetscViewerBinaryGetUseMPIIO() 1042 1043 @*/ 1044 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg) 1045 { 1046 PetscErrorCode ierr; 1047 1048 PetscFunctionBegin; 1049 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1050 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr); 1051 PetscFunctionReturn(0); 1052 } 1053 1054 /*@C 1055 PetscViewerFileSetMode - Sets the type of file to be open 1056 1057 Logically Collective on PetscViewer 1058 1059 Input Parameters: 1060 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1061 - type - type of file 1062 $ FILE_MODE_WRITE - create new file for binary output 1063 $ FILE_MODE_READ - open existing file for binary input 1064 $ FILE_MODE_APPEND - open existing file for binary output 1065 1066 Level: advanced 1067 1068 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1069 1070 @*/ 1071 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1072 { 1073 PetscErrorCode ierr; 1074 1075 PetscFunctionBegin; 1076 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1077 PetscValidLogicalCollectiveEnum(viewer,type,2); 1078 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1079 PetscFunctionReturn(0); 1080 } 1081 1082 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1083 { 1084 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1085 1086 PetscFunctionBegin; 1087 *type = vbinary->btype; 1088 PetscFunctionReturn(0); 1089 } 1090 1091 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1092 { 1093 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1094 1095 PetscFunctionBegin; 1096 vbinary->btype = type; 1097 PetscFunctionReturn(0); 1098 } 1099 1100 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1101 { 1102 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1103 PetscErrorCode ierr; 1104 1105 PetscFunctionBegin; 1106 if (vbinary->filename) { 1107 /* gzip can be run after the file with the previous filename has been closed */ 1108 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 1109 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr); 1110 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 1111 viewer->setupcalled = PETSC_FALSE; 1112 } 1113 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1114 PetscFunctionReturn(0); 1115 } 1116 /* 1117 Actually opens the file 1118 */ 1119 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1120 { 1121 PetscMPIInt rank; 1122 PetscErrorCode ierr; 1123 size_t len; 1124 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1125 const char *fname; 1126 char bname[PETSC_MAX_PATH_LEN],*gz; 1127 PetscBool found; 1128 PetscFileMode type = vbinary->btype; 1129 1130 PetscFunctionBegin; 1131 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1132 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1133 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1134 1135 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1136 1137 /* if ends in .gz strip that off and note user wants file compressed */ 1138 vbinary->storecompressed = PETSC_FALSE; 1139 if (!rank && type == FILE_MODE_WRITE) { 1140 /* remove .gz if it ends library name */ 1141 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1142 if (gz) { 1143 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1144 if (len == 3) { 1145 *gz = 0; 1146 vbinary->storecompressed = PETSC_TRUE; 1147 } 1148 } 1149 } 1150 1151 /* only first processor opens file if writeable */ 1152 if (!rank || type == FILE_MODE_READ) { 1153 1154 if (type == FILE_MODE_READ) { 1155 /* possibly get the file from remote site or compressed file */ 1156 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1157 fname = bname; 1158 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1159 else if (!found) { 1160 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1161 fname = 0; 1162 } 1163 } else fname = vbinary->filename; 1164 1165 #if defined(PETSC_HAVE_O_BINARY) 1166 if (type == FILE_MODE_WRITE) { 1167 if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1168 } else if (type == FILE_MODE_READ && fname) { 1169 if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1170 } else if (type == FILE_MODE_APPEND) { 1171 if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname); 1172 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1173 #else 1174 if (type == FILE_MODE_WRITE) { 1175 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1176 } else if (type == FILE_MODE_READ && fname) { 1177 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1178 } else if (type == FILE_MODE_APPEND) { 1179 if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname); 1180 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1181 #endif 1182 } else vbinary->fdes = -1; 1183 1184 /* 1185 try to open info file: all processors open this file if read only 1186 */ 1187 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1188 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1189 1190 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1191 /* remove .gz if it ends library name */ 1192 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1193 if (gz) { 1194 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1195 if (len == 3) *gz = 0; 1196 } 1197 1198 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1199 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1200 if (type == FILE_MODE_READ) { 1201 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1202 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1203 } else { 1204 vbinary->fdes_info = fopen(infoname,"w"); 1205 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1206 } 1207 } 1208 #if defined(PETSC_USE_LOG) 1209 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1210 #endif 1211 PetscFunctionReturn(0); 1212 } 1213 1214 #if defined(PETSC_HAVE_MPIIO) 1215 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1216 { 1217 PetscMPIInt rank; 1218 PetscErrorCode ierr; 1219 size_t len; 1220 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1221 char *gz; 1222 PetscBool found; 1223 PetscFileMode type = vbinary->btype; 1224 1225 PetscFunctionBegin; 1226 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1227 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1228 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1229 1230 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1231 1232 vbinary->storecompressed = PETSC_FALSE; 1233 1234 /* only first processor opens file if writeable */ 1235 if (type == FILE_MODE_READ) { 1236 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1237 } else if (type == FILE_MODE_WRITE) { 1238 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1239 } 1240 1241 /* 1242 try to open info file: all processors open this file if read only 1243 1244 Below is identical code to the code for Binary above, should be put in separate routine 1245 */ 1246 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1247 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1248 1249 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1250 /* remove .gz if it ends library name */ 1251 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1252 if (gz) { 1253 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1254 if (len == 3) *gz = 0; 1255 } 1256 1257 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1258 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1259 if (type == FILE_MODE_READ) { 1260 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1261 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1262 } else { 1263 vbinary->fdes_info = fopen(infoname,"w"); 1264 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1265 } 1266 } 1267 #if defined(PETSC_USE_LOG) 1268 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1269 #endif 1270 PetscFunctionReturn(0); 1271 } 1272 1273 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg) 1274 { 1275 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1276 PetscFunctionBegin; 1277 vbinary->usempiio = flg; 1278 PetscFunctionReturn(0); 1279 } 1280 #endif 1281 1282 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1283 { 1284 PetscErrorCode ierr; 1285 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1286 1287 PetscFunctionBegin; 1288 if (binary->filename) { 1289 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1290 } 1291 PetscFunctionReturn(0); 1292 } 1293 1294 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1295 { 1296 PetscErrorCode ierr; 1297 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1298 1299 PetscFunctionBegin; 1300 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1301 1302 #if defined(PETSC_HAVE_MPIIO) 1303 if (binary->usempiio) { 1304 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1305 } else { 1306 #endif 1307 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1308 #if defined(PETSC_HAVE_MPIIO) 1309 } 1310 #endif 1311 PetscFunctionReturn(0); 1312 } 1313 1314 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v) 1315 { 1316 PetscErrorCode ierr; 1317 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1318 char defaultname[PETSC_MAX_PATH_LEN]; 1319 PetscBool flg; 1320 1321 PetscFunctionBegin; 1322 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1323 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1324 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1325 if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); } 1326 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);CHKERRQ(ierr); 1327 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);CHKERRQ(ierr); 1328 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);CHKERRQ(ierr); 1329 #if defined(PETSC_HAVE_MPIIO) 1330 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);CHKERRQ(ierr); 1331 #elif defined(PETSC_HAVE_MPIUNI) 1332 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1333 #endif 1334 ierr = PetscOptionsTail();CHKERRQ(ierr); 1335 binary->setfromoptionscalled = PETSC_TRUE; 1336 PetscFunctionReturn(0); 1337 } 1338 1339 /*MC 1340 PETSCVIEWERBINARY - A viewer that saves to binary files 1341 1342 1343 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1344 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1345 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1346 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1347 1348 Level: beginner 1349 1350 M*/ 1351 1352 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1353 { 1354 PetscErrorCode ierr; 1355 PetscViewer_Binary *vbinary; 1356 1357 PetscFunctionBegin; 1358 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1359 v->data = (void*)vbinary; 1360 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1361 v->ops->destroy = PetscViewerDestroy_Binary; 1362 v->ops->view = PetscViewerView_Binary; 1363 v->ops->setup = PetscViewerSetUp_Binary; 1364 v->ops->flush = NULL; 1365 vbinary->fdes_info = 0; 1366 vbinary->fdes = 0; 1367 vbinary->skipinfo = PETSC_FALSE; 1368 vbinary->skipoptions = PETSC_TRUE; 1369 vbinary->skipheader = PETSC_FALSE; 1370 vbinary->setfromoptionscalled = PETSC_FALSE; 1371 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1372 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1373 v->ops->read = PetscViewerBinaryRead; 1374 vbinary->btype = (PetscFileMode) -1; 1375 vbinary->storecompressed = PETSC_FALSE; 1376 vbinary->filename = NULL; 1377 vbinary->ogzfilename = NULL; 1378 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1379 1380 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1381 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1382 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1383 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1384 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1385 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1386 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1387 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1388 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1389 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1390 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1391 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1392 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1393 #if defined(PETSC_HAVE_MPIIO) 1394 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1395 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1396 #endif 1397 PetscFunctionReturn(0); 1398 } 1399 1400 /* ---------------------------------------------------------------------*/ 1401 /* 1402 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1403 is attached to a communicator, in this case the attribute is a PetscViewer. 1404 */ 1405 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1406 1407 /*@C 1408 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1409 in a communicator. 1410 1411 Collective on MPI_Comm 1412 1413 Input Parameter: 1414 . comm - the MPI communicator to share the binary PetscViewer 1415 1416 Level: intermediate 1417 1418 Options Database Keys: 1419 + -viewer_binary_filename <name> 1420 . -viewer_binary_skip_info 1421 . -viewer_binary_skip_options 1422 . -viewer_binary_skip_header 1423 - -viewer_binary_mpiio 1424 1425 Environmental variables: 1426 - PETSC_VIEWER_BINARY_FILENAME 1427 1428 Notes: 1429 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1430 an error code. The binary PetscViewer is usually used in the form 1431 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1432 1433 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1434 PetscViewerDestroy() 1435 @*/ 1436 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1437 { 1438 PetscErrorCode ierr; 1439 PetscBool flg; 1440 PetscViewer viewer; 1441 char fname[PETSC_MAX_PATH_LEN]; 1442 MPI_Comm ncomm; 1443 1444 PetscFunctionBegin; 1445 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1446 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1447 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1448 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1449 } 1450 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1451 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1452 if (!flg) { /* PetscViewer not yet created */ 1453 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1454 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1455 if (!flg) { 1456 ierr = PetscStrcpy(fname,"binaryoutput"); 1457 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1458 } 1459 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1460 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1461 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1462 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1463 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1464 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1465 } 1466 ierr = PetscCommDestroy(&ncomm); 1467 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1468 PetscFunctionReturn(viewer); 1469 } 1470