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. 896 897 Level: beginner 898 899 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 900 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 901 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 902 @*/ 903 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 904 { 905 PetscErrorCode ierr; 906 PetscViewer_Binary *vbinary; 907 908 PetscFunctionBegin; 909 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY); 910 PetscValidLogicalCollectiveInt(viewer,num,3); 911 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 912 vbinary = (PetscViewer_Binary*)viewer->data; 913 #if defined(PETSC_HAVE_MPIIO) 914 if (vbinary->usempiio) { 915 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 916 } else { 917 #endif 918 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);CHKERRQ(ierr); 919 #if defined(PETSC_HAVE_MPIIO) 920 } 921 #endif 922 PetscFunctionReturn(0); 923 } 924 925 /*@C 926 PetscViewerBinaryWrite - writes to a binary file, only from the first process 927 928 Collective 929 930 Input Parameters: 931 + viewer - the binary viewer 932 . data - location of data 933 . count - number of items of data to write 934 - dtype - type of data to write 935 936 Level: beginner 937 938 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 939 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 940 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 941 @*/ 942 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,const void *data,PetscInt count,PetscDataType dtype) 943 { 944 PetscErrorCode ierr; 945 PetscViewer_Binary *vbinary; 946 947 PetscFunctionBegin; 948 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY); 949 PetscValidLogicalCollectiveInt(viewer,count,3); 950 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 951 vbinary = (PetscViewer_Binary*)viewer->data; 952 #if defined(PETSC_HAVE_MPIIO) 953 if (vbinary->usempiio) { 954 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,(void*)data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr); 955 } else { 956 #endif 957 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);CHKERRQ(ierr); 958 #if defined(PETSC_HAVE_MPIIO) 959 } 960 #endif 961 PetscFunctionReturn(0); 962 } 963 964 static PetscErrorCode PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype) 965 { 966 MPI_Comm comm = PetscObjectComm((PetscObject)viewer); 967 PetscMPIInt size,rank; 968 MPI_Datatype mdtype; 969 MPI_Aint lb,dsize; 970 PetscBool useMPIIO; 971 PetscErrorCode ierr; 972 973 PetscFunctionBegin; 974 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY); 975 PetscValidLogicalCollectiveBool(viewer,((start>=0)||(start==PETSC_DETERMINE)),4); 976 PetscValidLogicalCollectiveBool(viewer,((total>=0)||(total==PETSC_DETERMINE)),5); 977 PetscValidLogicalCollectiveInt(viewer,total,5); 978 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 979 980 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 981 ierr = MPI_Type_get_extent(mdtype,&lb,&dsize);CHKERRQ(ierr); 982 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 983 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 984 985 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr); 986 #if defined(PETSC_HAVE_MPIIO) 987 if (useMPIIO) { 988 MPI_File mfdes; 989 MPI_Offset off; 990 PetscMPIInt cnt; 991 992 if (start == PETSC_DETERMINE) { 993 ierr = MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); 994 start -= count; 995 } 996 if (total == PETSC_DETERMINE) { 997 total = start + count; 998 ierr = MPI_Bcast(&total,1,MPIU_INT,size-1,comm);CHKERRQ(ierr); 999 } 1000 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 1001 ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr); 1002 ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr); 1003 off += (MPI_Offset)(start*dsize); 1004 if (write) { 1005 ierr = MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1006 } else { 1007 ierr = MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1008 } 1009 off = (MPI_Offset)(total*dsize); 1010 ierr = PetscViewerBinaryAddMPIIOOffset(viewer,off);CHKERRQ(ierr); 1011 PetscFunctionReturn(0); 1012 } 1013 #endif 1014 { 1015 int fdes; 1016 char *workbuf = NULL; 1017 PetscInt maxcount=0,message_count,flowcontrolcount; 1018 PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j; 1019 MPI_Status status; 1020 1021 ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr); 1022 ierr = MPI_Reduce(&count,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);CHKERRQ(ierr); 1023 ierr = PetscMPIIntCast(maxcount,&maxcnt);CHKERRQ(ierr); 1024 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 1025 1026 ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr); 1027 ierr = PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);CHKERRQ(ierr); 1028 if (!rank) { 1029 ierr = PetscMalloc(maxcnt*dsize,&workbuf);CHKERRQ(ierr); 1030 if (write) { 1031 ierr = PetscBinaryWrite(fdes,data,cnt,dtype);CHKERRQ(ierr); 1032 } else { 1033 ierr = PetscBinaryRead(fdes,data,cnt,NULL,dtype);CHKERRQ(ierr); 1034 } 1035 for (j=1; j<size; j++) { 1036 ierr = PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);CHKERRQ(ierr); 1037 if (write) { 1038 ierr = MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);CHKERRQ(ierr); 1039 ierr = MPI_Get_count(&status,mdtype,&rcnt);CHKERRQ(ierr); 1040 ierr = PetscBinaryWrite(fdes,workbuf,rcnt,dtype);CHKERRQ(ierr); 1041 } else { 1042 ierr = MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1043 ierr = PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);CHKERRQ(ierr); 1044 ierr = MPI_Send(workbuf,scnt,mdtype,j,tag,comm);CHKERRQ(ierr); 1045 } 1046 } 1047 ierr = PetscFree(workbuf);CHKERRQ(ierr); 1048 ierr = PetscViewerFlowControlEndMaster(viewer,&message_count);CHKERRQ(ierr); 1049 } else { 1050 ierr = PetscViewerFlowControlStepWorker(viewer,rank,&message_count);CHKERRQ(ierr); 1051 if (write) { 1052 ierr = MPI_Send(data,cnt,mdtype,0,tag,comm);CHKERRQ(ierr); 1053 } else { 1054 ierr = MPI_Send(&cnt,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 1055 ierr = MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1056 } 1057 ierr = PetscViewerFlowControlEndWorker(viewer,&message_count);CHKERRQ(ierr); 1058 } 1059 } 1060 PetscFunctionReturn(0); 1061 } 1062 1063 1064 /*@C 1065 PetscViewerBinaryReadAll - reads from a binary file from all processes 1066 1067 Collective 1068 1069 Input Parameters: 1070 + viewer - the binary viewer 1071 . data - location of data 1072 . count - local number of items of data to read 1073 . start - local start, can be PETSC_DETERMINE 1074 . total - global number of items of data to read, can be PETSC_DETERMINE 1075 - dtype - type of data to read 1076 1077 Level: advanced 1078 1079 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscBinaryViewerRead(), PetscBinaryViewerWriteAll() 1080 @*/ 1081 PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype) 1082 { 1083 PetscErrorCode ierr; 1084 PetscFunctionBegin; 1085 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);CHKERRQ(ierr); 1086 PetscFunctionReturn(0); 1087 } 1088 1089 /*@C 1090 PetscViewerBinaryWriteAll - writes to a binary file from all processes 1091 1092 Collective 1093 1094 Input Parameters: 1095 + viewer - the binary viewer 1096 . data - location of data 1097 . count - local number of items of data to write 1098 . start - local start, can be PETSC_DETERMINE 1099 . total - global number of items of data to write, can be PETSC_DETERMINE 1100 - dtype - type of data to write 1101 1102 Level: advanced 1103 1104 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscBinaryViewerWriteAll(), PetscBinaryViewerReadAll() 1105 @*/ 1106 PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype) 1107 { 1108 PetscErrorCode ierr; 1109 PetscFunctionBegin; 1110 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);CHKERRQ(ierr); 1111 PetscFunctionReturn(0); 1112 } 1113 1114 /*@C 1115 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 1116 1117 Collective 1118 1119 Input Parameters: 1120 + viewer - the binary viewer 1121 - data - location of the array of strings 1122 1123 1124 Level: intermediate 1125 1126 Notes: 1127 array of strings is null terminated 1128 1129 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 1130 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1131 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 1132 @*/ 1133 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 1134 { 1135 PetscErrorCode ierr; 1136 PetscInt i,n = 0,*sizes; 1137 1138 PetscFunctionBegin; 1139 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1140 /* count number of strings */ 1141 while (data[n++]) ; 1142 n--; 1143 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 1144 sizes[0] = n; 1145 for (i=0; i<n; i++) { 1146 size_t tmp; 1147 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 1148 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 1149 } 1150 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);CHKERRQ(ierr); 1151 for (i=0; i<n; i++) { 1152 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);CHKERRQ(ierr); 1153 } 1154 ierr = PetscFree(sizes);CHKERRQ(ierr); 1155 PetscFunctionReturn(0); 1156 } 1157 1158 /*@C 1159 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 1160 1161 Collective 1162 1163 Input Parameter: 1164 . viewer - the binary viewer 1165 1166 Output Parameter: 1167 . data - location of the array of strings 1168 1169 Level: intermediate 1170 1171 Notes: 1172 array of strings is null terminated 1173 1174 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 1175 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1176 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 1177 @*/ 1178 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 1179 { 1180 PetscErrorCode ierr; 1181 PetscInt i,n,*sizes,N = 0; 1182 1183 PetscFunctionBegin; 1184 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1185 /* count number of strings */ 1186 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 1187 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 1188 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 1189 for (i=0; i<n; i++) N += sizes[i]; 1190 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 1191 (*data)[0] = (char*)((*data) + n + 1); 1192 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 1193 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 1194 1195 (*data)[n] = NULL; 1196 1197 ierr = PetscFree(sizes);CHKERRQ(ierr); 1198 PetscFunctionReturn(0); 1199 } 1200 1201 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 1202 { 1203 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1204 1205 PetscFunctionBegin; 1206 *name = vbinary->filename; 1207 PetscFunctionReturn(0); 1208 } 1209 1210 /*@C 1211 PetscViewerFileGetMode - Gets the type of file to be open 1212 1213 Not Collective 1214 1215 Input Parameter: 1216 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1217 1218 Output Parameter: 1219 . type - type of file 1220 $ FILE_MODE_WRITE - create new file for binary output 1221 $ FILE_MODE_READ - open existing file for binary input 1222 $ FILE_MODE_APPEND - open existing file for binary output 1223 1224 Level: advanced 1225 1226 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1227 1228 @*/ 1229 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 1230 { 1231 PetscErrorCode ierr; 1232 1233 PetscFunctionBegin; 1234 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1235 PetscValidPointer(type,2); 1236 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 1237 PetscFunctionReturn(0); 1238 } 1239 1240 /*@ 1241 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called 1242 before PetscViewerFileSetName() 1243 1244 Logically Collective on PetscViewer 1245 1246 Input Parameters: 1247 + viewer - the PetscViewer; must be a binary 1248 - flg - PETSC_TRUE means MPI-IO will be used 1249 1250 Options Database: 1251 -viewer_binary_mpiio : Flag for using MPI-IO 1252 1253 Level: advanced 1254 1255 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(), 1256 PetscViewerBinaryGetUseMPIIO() 1257 1258 @*/ 1259 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg) 1260 { 1261 PetscErrorCode ierr; 1262 1263 PetscFunctionBegin; 1264 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1265 PetscValidLogicalCollectiveBool(viewer,flg,2); 1266 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr); 1267 PetscFunctionReturn(0); 1268 } 1269 1270 /*@C 1271 PetscViewerFileSetMode - Sets the type of file to be open 1272 1273 Logically Collective on PetscViewer 1274 1275 Input Parameters: 1276 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1277 - type - type of file 1278 $ FILE_MODE_WRITE - create new file for output 1279 $ FILE_MODE_READ - open existing file for input 1280 $ FILE_MODE_APPEND - open existing file for output 1281 1282 Level: advanced 1283 1284 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1285 1286 @*/ 1287 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1288 { 1289 PetscErrorCode ierr; 1290 1291 PetscFunctionBegin; 1292 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1293 PetscValidLogicalCollectiveEnum(viewer,type,2); 1294 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1295 PetscFunctionReturn(0); 1296 } 1297 1298 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1299 { 1300 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1301 1302 PetscFunctionBegin; 1303 *type = vbinary->btype; 1304 PetscFunctionReturn(0); 1305 } 1306 1307 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1308 { 1309 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1310 1311 PetscFunctionBegin; 1312 if (viewer->setupcalled && vbinary->btype != type) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[type]); 1313 vbinary->btype = type; 1314 PetscFunctionReturn(0); 1315 } 1316 1317 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1318 { 1319 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1320 PetscErrorCode ierr; 1321 1322 PetscFunctionBegin; 1323 if (vbinary->filename) { 1324 /* gzip can be run after the file with the previous filename has been closed */ 1325 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 1326 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr); 1327 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 1328 viewer->setupcalled = PETSC_FALSE; 1329 } 1330 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1331 PetscFunctionReturn(0); 1332 } 1333 /* 1334 Actually opens the file 1335 */ 1336 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1337 { 1338 PetscMPIInt rank; 1339 PetscErrorCode ierr; 1340 size_t len; 1341 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1342 const char *fname; 1343 char bname[PETSC_MAX_PATH_LEN],*gz; 1344 PetscBool found; 1345 PetscFileMode type = vbinary->btype; 1346 1347 PetscFunctionBegin; 1348 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1349 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1350 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1351 1352 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1353 1354 /* if ends in .gz strip that off and note user wants file compressed */ 1355 vbinary->storecompressed = PETSC_FALSE; 1356 if (!rank && type == FILE_MODE_WRITE) { 1357 /* remove .gz if it ends library name */ 1358 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1359 if (gz) { 1360 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1361 if (len == 3) { 1362 *gz = 0; 1363 vbinary->storecompressed = PETSC_TRUE; 1364 } 1365 } 1366 } 1367 1368 /* only first processor opens file if writeable */ 1369 if (!rank || type == FILE_MODE_READ) { 1370 1371 if (type == FILE_MODE_READ) { 1372 /* possibly get the file from remote site or compressed file */ 1373 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1374 fname = bname; 1375 /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */ 1376 if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1377 } else fname = vbinary->filename; 1378 if (type == FILE_MODE_APPEND) { /* check if asked to append to a non-existing file */ 1379 ierr = PetscTestFile(fname,'\0',&found);CHKERRQ(ierr); 1380 } 1381 1382 #if defined(PETSC_HAVE_O_BINARY) 1383 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1384 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); 1385 } else if (type == FILE_MODE_READ && fname) { 1386 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); 1387 } else if (type == FILE_MODE_APPEND) { 1388 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); 1389 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1390 #else 1391 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1392 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1393 } else if (type == FILE_MODE_READ && fname) { 1394 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1395 } else if (type == FILE_MODE_APPEND) { 1396 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); 1397 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1398 #endif 1399 } else vbinary->fdes = -1; 1400 1401 /* 1402 try to open info file: all processors open this file if read only 1403 */ 1404 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1405 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1406 1407 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1408 /* remove .gz if it ends library name */ 1409 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1410 if (gz) { 1411 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1412 if (len == 3) *gz = 0; 1413 } 1414 1415 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1416 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1417 if (type == FILE_MODE_READ) { 1418 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1419 if (found) { 1420 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1421 } 1422 } else { 1423 vbinary->fdes_info = fopen(infoname,"w"); 1424 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1425 } 1426 } 1427 #if defined(PETSC_USE_LOG) 1428 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1429 #endif 1430 PetscFunctionReturn(0); 1431 } 1432 1433 #if defined(PETSC_HAVE_MPIIO) 1434 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1435 { 1436 PetscMPIInt rank; 1437 PetscErrorCode ierr; 1438 size_t len; 1439 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1440 char *gz; 1441 PetscBool found; 1442 PetscFileMode type = vbinary->btype; 1443 int amode; 1444 1445 PetscFunctionBegin; 1446 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1447 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1448 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1449 1450 vbinary->storecompressed = PETSC_FALSE; 1451 1452 switch (type) { 1453 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break; 1454 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break; 1455 case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break; 1456 default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]); 1457 } 1458 ierr = MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1459 /* 1460 The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero. 1461 */ 1462 if (type == FILE_MODE_WRITE) {ierr = MPI_File_set_size(vbinary->mfdes,0);CHKERRQ(ierr);} 1463 /* 1464 Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND, 1465 MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file. 1466 Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert 1467 the offset in etype units to an absolute byte position. 1468 */ 1469 if (type == FILE_MODE_APPEND) {ierr = MPI_File_get_position(vbinary->mfdes,&vbinary->moff);CHKERRQ(ierr);} 1470 1471 /* 1472 try to open info file: all processors open this file if read only 1473 1474 Below is identical code to the code for Binary above, should be put in separate routine 1475 */ 1476 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1477 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1478 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1479 1480 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1481 /* remove .gz if it ends library name */ 1482 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1483 if (gz) { 1484 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1485 if (len == 3) *gz = 0; 1486 } 1487 1488 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1489 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1490 if (type == FILE_MODE_READ) { 1491 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1492 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1493 } else { 1494 vbinary->fdes_info = fopen(infoname,"w"); 1495 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1496 } 1497 } 1498 #if defined(PETSC_USE_LOG) 1499 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1500 #endif 1501 PetscFunctionReturn(0); 1502 } 1503 1504 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg) 1505 { 1506 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1507 PetscFunctionBegin; 1508 if (viewer->setupcalled && vbinary->usempiio != flg) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change MPIIO to %s after setup",PetscBools[flg]); 1509 vbinary->usempiio = flg; 1510 PetscFunctionReturn(0); 1511 } 1512 #endif 1513 1514 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1515 { 1516 PetscErrorCode ierr; 1517 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 1518 const char *fname = vbinary->filename ? vbinary->filename : "not yet set"; 1519 const char *fmode = vbinary->btype != (PetscFileMode) -1 ? PetscFileModes[vbinary->btype] : "not yet set"; 1520 PetscBool usempiio; 1521 1522 PetscFunctionBegin; 1523 ierr = PetscViewerBinaryGetUseMPIIO(v,&usempiio);CHKERRQ(ierr); 1524 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);CHKERRQ(ierr); 1525 ierr = PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");CHKERRQ(ierr); 1526 PetscFunctionReturn(0); 1527 } 1528 1529 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1530 { 1531 PetscErrorCode ierr; 1532 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1533 1534 PetscFunctionBegin; 1535 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1536 1537 #if defined(PETSC_HAVE_MPIIO) 1538 if (binary->usempiio) { 1539 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1540 } else { 1541 #endif 1542 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1543 #if defined(PETSC_HAVE_MPIIO) 1544 } 1545 #endif 1546 PetscFunctionReturn(0); 1547 } 1548 1549 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer) 1550 { 1551 PetscErrorCode ierr; 1552 PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data; 1553 char defaultname[PETSC_MAX_PATH_LEN]; 1554 PetscBool flg; 1555 1556 PetscFunctionBegin; 1557 if (viewer->setupcalled) PetscFunctionReturn(0); 1558 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1559 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1560 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1561 if (flg) { ierr = PetscViewerFileSetName_Binary(viewer,defaultname);CHKERRQ(ierr); } 1562 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);CHKERRQ(ierr); 1563 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);CHKERRQ(ierr); 1564 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);CHKERRQ(ierr); 1565 #if defined(PETSC_HAVE_MPIIO) 1566 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);CHKERRQ(ierr); 1567 #else 1568 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1569 #endif 1570 ierr = PetscOptionsTail();CHKERRQ(ierr); 1571 binary->setfromoptionscalled = PETSC_TRUE; 1572 PetscFunctionReturn(0); 1573 } 1574 1575 /*MC 1576 PETSCVIEWERBINARY - A viewer that saves to binary files 1577 1578 1579 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1580 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1581 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1582 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1583 1584 Level: beginner 1585 1586 M*/ 1587 1588 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1589 { 1590 PetscErrorCode ierr; 1591 PetscViewer_Binary *vbinary; 1592 1593 PetscFunctionBegin; 1594 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1595 v->data = (void*)vbinary; 1596 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1597 v->ops->destroy = PetscViewerDestroy_Binary; 1598 v->ops->view = PetscViewerView_Binary; 1599 v->ops->setup = PetscViewerSetUp_Binary; 1600 v->ops->flush = NULL; 1601 vbinary->fdes = 0; 1602 #if defined(PETSC_HAVE_MPIIO) 1603 vbinary->mfdes = MPI_FILE_NULL; 1604 vbinary->mfsub = MPI_FILE_NULL; 1605 #endif 1606 vbinary->fdes_info = NULL; 1607 vbinary->skipinfo = PETSC_FALSE; 1608 vbinary->skipoptions = PETSC_TRUE; 1609 vbinary->skipheader = PETSC_FALSE; 1610 vbinary->setfromoptionscalled = PETSC_FALSE; 1611 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1612 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1613 v->ops->read = PetscViewerBinaryRead; 1614 vbinary->btype = (PetscFileMode) -1; 1615 vbinary->storecompressed = PETSC_FALSE; 1616 vbinary->filename = NULL; 1617 vbinary->ogzfilename = NULL; 1618 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1619 1620 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1621 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1622 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1623 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1624 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1625 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1626 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1627 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1628 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1629 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1630 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1631 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1632 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1633 #if defined(PETSC_HAVE_MPIIO) 1634 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1635 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1636 #endif 1637 PetscFunctionReturn(0); 1638 } 1639 1640 /* ---------------------------------------------------------------------*/ 1641 /* 1642 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1643 is attached to a communicator, in this case the attribute is a PetscViewer. 1644 */ 1645 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1646 1647 /*@C 1648 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1649 in a communicator. 1650 1651 Collective 1652 1653 Input Parameter: 1654 . comm - the MPI communicator to share the binary PetscViewer 1655 1656 Level: intermediate 1657 1658 Options Database Keys: 1659 + -viewer_binary_filename <name> 1660 . -viewer_binary_skip_info 1661 . -viewer_binary_skip_options 1662 . -viewer_binary_skip_header 1663 - -viewer_binary_mpiio 1664 1665 Environmental variables: 1666 - PETSC_VIEWER_BINARY_FILENAME 1667 1668 Notes: 1669 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1670 an error code. The binary PetscViewer is usually used in the form 1671 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1672 1673 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1674 PetscViewerDestroy() 1675 @*/ 1676 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1677 { 1678 PetscErrorCode ierr; 1679 PetscBool flg; 1680 PetscViewer viewer; 1681 char fname[PETSC_MAX_PATH_LEN]; 1682 MPI_Comm ncomm; 1683 1684 PetscFunctionBegin; 1685 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1686 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1687 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL); 1688 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1689 } 1690 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1691 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1692 if (!flg) { /* PetscViewer not yet created */ 1693 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1694 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1695 if (!flg) { 1696 ierr = PetscStrcpy(fname,"binaryoutput"); 1697 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1698 } 1699 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1700 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1701 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1702 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1703 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1704 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1705 } 1706 ierr = PetscCommDestroy(&ncomm); 1707 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1708 PetscFunctionReturn(viewer); 1709 } 1710