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