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