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