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