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