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