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 PetscErrorCode ierr; 237 238 PetscFunctionBegin; 239 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr); 240 PetscFunctionReturn(0); 241 } 242 243 #undef __FUNCT__ 244 #define __FUNCT__ "PetscViewerBinarySetFlowControl_Binary" 245 PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc) 246 { 247 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 248 249 PetscFunctionBegin; 250 if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc); 251 vbinary->flowcontrol = fc; 252 PetscFunctionReturn(0); 253 } 254 255 #undef __FUNCT__ 256 #define __FUNCT__ "PetscViewerBinarySetFlowControl" 257 /*@C 258 PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes 259 260 Not Collective 261 262 Input Parameter: 263 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 264 - fc - the number of messages, defaults to 256 if this function was not called 265 266 Level: advanced 267 268 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl() 269 270 @*/ 271 PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc) 272 { 273 PetscErrorCode ierr; 274 275 PetscFunctionBegin; 276 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr); 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "PetscViewerBinaryGetDescriptor" 282 /*@C 283 PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer. 284 285 Not Collective 286 287 Input Parameter: 288 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 289 290 Output Parameter: 291 . fdes - file descriptor 292 293 Level: advanced 294 295 Notes: 296 For writable binary PetscViewers, the descriptor will only be valid for the 297 first processor in the communicator that shares the PetscViewer. For readable 298 files it will only be valid on nodes that have the file. If node 0 does not 299 have the file it generates an error even if another node does have the file. 300 301 Fortran Note: 302 This routine is not supported in Fortran. 303 304 Concepts: file descriptor^getting 305 Concepts: PetscViewerBinary^accessing file descriptor 306 307 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer() 308 @*/ 309 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes) 310 { 311 PetscErrorCode ierr; 312 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 313 314 PetscFunctionBegin; 315 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 316 *fdes = vbinary->fdes; 317 PetscFunctionReturn(0); 318 } 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "PetscViewerBinarySkipInfo" 322 /*@ 323 PetscViewerBinarySkipInfo - Binary file will not have .info file created with it 324 325 Not Collective 326 327 Input Paramter: 328 . viewer - PetscViewer context, obtained from PetscViewerCreate() 329 330 Options Database Key: 331 . -viewer_binary_skip_info 332 333 Level: advanced 334 335 Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then 336 you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the 337 viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo(). 338 339 The .info contains meta information about the data in the binary file, for example the block size if it was 340 set for a vector or matrix. 341 342 Concepts: PetscViewerBinary^accessing info file 343 344 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 345 PetscViewerBinaryGetSkipOptions() 346 @*/ 347 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer) 348 { 349 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 350 351 PetscFunctionBegin; 352 vbinary->skipinfo = PETSC_TRUE; 353 PetscFunctionReturn(0); 354 } 355 356 #undef __FUNCT__ 357 #define __FUNCT__ "PetscViewerBinarySetSkipOptions" 358 /*@ 359 PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects 360 361 Not Collective 362 363 Input Parameters: 364 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 365 - skip - PETSC_TRUE means do not use 366 367 Options Database Key: 368 . -viewer_binary_skip_options 369 370 Level: advanced 371 372 Notes: This must be called after PetscViewerSetType() 373 374 Concepts: PetscViewerBinary^accessing info file 375 376 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 377 PetscViewerBinaryGetSkipOptions() 378 @*/ 379 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip) 380 { 381 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 382 383 PetscFunctionBegin; 384 vbinary->skipoptions = skip; 385 PetscFunctionReturn(0); 386 } 387 388 #undef __FUNCT__ 389 #define __FUNCT__ "PetscViewerBinaryGetSkipOptions" 390 /*@ 391 PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects 392 393 Not Collective 394 395 Input Parameter: 396 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 397 398 Output Parameter: 399 . skip - PETSC_TRUE means do not use 400 401 Level: advanced 402 403 Notes: This must be called after PetscViewerSetType() 404 405 Concepts: PetscViewerBinary^accessing info file 406 407 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 408 PetscViewerBinarySetSkipOptions() 409 @*/ 410 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip) 411 { 412 PetscViewer_Binary *vbinary; 413 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 416 vbinary = (PetscViewer_Binary*)viewer->data; 417 *skip = vbinary->skipoptions; 418 PetscFunctionReturn(0); 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "PetscViewerBinarySetSkipHeader_Binary" 423 PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip) 424 { 425 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 426 427 PetscFunctionBegin; 428 vbinary->skipheader = skip; 429 PetscFunctionReturn(0); 430 } 431 432 #undef __FUNCT__ 433 #define __FUNCT__ "PetscViewerBinarySetSkipHeader" 434 /*@ 435 PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data 436 437 Not Collective 438 439 Input Parameters: 440 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 441 - skip - PETSC_TRUE means do not write header 442 443 Options Database Key: 444 . -viewer_binary_skip_header 445 446 Level: advanced 447 448 Notes: This must be called after PetscViewerSetType() 449 450 Can ONLY be called on a binary viewer 451 452 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 453 PetscViewerBinaryGetSkipHeader() 454 @*/ 455 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip) 456 { 457 PetscErrorCode ierr; 458 459 PetscFunctionBegin; 460 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 461 PetscFunctionReturn(0); 462 } 463 464 #undef __FUNCT__ 465 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader_Binary" 466 PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip) 467 { 468 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 469 470 PetscFunctionBegin; 471 *skip = vbinary->skipheader; 472 PetscFunctionReturn(0); 473 } 474 475 #undef __FUNCT__ 476 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader" 477 /*@ 478 PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data 479 480 Not Collective 481 482 Input Parameter: 483 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 484 485 Output Parameter: 486 . skip - PETSC_TRUE means do not write header 487 488 Level: advanced 489 490 Notes: This must be called after PetscViewerSetType() 491 492 Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it. 493 494 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 495 PetscViewerBinarySetSkipHeader() 496 @*/ 497 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip) 498 { 499 PetscErrorCode ierr; 500 501 PetscFunctionBegin; 502 *skip = PETSC_FALSE; 503 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 504 PetscFunctionReturn(0); 505 } 506 507 #undef __FUNCT__ 508 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer_Binary" 509 PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file) 510 { 511 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 512 PetscErrorCode ierr; 513 MPI_Comm comm; 514 515 PetscFunctionBegin; 516 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 517 *file = vbinary->fdes_info; 518 if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) { 519 vbinary->matlabheaderwritten = PETSC_TRUE; 520 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 521 ierr = PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 522 ierr = PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr); 523 ierr = PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr); 524 ierr = PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 525 } 526 PetscFunctionReturn(0); 527 } 528 529 #undef __FUNCT__ 530 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer" 531 /*@C 532 PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII 533 info file associated with a binary file. 534 535 Not Collective 536 537 Input Parameter: 538 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 539 540 Output Parameter: 541 . file - file pointer Always returns NULL if not a binary viewer 542 543 Level: advanced 544 545 Notes: 546 For writable binary PetscViewers, the descriptor will only be valid for the 547 first processor in the communicator that shares the PetscViewer. 548 549 Fortran Note: 550 This routine is not supported in Fortran. 551 552 Concepts: PetscViewerBinary^accessing info file 553 554 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor() 555 @*/ 556 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file) 557 { 558 PetscErrorCode ierr; 559 560 PetscFunctionBegin; 561 *file = NULL; 562 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr); 563 PetscFunctionReturn(0); 564 } 565 566 #undef __FUNCT__ 567 #define __FUNCT__ "PetscViewerFileClose_Binary" 568 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v) 569 { 570 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 571 PetscErrorCode ierr; 572 PetscMPIInt rank; 573 int err; 574 575 PetscFunctionBegin; 576 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr); 577 if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) { 578 close(vbinary->fdes); 579 if (!rank && vbinary->storecompressed) { 580 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 581 FILE *fp; 582 /* compress the file */ 583 ierr = PetscStrcpy(par,"gzip -f ");CHKERRQ(ierr); 584 ierr = PetscStrcat(par,vbinary->filename);CHKERRQ(ierr); 585 #if defined(PETSC_HAVE_POPEN) 586 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 587 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf); 588 ierr = PetscPClose(PETSC_COMM_SELF,fp,NULL);CHKERRQ(ierr); 589 #else 590 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 591 #endif 592 } 593 } 594 if (vbinary->fdes_info) { 595 err = fclose(vbinary->fdes_info); 596 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 597 } 598 PetscFunctionReturn(0); 599 } 600 601 #if defined(PETSC_HAVE_MPIIO) 602 #undef __FUNCT__ 603 #define __FUNCT__ "PetscViewerFileClose_BinaryMPIIO" 604 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v) 605 { 606 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 607 int err; 608 PetscErrorCode ierr; 609 610 PetscFunctionBegin; 611 if (vbinary->mfdes) { 612 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr); 613 } 614 if (vbinary->fdes_info) { 615 err = fclose(vbinary->fdes_info); 616 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 617 } 618 PetscFunctionReturn(0); 619 } 620 #endif 621 622 #undef __FUNCT__ 623 #define __FUNCT__ "PetscViewerDestroy_Binary" 624 PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v) 625 { 626 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 627 PetscErrorCode ierr; 628 629 PetscFunctionBegin; 630 if (v->format == PETSC_VIEWER_BINARY_MATLAB) { 631 MPI_Comm comm; 632 FILE *info; 633 634 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 635 ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr); 636 ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 637 ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr); 638 ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 639 } 640 #if defined(PETSC_HAVE_MPIIO) 641 if (vbinary->MPIIO) { 642 ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr); 643 } else { 644 #endif 645 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr); 646 #if defined(PETSC_HAVE_MPIIO) 647 } 648 #endif 649 if (vbinary->filename) { ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); } 650 ierr = PetscFree(vbinary);CHKERRQ(ierr); 651 PetscFunctionReturn(0); 652 } 653 654 #undef __FUNCT__ 655 #define __FUNCT__ "PetscViewerBinaryOpen" 656 /*@C 657 PetscViewerBinaryOpen - Opens a file for binary input/output. 658 659 Collective on MPI_Comm 660 661 Input Parameters: 662 + comm - MPI communicator 663 . name - name of file 664 - type - type of file 665 $ FILE_MODE_WRITE - create new file for binary output 666 $ FILE_MODE_READ - open existing file for binary input 667 $ FILE_MODE_APPEND - open existing file for binary output 668 669 Output Parameter: 670 . binv - PetscViewer for binary input/output to use with the specified file 671 672 Options Database Keys: 673 + -viewer_binary_filename <name> 674 . -viewer_binary_skip_info 675 . -viewer_binary_skip_options 676 . -viewer_binary_skip_header 677 - -viewer_binary_mpiio 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 char defaultname[PETSC_MAX_PATH_LEN]; 1275 PetscBool flg; 1276 #if defined(PETSC_HAVE_MPIIO) 1277 PetscBool useMPIIO = PETSC_FALSE; 1278 #endif 1279 1280 PetscFunctionBegin; 1281 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1282 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1283 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1284 if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); } 1285 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySkipInfo",PETSC_FALSE,&binary->skipinfo,&flg);CHKERRQ(ierr); 1286 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,&flg);CHKERRQ(ierr); 1287 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,&flg);CHKERRQ(ierr); 1288 #if defined(PETSC_HAVE_MPIIO) 1289 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetMPIIO",PETSC_FALSE,&useMPIIO,&flg);CHKERRQ(ierr); 1290 if (useMPIIO) { 1291 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1292 } 1293 #endif 1294 ierr = PetscOptionsTail();CHKERRQ(ierr); 1295 binary->setfromoptionscalled = PETSC_FALSE; 1296 PetscFunctionReturn(0); 1297 } 1298 1299 #undef __FUNCT__ 1300 #define __FUNCT__ "PetscViewerCreate_Binary" 1301 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1302 { 1303 PetscErrorCode ierr; 1304 PetscViewer_Binary *vbinary; 1305 1306 PetscFunctionBegin; 1307 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1308 v->data = (void*)vbinary; 1309 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1310 v->ops->destroy = PetscViewerDestroy_Binary; 1311 v->ops->view = PetscViewerView_Binary; 1312 v->ops->flush = 0; 1313 vbinary->fdes_info = 0; 1314 vbinary->fdes = 0; 1315 vbinary->skipinfo = PETSC_FALSE; 1316 vbinary->skipoptions = PETSC_TRUE; 1317 vbinary->skipheader = PETSC_FALSE; 1318 vbinary->setupcalled = PETSC_FALSE; 1319 vbinary->setfromoptionscalled = PETSC_FALSE; 1320 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1321 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1322 v->ops->read = PetscViewerBinaryRead; 1323 vbinary->btype = (PetscFileMode) -1; 1324 vbinary->storecompressed = PETSC_FALSE; 1325 vbinary->filename = 0; 1326 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1327 1328 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1329 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1330 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1331 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1332 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1333 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1334 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1335 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1336 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1337 #if defined(PETSC_HAVE_MPIIO) 1338 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1339 #endif 1340 PetscFunctionReturn(0); 1341 } 1342 1343 /* ---------------------------------------------------------------------*/ 1344 /* 1345 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1346 is attached to a communicator, in this case the attribute is a PetscViewer. 1347 */ 1348 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1349 1350 #undef __FUNCT__ 1351 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1352 /*@C 1353 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1354 in a communicator. 1355 1356 Collective on MPI_Comm 1357 1358 Input Parameter: 1359 . comm - the MPI communicator to share the binary PetscViewer 1360 1361 Level: intermediate 1362 1363 Options Database Keys: 1364 + -viewer_binary_filename <name> 1365 . -viewer_binary_skip_info 1366 . -viewer_binary_skip_options 1367 . -viewer_binary_skip_header 1368 - -viewer_binary_mpiio 1369 1370 Environmental variables: 1371 - PETSC_VIEWER_BINARY_FILENAME 1372 1373 Notes: 1374 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1375 an error code. The binary PetscViewer is usually used in the form 1376 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1377 1378 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1379 PetscViewerDestroy() 1380 @*/ 1381 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1382 { 1383 PetscErrorCode ierr; 1384 PetscBool flg; 1385 PetscViewer viewer; 1386 char fname[PETSC_MAX_PATH_LEN]; 1387 MPI_Comm ncomm; 1388 1389 PetscFunctionBegin; 1390 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1391 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1392 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1393 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1394 } 1395 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1396 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1397 if (!flg) { /* PetscViewer not yet created */ 1398 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1399 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1400 if (!flg) { 1401 ierr = PetscStrcpy(fname,"binaryoutput"); 1402 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1403 } 1404 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1405 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1406 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1407 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1408 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1409 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1410 } 1411 ierr = PetscCommDestroy(&ncomm); 1412 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1413 PetscFunctionReturn(viewer); 1414 } 1415