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