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