1 #define PETSC_DLL 2 3 /* 4 This file contains simple binary read/write routines. 5 */ 6 7 #include "petsc.h" 8 #include "petscsys.h" /*I "petscsys.h" I*/ 9 10 #include <errno.h> 11 #include <fcntl.h> 12 #if defined(PETSC_HAVE_UNISTD_H) 13 #include <unistd.h> 14 #endif 15 #if defined (PETSC_HAVE_IO_H) 16 #include <io.h> 17 #endif 18 #include "petscbt.h" 19 20 #if (PETSC_SIZEOF_INT == 8) 21 #define PetscInt32 short 22 #else 23 #define PetscInt32 int 24 #endif 25 26 #if !defined(PETSC_WORDS_BIGENDIAN) 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "PetscByteSwapInt" 30 /* 31 PetscByteSwapInt - Swap bytes in a 32 bit integer. NOT a PetscInt! Note that PETSc binary read and write 32 always store and read only 32 bit integers! (See PetscBinaryRead(), PetscBinaryWrite()). 33 34 */ 35 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapInt(PetscInt32 *buff,PetscInt n) 36 { 37 PetscInt i,j,tmp = 0; 38 PetscInt *tptr = &tmp; /* Need to access tmp indirectly to get */ 39 char *ptr1,*ptr2 = (char*)&tmp; /* arround the bug in DEC-ALPHA g++ */ 40 41 PetscFunctionBegin; 42 for (j=0; j<n; j++) { 43 ptr1 = (char*)(buff + j); 44 for (i=0; i<(int)sizeof(PetscInt32); i++) { 45 ptr2[i] = ptr1[sizeof(PetscInt32)-1-i]; 46 } 47 buff[j] = *tptr; 48 } 49 PetscFunctionReturn(0); 50 } 51 /* --------------------------------------------------------- */ 52 #undef __FUNCT__ 53 #define __FUNCT__ "PetscByteSwapShort" 54 /* 55 PetscByteSwapShort - Swap bytes in a short 56 */ 57 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapShort(short *buff,PetscInt n) 58 { 59 PetscInt i,j; 60 short tmp; 61 short *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 62 char *ptr1,*ptr2 = (char*)&tmp; 63 64 PetscFunctionBegin; 65 for (j=0; j<n; j++) { 66 ptr1 = (char*)(buff + j); 67 for (i=0; i<(int) sizeof(short); i++) { 68 ptr2[i] = ptr1[sizeof(int)-1-i]; 69 } 70 buff[j] = *tptr; 71 } 72 PetscFunctionReturn(0); 73 } 74 /* --------------------------------------------------------- */ 75 #undef __FUNCT__ 76 #define __FUNCT__ "PetscByteSwapScalar" 77 /* 78 PetscByteSwapScalar - Swap bytes in a double 79 Complex is dealt with as if array of double twice as long. 80 */ 81 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapScalar(PetscScalar *buff,PetscInt n) 82 { 83 PetscInt i,j; 84 PetscReal tmp,*buff1 = (PetscReal*)buff; 85 PetscReal *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 86 char *ptr1,*ptr2 = (char*)&tmp; 87 88 PetscFunctionBegin; 89 #if defined(PETSC_USE_COMPLEX) 90 n *= 2; 91 #endif 92 for (j=0; j<n; j++) { 93 ptr1 = (char*)(buff1 + j); 94 for (i=0; i<(int) sizeof(PetscReal); i++) { 95 ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 96 } 97 buff1[j] = *tptr; 98 } 99 PetscFunctionReturn(0); 100 } 101 /* --------------------------------------------------------- */ 102 #undef __FUNCT__ 103 #define __FUNCT__ "PetscByteSwapDouble" 104 /* 105 PetscByteSwapDouble - Swap bytes in a double 106 */ 107 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapDouble(double *buff,PetscInt n) 108 { 109 PetscInt i,j; 110 double tmp,*buff1 = (double*)buff; 111 double *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 112 char *ptr1,*ptr2 = (char*)&tmp; 113 114 PetscFunctionBegin; 115 for (j=0; j<n; j++) { 116 ptr1 = (char*)(buff1 + j); 117 for (i=0; i<(int) sizeof(double); i++) { 118 ptr2[i] = ptr1[sizeof(double)-1-i]; 119 } 120 buff1[j] = *tptr; 121 } 122 PetscFunctionReturn(0); 123 } 124 #endif 125 /* --------------------------------------------------------- */ 126 #undef __FUNCT__ 127 #define __FUNCT__ "PetscBinaryRead" 128 /*@ 129 PetscBinaryRead - Reads from a binary file. 130 131 Not Collective 132 133 Input Parameters: 134 + fd - the file 135 . n - the number of items to read 136 - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 137 138 Output Parameters: 139 . p - the buffer 140 141 142 143 Level: developer 144 145 Notes: 146 PetscBinaryRead() uses byte swapping to work on all machines; the files 147 are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers 148 are converted to the small-endian format when they are read in from the file. 149 Integers are stored on the file as 32 bits long, regardless of whether 150 they are stored in the machine as 32 bits or 64 bits, this means the same 151 binary file may be read on any machine. 152 153 Concepts: files^reading binary 154 Concepts: binary files^reading 155 156 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor() 157 @*/ 158 PetscErrorCode PETSC_DLLEXPORT PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type) 159 { 160 #if (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) || !defined(PETSC_WORDS_BIGENDIAN) 161 PetscErrorCode ierr; 162 #endif 163 int wsize,err; 164 size_t m = (size_t) n,maxblock = 65536; 165 char *pp = (char*)p; 166 #if (PETSC_SIZEOF_INT == 8) || !defined(PETSC_WORDS_BIGENDIAN) || defined(PETSC_USE_64BIT_INDICES) 167 void *ptmp = p; 168 #endif 169 170 PetscFunctionBegin; 171 if (!n) PetscFunctionReturn(0); 172 173 if (type == PETSC_INT){ 174 m *= sizeof(PetscInt32); 175 #if (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) 176 /* read them in as 32 bit ints, later stretch into ints */ 177 ierr = PetscMalloc(m,&pp);CHKERRQ(ierr); 178 ptmp = (void*)pp; 179 #endif 180 } 181 else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 182 else if (type == PETSC_DOUBLE) m *= sizeof(double); 183 else if (type == PETSC_SHORT) m *= sizeof(short); 184 else if (type == PETSC_CHAR) m *= sizeof(char); 185 else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 186 else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth); 187 else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char); 188 else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 189 190 while (m) { 191 wsize = (m < maxblock) ? m : maxblock; 192 err = read(fd,pp,wsize); 193 if (err < 0 && errno == EINTR) continue; 194 if (!err && wsize > 0) SETERRQ(PETSC_ERR_FILE_READ,"Read past end of file"); 195 if (err < 0) SETERRQ1(PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); 196 m -= err; 197 pp += err; 198 } 199 #if !defined(PETSC_WORDS_BIGENDIAN) 200 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 201 else if (type == PETSC_ENUM) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 202 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 203 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 204 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 205 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 206 #endif 207 208 #if (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) 209 if (type == PETSC_INT) { 210 PetscInt *p_int = (PetscInt*)p,i; 211 PetscInt32 *p_short = (PetscInt32 *)ptmp; 212 for (i=0; i<n; i++) { 213 p_int[i] = (PetscInt)p_short[i]; 214 } 215 ierr = PetscFree(ptmp);CHKERRQ(ierr); 216 } 217 #endif 218 PetscFunctionReturn(0); 219 } 220 /* --------------------------------------------------------- */ 221 #undef __FUNCT__ 222 #define __FUNCT__ "PetscBinaryWrite" 223 /*@ 224 PetscBinaryWrite - Writes to a binary file. 225 226 Not Collective 227 228 Input Parameters: 229 + fd - the file 230 . p - the buffer 231 . n - the number of items to write 232 . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 233 - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. 234 235 Level: advanced 236 237 Notes: 238 PetscBinaryWrite() uses byte swapping to work on all machines; the files 239 are written using big-endian ordering to the file. On small-endian machines the numbers 240 are converted to the big-endian format when they are written to disk. 241 Integers are stored on the file as 32 bits long, regardless of whether 242 they are stored in the machine as 32 bits or 64 bits, this means the same 243 binary file may be read on any machine. It also means that 64 bit integers larger than 244 roughly 2 billion are TRUNCATED/WRONG when written to the file. 245 246 The Buffer p should be read-write buffer, and not static data. 247 This way, byte-swapping is done in-place, and then the buffer is 248 written to the file. 249 250 This routine restores the original contents of the buffer, after 251 it is written to the file. This is done by byte-swapping in-place 252 the second time. If the flag istemp is set to PETSC_TRUE, the second 253 byte-swapping operation is not done, thus saving some computation, 254 but the buffer corrupted is corrupted. 255 256 Concepts: files^writing binary 257 Concepts: binary files^writing 258 259 .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor() 260 @*/ 261 PetscErrorCode PETSC_DLLEXPORT PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 262 { 263 char *pp = (char*)p; 264 int err,wsize; 265 size_t m = (size_t)n,maxblock=65536; 266 #if !defined(PETSC_WORDS_BIGENDIAN) || (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) 267 PetscErrorCode ierr; 268 void *ptmp = p; 269 #endif 270 271 PetscFunctionBegin; 272 if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 273 if (!n) PetscFunctionReturn(0); 274 275 if (type == PETSC_INT){ 276 m *= sizeof(PetscInt32); 277 #if (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) 278 PetscInt *p_int = (PetscInt*)p,i; 279 PetscInt32 *p_short; 280 ierr = PetscMalloc(m,&pp);CHKERRQ(ierr); 281 ptmp = (void*)pp; 282 p_short = (PetscInt32*)pp; 283 284 for (i=0; i<n; i++) { 285 p_short[i] = (PetscInt32) p_int[i]; 286 } 287 istemp = PETSC_TRUE; 288 #endif 289 } 290 else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 291 else if (type == PETSC_DOUBLE) m *= sizeof(double); 292 else if (type == PETSC_SHORT) m *= sizeof(short); 293 else if (type == PETSC_CHAR) m *= sizeof(char); 294 else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 295 else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth); 296 else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char); 297 else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 298 299 #if !defined(PETSC_WORDS_BIGENDIAN) 300 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 301 else if (type == PETSC_ENUM) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 302 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 303 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 304 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 305 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 306 #endif 307 308 while (m) { 309 wsize = (m < maxblock) ? m : maxblock; 310 err = write(fd,pp,wsize); 311 if (err < 0 && errno == EINTR) continue; 312 if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file."); 313 m -= wsize; 314 pp += wsize; 315 } 316 317 #if !defined(PETSC_WORDS_BIGENDIAN) 318 if (!istemp) { 319 if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 320 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 321 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 322 else if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 323 else if (type == PETSC_ENUM) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 324 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapInt((PetscInt32*)ptmp,n);CHKERRQ(ierr);} 325 } 326 #endif 327 328 #if (PETSC_SIZEOF_INT == 8) || defined(PETSC_USE_64BIT_INDICES) 329 if (type == PETSC_INT){ 330 ierr = PetscFree(ptmp);CHKERRQ(ierr); 331 } 332 #endif 333 PetscFunctionReturn(0); 334 } 335 336 #undef __FUNCT__ 337 #define __FUNCT__ "PetscBinaryOpen" 338 /*@C 339 PetscBinaryOpen - Opens a PETSc binary file. 340 341 Not Collective 342 343 Input Parameters: 344 + name - filename 345 - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE 346 347 Output Parameter: 348 . fd - the file 349 350 Level: advanced 351 352 Concepts: files^opening binary 353 Concepts: binary files^opening 354 355 Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in 356 big-endian format. This means the file can be accessed using PetscBinaryOpen() and 357 PetscBinaryRead() and PetscBinaryWrite() on any machine. 358 359 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor() 360 361 @*/ 362 PetscErrorCode PETSC_DLLEXPORT PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd) 363 { 364 PetscFunctionBegin; 365 #if defined(PETSC_HAVE_O_BINARY) 366 if (mode == FILE_MODE_WRITE) { 367 if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) { 368 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 369 } 370 } else if (mode == FILE_MODE_READ) { 371 if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) { 372 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 373 } 374 } else if (mode == FILE_MODE_APPEND) { 375 if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) { 376 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 377 } 378 #else 379 if (mode == FILE_MODE_WRITE) { 380 if ((*fd = creat(name,0666)) == -1) { 381 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 382 } 383 } else if (mode == FILE_MODE_READ) { 384 if ((*fd = open(name,O_RDONLY,0)) == -1) { 385 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 386 } 387 } 388 else if (mode == FILE_MODE_APPEND) { 389 if ((*fd = open(name,O_WRONLY,0)) == -1) { 390 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 391 } 392 #endif 393 } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode"); 394 PetscFunctionReturn(0); 395 } 396 397 #undef __FUNCT__ 398 #define __FUNCT__ "PetscBinaryClose" 399 /*@ 400 PetscBinaryClose - Closes a PETSc binary file. 401 402 Not Collective 403 404 Output Parameter: 405 . fd - the file 406 407 Level: advanced 408 409 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen() 410 @*/ 411 PetscErrorCode PETSC_DLLEXPORT PetscBinaryClose(int fd) 412 { 413 PetscFunctionBegin; 414 close(fd); 415 PetscFunctionReturn(0); 416 } 417 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "PetscBinarySeek" 421 /*@ 422 PetscBinarySeek - Moves the file pointer on a PETSc binary file. 423 424 Not Collective 425 426 Input Parameters: 427 + fd - the file 428 . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 429 etc. in your calculation rather than sizeof() to compute byte lengths. 430 - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file 431 if PETSC_BINARY_SEEK_CUR then off is an offset from the current location 432 if PETSC_BINARY_SEEK_END then off is an offset from the end of file 433 434 Output Parameter: 435 . offset - new offset in file 436 437 Level: developer 438 439 Notes: 440 Integers are stored on the file as 32 long, regardless of whether 441 they are stored in the machine as 32 or 64, this means the same 442 binary file may be read on any machine. Hence you CANNOT use sizeof() 443 to determine the offset or location. 444 445 Concepts: files^binary seeking 446 Concepts: binary files^seeking 447 448 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen() 449 @*/ 450 PetscErrorCode PETSC_DLLEXPORT PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 451 { 452 int iwhence = 0; 453 454 PetscFunctionBegin; 455 if (whence == PETSC_BINARY_SEEK_SET) { 456 iwhence = SEEK_SET; 457 } else if (whence == PETSC_BINARY_SEEK_CUR) { 458 iwhence = SEEK_CUR; 459 } else if (whence == PETSC_BINARY_SEEK_END) { 460 iwhence = SEEK_END; 461 } else { 462 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location"); 463 } 464 #if defined(PETSC_HAVE_LSEEK) 465 *offset = lseek(fd,off,iwhence); 466 #elif defined(PETSC_HAVE__LSEEK) 467 *offset = _lseek(fd,(long)off,iwhence); 468 #else 469 SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file"); 470 #endif 471 PetscFunctionReturn(0); 472 } 473 474 #undef __FUNCT__ 475 #define __FUNCT__ "PetscBinarySynchronizedRead" 476 /*@C 477 PetscBinarySynchronizedRead - Reads from a binary file. 478 479 Collective on MPI_Comm 480 481 Input Parameters: 482 + comm - the MPI communicator 483 . fd - the file 484 . n - the number of items to read 485 - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 486 487 Output Parameters: 488 . p - the buffer 489 490 Options Database Key: 491 . -binary_longints - indicates the file was generated on a Cray vector 492 machine (not the T3E/D) and the ints are stored as 64 bit 493 quantities, otherwise they are stored as 32 bit 494 495 Level: developer 496 497 Notes: 498 Does a PetscBinaryRead() followed by an MPI_Bcast() 499 500 PetscBinarySynchronizedRead() uses byte swapping to work on all machines. 501 Integers are stored on the file as 32 long, regardless of whether 502 they are stored in the machine as 32 or 64, this means the same 503 binary file may be read on any machine. 504 505 Concepts: files^synchronized reading of binary files 506 Concepts: binary files^reading, synchronized 507 508 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead() 509 @*/ 510 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type) 511 { 512 PetscErrorCode ierr; 513 PetscMPIInt rank; 514 MPI_Datatype mtype; 515 516 PetscFunctionBegin; 517 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 518 if (!rank) { 519 ierr = PetscBinaryRead(fd,p,n,type);CHKERRQ(ierr); 520 } 521 ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr); 522 ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr); 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "PetscBinarySynchronizedWrite" 528 /*@C 529 PetscBinarySynchronizedWrite - writes to a binary file. 530 531 Collective on MPI_Comm 532 533 Input Parameters: 534 + comm - the MPI communicator 535 . fd - the file 536 . n - the number of items to write 537 . p - the buffer 538 . istemp - the buffer may be changed 539 - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 540 541 Level: developer 542 543 Notes: 544 Process 0 does a PetscBinaryWrite() 545 546 PetscBinarySynchronizedWrite() uses byte swapping to work on all machines. 547 Integers are stored on the file as 32 long, regardless of whether 548 they are stored in the machine as 32 or 64, this means the same 549 binary file may be read on any machine. 550 551 WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0, 552 while PetscSynchronizedFPrintf() has all processes print their strings in order. 553 554 Concepts: files^synchronized writing of binary files 555 Concepts: binary files^reading, synchronized 556 557 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead() 558 @*/ 559 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 560 { 561 PetscErrorCode ierr; 562 PetscMPIInt rank; 563 564 PetscFunctionBegin; 565 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 566 if (!rank) { 567 ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr); 568 } 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "PetscBinarySynchronizedSeek" 574 /*@C 575 PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file. 576 577 578 Input Parameters: 579 + fd - the file 580 . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file 581 if PETSC_BINARY_SEEK_CUR then size is offset from current location 582 if PETSC_BINARY_SEEK_END then size is offset from end of file 583 - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 584 etc. in your calculation rather than sizeof() to compute byte lengths. 585 586 Output Parameter: 587 . offset - new offset in file 588 589 Level: developer 590 591 Notes: 592 Integers are stored on the file as 32 long, regardless of whether 593 they are stored in the machine as 32 or 64, this means the same 594 binary file may be read on any machine. Hence you CANNOT use sizeof() 595 to determine the offset or location. 596 597 Concepts: binary files^seeking 598 Concepts: files^seeking in binary 599 600 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen() 601 @*/ 602 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 603 { 604 PetscErrorCode ierr; 605 PetscMPIInt rank; 606 607 PetscFunctionBegin; 608 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 609 if (!rank) { 610 ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr); 611 } 612 PetscFunctionReturn(0); 613 } 614 615