Actual source code: sysio.c
1: #define PETSC_DLL
3: /*
4: This file contains simple binary read/write routines.
5: */
7: #include petscsys.h
8: #include <errno.h>
9: #include <fcntl.h>
10: #if defined(PETSC_HAVE_UNISTD_H)
11: #include <unistd.h>
12: #endif
13: #if defined (PETSC_HAVE_IO_H)
14: #include <io.h>
15: #endif
16: #include petscbt.h
18: #if !defined(PETSC_WORDS_BIGENDIAN)
20: /* --------------------------------------------------------- */
23: /*
24: PetscByteSwapEnum - Swap bytes in a PETSc Enum
26: */
27: PetscErrorCode PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
28: {
29: PetscInt i,j;
30: PetscEnum tmp = ENUM_DUMMY;
31: char *ptr1,*ptr2 = (char*)&tmp;
32:
34: for (j=0; j<n; j++) {
35: ptr1 = (char*)(buff + j);
36: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
37: ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
38: }
39: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
40: ptr1[i] = ptr2[i];
41: }
42: }
43: return(0);
44: }
48: /*
49: PetscByteSwapTruth - Swap bytes in a PETSc Truth
51: */
52: PetscErrorCode PetscByteSwapTruth(PetscTruth *buff,PetscInt n)
53: {
54: PetscInt i,j;
55: PetscTruth tmp = PETSC_FALSE;
56: char *ptr1,*ptr2 = (char*)&tmp;
57:
59: for (j=0; j<n; j++) {
60: ptr1 = (char*)(buff + j);
61: for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
62: ptr2[i] = ptr1[sizeof(PetscTruth)-1-i];
63: }
64: for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
65: ptr1[i] = ptr2[i];
66: }
67: }
68: return(0);
69: }
73: /*
74: PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits)
76: */
77: PetscErrorCode PetscByteSwapInt(PetscInt *buff,PetscInt n)
78: {
79: PetscInt i,j,tmp = 0;
80: char *ptr1,*ptr2 = (char*)&tmp;
81:
83: for (j=0; j<n; j++) {
84: ptr1 = (char*)(buff + j);
85: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
86: ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
87: }
88: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
89: ptr1[i] = ptr2[i];
90: }
91: }
92: return(0);
93: }
94: /* --------------------------------------------------------- */
97: /*
98: PetscByteSwapShort - Swap bytes in a short
99: */
100: PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n)
101: {
102: PetscInt i,j;
103: short tmp;
104: char *ptr1,*ptr2 = (char*)&tmp;
107: for (j=0; j<n; j++) {
108: ptr1 = (char*)(buff + j);
109: for (i=0; i<(PetscInt) sizeof(short); i++) {
110: ptr2[i] = ptr1[sizeof(int)-1-i];
111: }
112: for (i=0; i<(PetscInt) sizeof(short); i++) {
113: ptr1[i] = ptr2[i];
114: }
115: }
116: return(0);
117: }
118: /* --------------------------------------------------------- */
121: /*
122: PetscByteSwapScalar - Swap bytes in a double
123: Complex is dealt with as if array of double twice as long.
124: */
125: PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
126: {
127: PetscInt i,j;
128: PetscReal tmp,*buff1 = (PetscReal*)buff;
129: char *ptr1,*ptr2 = (char*)&tmp;
132: #if defined(PETSC_USE_COMPLEX)
133: n *= 2;
134: #endif
135: for (j=0; j<n; j++) {
136: ptr1 = (char*)(buff1 + j);
137: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
138: ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
139: }
140: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
141: ptr1[i] = ptr2[i];
142: }
143: }
144: return(0);
145: }
146: /* --------------------------------------------------------- */
149: /*
150: PetscByteSwapDouble - Swap bytes in a double
151: */
152: PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n)
153: {
154: PetscInt i,j;
155: double tmp,*buff1 = (double*)buff;
156: char *ptr1,*ptr2 = (char*)&tmp;
159: for (j=0; j<n; j++) {
160: ptr1 = (char*)(buff1 + j);
161: for (i=0; i<(PetscInt) sizeof(double); i++) {
162: ptr2[i] = ptr1[sizeof(double)-1-i];
163: }
164: for (i=0; i<(PetscInt) sizeof(double); i++) {
165: ptr1[i] = ptr2[i];
166: }
167: }
168: return(0);
169: }
173: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
174: {
178: if (pdtype == PETSC_INT) {PetscByteSwapInt((PetscInt*)data,count);}
179: else if (pdtype == PETSC_ENUM) {PetscByteSwapEnum((PetscEnum*)data,count);}
180: else if (pdtype == PETSC_TRUTH) {PetscByteSwapTruth((PetscTruth*)data,count);}
181: else if (pdtype == PETSC_SCALAR) {PetscByteSwapScalar((PetscScalar*)data,count);}
182: else if (pdtype == PETSC_DOUBLE) {PetscByteSwapDouble((double*)data,count);}
183: else if (pdtype == PETSC_SHORT) {PetscByteSwapShort((short*)data,count);}
184: return(0);
185: }
187: #endif
188: /* --------------------------------------------------------- */
191: /*@
192: PetscBinaryRead - Reads from a binary file.
194: Not Collective
196: Input Parameters:
197: + fd - the file
198: . n - the number of items to read
199: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
201: Output Parameters:
202: . p - the buffer
206: Level: developer
208: Notes:
209: PetscBinaryRead() uses byte swapping to work on all machines; the files
210: are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
211: are converted to the small-endian format when they are read in from the file.
212: When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
213: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
214: is used.
216: Concepts: files^reading binary
217: Concepts: binary files^reading
219: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
220: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
221: @*/
222: PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
223: {
224: int wsize,err;
225: size_t m = (size_t) n,maxblock = 65536;
226: char *pp = (char*)p;
227: #if !defined(PETSC_WORDS_BIGENDIAN)
228: PetscErrorCode ierr;
229: void *ptmp = p;
230: #endif
233: if (!n) return(0);
235: if (type == PETSC_INT) m *= sizeof(PetscInt);
236: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
237: else if (type == PETSC_DOUBLE) m *= sizeof(double);
238: else if (type == PETSC_SHORT) m *= sizeof(short);
239: else if (type == PETSC_CHAR) m *= sizeof(char);
240: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
241: else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth);
242: else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char);
243: else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
244:
245: while (m) {
246: wsize = (m < maxblock) ? m : maxblock;
247: err = read(fd,pp,wsize);
248: if (err < 0 && errno == EINTR) continue;
249: if (!err && wsize > 0) SETERRQ(PETSC_ERR_FILE_READ,"Read past end of file");
250: if (err < 0) SETERRQ1(PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
251: m -= err;
252: pp += err;
253: }
254: #if !defined(PETSC_WORDS_BIGENDIAN)
255: PetscByteSwap(ptmp,type,n);
256: #endif
258: return(0);
259: }
260: /* --------------------------------------------------------- */
263: /*@
264: PetscBinaryWrite - Writes to a binary file.
266: Not Collective
268: Input Parameters:
269: + fd - the file
270: . p - the buffer
271: . n - the number of items to write
272: . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
273: - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
275: Level: advanced
277: Notes:
278: PetscBinaryWrite() uses byte swapping to work on all machines; the files
279: are written using big-endian ordering to the file. On small-endian machines the numbers
280: are converted to the big-endian format when they are written to disk.
281: When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
282: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
283: is used.
285: The Buffer p should be read-write buffer, and not static data.
286: This way, byte-swapping is done in-place, and then the buffer is
287: written to the file.
288:
289: This routine restores the original contents of the buffer, after
290: it is written to the file. This is done by byte-swapping in-place
291: the second time. If the flag istemp is set to PETSC_TRUE, the second
292: byte-swapping operation is not done, thus saving some computation,
293: but the buffer corrupted is corrupted.
295: Because byte-swapping may be done on the values in data it cannot be declared const
297: Concepts: files^writing binary
298: Concepts: binary files^writing
300: .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
301: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
302: @*/
303: PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
304: {
305: char *pp = (char*)p;
306: int err,wsize;
307: size_t m = (size_t)n,maxblock=65536;
308: #if !defined(PETSC_WORDS_BIGENDIAN)
310: void *ptmp = p;
311: #endif
314: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
315: if (!n) return(0);
317: if (type == PETSC_INT) m *= sizeof(PetscInt);
318: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
319: else if (type == PETSC_DOUBLE) m *= sizeof(double);
320: else if (type == PETSC_SHORT) m *= sizeof(short);
321: else if (type == PETSC_CHAR) m *= sizeof(char);
322: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
323: else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth);
324: else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char);
325: else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
327: #if !defined(PETSC_WORDS_BIGENDIAN)
328: PetscByteSwap(ptmp,type,n);
329: #endif
331: while (m) {
332: wsize = (m < maxblock) ? m : maxblock;
333: err = write(fd,pp,wsize);
334: if (err < 0 && errno == EINTR) continue;
335: if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file.");
336: m -= wsize;
337: pp += wsize;
338: }
340: #if !defined(PETSC_WORDS_BIGENDIAN)
341: if (!istemp) {
342: PetscByteSwap(ptmp,type,n);
343: }
344: #endif
345: return(0);
346: }
350: /*@C
351: PetscBinaryOpen - Opens a PETSc binary file.
353: Not Collective
355: Input Parameters:
356: + name - filename
357: - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
359: Output Parameter:
360: . fd - the file
362: Level: advanced
364: Concepts: files^opening binary
365: Concepts: binary files^opening
367: Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
368: big-endian format. This means the file can be accessed using PetscBinaryOpen() and
369: PetscBinaryRead() and PetscBinaryWrite() on any machine.
371: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
372: PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
374: @*/
375: PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
376: {
378: #if defined(PETSC_HAVE_O_BINARY)
379: if (mode == FILE_MODE_WRITE) {
380: if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,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|O_BINARY,0)) == -1) {
385: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
386: }
387: } else if (mode == FILE_MODE_APPEND) {
388: if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) {
389: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
390: }
391: #else
392: if (mode == FILE_MODE_WRITE) {
393: if ((*fd = creat(name,0666)) == -1) {
394: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
395: }
396: } else if (mode == FILE_MODE_READ) {
397: if ((*fd = open(name,O_RDONLY,0)) == -1) {
398: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
399: }
400: }
401: else if (mode == FILE_MODE_APPEND) {
402: if ((*fd = open(name,O_WRONLY,0)) == -1) {
403: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
404: }
405: #endif
406: } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
407: return(0);
408: }
412: /*@
413: PetscBinaryClose - Closes a PETSc binary file.
415: Not Collective
417: Output Parameter:
418: . fd - the file
420: Level: advanced
422: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
423: PetscBinarySynchronizedSeek()
424: @*/
425: PetscErrorCode PetscBinaryClose(int fd)
426: {
428: close(fd);
429: return(0);
430: }
435: /*@
436: PetscBinarySeek - Moves the file pointer on a PETSc binary file.
438: Not Collective
440: Input Parameters:
441: + fd - the file
442: . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
443: etc. in your calculation rather than sizeof() to compute byte lengths.
444: - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
445: if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
446: if PETSC_BINARY_SEEK_END then off is an offset from the end of file
448: Output Parameter:
449: . offset - new offset in file
451: Level: developer
453: Notes:
454: Integers are stored on the file as 32 long, regardless of whether
455: they are stored in the machine as 32 or 64, this means the same
456: binary file may be read on any machine. Hence you CANNOT use sizeof()
457: to determine the offset or location.
459: Concepts: files^binary seeking
460: Concepts: binary files^seeking
462: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
463: PetscBinarySynchronizedSeek()
464: @*/
465: PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
466: {
467: int iwhence = 0;
470: if (whence == PETSC_BINARY_SEEK_SET) {
471: iwhence = SEEK_SET;
472: } else if (whence == PETSC_BINARY_SEEK_CUR) {
473: iwhence = SEEK_CUR;
474: } else if (whence == PETSC_BINARY_SEEK_END) {
475: iwhence = SEEK_END;
476: } else {
477: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
478: }
479: #if defined(PETSC_HAVE_LSEEK)
480: *offset = lseek(fd,off,iwhence);
481: #elif defined(PETSC_HAVE__LSEEK)
482: *offset = _lseek(fd,(long)off,iwhence);
483: #else
484: SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
485: #endif
486: return(0);
487: }
491: /*@C
492: PetscBinarySynchronizedRead - Reads from a binary file.
494: Collective on MPI_Comm
496: Input Parameters:
497: + comm - the MPI communicator
498: . fd - the file
499: . n - the number of items to read
500: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
502: Output Parameters:
503: . p - the buffer
505: Options Database Key:
506: . -binary_longints - indicates the file was generated on a Cray vector
507: machine (not the T3E/D) and the ints are stored as 64 bit
508: quantities, otherwise they are stored as 32 bit
510: Level: developer
512: Notes:
513: Does a PetscBinaryRead() followed by an MPI_Bcast()
515: PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
516: Integers are stored on the file as 32 long, regardless of whether
517: they are stored in the machine as 32 or 64, this means the same
518: binary file may be read on any machine.
520: Concepts: files^synchronized reading of binary files
521: Concepts: binary files^reading, synchronized
523: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
524: PetscBinarySynchronizedSeek()
525: @*/
526: PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
527: {
529: PetscMPIInt rank;
530: MPI_Datatype mtype;
533: MPI_Comm_rank(comm,&rank);
534: if (!rank) {
535: PetscBinaryRead(fd,p,n,type);
536: }
537: PetscDataTypeToMPIDataType(type,&mtype);
538: MPI_Bcast(p,n,mtype,0,comm);
539: return(0);
540: }
544: /*@C
545: PetscBinarySynchronizedWrite - writes to a binary file.
547: Collective on MPI_Comm
549: Input Parameters:
550: + comm - the MPI communicator
551: . fd - the file
552: . n - the number of items to write
553: . p - the buffer
554: . istemp - the buffer may be changed
555: - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
557: Level: developer
559: Notes:
560: Process 0 does a PetscBinaryWrite()
562: PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
563: Integers are stored on the file as 32 long, regardless of whether
564: they are stored in the machine as 32 or 64, this means the same
565: binary file may be read on any machine.
567: Notes: because byte-swapping may be done on the values in data it cannot be declared const
569: WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
570: while PetscSynchronizedFPrintf() has all processes print their strings in order.
572: Concepts: files^synchronized writing of binary files
573: Concepts: binary files^reading, synchronized
575: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
576: PetscBinarySynchronizedSeek()
577: @*/
578: PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
579: {
581: PetscMPIInt rank;
584: MPI_Comm_rank(comm,&rank);
585: if (!rank) {
586: PetscBinaryWrite(fd,p,n,type,istemp);
587: }
588: return(0);
589: }
593: /*@C
594: PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
597: Input Parameters:
598: + fd - the file
599: . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
600: if PETSC_BINARY_SEEK_CUR then size is offset from current location
601: if PETSC_BINARY_SEEK_END then size is offset from end of file
602: - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
603: etc. in your calculation rather than sizeof() to compute byte lengths.
605: Output Parameter:
606: . offset - new offset in file
608: Level: developer
610: Notes:
611: Integers are stored on the file as 32 long, regardless of whether
612: they are stored in the machine as 32 or 64, this means the same
613: binary file may be read on any machine. Hence you CANNOT use sizeof()
614: to determine the offset or location.
616: Concepts: binary files^seeking
617: Concepts: files^seeking in binary
619: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
620: PetscBinarySynchronizedSeek()
621: @*/
622: PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
623: {
625: PetscMPIInt rank;
628: MPI_Comm_rank(comm,&rank);
629: if (!rank) {
630: PetscBinarySeek(fd,off,whence,offset);
631: }
632: return(0);
633: }
635: #if defined(PETSC_HAVE_MPIIO)
636: #if !defined(PETSC_WORDS_BIGENDIAN)
638: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
640: /*
641: MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
642: These are set into MPI in PetscInitialize() via MPI_Register_datarep()
644: Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
646: The next three routines are not used because MPICH does not support their use
648: */
649: PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
650: {
651: MPI_Aint ub;
652: PetscMPIInt ierr;
653:
654: MPI_Type_get_extent(datatype,&ub,file_extent);
655: return ierr;
656: }
658: PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
659: {
660: PetscDataType pdtype;
661: PetscMPIInt ierr;
662: size_t dsize;
663:
664: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
665: PetscDataTypeGetSize(pdtype,&dsize);
667: /* offset is given in units of MPI_Datatype */
668: userbuf = ((char *)userbuf) + dsize*position;
670: PetscMemcpy(userbuf,filebuf,count*dsize);
671: PetscByteSwap(userbuf,pdtype,count);
672: return ierr;
673: }
675: PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
676: {
677: PetscDataType pdtype;
678: PetscMPIInt ierr;
679: size_t dsize;
680:
681: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
682: PetscDataTypeGetSize(pdtype,&dsize);
684: /* offset is given in units of MPI_Datatype */
685: userbuf = ((char *)userbuf) + dsize*position;
687: PetscMemcpy(filebuf,userbuf,count*dsize);
688: PetscByteSwap(filebuf,pdtype,count);
689: return ierr;
690: }
692: #endif
694: PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
695: {
697: PetscDataType pdtype;
700: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
701: PetscByteSwap(data,pdtype,cnt);
702: MPI_File_write_all(fd,data,cnt,dtype,status);
703: PetscByteSwap(data,pdtype,cnt);
704: return(0);
705: }
707: PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
708: {
710: PetscDataType pdtype;
713: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
714: MPI_File_read_all(fd,data,cnt,dtype,status);
715: PetscByteSwap(data,pdtype,cnt);
716: return(0);
717: }
718: #endif
719: #endif