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