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