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(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset() 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(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 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(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 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(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 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(), PetscViewerBinarySetUseMPIIO(), 764 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 765 @*/ 766 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 767 { 768 PetscErrorCode ierr; 769 770 PetscFunctionBegin; 771 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 772 ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr); 773 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 774 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 775 ierr = PetscViewerSetFromOptions(*binv);CHKERRQ(ierr); 776 PetscFunctionReturn(0); 777 } 778 779 #if defined(PETSC_HAVE_MPIIO) 780 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write) 781 { 782 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 783 PetscErrorCode ierr; 784 MPI_Datatype mdtype; 785 PetscMPIInt cnt; 786 MPI_Status status; 787 MPI_Aint ul,dsize; 788 789 PetscFunctionBegin; 790 ierr = PetscMPIIntCast(num,&cnt);CHKERRQ(ierr); 791 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 792 ierr = MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 793 if (write) { 794 ierr = MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 795 } else { 796 ierr = MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 797 } 798 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 799 800 vbinary->moff += dsize*cnt; 801 if (count) *count = num; 802 PetscFunctionReturn(0); 803 } 804 #endif 805 806 /*@C 807 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 808 809 Collective on MPI_Comm 810 811 Input Parameters: 812 + viewer - the binary viewer 813 . data - location of the data to be written 814 . num - number of items of data to read 815 - dtype - type of data to read 816 817 Output Parameters: 818 . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num. 819 820 Level: beginner 821 822 Concepts: binary files 823 824 Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves. 825 826 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 827 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 828 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 829 @*/ 830 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 831 { 832 PetscErrorCode ierr; 833 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 834 835 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 836 #if defined(PETSC_HAVE_MPIIO) 837 if (vbinary->usempiio) { 838 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 839 } else { 840 #endif 841 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);CHKERRQ(ierr); 842 if (count) *count = num; 843 #if defined(PETSC_HAVE_MPIIO) 844 } 845 #endif 846 PetscFunctionReturn(0); 847 } 848 849 /*@C 850 PetscViewerBinaryWrite - writes to a binary file, only from the first process 851 852 Collective on MPI_Comm 853 854 Input Parameters: 855 + viewer - the binary viewer 856 . data - location of data 857 . count - number of items of data to write 858 . dtype - type of data to write 859 - istemp - data may be overwritten 860 861 Level: beginner 862 863 Notes: because byte-swapping may be done on the values in data it cannot be declared const 864 865 Concepts: binary files 866 867 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 868 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 869 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 870 @*/ 871 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 872 { 873 PetscErrorCode ierr; 874 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 875 876 PetscFunctionBegin; 877 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 878 #if defined(PETSC_HAVE_MPIIO) 879 if (vbinary->usempiio) { 880 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr); 881 } else { 882 #endif 883 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 884 #if defined(PETSC_HAVE_MPIIO) 885 } 886 #endif 887 PetscFunctionReturn(0); 888 } 889 890 /*@C 891 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 892 893 Collective on MPI_Comm 894 895 Input Parameters: 896 + viewer - the binary viewer 897 - data - location of the array of strings 898 899 900 Level: intermediate 901 902 Concepts: binary files 903 904 Notes: array of strings is null terminated 905 906 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 907 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 908 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 909 @*/ 910 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 911 { 912 PetscErrorCode ierr; 913 PetscInt i,n = 0,*sizes; 914 915 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 916 /* count number of strings */ 917 while (data[n++]) ; 918 n--; 919 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 920 sizes[0] = n; 921 for (i=0; i<n; i++) { 922 size_t tmp; 923 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 924 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 925 } 926 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 927 for (i=0; i<n; i++) { 928 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 929 } 930 ierr = PetscFree(sizes);CHKERRQ(ierr); 931 PetscFunctionReturn(0); 932 } 933 934 /*@C 935 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 936 937 Collective on MPI_Comm 938 939 Input Parameter: 940 . viewer - the binary viewer 941 942 Output Parameter: 943 . data - location of the array of strings 944 945 Level: intermediate 946 947 Concepts: binary files 948 949 Notes: array of strings is null terminated 950 951 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 952 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 953 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 954 @*/ 955 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 956 { 957 PetscErrorCode ierr; 958 PetscInt i,n,*sizes,N = 0; 959 960 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 961 /* count number of strings */ 962 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 963 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 964 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 965 for (i=0; i<n; i++) N += sizes[i]; 966 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 967 (*data)[0] = (char*)((*data) + n + 1); 968 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 969 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 970 971 (*data)[n] = 0; 972 973 ierr = PetscFree(sizes);CHKERRQ(ierr); 974 PetscFunctionReturn(0); 975 } 976 977 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 978 { 979 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 980 981 PetscFunctionBegin; 982 *name = vbinary->filename; 983 PetscFunctionReturn(0); 984 } 985 986 /*@C 987 PetscViewerFileGetMode - Gets the type of file to be open 988 989 Not Collective 990 991 Input Parameter: 992 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 993 994 Output Parameter: 995 . type - type of file 996 $ FILE_MODE_WRITE - create new file for binary output 997 $ FILE_MODE_READ - open existing file for binary input 998 $ FILE_MODE_APPEND - open existing file for binary output 999 1000 Level: advanced 1001 1002 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1003 1004 @*/ 1005 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 1006 { 1007 PetscErrorCode ierr; 1008 1009 PetscFunctionBegin; 1010 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1011 PetscValidPointer(type,2); 1012 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 1013 PetscFunctionReturn(0); 1014 } 1015 1016 /*@ 1017 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called 1018 before PetscViewerFileSetName() 1019 1020 Logically Collective on PetscViewer 1021 1022 Input Parameters: 1023 + viewer - the PetscViewer; must be a binary 1024 - flg - PETSC_TRUE means MPI-IO will be used 1025 1026 Options Database: 1027 -viewer_binary_mpiio : Flag for using MPI-IO 1028 1029 Level: advanced 1030 1031 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(), 1032 PetscViewerBinaryGetUseMPIIO() 1033 1034 @*/ 1035 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg) 1036 { 1037 PetscErrorCode ierr; 1038 1039 PetscFunctionBegin; 1040 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1041 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr); 1042 PetscFunctionReturn(0); 1043 } 1044 1045 /*@C 1046 PetscViewerFileSetMode - Sets the type of file to be open 1047 1048 Logically Collective on PetscViewer 1049 1050 Input Parameters: 1051 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1052 - type - type of file 1053 $ FILE_MODE_WRITE - create new file for binary output 1054 $ FILE_MODE_READ - open existing file for binary input 1055 $ FILE_MODE_APPEND - open existing file for binary output 1056 1057 Level: advanced 1058 1059 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1060 1061 @*/ 1062 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1063 { 1064 PetscErrorCode ierr; 1065 1066 PetscFunctionBegin; 1067 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1068 PetscValidLogicalCollectiveEnum(viewer,type,2); 1069 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1070 PetscFunctionReturn(0); 1071 } 1072 1073 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1074 { 1075 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1076 1077 PetscFunctionBegin; 1078 *type = vbinary->btype; 1079 PetscFunctionReturn(0); 1080 } 1081 1082 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1083 { 1084 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1085 1086 PetscFunctionBegin; 1087 vbinary->btype = type; 1088 PetscFunctionReturn(0); 1089 } 1090 1091 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1092 { 1093 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1094 PetscErrorCode ierr; 1095 1096 PetscFunctionBegin; 1097 if (vbinary->filename) { ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); } 1098 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1099 PetscFunctionReturn(0); 1100 } 1101 /* 1102 Actually opens the file 1103 */ 1104 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1105 { 1106 PetscMPIInt rank; 1107 PetscErrorCode ierr; 1108 size_t len; 1109 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1110 const char *fname; 1111 char bname[PETSC_MAX_PATH_LEN],*gz; 1112 PetscBool found; 1113 PetscFileMode type = vbinary->btype; 1114 1115 PetscFunctionBegin; 1116 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1117 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1118 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1119 1120 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1121 1122 /* if ends in .gz strip that off and note user wants file compressed */ 1123 vbinary->storecompressed = PETSC_FALSE; 1124 if (!rank && type == FILE_MODE_WRITE) { 1125 /* remove .gz if it ends library name */ 1126 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1127 if (gz) { 1128 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1129 if (len == 3) { 1130 *gz = 0; 1131 vbinary->storecompressed = PETSC_TRUE; 1132 } 1133 } 1134 } 1135 1136 /* only first processor opens file if writeable */ 1137 if (!rank || type == FILE_MODE_READ) { 1138 1139 if (type == FILE_MODE_READ) { 1140 /* possibly get the file from remote site or compressed file */ 1141 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1142 fname = bname; 1143 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1144 else if (!found) { 1145 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1146 fname = 0; 1147 } 1148 } else fname = vbinary->filename; 1149 1150 #if defined(PETSC_HAVE_O_BINARY) 1151 if (type == FILE_MODE_WRITE) { 1152 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); 1153 } else if (type == FILE_MODE_READ && fname) { 1154 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); 1155 } else if (type == FILE_MODE_APPEND) { 1156 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); 1157 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1158 #else 1159 if (type == FILE_MODE_WRITE) { 1160 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1161 } else if (type == FILE_MODE_READ && fname) { 1162 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1163 } else if (type == FILE_MODE_APPEND) { 1164 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); 1165 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1166 #endif 1167 } else vbinary->fdes = -1; 1168 1169 /* 1170 try to open info file: all processors open this file if read only 1171 */ 1172 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1173 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1174 1175 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1176 /* remove .gz if it ends library name */ 1177 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1178 if (gz) { 1179 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1180 if (len == 3) *gz = 0; 1181 } 1182 1183 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1184 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1185 if (type == FILE_MODE_READ) { 1186 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1187 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1188 } else { 1189 vbinary->fdes_info = fopen(infoname,"w"); 1190 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1191 } 1192 } 1193 #if defined(PETSC_USE_LOG) 1194 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1195 #endif 1196 PetscFunctionReturn(0); 1197 } 1198 1199 #if defined(PETSC_HAVE_MPIIO) 1200 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1201 { 1202 PetscMPIInt rank; 1203 PetscErrorCode ierr; 1204 size_t len; 1205 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1206 char *gz; 1207 PetscBool found; 1208 PetscFileMode type = vbinary->btype; 1209 1210 PetscFunctionBegin; 1211 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1212 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1213 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1214 1215 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1216 1217 vbinary->storecompressed = PETSC_FALSE; 1218 1219 /* only first processor opens file if writeable */ 1220 if (type == FILE_MODE_READ) { 1221 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1222 } else if (type == FILE_MODE_WRITE) { 1223 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1224 } 1225 1226 /* 1227 try to open info file: all processors open this file if read only 1228 1229 Below is identical code to the code for Binary above, should be put in separate routine 1230 */ 1231 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1232 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1233 1234 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1235 /* remove .gz if it ends library name */ 1236 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1237 if (gz) { 1238 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1239 if (len == 3) *gz = 0; 1240 } 1241 1242 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1243 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1244 if (type == FILE_MODE_READ) { 1245 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1246 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1247 } else { 1248 vbinary->fdes_info = fopen(infoname,"w"); 1249 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1250 } 1251 } 1252 #if defined(PETSC_USE_LOG) 1253 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1254 #endif 1255 PetscFunctionReturn(0); 1256 } 1257 1258 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg) 1259 { 1260 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1261 PetscFunctionBegin; 1262 vbinary->usempiio = flg; 1263 PetscFunctionReturn(0); 1264 } 1265 #endif 1266 1267 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1268 { 1269 PetscErrorCode ierr; 1270 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1271 1272 PetscFunctionBegin; 1273 if (binary->filename) { 1274 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1275 } 1276 PetscFunctionReturn(0); 1277 } 1278 1279 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1280 { 1281 PetscErrorCode ierr; 1282 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1283 1284 PetscFunctionBegin; 1285 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1286 1287 #if defined(PETSC_HAVE_MPIIO) 1288 if (binary->usempiio) { 1289 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1290 } else { 1291 #endif 1292 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1293 #if defined(PETSC_HAVE_MPIIO) 1294 } 1295 #endif 1296 PetscFunctionReturn(0); 1297 } 1298 1299 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v) 1300 { 1301 PetscErrorCode ierr; 1302 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1303 char defaultname[PETSC_MAX_PATH_LEN]; 1304 PetscBool flg; 1305 1306 PetscFunctionBegin; 1307 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1308 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1309 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1310 if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); } 1311 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);CHKERRQ(ierr); 1312 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);CHKERRQ(ierr); 1313 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);CHKERRQ(ierr); 1314 #if defined(PETSC_HAVE_MPIIO) 1315 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);CHKERRQ(ierr); 1316 #elif defined(PETSC_HAVE_MPIUNI) 1317 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1318 #endif 1319 ierr = PetscOptionsTail();CHKERRQ(ierr); 1320 binary->setfromoptionscalled = PETSC_TRUE; 1321 PetscFunctionReturn(0); 1322 } 1323 1324 /*MC 1325 PETSCVIEWERBINARY - A viewer that saves to binary files 1326 1327 1328 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1329 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1330 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1331 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1332 1333 Level: beginner 1334 1335 M*/ 1336 1337 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1338 { 1339 PetscErrorCode ierr; 1340 PetscViewer_Binary *vbinary; 1341 1342 PetscFunctionBegin; 1343 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1344 v->data = (void*)vbinary; 1345 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1346 v->ops->destroy = PetscViewerDestroy_Binary; 1347 v->ops->view = PetscViewerView_Binary; 1348 v->ops->setup = PetscViewerSetUp_Binary; 1349 v->ops->flush = NULL; 1350 vbinary->fdes_info = 0; 1351 vbinary->fdes = 0; 1352 vbinary->skipinfo = PETSC_FALSE; 1353 vbinary->skipoptions = PETSC_TRUE; 1354 vbinary->skipheader = PETSC_FALSE; 1355 vbinary->setfromoptionscalled = PETSC_FALSE; 1356 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1357 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1358 v->ops->read = PetscViewerBinaryRead; 1359 vbinary->btype = (PetscFileMode) -1; 1360 vbinary->storecompressed = PETSC_FALSE; 1361 vbinary->filename = 0; 1362 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1363 1364 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1365 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1366 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1367 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1368 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1369 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1370 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1371 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1372 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1373 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1374 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1375 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1376 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1377 #if defined(PETSC_HAVE_MPIIO) 1378 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1379 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1380 #endif 1381 PetscFunctionReturn(0); 1382 } 1383 1384 /* ---------------------------------------------------------------------*/ 1385 /* 1386 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1387 is attached to a communicator, in this case the attribute is a PetscViewer. 1388 */ 1389 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1390 1391 /*@C 1392 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1393 in a communicator. 1394 1395 Collective on MPI_Comm 1396 1397 Input Parameter: 1398 . comm - the MPI communicator to share the binary PetscViewer 1399 1400 Level: intermediate 1401 1402 Options Database Keys: 1403 + -viewer_binary_filename <name> 1404 . -viewer_binary_skip_info 1405 . -viewer_binary_skip_options 1406 . -viewer_binary_skip_header 1407 - -viewer_binary_mpiio 1408 1409 Environmental variables: 1410 - PETSC_VIEWER_BINARY_FILENAME 1411 1412 Notes: 1413 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1414 an error code. The binary PetscViewer is usually used in the form 1415 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1416 1417 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1418 PetscViewerDestroy() 1419 @*/ 1420 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1421 { 1422 PetscErrorCode ierr; 1423 PetscBool flg; 1424 PetscViewer viewer; 1425 char fname[PETSC_MAX_PATH_LEN]; 1426 MPI_Comm ncomm; 1427 1428 PetscFunctionBegin; 1429 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1430 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1431 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1432 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1433 } 1434 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1435 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1436 if (!flg) { /* PetscViewer not yet created */ 1437 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1438 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1439 if (!flg) { 1440 ierr = PetscStrcpy(fname,"binaryoutput"); 1441 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1442 } 1443 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1444 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1445 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1446 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1447 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1448 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1449 } 1450 ierr = PetscCommDestroy(&ncomm); 1451 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1452 PetscFunctionReturn(viewer); 1453 } 1454