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