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 } 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 } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get singleton viewer for binary files or sockets"); 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 #undef __FUNCT__ 200 #define __FUNCT__ "PetscViewerBinaryGetFlowControl_Binary" 201 PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc) 202 { 203 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 204 205 PetscFunctionBegin; 206 *fc = vbinary->flowcontrol; 207 PetscFunctionReturn(0); 208 } 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "PetscViewerBinaryGetFlowControl" 212 /*@C 213 PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes 214 215 Not Collective 216 217 Input Parameter: 218 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 219 220 Output Parameter: 221 . fc - the number of messages 222 223 Level: advanced 224 225 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl() 226 227 @*/ 228 PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc) 229 { 230 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 231 PetscErrorCode ierr; 232 233 PetscFunctionBegin; 234 *fc = vbinary->flowcontrol; 235 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr); 236 PetscFunctionReturn(0); 237 } 238 239 #undef __FUNCT__ 240 #define __FUNCT__ "PetscViewerBinarySetFlowControl_Binary" 241 PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc) 242 { 243 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 244 245 PetscFunctionBegin; 246 if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc); 247 vbinary->flowcontrol = fc; 248 PetscFunctionReturn(0); 249 } 250 251 #undef __FUNCT__ 252 #define __FUNCT__ "PetscViewerBinarySetFlowControl" 253 /*@C 254 PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes 255 256 Not Collective 257 258 Input Parameter: 259 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 260 - fc - the number of messages, defaults to 256 if this function was not called 261 262 Level: advanced 263 264 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl() 265 266 @*/ 267 PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc) 268 { 269 PetscErrorCode ierr; 270 271 PetscFunctionBegin; 272 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr); 273 PetscFunctionReturn(0); 274 } 275 276 #undef __FUNCT__ 277 #define __FUNCT__ "PetscViewerBinaryGetDescriptor" 278 /*@C 279 PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer. 280 281 Not Collective 282 283 Input Parameter: 284 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 285 286 Output Parameter: 287 . fdes - file descriptor 288 289 Level: advanced 290 291 Notes: 292 For writable binary PetscViewers, the descriptor will only be valid for the 293 first processor in the communicator that shares the PetscViewer. For readable 294 files it will only be valid on nodes that have the file. If node 0 does not 295 have the file it generates an error even if another node does have the file. 296 297 Fortran Note: 298 This routine is not supported in Fortran. 299 300 Concepts: file descriptor^getting 301 Concepts: PetscViewerBinary^accessing file descriptor 302 303 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer() 304 @*/ 305 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes) 306 { 307 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 308 309 PetscFunctionBegin; 310 *fdes = vbinary->fdes; 311 PetscFunctionReturn(0); 312 } 313 314 #undef __FUNCT__ 315 #define __FUNCT__ "PetscViewerBinarySkipInfo" 316 /*@ 317 PetscViewerBinarySkipInfo - Binary file will not have .info file created with it 318 319 Not Collective 320 321 Input Paramter: 322 . viewer - PetscViewer context, obtained from PetscViewerCreate() 323 324 Options Database Key: 325 . -viewer_binary_skip_info 326 327 Level: advanced 328 329 Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then 330 you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the 331 viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName(). 332 333 The .info contains meta information about the data in the binary file, for example the block size if it was 334 set for a vector or matrix. 335 336 Concepts: PetscViewerBinary^accessing info file 337 338 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 339 PetscViewerBinaryGetSkipOptions() 340 @*/ 341 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer) 342 { 343 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 344 345 PetscFunctionBegin; 346 vbinary->skipinfo = PETSC_TRUE; 347 PetscFunctionReturn(0); 348 } 349 350 #undef __FUNCT__ 351 #define __FUNCT__ "PetscViewerBinarySetSkipOptions" 352 /*@ 353 PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects 354 355 Not Collective 356 357 Input Parameters: 358 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 359 - skip - PETSC_TRUE means do not use 360 361 Options Database Key: 362 . -viewer_binary_skip_options 363 364 Level: advanced 365 366 Notes: This must be called after PetscViewerSetType() 367 368 Concepts: PetscViewerBinary^accessing info file 369 370 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 371 PetscViewerBinaryGetSkipOptions() 372 @*/ 373 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip) 374 { 375 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 376 377 PetscFunctionBegin; 378 vbinary->skipoptions = skip; 379 PetscFunctionReturn(0); 380 } 381 382 #undef __FUNCT__ 383 #define __FUNCT__ "PetscViewerBinaryGetSkipOptions" 384 /*@ 385 PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects 386 387 Not Collective 388 389 Input Parameter: 390 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 391 392 Output Parameter: 393 . skip - PETSC_TRUE means do not use 394 395 Level: advanced 396 397 Notes: This must be called after PetscViewerSetType() 398 399 Concepts: PetscViewerBinary^accessing info file 400 401 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 402 PetscViewerBinarySetSkipOptions() 403 @*/ 404 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip) 405 { 406 PetscViewer_Binary *vbinary; 407 408 PetscFunctionBegin; 409 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 410 vbinary = (PetscViewer_Binary*)viewer->data; 411 *skip = vbinary->skipoptions; 412 PetscFunctionReturn(0); 413 } 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "PetscViewerBinarySetSkipHeader_Binary" 417 PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip) 418 { 419 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 420 421 PetscFunctionBegin; 422 vbinary->skipheader = skip; 423 PetscFunctionReturn(0); 424 } 425 426 #undef __FUNCT__ 427 #define __FUNCT__ "PetscViewerBinarySetSkipHeader" 428 /*@ 429 PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data 430 431 Not Collective 432 433 Input Parameters: 434 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 435 - skip - PETSC_TRUE means do not write header 436 437 Options Database Key: 438 . -viewer_binary_skip_header 439 440 Level: advanced 441 442 Notes: This must be called after PetscViewerSetType() 443 444 Can ONLY be called on a binary viewer 445 446 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 447 PetscViewerBinaryGetSkipHeader() 448 @*/ 449 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip) 450 { 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 455 PetscFunctionReturn(0); 456 } 457 458 #undef __FUNCT__ 459 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader_Binary" 460 PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip) 461 { 462 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 463 464 PetscFunctionBegin; 465 *skip = vbinary->skipheader; 466 PetscFunctionReturn(0); 467 } 468 469 #undef __FUNCT__ 470 #define __FUNCT__ "PetscViewerBinaryGetSkipHeader" 471 /*@ 472 PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data 473 474 Not Collective 475 476 Input Parameter: 477 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 478 479 Output Parameter: 480 . skip - PETSC_TRUE means do not write header 481 482 Level: advanced 483 484 Notes: This must be called after PetscViewerSetType() 485 486 Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it. 487 488 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 489 PetscViewerBinarySetSkipHeader() 490 @*/ 491 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip) 492 { 493 PetscErrorCode ierr; 494 495 PetscFunctionBegin; 496 *skip = PETSC_FALSE; 497 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 498 PetscFunctionReturn(0); 499 } 500 501 #undef __FUNCT__ 502 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer_Binary" 503 PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file) 504 { 505 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 506 PetscErrorCode ierr; 507 MPI_Comm comm; 508 509 PetscFunctionBegin; 510 *file = vbinary->fdes_info; 511 if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) { 512 vbinary->matlabheaderwritten = PETSC_TRUE; 513 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 514 ierr = PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 515 ierr = PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr); 516 ierr = PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr); 517 ierr = PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 518 } 519 PetscFunctionReturn(0); 520 } 521 522 #undef __FUNCT__ 523 #define __FUNCT__ "PetscViewerBinaryGetInfoPointer" 524 /*@C 525 PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII 526 info file associated with a binary file. 527 528 Not Collective 529 530 Input Parameter: 531 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 532 533 Output Parameter: 534 . file - file pointer Always returns NULL if not a binary viewer 535 536 Level: advanced 537 538 Notes: 539 For writable binary PetscViewers, the descriptor will only be valid for the 540 first processor in the communicator that shares the PetscViewer. 541 542 Fortran Note: 543 This routine is not supported in Fortran. 544 545 Concepts: PetscViewerBinary^accessing info file 546 547 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor() 548 @*/ 549 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file) 550 { 551 PetscErrorCode ierr; 552 553 PetscFunctionBegin; 554 *file = NULL; 555 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr); 556 PetscFunctionReturn(0); 557 } 558 559 #undef __FUNCT__ 560 #define __FUNCT__ "PetscViewerFileClose_Binary" 561 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v) 562 { 563 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 564 PetscErrorCode ierr; 565 PetscMPIInt rank; 566 int err; 567 568 PetscFunctionBegin; 569 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr); 570 if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) { 571 close(vbinary->fdes); 572 if (!rank && vbinary->storecompressed) { 573 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 574 FILE *fp; 575 /* compress the file */ 576 ierr = PetscStrcpy(par,"gzip -f ");CHKERRQ(ierr); 577 ierr = PetscStrcat(par,vbinary->filename);CHKERRQ(ierr); 578 #if defined(PETSC_HAVE_POPEN) 579 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 580 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf); 581 ierr = PetscPClose(PETSC_COMM_SELF,fp,NULL);CHKERRQ(ierr); 582 #else 583 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 584 #endif 585 } 586 } 587 if (vbinary->fdes_info) { 588 err = fclose(vbinary->fdes_info); 589 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 590 } 591 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 592 PetscFunctionReturn(0); 593 } 594 595 #undef __FUNCT__ 596 #define __FUNCT__ "PetscViewerDestroy_Binary" 597 PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v) 598 { 599 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 600 PetscErrorCode ierr; 601 602 PetscFunctionBegin; 603 if (v->format == PETSC_VIEWER_BINARY_MATLAB) { 604 MPI_Comm comm; 605 FILE *info; 606 607 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 608 ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr); 609 ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 610 ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr); 611 ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 612 } 613 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr); 614 ierr = PetscFree(vbinary);CHKERRQ(ierr); 615 PetscFunctionReturn(0); 616 } 617 618 #if defined(PETSC_HAVE_MPIIO) 619 #undef __FUNCT__ 620 #define __FUNCT__ "PetscViewerFileClose_MPIIO" 621 static PetscErrorCode PetscViewerFileClose_MPIIO(PetscViewer v) 622 { 623 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 624 int err; 625 PetscErrorCode ierr; 626 627 PetscFunctionBegin; 628 if (vbinary->mfdes) { 629 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr); 630 } 631 if (vbinary->fdes_info) { 632 err = fclose(vbinary->fdes_info); 633 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 634 } 635 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 636 PetscFunctionReturn(0); 637 } 638 639 640 #undef __FUNCT__ 641 #define __FUNCT__ "PetscViewerDestroy_MPIIO" 642 PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v) 643 { 644 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 645 PetscErrorCode ierr; 646 647 PetscFunctionBegin; 648 ierr = PetscViewerFileClose_MPIIO(v);CHKERRQ(ierr); 649 ierr = PetscFree(vbinary);CHKERRQ(ierr); 650 PetscFunctionReturn(0); 651 } 652 #endif 653 654 #undef __FUNCT__ 655 #define __FUNCT__ "PetscViewerBinaryOpen" 656 /*@C 657 PetscViewerBinaryOpen - Opens a file for binary input/output. 658 659 Collective on MPI_Comm 660 661 Input Parameters: 662 + comm - MPI communicator 663 . name - name of file 664 - type - type of file 665 $ FILE_MODE_WRITE - create new file for binary output 666 $ FILE_MODE_READ - open existing file for binary input 667 $ FILE_MODE_APPEND - open existing file for binary output 668 669 Output Parameter: 670 . binv - PetscViewer for binary input/output to use with the specified file 671 672 Options Database Keys: 673 + -viewer_binary_skip_info 674 . -viewer_binary_skip_options 675 - -viewer_binary_skip_header 676 677 Level: beginner 678 679 Note: 680 This PetscViewer should be destroyed with PetscViewerDestroy(). 681 682 For reading files, the filename may begin with ftp:// or http:// and/or 683 end with .gz; in this case file is brought over and uncompressed. 684 685 For creating files, if the file name ends with .gz it is automatically 686 compressed when closed. 687 688 For writing files it only opens the file on processor 0 in the communicator. 689 For readable files it opens the file on all nodes that have the file. If 690 node 0 does not have the file it generates an error even if other nodes 691 do have the file. 692 693 Concepts: binary files 694 Concepts: PetscViewerBinary^creating 695 Concepts: gzip 696 Concepts: accessing remote file 697 Concepts: remote file 698 699 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 700 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 701 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 702 @*/ 703 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 704 { 705 PetscErrorCode ierr; 706 707 PetscFunctionBegin; 708 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 709 ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr); 710 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 711 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 712 PetscFunctionReturn(0); 713 } 714 715 #if defined(PETSC_HAVE_MPIIO) 716 #undef __FUNCT__ 717 #define __FUNCT__ "PetscViewerBinaryMPIIO" 718 static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool write) 719 { 720 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 721 PetscErrorCode ierr; 722 MPI_Datatype mdtype; 723 PetscMPIInt cnt; 724 MPI_Status status; 725 MPI_Aint ul,dsize; 726 727 PetscFunctionBegin; 728 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 729 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 730 ierr = MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 731 if (write) { 732 ierr = MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 733 } else { 734 ierr = MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 735 } 736 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 737 738 vbinary->moff += dsize*cnt; 739 PetscFunctionReturn(0); 740 } 741 #endif 742 743 #undef __FUNCT__ 744 #define __FUNCT__ "PetscViewerBinaryRead" 745 /*@C 746 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 747 748 Collective on MPI_Comm 749 750 Input Parameters: 751 + viewer - the binary viewer 752 . data - location to write the data 753 . count - number of items of data to read 754 - datatype - type of data to read 755 756 Level: beginner 757 758 Concepts: binary files 759 760 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 761 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 762 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 763 @*/ 764 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype) 765 { 766 PetscErrorCode ierr; 767 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 768 769 #if defined(PETSC_HAVE_MPIIO) 770 if (vbinary->MPIIO) { 771 ierr = PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 772 } else { 773 #endif 774 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);CHKERRQ(ierr); 775 #if defined(PETSC_HAVE_MPIIO) 776 } 777 #endif 778 PetscFunctionReturn(0); 779 } 780 781 782 #undef __FUNCT__ 783 #define __FUNCT__ "PetscViewerBinaryWrite" 784 /*@C 785 PetscViewerBinaryWrite - writes to a binary file, only from the first process 786 787 Collective on MPI_Comm 788 789 Input Parameters: 790 + viewer - the binary viewer 791 . data - location of data 792 . count - number of items of data to write 793 . dtype - type of data to write 794 - istemp - data may be overwritten 795 796 Level: beginner 797 798 Notes: because byte-swapping may be done on the values in data it cannot be declared const 799 800 Concepts: binary files 801 802 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 803 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 804 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 805 @*/ 806 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 807 { 808 PetscErrorCode ierr; 809 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 810 811 PetscFunctionBegin; 812 #if defined(PETSC_HAVE_MPIIO) 813 if (vbinary->MPIIO) { 814 ierr = PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);CHKERRQ(ierr); 815 } else { 816 #endif 817 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 818 #if defined(PETSC_HAVE_MPIIO) 819 } 820 #endif 821 PetscFunctionReturn(0); 822 } 823 824 #undef __FUNCT__ 825 #define __FUNCT__ "PetscViewerBinaryWriteStringArray" 826 /*@C 827 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 828 829 Collective on MPI_Comm 830 831 Input Parameters: 832 + viewer - the binary viewer 833 - data - location of the array of strings 834 835 836 Level: intermediate 837 838 Concepts: binary files 839 840 Notes: array of strings is null terminated 841 842 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 843 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 844 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 845 @*/ 846 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data) 847 { 848 PetscErrorCode ierr; 849 PetscInt i,n = 0,*sizes; 850 851 /* count number of strings */ 852 while (data[n++]) ; 853 n--; 854 ierr = PetscMalloc1((n+1),&sizes);CHKERRQ(ierr); 855 sizes[0] = n; 856 for (i=0; i<n; i++) { 857 size_t tmp; 858 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 859 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 860 } 861 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 862 for (i=0; i<n; i++) { 863 ierr = PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 864 } 865 ierr = PetscFree(sizes);CHKERRQ(ierr); 866 PetscFunctionReturn(0); 867 } 868 869 /*@C 870 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 871 872 Collective on MPI_Comm 873 874 Input Parameter: 875 . viewer - the binary viewer 876 877 Output Parameter: 878 . data - location of the array of strings 879 880 Level: intermediate 881 882 Concepts: binary files 883 884 Notes: array of strings is null terminated 885 886 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 887 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 888 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 889 @*/ 890 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 891 { 892 PetscErrorCode ierr; 893 PetscInt i,n,*sizes,N = 0; 894 895 /* count number of strings */ 896 ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr); 897 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 898 ierr = PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);CHKERRQ(ierr); 899 for (i=0; i<n; i++) N += sizes[i]; 900 ierr = PetscMalloc1((n+1)*sizeof(char*) + N,data);CHKERRQ(ierr); 901 (*data)[0] = (char*)((*data) + n + 1); 902 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 903 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);CHKERRQ(ierr); 904 905 (*data)[n] = 0; 906 907 ierr = PetscFree(sizes);CHKERRQ(ierr); 908 PetscFunctionReturn(0); 909 } 910 911 #undef __FUNCT__ 912 #define __FUNCT__ "PetscViewerFileGetName_Binary" 913 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 914 { 915 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 916 917 PetscFunctionBegin; 918 *name = vbinary->filename; 919 PetscFunctionReturn(0); 920 } 921 922 #undef __FUNCT__ 923 #define __FUNCT__ "PetscViewerFileGetMode" 924 /*@C 925 PetscViewerFileGetMode - Gets the type of file to be open 926 927 Not Collective 928 929 Input Parameter: 930 . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer 931 932 Output Parameter: 933 . type - type of file 934 $ FILE_MODE_WRITE - create new file for binary output 935 $ FILE_MODE_READ - open existing file for binary input 936 $ FILE_MODE_APPEND - open existing file for binary output 937 938 Level: advanced 939 940 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 941 942 @*/ 943 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 944 { 945 PetscErrorCode ierr; 946 947 PetscFunctionBegin; 948 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 949 PetscValidPointer(type,2); 950 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 951 PetscFunctionReturn(0); 952 } 953 954 #undef __FUNCT__ 955 #define __FUNCT__ "PetscViewerBinarySetMPIIO" 956 /*@ 957 PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called 958 before PetscViewerFileSetName() 959 960 Logically Collective on PetscViewer 961 962 Input Parameters: 963 . viewer - the PetscViewer; must be a binary 964 965 Options Database: 966 -viewer_binary_mpiio : Flag for using MPI-IO 967 968 Level: advanced 969 970 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 971 972 @*/ 973 PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer) 974 { 975 PetscErrorCode ierr; 976 977 PetscFunctionBegin; 978 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 979 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));CHKERRQ(ierr); 980 PetscFunctionReturn(0); 981 } 982 983 984 #undef __FUNCT__ 985 #define __FUNCT__ "PetscViewerFileSetMode" 986 /*@C 987 PetscViewerFileSetMode - Sets the type of file to be open 988 989 Logically Collective on PetscViewer 990 991 Input Parameters: 992 + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer 993 - type - type of file 994 $ FILE_MODE_WRITE - create new file for binary output 995 $ FILE_MODE_READ - open existing file for binary input 996 $ FILE_MODE_APPEND - open existing file for binary output 997 998 Level: advanced 999 1000 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1001 1002 @*/ 1003 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1004 { 1005 PetscErrorCode ierr; 1006 1007 PetscFunctionBegin; 1008 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1009 PetscValidLogicalCollectiveEnum(viewer,type,2); 1010 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1011 PetscFunctionReturn(0); 1012 } 1013 1014 #undef __FUNCT__ 1015 #define __FUNCT__ "PetscViewerFileGetMode_Binary" 1016 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1017 { 1018 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1019 1020 PetscFunctionBegin; 1021 *type = vbinary->btype; 1022 PetscFunctionReturn(0); 1023 } 1024 1025 #undef __FUNCT__ 1026 #define __FUNCT__ "PetscViewerFileSetMode_Binary" 1027 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1028 { 1029 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1030 1031 PetscFunctionBegin; 1032 vbinary->btype = type; 1033 PetscFunctionReturn(0); 1034 } 1035 1036 /* 1037 Actually opens the file 1038 */ 1039 #undef __FUNCT__ 1040 #define __FUNCT__ "PetscViewerFileSetName_Binary" 1041 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1042 { 1043 PetscMPIInt rank; 1044 PetscErrorCode ierr; 1045 size_t len; 1046 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1047 const char *fname; 1048 char bname[PETSC_MAX_PATH_LEN],*gz; 1049 PetscBool found; 1050 PetscFileMode type = vbinary->btype; 1051 1052 PetscFunctionBegin; 1053 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1054 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1055 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);CHKERRQ(ierr); 1056 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);CHKERRQ(ierr); 1057 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,NULL);CHKERRQ(ierr); 1058 1059 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1060 1061 /* copy name so we can edit it */ 1062 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1063 1064 /* if ends in .gz strip that off and note user wants file compressed */ 1065 vbinary->storecompressed = PETSC_FALSE; 1066 if (!rank && type == FILE_MODE_WRITE) { 1067 /* remove .gz if it ends library name */ 1068 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1069 if (gz) { 1070 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1071 if (len == 3) { 1072 *gz = 0; 1073 vbinary->storecompressed = PETSC_TRUE; 1074 } 1075 } 1076 } 1077 1078 /* only first processor opens file if writeable */ 1079 if (!rank || type == FILE_MODE_READ) { 1080 1081 if (type == FILE_MODE_READ) { 1082 /* possibly get the file from remote site or compressed file */ 1083 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1084 fname = bname; 1085 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1086 else if (!found) { 1087 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1088 fname = 0; 1089 } 1090 } else fname = vbinary->filename; 1091 1092 #if defined(PETSC_HAVE_O_BINARY) 1093 if (type == FILE_MODE_WRITE) { 1094 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); 1095 } else if (type == FILE_MODE_READ && fname) { 1096 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); 1097 } else if (type == FILE_MODE_APPEND) { 1098 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); 1099 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1100 #else 1101 if (type == FILE_MODE_WRITE) { 1102 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1103 } else if (type == FILE_MODE_READ && fname) { 1104 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1105 } else if (type == FILE_MODE_APPEND) { 1106 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); 1107 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1108 #endif 1109 } else vbinary->fdes = -1; 1110 1111 /* 1112 try to open info file: all processors open this file if read only 1113 */ 1114 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1115 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1116 1117 ierr = PetscStrcpy(infoname,name);CHKERRQ(ierr); 1118 /* remove .gz if it ends library name */ 1119 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1120 if (gz) { 1121 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1122 if (len == 3) *gz = 0; 1123 } 1124 1125 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1126 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1127 if (type == FILE_MODE_READ) { 1128 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1129 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1130 } else { 1131 vbinary->fdes_info = fopen(infoname,"w"); 1132 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1133 } 1134 } 1135 1136 #if defined(PETSC_USE_LOG) 1137 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1138 #endif 1139 PetscFunctionReturn(0); 1140 } 1141 1142 #if defined(PETSC_HAVE_MPIIO) 1143 #undef __FUNCT__ 1144 #define __FUNCT__ "PetscViewerFileSetName_MPIIO" 1145 PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[]) 1146 { 1147 PetscMPIInt rank; 1148 PetscErrorCode ierr; 1149 size_t len; 1150 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1151 char *gz; 1152 PetscBool found; 1153 PetscFileMode type = vbinary->btype; 1154 1155 PetscFunctionBegin; 1156 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1157 ierr = PetscViewerFileClose_MPIIO(viewer);CHKERRQ(ierr); 1158 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);CHKERRQ(ierr); 1159 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);CHKERRQ(ierr); 1160 1161 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1162 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1163 1164 vbinary->storecompressed = PETSC_FALSE; 1165 1166 /* only first processor opens file if writeable */ 1167 if (type == FILE_MODE_READ) { 1168 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1169 } else if (type == FILE_MODE_WRITE) { 1170 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1171 } 1172 1173 /* 1174 try to open info file: all processors open this file if read only 1175 1176 Below is identical code to the code for Binary above, should be put in seperate routine 1177 */ 1178 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1179 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1180 1181 ierr = PetscStrcpy(infoname,name);CHKERRQ(ierr); 1182 /* remove .gz if it ends library name */ 1183 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1184 if (gz) { 1185 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1186 if (len == 3) *gz = 0; 1187 } 1188 1189 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1190 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1191 if (type == FILE_MODE_READ) { 1192 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1193 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1194 } else { 1195 vbinary->fdes_info = fopen(infoname,"w"); 1196 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1197 } 1198 } 1199 1200 #if defined(PETSC_USE_LOG) 1201 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1202 #endif 1203 PetscFunctionReturn(0); 1204 } 1205 1206 #undef __FUNCT__ 1207 #define __FUNCT__ "PetscViewerBinarySetMPIIO_Binary" 1208 PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer) 1209 { 1210 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1211 PetscErrorCode ierr; 1212 1213 PetscFunctionBegin; 1214 if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()"); 1215 viewer->ops->destroy = PetscViewerDestroy_MPIIO; 1216 vbinary->MPIIO = PETSC_TRUE; 1217 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_MPIIO);CHKERRQ(ierr); 1218 PetscFunctionReturn(0); 1219 } 1220 #endif 1221 1222 #undef __FUNCT__ 1223 #define __FUNCT__ "PetscViewerView_Binary" 1224 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1225 { 1226 PetscErrorCode ierr; 1227 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1228 1229 PetscFunctionBegin; 1230 if (binary->filename) { 1231 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1232 } 1233 PetscFunctionReturn(0); 1234 } 1235 1236 #undef __FUNCT__ 1237 #define __FUNCT__ "PetscViewerCreate_Binary" 1238 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1239 { 1240 PetscErrorCode ierr; 1241 PetscViewer_Binary *vbinary; 1242 #if defined(PETSC_HAVE_MPIIO) 1243 PetscBool useMPIIO = PETSC_FALSE; 1244 #endif 1245 1246 PetscFunctionBegin; 1247 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1248 v->data = (void*)vbinary; 1249 v->ops->destroy = PetscViewerDestroy_Binary; 1250 v->ops->view = PetscViewerView_Binary; 1251 v->ops->flush = 0; 1252 vbinary->fdes_info = 0; 1253 vbinary->fdes = 0; 1254 vbinary->skipinfo = PETSC_FALSE; 1255 vbinary->skipoptions = PETSC_TRUE; 1256 vbinary->skipheader = PETSC_FALSE; 1257 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1258 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1259 vbinary->btype = (PetscFileMode) -1; 1260 vbinary->storecompressed = PETSC_FALSE; 1261 vbinary->filename = 0; 1262 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1263 1264 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1265 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1266 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1267 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1268 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1269 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1270 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1271 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1272 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1273 #if defined(PETSC_HAVE_MPIIO) 1274 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1275 1276 ierr = PetscOptionsGetBool(NULL,"-viewer_binary_mpiio",&useMPIIO,NULL);CHKERRQ(ierr); 1277 if (useMPIIO) { 1278 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1279 } 1280 #endif 1281 PetscFunctionReturn(0); 1282 } 1283 1284 /* ---------------------------------------------------------------------*/ 1285 /* 1286 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1287 is attached to a communicator, in this case the attribute is a PetscViewer. 1288 */ 1289 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1290 1291 #undef __FUNCT__ 1292 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1293 /*@C 1294 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1295 in a communicator. 1296 1297 Collective on MPI_Comm 1298 1299 Input Parameter: 1300 . comm - the MPI communicator to share the binary PetscViewer 1301 1302 Level: intermediate 1303 1304 Options Database Keys: 1305 + -viewer_binary_filename <name> 1306 . -viewer_binary_skip_info 1307 - -viewer_binary_skip_options 1308 1309 Environmental variables: 1310 - PETSC_VIEWER_BINARY_FILENAME 1311 1312 Notes: 1313 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1314 an error code. The binary PetscViewer is usually used in the form 1315 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1316 1317 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1318 PetscViewerDestroy() 1319 @*/ 1320 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1321 { 1322 PetscErrorCode ierr; 1323 PetscBool flg; 1324 PetscViewer viewer; 1325 char fname[PETSC_MAX_PATH_LEN]; 1326 MPI_Comm ncomm; 1327 1328 PetscFunctionBegin; 1329 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1330 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1331 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1332 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1333 } 1334 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1335 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1336 if (!flg) { /* PetscViewer not yet created */ 1337 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1338 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1339 if (!flg) { 1340 ierr = PetscStrcpy(fname,"binaryoutput"); 1341 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1342 } 1343 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1344 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1345 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1346 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1347 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1348 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1349 } 1350 ierr = PetscCommDestroy(&ncomm); 1351 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1352 PetscFunctionReturn(viewer); 1353 } 1354