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