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; 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__ "PetscViewerBinaryMPIIO" 722 static PetscErrorCode PetscViewerBinaryMPIIO(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 = PetscViewerBinaryMPIIO(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 = PetscViewerBinaryMPIIO(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 /*@C 877 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 878 879 Collective on MPI_Comm 880 881 Input Parameter: 882 . viewer - the binary viewer 883 884 Output Parameter: 885 . data - location of the array of strings 886 887 Level: intermediate 888 889 Concepts: binary files 890 891 Notes: array of strings is null terminated 892 893 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 894 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 895 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 896 @*/ 897 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 898 { 899 PetscErrorCode ierr; 900 PetscInt i,n,*sizes,N = 0; 901 902 ierr = PetscViewerSetUp_Binary(viewer);CHKERRQ(ierr); 903 /* count number of strings */ 904 ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr); 905 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 906 ierr = PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);CHKERRQ(ierr); 907 for (i=0; i<n; i++) N += sizes[i]; 908 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 909 (*data)[0] = (char*)((*data) + n + 1); 910 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 911 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);CHKERRQ(ierr); 912 913 (*data)[n] = 0; 914 915 ierr = PetscFree(sizes);CHKERRQ(ierr); 916 PetscFunctionReturn(0); 917 } 918 919 #undef __FUNCT__ 920 #define __FUNCT__ "PetscViewerFileGetName_Binary" 921 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 922 { 923 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 924 925 PetscFunctionBegin; 926 *name = vbinary->filename; 927 PetscFunctionReturn(0); 928 } 929 930 #undef __FUNCT__ 931 #define __FUNCT__ "PetscViewerFileGetMode" 932 /*@C 933 PetscViewerFileGetMode - Gets the type of file to be open 934 935 Not Collective 936 937 Input Parameter: 938 . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer 939 940 Output Parameter: 941 . type - type of file 942 $ FILE_MODE_WRITE - create new file for binary output 943 $ FILE_MODE_READ - open existing file for binary input 944 $ FILE_MODE_APPEND - open existing file for binary output 945 946 Level: advanced 947 948 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 949 950 @*/ 951 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 952 { 953 PetscErrorCode ierr; 954 955 PetscFunctionBegin; 956 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 957 PetscValidPointer(type,2); 958 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 959 PetscFunctionReturn(0); 960 } 961 962 #undef __FUNCT__ 963 #define __FUNCT__ "PetscViewerBinarySetMPIIO" 964 /*@ 965 PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called 966 before PetscViewerFileSetName() 967 968 Logically Collective on PetscViewer 969 970 Input Parameters: 971 . viewer - the PetscViewer; must be a binary 972 973 Options Database: 974 -viewer_binary_mpiio : Flag for using MPI-IO 975 976 Level: advanced 977 978 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 979 980 @*/ 981 PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer) 982 { 983 PetscErrorCode ierr; 984 985 PetscFunctionBegin; 986 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 987 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));CHKERRQ(ierr); 988 PetscFunctionReturn(0); 989 } 990 991 992 #undef __FUNCT__ 993 #define __FUNCT__ "PetscViewerFileSetMode" 994 /*@C 995 PetscViewerFileSetMode - Sets the type of file to be open 996 997 Logically Collective on PetscViewer 998 999 Input Parameters: 1000 + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer 1001 - type - type of file 1002 $ FILE_MODE_WRITE - create new file for binary output 1003 $ FILE_MODE_READ - open existing file for binary input 1004 $ FILE_MODE_APPEND - open existing file for binary output 1005 1006 Level: advanced 1007 1008 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1009 1010 @*/ 1011 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1012 { 1013 PetscErrorCode ierr; 1014 1015 PetscFunctionBegin; 1016 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1017 PetscValidLogicalCollectiveEnum(viewer,type,2); 1018 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1019 PetscFunctionReturn(0); 1020 } 1021 1022 #undef __FUNCT__ 1023 #define __FUNCT__ "PetscViewerFileGetMode_Binary" 1024 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1025 { 1026 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1027 1028 PetscFunctionBegin; 1029 *type = vbinary->btype; 1030 PetscFunctionReturn(0); 1031 } 1032 1033 #undef __FUNCT__ 1034 #define __FUNCT__ "PetscViewerFileSetMode_Binary" 1035 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1036 { 1037 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1038 1039 PetscFunctionBegin; 1040 vbinary->btype = type; 1041 PetscFunctionReturn(0); 1042 } 1043 1044 #undef __FUNCT__ 1045 #define __FUNCT__ "PetscViewerFileSetName_Binary" 1046 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1047 { 1048 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1049 PetscErrorCode ierr; 1050 1051 PetscFunctionBegin; 1052 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1053 PetscFunctionReturn(0); 1054 } 1055 /* 1056 Actually opens the file 1057 */ 1058 #undef __FUNCT__ 1059 #define __FUNCT__ "PetscViewerFileSetUp_Binary" 1060 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1061 { 1062 PetscMPIInt rank; 1063 PetscErrorCode ierr; 1064 size_t len; 1065 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1066 const char *fname; 1067 char bname[PETSC_MAX_PATH_LEN],*gz; 1068 PetscBool found; 1069 PetscFileMode type = vbinary->btype; 1070 1071 PetscFunctionBegin; 1072 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1073 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1074 1075 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1076 1077 /* if ends in .gz strip that off and note user wants file compressed */ 1078 vbinary->storecompressed = PETSC_FALSE; 1079 if (!rank && type == FILE_MODE_WRITE) { 1080 /* remove .gz if it ends library name */ 1081 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1082 if (gz) { 1083 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1084 if (len == 3) { 1085 *gz = 0; 1086 vbinary->storecompressed = PETSC_TRUE; 1087 } 1088 } 1089 } 1090 1091 /* only first processor opens file if writeable */ 1092 if (!rank || type == FILE_MODE_READ) { 1093 1094 if (type == FILE_MODE_READ) { 1095 /* possibly get the file from remote site or compressed file */ 1096 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1097 fname = bname; 1098 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1099 else if (!found) { 1100 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1101 fname = 0; 1102 } 1103 } else fname = vbinary->filename; 1104 1105 #if defined(PETSC_HAVE_O_BINARY) 1106 if (type == FILE_MODE_WRITE) { 1107 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); 1108 } else if (type == FILE_MODE_READ && fname) { 1109 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); 1110 } else if (type == FILE_MODE_APPEND) { 1111 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); 1112 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1113 #else 1114 if (type == FILE_MODE_WRITE) { 1115 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1116 } else if (type == FILE_MODE_READ && fname) { 1117 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1118 } else if (type == FILE_MODE_APPEND) { 1119 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); 1120 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1121 #endif 1122 } else vbinary->fdes = -1; 1123 1124 /* 1125 try to open info file: all processors open this file if read only 1126 */ 1127 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1128 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1129 1130 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1131 /* remove .gz if it ends library name */ 1132 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1133 if (gz) { 1134 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1135 if (len == 3) *gz = 0; 1136 } 1137 1138 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1139 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1140 if (type == FILE_MODE_READ) { 1141 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1142 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1143 } else { 1144 vbinary->fdes_info = fopen(infoname,"w"); 1145 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1146 } 1147 } 1148 1149 #if defined(PETSC_USE_LOG) 1150 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1151 #endif 1152 PetscFunctionReturn(0); 1153 } 1154 1155 #if defined(PETSC_HAVE_MPIIO) 1156 #undef __FUNCT__ 1157 #define __FUNCT__ "PetscViewerFileSetUp_BinaryMPIIO" 1158 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1159 { 1160 PetscMPIInt rank; 1161 PetscErrorCode ierr; 1162 size_t len; 1163 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1164 char *gz; 1165 PetscBool found; 1166 PetscFileMode type = vbinary->btype; 1167 1168 PetscFunctionBegin; 1169 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1170 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1171 1172 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1173 1174 vbinary->storecompressed = PETSC_FALSE; 1175 1176 /* only first processor opens file if writeable */ 1177 if (type == FILE_MODE_READ) { 1178 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1179 } else if (type == FILE_MODE_WRITE) { 1180 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1181 } 1182 1183 /* 1184 try to open info file: all processors open this file if read only 1185 1186 Below is identical code to the code for Binary above, should be put in seperate routine 1187 */ 1188 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1189 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1190 1191 ierr = PetscStrcpy(infoname,vbinary->filename);CHKERRQ(ierr); 1192 /* remove .gz if it ends library name */ 1193 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1194 if (gz) { 1195 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1196 if (len == 3) *gz = 0; 1197 } 1198 1199 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1200 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1201 if (type == FILE_MODE_READ) { 1202 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1203 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1204 } else { 1205 vbinary->fdes_info = fopen(infoname,"w"); 1206 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1207 } 1208 } 1209 1210 #if defined(PETSC_USE_LOG) 1211 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1212 #endif 1213 PetscFunctionReturn(0); 1214 } 1215 1216 #undef __FUNCT__ 1217 #define __FUNCT__ "PetscViewerBinarySetMPIIO_Binary" 1218 PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer) 1219 { 1220 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1221 PetscFunctionBegin; 1222 vbinary->MPIIO = PETSC_TRUE; 1223 PetscFunctionReturn(0); 1224 } 1225 #endif 1226 1227 #undef __FUNCT__ 1228 #define __FUNCT__ "PetscViewerView_Binary" 1229 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1230 { 1231 PetscErrorCode ierr; 1232 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1233 1234 PetscFunctionBegin; 1235 if (binary->filename) { 1236 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1237 } 1238 PetscFunctionReturn(0); 1239 } 1240 1241 #undef __FUNCT__ 1242 #define __FUNCT__ "PetscViewerSetUp_Binary" 1243 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1244 { 1245 PetscErrorCode ierr; 1246 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1247 1248 PetscFunctionBegin; 1249 if (binary->setupcalled) { PetscFunctionReturn(0); } 1250 1251 #if defined(PETSC_HAVE_MPIIO) 1252 if (binary->MPIIO) { 1253 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1254 } else { 1255 #endif 1256 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1257 #if defined(PETSC_HAVE_MPIIO) 1258 } 1259 #endif 1260 binary->setupcalled = PETSC_TRUE; 1261 1262 PetscFunctionReturn(0); 1263 } 1264 1265 #undef __FUNCT__ 1266 #define __FUNCT__ "PetscViewerSetFromOptions_Binary" 1267 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptions *PetscOptionsObject,PetscViewer v) 1268 { 1269 PetscErrorCode ierr; 1270 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1271 PetscBool flg; 1272 #if defined(PETSC_HAVE_MPIIO) 1273 PetscBool useMPIIO = PETSC_FALSE; 1274 #endif 1275 1276 PetscFunctionBegin; 1277 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1278 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySkipInfo",PETSC_FALSE,&binary->skipinfo,&flg);CHKERRQ(ierr); 1279 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,&flg);CHKERRQ(ierr); 1280 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,&flg);CHKERRQ(ierr); 1281 #if defined(PETSC_HAVE_MPIIO) 1282 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write binary file","PetscViewerBinarySetMPIIO",PETSC_FALSE,&useMPIIO,&flg);CHKERRQ(ierr); 1283 if (useMPIIO) { 1284 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1285 } 1286 #endif 1287 ierr = PetscOptionsTail();CHKERRQ(ierr); 1288 ierr = PetscViewerSetUp_Binary(v);CHKERRQ(ierr); 1289 PetscFunctionReturn(0); 1290 } 1291 1292 #undef __FUNCT__ 1293 #define __FUNCT__ "PetscViewerCreate_Binary" 1294 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1295 { 1296 PetscErrorCode ierr; 1297 PetscViewer_Binary *vbinary; 1298 1299 PetscFunctionBegin; 1300 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1301 v->data = (void*)vbinary; 1302 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1303 v->ops->destroy = PetscViewerDestroy_Binary; 1304 v->ops->view = PetscViewerView_Binary; 1305 v->ops->flush = 0; 1306 vbinary->fdes_info = 0; 1307 vbinary->fdes = 0; 1308 vbinary->skipinfo = PETSC_FALSE; 1309 vbinary->skipoptions = PETSC_TRUE; 1310 vbinary->skipheader = PETSC_FALSE; 1311 vbinary->setupcalled = PETSC_FALSE; 1312 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1313 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1314 v->ops->read = PetscViewerBinaryRead; 1315 vbinary->btype = (PetscFileMode) -1; 1316 vbinary->storecompressed = PETSC_FALSE; 1317 vbinary->filename = 0; 1318 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1319 1320 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1321 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1322 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1323 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1324 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1325 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1326 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1327 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1328 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1329 #if defined(PETSC_HAVE_MPIIO) 1330 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1331 #endif 1332 PetscFunctionReturn(0); 1333 } 1334 1335 /* ---------------------------------------------------------------------*/ 1336 /* 1337 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1338 is attached to a communicator, in this case the attribute is a PetscViewer. 1339 */ 1340 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1341 1342 #undef __FUNCT__ 1343 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1344 /*@C 1345 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1346 in a communicator. 1347 1348 Collective on MPI_Comm 1349 1350 Input Parameter: 1351 . comm - the MPI communicator to share the binary PetscViewer 1352 1353 Level: intermediate 1354 1355 Options Database Keys: 1356 + -viewer_binary_filename <name> 1357 . -viewer_binary_skip_info 1358 - -viewer_binary_skip_options 1359 1360 Environmental variables: 1361 - PETSC_VIEWER_BINARY_FILENAME 1362 1363 Notes: 1364 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1365 an error code. The binary PetscViewer is usually used in the form 1366 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1367 1368 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1369 PetscViewerDestroy() 1370 @*/ 1371 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1372 { 1373 PetscErrorCode ierr; 1374 PetscBool flg; 1375 PetscViewer viewer; 1376 char fname[PETSC_MAX_PATH_LEN]; 1377 MPI_Comm ncomm; 1378 1379 PetscFunctionBegin; 1380 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1381 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1382 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1383 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1384 } 1385 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1386 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1387 if (!flg) { /* PetscViewer not yet created */ 1388 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1389 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1390 if (!flg) { 1391 ierr = PetscStrcpy(fname,"binaryoutput"); 1392 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1393 } 1394 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1395 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1396 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1397 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1398 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1399 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1400 } 1401 ierr = PetscCommDestroy(&ncomm); 1402 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1403 PetscFunctionReturn(viewer); 1404 } 1405