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 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 601 PetscFunctionReturn(0); 602 } 603 604 #if defined(PETSC_HAVE_MPIIO) 605 #undef __FUNCT__ 606 #define __FUNCT__ "PetscViewerFileClose_BinaryMPIIO" 607 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v) 608 { 609 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 610 int err; 611 PetscErrorCode ierr; 612 613 PetscFunctionBegin; 614 if (vbinary->mfdes) { 615 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr); 616 } 617 if (vbinary->fdes_info) { 618 err = fclose(vbinary->fdes_info); 619 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 620 } 621 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 622 PetscFunctionReturn(0); 623 } 624 #endif 625 626 #undef __FUNCT__ 627 #define __FUNCT__ "PetscViewerDestroy_Binary" 628 PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v) 629 { 630 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 631 PetscErrorCode ierr; 632 633 PetscFunctionBegin; 634 if (v->format == PETSC_VIEWER_BINARY_MATLAB) { 635 MPI_Comm comm; 636 FILE *info; 637 638 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 639 ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr); 640 ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 641 ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr); 642 ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 643 } 644 #if defined(PETSC_HAVE_MPIIO) 645 if (vbinary->MPIIO) { 646 ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr); 647 } else { 648 #endif 649 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr); 650 #if defined(PETSC_HAVE_MPIIO) 651 } 652 #endif 653 ierr = PetscFree(vbinary);CHKERRQ(ierr); 654 PetscFunctionReturn(0); 655 } 656 657 #undef __FUNCT__ 658 #define __FUNCT__ "PetscViewerBinaryOpen" 659 /*@C 660 PetscViewerBinaryOpen - Opens a file for binary input/output. 661 662 Collective on MPI_Comm 663 664 Input Parameters: 665 + comm - MPI communicator 666 . name - name of file 667 - type - type of file 668 $ FILE_MODE_WRITE - create new file for binary output 669 $ FILE_MODE_READ - open existing file for binary input 670 $ FILE_MODE_APPEND - open existing file for binary output 671 672 Output Parameter: 673 . binv - PetscViewer for binary input/output to use with the specified file 674 675 Options Database Keys: 676 + -viewer_binary_skip_info 677 . -viewer_binary_skip_options 678 - -viewer_binary_skip_header 679 680 Level: beginner 681 682 Note: 683 This PetscViewer should be destroyed with PetscViewerDestroy(). 684 685 For reading files, the filename may begin with ftp:// or http:// and/or 686 end with .gz; in this case file is brought over and uncompressed. 687 688 For creating files, if the file name ends with .gz it is automatically 689 compressed when closed. 690 691 For writing files it only opens the file on processor 0 in the communicator. 692 For readable files it opens the file on all nodes that have the file. If 693 node 0 does not have the file it generates an error even if other nodes 694 do have the file. 695 696 Concepts: binary files 697 Concepts: PetscViewerBinary^creating 698 Concepts: gzip 699 Concepts: accessing remote file 700 Concepts: remote file 701 702 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 703 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 704 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 705 @*/ 706 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 707 { 708 PetscErrorCode ierr; 709 710 PetscFunctionBegin; 711 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 712 ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr); 713 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 714 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 715 ierr = PetscViewerSetFromOptions(*binv);CHKERRQ(ierr); 716 PetscFunctionReturn(0); 717 } 718 719 #if defined(PETSC_HAVE_MPIIO) 720 #undef __FUNCT__ 721 #define __FUNCT__ "PetscViewerBinaryWriteReadMPIIO" 722 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool write) 723 { 724 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 725 PetscErrorCode ierr; 726 MPI_Datatype mdtype; 727 PetscMPIInt cnt; 728 MPI_Status status; 729 MPI_Aint ul,dsize; 730 731 PetscFunctionBegin; 732 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 733 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 734 ierr = MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 735 if (write) { 736 ierr = MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 737 } else { 738 ierr = MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 739 } 740 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 741 742 vbinary->moff += dsize*cnt; 743 PetscFunctionReturn(0); 744 } 745 #endif 746 747 #undef __FUNCT__ 748 #define __FUNCT__ "PetscViewerBinaryRead" 749 /*@C 750 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 751 752 Collective on MPI_Comm 753 754 Input Parameters: 755 + viewer - the binary viewer 756 . data - location of the data to be written 757 . count - number of items of data to read 758 - dtype - type of data to read 759 760 Level: beginner 761 762 Concepts: binary files 763 764 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 765 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 766 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 767 @*/ 768 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype) 769 { 770 PetscErrorCode ierr; 771 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 772 773 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 774 #if defined(PETSC_HAVE_MPIIO) 775 if (vbinary->MPIIO) { 776 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 777 } else { 778 #endif 779 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);CHKERRQ(ierr); 780 #if defined(PETSC_HAVE_MPIIO) 781 } 782 #endif 783 PetscFunctionReturn(0); 784 } 785 786 787 #undef __FUNCT__ 788 #define __FUNCT__ "PetscViewerBinaryWrite" 789 /*@C 790 PetscViewerBinaryWrite - writes to a binary file, only from the first process 791 792 Collective on MPI_Comm 793 794 Input Parameters: 795 + viewer - the binary viewer 796 . data - location of data 797 . count - number of items of data to write 798 . dtype - type of data to write 799 - istemp - data may be overwritten 800 801 Level: beginner 802 803 Notes: because byte-swapping may be done on the values in data it cannot be declared const 804 805 Concepts: binary files 806 807 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 808 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 809 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 810 @*/ 811 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 812 { 813 PetscErrorCode ierr; 814 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 815 816 PetscFunctionBegin; 817 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 818 #if defined(PETSC_HAVE_MPIIO) 819 if (vbinary->MPIIO) { 820 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,dtype,PETSC_TRUE);CHKERRQ(ierr); 821 } else { 822 #endif 823 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 824 #if defined(PETSC_HAVE_MPIIO) 825 } 826 #endif 827 PetscFunctionReturn(0); 828 } 829 830 #undef __FUNCT__ 831 #define __FUNCT__ "PetscViewerBinaryWriteStringArray" 832 /*@C 833 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 834 835 Collective on MPI_Comm 836 837 Input Parameters: 838 + viewer - the binary viewer 839 - data - location of the array of strings 840 841 842 Level: intermediate 843 844 Concepts: binary files 845 846 Notes: array of strings is null terminated 847 848 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 849 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 850 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 851 @*/ 852 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data) 853 { 854 PetscErrorCode ierr; 855 PetscInt i,n = 0,*sizes; 856 857 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 858 /* count number of strings */ 859 while (data[n++]) ; 860 n--; 861 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 862 sizes[0] = n; 863 for (i=0; i<n; i++) { 864 size_t tmp; 865 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 866 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 867 } 868 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 869 for (i=0; i<n; i++) { 870 ierr = PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 871 } 872 ierr = PetscFree(sizes);CHKERRQ(ierr); 873 PetscFunctionReturn(0); 874 } 875 876 #undef __FUNCT__ 877 #define __FUNCT__ "PetscViewerBinaryReadStringArray" 878 /*@C 879 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 880 881 Collective on MPI_Comm 882 883 Input Parameter: 884 . viewer - the binary viewer 885 886 Output Parameter: 887 . data - location of the array of strings 888 889 Level: intermediate 890 891 Concepts: binary files 892 893 Notes: array of strings is null terminated 894 895 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 896 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 897 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 898 @*/ 899 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 900 { 901 PetscErrorCode ierr; 902 PetscInt i,n,*sizes,N = 0; 903 904 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 905 /* count number of strings */ 906 ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr); 907 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 908 ierr = PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);CHKERRQ(ierr); 909 for (i=0; i<n; i++) N += sizes[i]; 910 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 911 (*data)[0] = (char*)((*data) + n + 1); 912 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 913 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);CHKERRQ(ierr); 914 915 (*data)[n] = 0; 916 917 ierr = PetscFree(sizes);CHKERRQ(ierr); 918 PetscFunctionReturn(0); 919 } 920 921 #undef __FUNCT__ 922 #define __FUNCT__ "PetscViewerFileGetName_Binary" 923 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 924 { 925 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 926 927 PetscFunctionBegin; 928 *name = vbinary->filename; 929 PetscFunctionReturn(0); 930 } 931 932 #undef __FUNCT__ 933 #define __FUNCT__ "PetscViewerFileGetMode" 934 /*@C 935 PetscViewerFileGetMode - Gets the type of file to be open 936 937 Not Collective 938 939 Input Parameter: 940 . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer 941 942 Output Parameter: 943 . type - type of file 944 $ FILE_MODE_WRITE - create new file for binary output 945 $ FILE_MODE_READ - open existing file for binary input 946 $ FILE_MODE_APPEND - open existing file for binary output 947 948 Level: advanced 949 950 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 951 952 @*/ 953 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 954 { 955 PetscErrorCode ierr; 956 957 PetscFunctionBegin; 958 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 959 PetscValidPointer(type,2); 960 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 961 PetscFunctionReturn(0); 962 } 963 964 #undef __FUNCT__ 965 #define __FUNCT__ "PetscViewerBinarySetMPIIO" 966 /*@ 967 PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called 968 before PetscViewerFileSetName() 969 970 Logically Collective on PetscViewer 971 972 Input Parameters: 973 . viewer - the PetscViewer; must be a binary 974 975 Options Database: 976 -viewer_binary_mpiio : Flag for using MPI-IO 977 978 Level: advanced 979 980 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 981 982 @*/ 983 PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer) 984 { 985 PetscErrorCode ierr; 986 987 PetscFunctionBegin; 988 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 989 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));CHKERRQ(ierr); 990 PetscFunctionReturn(0); 991 } 992 993 994 #undef __FUNCT__ 995 #define __FUNCT__ "PetscViewerFileSetMode" 996 /*@C 997 PetscViewerFileSetMode - Sets the type of file to be open 998 999 Logically Collective on PetscViewer 1000 1001 Input Parameters: 1002 + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer 1003 - type - type of file 1004 $ FILE_MODE_WRITE - create new file for binary output 1005 $ FILE_MODE_READ - open existing file for binary input 1006 $ FILE_MODE_APPEND - open existing file for binary output 1007 1008 Level: advanced 1009 1010 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1011 1012 @*/ 1013 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1014 { 1015 PetscErrorCode ierr; 1016 1017 PetscFunctionBegin; 1018 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1019 PetscValidLogicalCollectiveEnum(viewer,type,2); 1020 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1021 PetscFunctionReturn(0); 1022 } 1023 1024 #undef __FUNCT__ 1025 #define __FUNCT__ "PetscViewerFileGetMode_Binary" 1026 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1027 { 1028 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1029 1030 PetscFunctionBegin; 1031 *type = vbinary->btype; 1032 PetscFunctionReturn(0); 1033 } 1034 1035 #undef __FUNCT__ 1036 #define __FUNCT__ "PetscViewerFileSetMode_Binary" 1037 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1038 { 1039 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1040 1041 PetscFunctionBegin; 1042 vbinary->btype = type; 1043 PetscFunctionReturn(0); 1044 } 1045 1046 #undef __FUNCT__ 1047 #define __FUNCT__ "PetscViewerFileSetName_Binary" 1048 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1049 { 1050 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1051 PetscErrorCode ierr; 1052 1053 PetscFunctionBegin; 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,*tfilename; 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 ierr = PetscStrallocpy(vbinary->filename,&tfilename);CHKERRQ(ierr); 1076 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1077 1078 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1079 1080 /* copy name so we can edit it */ 1081 ierr = PetscStrallocpy(tfilename,&vbinary->filename);CHKERRQ(ierr); 1082 1083 /* if ends in .gz strip that off and note user wants file compressed */ 1084 vbinary->storecompressed = PETSC_FALSE; 1085 if (!rank && type == FILE_MODE_WRITE) { 1086 /* remove .gz if it ends library name */ 1087 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1088 if (gz) { 1089 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1090 if (len == 3) { 1091 *gz = 0; 1092 vbinary->storecompressed = PETSC_TRUE; 1093 } 1094 } 1095 } 1096 1097 /* only first processor opens file if writeable */ 1098 if (!rank || type == FILE_MODE_READ) { 1099 1100 if (type == FILE_MODE_READ) { 1101 /* possibly get the file from remote site or compressed file */ 1102 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1103 fname = bname; 1104 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1105 else if (!found) { 1106 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1107 fname = 0; 1108 } 1109 } else fname = vbinary->filename; 1110 1111 #if defined(PETSC_HAVE_O_BINARY) 1112 if (type == FILE_MODE_WRITE) { 1113 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); 1114 } else if (type == FILE_MODE_READ && fname) { 1115 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); 1116 } else if (type == FILE_MODE_APPEND) { 1117 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); 1118 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1119 #else 1120 if (type == FILE_MODE_WRITE) { 1121 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1122 } else if (type == FILE_MODE_READ && fname) { 1123 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1124 } else if (type == FILE_MODE_APPEND) { 1125 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); 1126 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1127 #endif 1128 } else vbinary->fdes = -1; 1129 1130 /* 1131 try to open info file: all processors open this file if read only 1132 */ 1133 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1134 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1135 1136 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1137 /* remove .gz if it ends library name */ 1138 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1139 if (gz) { 1140 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1141 if (len == 3) *gz = 0; 1142 } 1143 1144 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1145 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1146 if (type == FILE_MODE_READ) { 1147 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1148 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1149 } else { 1150 vbinary->fdes_info = fopen(infoname,"w"); 1151 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1152 } 1153 } 1154 1155 ierr = PetscFree(tfilename);CHKERRQ(ierr); 1156 #if defined(PETSC_USE_LOG) 1157 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1158 #endif 1159 PetscFunctionReturn(0); 1160 } 1161 1162 #if defined(PETSC_HAVE_MPIIO) 1163 #undef __FUNCT__ 1164 #define __FUNCT__ "PetscViewerFileSetUp_BinaryMPIIO" 1165 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1166 { 1167 PetscMPIInt rank; 1168 PetscErrorCode ierr; 1169 size_t len; 1170 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1171 char *gz,*tfilename; 1172 PetscBool found; 1173 PetscFileMode type = vbinary->btype; 1174 1175 PetscFunctionBegin; 1176 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1177 ierr = PetscStrallocpy(vbinary->filename,&tfilename);CHKERRQ(ierr); 1178 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1179 1180 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1181 ierr = PetscStrallocpy(tfilename,&vbinary->filename);CHKERRQ(ierr); 1182 1183 vbinary->storecompressed = PETSC_FALSE; 1184 1185 /* only first processor opens file if writeable */ 1186 if (type == FILE_MODE_READ) { 1187 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1188 } else if (type == FILE_MODE_WRITE) { 1189 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1190 } 1191 1192 /* 1193 try to open info file: all processors open this file if read only 1194 1195 Below is identical code to the code for Binary above, should be put in seperate routine 1196 */ 1197 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1198 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1199 1200 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1201 /* remove .gz if it ends library name */ 1202 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1203 if (gz) { 1204 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1205 if (len == 3) *gz = 0; 1206 } 1207 1208 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1209 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1210 if (type == FILE_MODE_READ) { 1211 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1212 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1213 } else { 1214 vbinary->fdes_info = fopen(infoname,"w"); 1215 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1216 } 1217 } 1218 1219 ierr = PetscFree(tfilename);CHKERRQ(ierr); 1220 #if defined(PETSC_USE_LOG) 1221 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1222 #endif 1223 PetscFunctionReturn(0); 1224 } 1225 1226 #undef __FUNCT__ 1227 #define __FUNCT__ "PetscViewerBinarySetMPIIO_Binary" 1228 PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer) 1229 { 1230 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1231 PetscFunctionBegin; 1232 vbinary->MPIIO = PETSC_TRUE; 1233 PetscFunctionReturn(0); 1234 } 1235 #endif 1236 1237 #undef __FUNCT__ 1238 #define __FUNCT__ "PetscViewerView_Binary" 1239 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1240 { 1241 PetscErrorCode ierr; 1242 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1243 1244 PetscFunctionBegin; 1245 if (binary->filename) { 1246 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1247 } 1248 PetscFunctionReturn(0); 1249 } 1250 1251 #undef __FUNCT__ 1252 #define __FUNCT__ "PetscViewerSetUp_Binary" 1253 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1254 { 1255 PetscErrorCode ierr; 1256 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1257 1258 PetscFunctionBegin; 1259 if (binary->setupcalled) { PetscFunctionReturn(0); } 1260 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1261 1262 #if defined(PETSC_HAVE_MPIIO) 1263 if (binary->MPIIO) { 1264 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1265 } else { 1266 #endif 1267 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1268 #if defined(PETSC_HAVE_MPIIO) 1269 } 1270 #endif 1271 binary->setupcalled = PETSC_TRUE; 1272 1273 PetscFunctionReturn(0); 1274 } 1275 1276 #undef __FUNCT__ 1277 #define __FUNCT__ "PetscViewerSetFromOptions_Binary" 1278 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptions *PetscOptionsObject,PetscViewer v) 1279 { 1280 PetscErrorCode ierr; 1281 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1282 PetscBool flg; 1283 #if defined(PETSC_HAVE_MPIIO) 1284 PetscBool useMPIIO = PETSC_FALSE; 1285 #endif 1286 1287 PetscFunctionBegin; 1288 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1289 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySkipInfo",PETSC_FALSE,&binary->skipinfo,&flg);CHKERRQ(ierr); 1290 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,&flg);CHKERRQ(ierr); 1291 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,&flg);CHKERRQ(ierr); 1292 #if defined(PETSC_HAVE_MPIIO) 1293 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write binary file","PetscViewerBinarySetMPIIO",PETSC_FALSE,&useMPIIO,&flg);CHKERRQ(ierr); 1294 if (useMPIIO) { 1295 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1296 } 1297 #endif 1298 ierr = PetscOptionsTail();CHKERRQ(ierr); 1299 binary->setfromoptionscalled = PETSC_FALSE; 1300 PetscFunctionReturn(0); 1301 } 1302 1303 #undef __FUNCT__ 1304 #define __FUNCT__ "PetscViewerCreate_Binary" 1305 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1306 { 1307 PetscErrorCode ierr; 1308 PetscViewer_Binary *vbinary; 1309 1310 PetscFunctionBegin; 1311 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1312 v->data = (void*)vbinary; 1313 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1314 v->ops->destroy = PetscViewerDestroy_Binary; 1315 v->ops->view = PetscViewerView_Binary; 1316 v->ops->flush = 0; 1317 vbinary->fdes_info = 0; 1318 vbinary->fdes = 0; 1319 vbinary->skipinfo = PETSC_FALSE; 1320 vbinary->skipoptions = PETSC_TRUE; 1321 vbinary->skipheader = PETSC_FALSE; 1322 vbinary->setupcalled = PETSC_FALSE; 1323 vbinary->setfromoptionscalled = PETSC_FALSE; 1324 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1325 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1326 v->ops->read = PetscViewerBinaryRead; 1327 vbinary->btype = (PetscFileMode) -1; 1328 vbinary->storecompressed = PETSC_FALSE; 1329 vbinary->filename = 0; 1330 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1331 1332 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1333 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1334 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1335 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1336 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1337 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1338 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1339 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1340 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1341 #if defined(PETSC_HAVE_MPIIO) 1342 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1343 #endif 1344 PetscFunctionReturn(0); 1345 } 1346 1347 /* ---------------------------------------------------------------------*/ 1348 /* 1349 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1350 is attached to a communicator, in this case the attribute is a PetscViewer. 1351 */ 1352 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1353 1354 #undef __FUNCT__ 1355 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1356 /*@C 1357 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1358 in a communicator. 1359 1360 Collective on MPI_Comm 1361 1362 Input Parameter: 1363 . comm - the MPI communicator to share the binary PetscViewer 1364 1365 Level: intermediate 1366 1367 Options Database Keys: 1368 + -viewer_binary_filename <name> 1369 . -viewer_binary_skip_info 1370 - -viewer_binary_skip_options 1371 1372 Environmental variables: 1373 - PETSC_VIEWER_BINARY_FILENAME 1374 1375 Notes: 1376 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1377 an error code. The binary PetscViewer is usually used in the form 1378 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1379 1380 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1381 PetscViewerDestroy() 1382 @*/ 1383 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1384 { 1385 PetscErrorCode ierr; 1386 PetscBool flg; 1387 PetscViewer viewer; 1388 char fname[PETSC_MAX_PATH_LEN]; 1389 MPI_Comm ncomm; 1390 1391 PetscFunctionBegin; 1392 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1393 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1394 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1395 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1396 } 1397 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1398 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1399 if (!flg) { /* PetscViewer not yet created */ 1400 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1401 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1402 if (!flg) { 1403 ierr = PetscStrcpy(fname,"binaryoutput"); 1404 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1405 } 1406 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1407 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1408 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1409 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1410 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1411 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1412 } 1413 ierr = PetscCommDestroy(&ncomm); 1414 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1415 PetscFunctionReturn(viewer); 1416 } 1417