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