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