Actual source code: sysio.c
1: #define PETSC_DLL
3: /*
4: This file contains simple binary read/write routines.
5: */
7: #include petsc.h
8: #include petscsys.h
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
20: #if !defined(PETSC_WORDS_BIGENDIAN)
22: /* --------------------------------------------------------- */
25: /*
26: PetscByteSwapEnum - Swap bytes in a PETSc Enum
28: */
29: PetscErrorCode PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
30: {
31: PetscInt i,j;
32: PetscEnum tmp = ENUM_DUMMY;
33: char *ptr1,*ptr2 = (char*)&tmp;
34:
36: for (j=0; j<n; j++) {
37: ptr1 = (char*)(buff + j);
38: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
39: ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
40: }
41: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
42: ptr1[i] = ptr2[i];
43: }
44: }
45: return(0);
46: }
50: /*
51: PetscByteSwapTruth - Swap bytes in a PETSc Truth
53: */
54: PetscErrorCode PetscByteSwapTruth(PetscTruth *buff,PetscInt n)
55: {
56: PetscInt i,j;
57: PetscTruth tmp = PETSC_FALSE;
58: char *ptr1,*ptr2 = (char*)&tmp;
59:
61: for (j=0; j<n; j++) {
62: ptr1 = (char*)(buff + j);
63: for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
64: ptr2[i] = ptr1[sizeof(PetscTruth)-1-i];
65: }
66: for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
67: ptr1[i] = ptr2[i];
68: }
69: }
70: return(0);
71: }
75: /*
76: PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits)
78: */
79: PetscErrorCode PetscByteSwapInt(PetscInt *buff,PetscInt n)
80: {
81: PetscInt i,j,tmp = 0;
82: char *ptr1,*ptr2 = (char*)&tmp;
83:
85: for (j=0; j<n; j++) {
86: ptr1 = (char*)(buff + j);
87: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
88: ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
89: }
90: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
91: ptr1[i] = ptr2[i];
92: }
93: }
94: return(0);
95: }
96: /* --------------------------------------------------------- */
99: /*
100: PetscByteSwapShort - Swap bytes in a short
101: */
102: PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n)
103: {
104: PetscInt i,j;
105: short tmp;
106: char *ptr1,*ptr2 = (char*)&tmp;
109: for (j=0; j<n; j++) {
110: ptr1 = (char*)(buff + j);
111: for (i=0; i<(PetscInt) sizeof(short); i++) {
112: ptr2[i] = ptr1[sizeof(int)-1-i];
113: }
114: for (i=0; i<(PetscInt) sizeof(short); i++) {
115: ptr1[i] = ptr2[i];
116: }
117: }
118: return(0);
119: }
120: /* --------------------------------------------------------- */
123: /*
124: PetscByteSwapScalar - Swap bytes in a double
125: Complex is dealt with as if array of double twice as long.
126: */
127: PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
128: {
129: PetscInt i,j;
130: PetscReal tmp,*buff1 = (PetscReal*)buff;
131: char *ptr1,*ptr2 = (char*)&tmp;
134: #if defined(PETSC_USE_COMPLEX)
135: n *= 2;
136: #endif
137: for (j=0; j<n; j++) {
138: ptr1 = (char*)(buff1 + j);
139: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
140: ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
141: }
142: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
143: ptr1[i] = ptr2[i];
144: }
145: }
146: return(0);
147: }
148: /* --------------------------------------------------------- */
151: /*
152: PetscByteSwapDouble - Swap bytes in a double
153: */
154: PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n)
155: {
156: PetscInt i,j;
157: double tmp,*buff1 = (double*)buff;
158: char *ptr1,*ptr2 = (char*)&tmp;
161: for (j=0; j<n; j++) {
162: ptr1 = (char*)(buff1 + j);
163: for (i=0; i<(PetscInt) sizeof(double); i++) {
164: ptr2[i] = ptr1[sizeof(double)-1-i];
165: }
166: for (i=0; i<(PetscInt) sizeof(double); i++) {
167: ptr1[i] = ptr2[i];
168: }
169: }
170: return(0);
171: }
175: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
176: {
180: if (pdtype == PETSC_INT) {PetscByteSwapInt((PetscInt*)data,count);}
181: else if (pdtype == PETSC_ENUM) {PetscByteSwapEnum((PetscEnum*)data,count);}
182: else if (pdtype == PETSC_TRUTH) {PetscByteSwapTruth((PetscTruth*)data,count);}
183: else if (pdtype == PETSC_SCALAR) {PetscByteSwapScalar((PetscScalar*)data,count);}
184: else if (pdtype == PETSC_DOUBLE) {PetscByteSwapDouble((double*)data,count);}
185: else if (pdtype == PETSC_SHORT) {PetscByteSwapShort((short*)data,count);}
186: return(0);
187: }
189: #endif
190: /* --------------------------------------------------------- */
193: /*@
194: PetscBinaryRead - Reads from a binary file.
196: Not Collective
198: Input Parameters:
199: + fd - the file
200: . n - the number of items to read
201: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
203: Output Parameters:
204: . p - the buffer
208: Level: developer
210: Notes:
211: PetscBinaryRead() uses byte swapping to work on all machines; the files
212: are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
213: are converted to the small-endian format when they are read in from the file.
214: When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
215: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
216: is used.
218: Concepts: files^reading binary
219: Concepts: binary files^reading
221: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
222: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
223: @*/
224: PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
225: {
226: int wsize,err;
227: size_t m = (size_t) n,maxblock = 65536;
228: char *pp = (char*)p;
229: #if !defined(PETSC_WORDS_BIGENDIAN)
230: PetscErrorCode ierr;
231: void *ptmp = p;
232: #endif
235: if (!n) return(0);
237: if (type == PETSC_INT) m *= sizeof(PetscInt);
238: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
239: else if (type == PETSC_DOUBLE) m *= sizeof(double);
240: else if (type == PETSC_SHORT) m *= sizeof(short);
241: else if (type == PETSC_CHAR) m *= sizeof(char);
242: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
243: else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth);
244: else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char);
245: else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
246:
247: while (m) {
248: wsize = (m < maxblock) ? m : maxblock;
249: err = read(fd,pp,wsize);
250: if (err < 0 && errno == EINTR) continue;
251: if (!err && wsize > 0) SETERRQ(PETSC_ERR_FILE_READ,"Read past end of file");
252: if (err < 0) SETERRQ1(PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
253: m -= err;
254: pp += err;
255: }
256: #if !defined(PETSC_WORDS_BIGENDIAN)
257: PetscByteSwap(ptmp,type,n);
258: #endif
260: return(0);
261: }
262: /* --------------------------------------------------------- */
265: /*@
266: PetscBinaryWrite - Writes to a binary file.
268: Not Collective
270: Input Parameters:
271: + fd - the file
272: . p - the buffer
273: . n - the number of items to write
274: . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
275: - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
277: Level: advanced
279: Notes:
280: PetscBinaryWrite() uses byte swapping to work on all machines; the files
281: are written using big-endian ordering to the file. On small-endian machines the numbers
282: are converted to the big-endian format when they are written to disk.
283: When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
284: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
285: is used.
287: The Buffer p should be read-write buffer, and not static data.
288: This way, byte-swapping is done in-place, and then the buffer is
289: written to the file.
290:
291: This routine restores the original contents of the buffer, after
292: it is written to the file. This is done by byte-swapping in-place
293: the second time. If the flag istemp is set to PETSC_TRUE, the second
294: byte-swapping operation is not done, thus saving some computation,
295: but the buffer corrupted is corrupted.
297: Because byte-swapping may be done on the values in data it cannot be declared const
299: Concepts: files^writing binary
300: Concepts: binary files^writing
302: .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
303: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
304: @*/
305: PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
306: {
307: char *pp = (char*)p;
308: int err,wsize;
309: size_t m = (size_t)n,maxblock=65536;
310: #if !defined(PETSC_WORDS_BIGENDIAN)
312: void *ptmp = p;
313: #endif
316: if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
317: if (!n) return(0);
319: if (type == PETSC_INT) m *= sizeof(PetscInt);
320: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
321: else if (type == PETSC_DOUBLE) m *= sizeof(double);
322: else if (type == PETSC_SHORT) m *= sizeof(short);
323: else if (type == PETSC_CHAR) m *= sizeof(char);
324: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
325: else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth);
326: else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char);
327: else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
329: #if !defined(PETSC_WORDS_BIGENDIAN)
330: PetscByteSwap(ptmp,type,n);
331: #endif
333: while (m) {
334: wsize = (m < maxblock) ? m : maxblock;
335: err = write(fd,pp,wsize);
336: if (err < 0 && errno == EINTR) continue;
337: if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file.");
338: m -= wsize;
339: pp += wsize;
340: }
342: #if !defined(PETSC_WORDS_BIGENDIAN)
343: if (!istemp) {
344: PetscByteSwap(ptmp,type,n);
345: }
346: #endif
347: return(0);
348: }
352: /*@C
353: PetscBinaryOpen - Opens a PETSc binary file.
355: Not Collective
357: Input Parameters:
358: + name - filename
359: - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
361: Output Parameter:
362: . fd - the file
364: Level: advanced
366: Concepts: files^opening binary
367: Concepts: binary files^opening
369: Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
370: big-endian format. This means the file can be accessed using PetscBinaryOpen() and
371: PetscBinaryRead() and PetscBinaryWrite() on any machine.
373: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
374: PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
376: @*/
377: PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
378: {
380: #if defined(PETSC_HAVE_O_BINARY)
381: if (mode == FILE_MODE_WRITE) {
382: if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
383: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
384: }
385: } else if (mode == FILE_MODE_READ) {
386: if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) {
387: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
388: }
389: } else if (mode == FILE_MODE_APPEND) {
390: if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) {
391: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
392: }
393: #else
394: if (mode == FILE_MODE_WRITE) {
395: if ((*fd = creat(name,0666)) == -1) {
396: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
397: }
398: } else if (mode == FILE_MODE_READ) {
399: if ((*fd = open(name,O_RDONLY,0)) == -1) {
400: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
401: }
402: }
403: else if (mode == FILE_MODE_APPEND) {
404: if ((*fd = open(name,O_WRONLY,0)) == -1) {
405: SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
406: }
407: #endif
408: } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
409: return(0);
410: }
414: /*@
415: PetscBinaryClose - Closes a PETSc binary file.
417: Not Collective
419: Output Parameter:
420: . fd - the file
422: Level: advanced
424: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
425: PetscBinarySynchronizedSeek()
426: @*/
427: PetscErrorCode PetscBinaryClose(int fd)
428: {
430: close(fd);
431: return(0);
432: }
437: /*@
438: PetscBinarySeek - Moves the file pointer on a PETSc binary file.
440: Not Collective
442: Input Parameters:
443: + fd - the file
444: . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
445: etc. in your calculation rather than sizeof() to compute byte lengths.
446: - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
447: if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
448: if PETSC_BINARY_SEEK_END then off is an offset from the end of file
450: Output Parameter:
451: . offset - new offset in file
453: Level: developer
455: Notes:
456: Integers are stored on the file as 32 long, regardless of whether
457: they are stored in the machine as 32 or 64, this means the same
458: binary file may be read on any machine. Hence you CANNOT use sizeof()
459: to determine the offset or location.
461: Concepts: files^binary seeking
462: Concepts: binary files^seeking
464: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
465: PetscBinarySynchronizedSeek()
466: @*/
467: PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
468: {
469: int iwhence = 0;
472: if (whence == PETSC_BINARY_SEEK_SET) {
473: iwhence = SEEK_SET;
474: } else if (whence == PETSC_BINARY_SEEK_CUR) {
475: iwhence = SEEK_CUR;
476: } else if (whence == PETSC_BINARY_SEEK_END) {
477: iwhence = SEEK_END;
478: } else {
479: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
480: }
481: #if defined(PETSC_HAVE_LSEEK)
482: *offset = lseek(fd,off,iwhence);
483: #elif defined(PETSC_HAVE__LSEEK)
484: *offset = _lseek(fd,(long)off,iwhence);
485: #else
486: SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
487: #endif
488: return(0);
489: }
493: /*@C
494: PetscBinarySynchronizedRead - Reads from a binary file.
496: Collective on MPI_Comm
498: Input Parameters:
499: + comm - the MPI communicator
500: . fd - the file
501: . n - the number of items to read
502: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
504: Output Parameters:
505: . p - the buffer
507: Options Database Key:
508: . -binary_longints - indicates the file was generated on a Cray vector
509: machine (not the T3E/D) and the ints are stored as 64 bit
510: quantities, otherwise they are stored as 32 bit
512: Level: developer
514: Notes:
515: Does a PetscBinaryRead() followed by an MPI_Bcast()
517: PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
518: Integers are stored on the file as 32 long, regardless of whether
519: they are stored in the machine as 32 or 64, this means the same
520: binary file may be read on any machine.
522: Concepts: files^synchronized reading of binary files
523: Concepts: binary files^reading, synchronized
525: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
526: PetscBinarySynchronizedSeek()
527: @*/
528: PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
529: {
531: PetscMPIInt rank;
532: MPI_Datatype mtype;
535: MPI_Comm_rank(comm,&rank);
536: if (!rank) {
537: PetscBinaryRead(fd,p,n,type);
538: }
539: PetscDataTypeToMPIDataType(type,&mtype);
540: MPI_Bcast(p,n,mtype,0,comm);
541: return(0);
542: }
546: /*@C
547: PetscBinarySynchronizedWrite - writes to a binary file.
549: Collective on MPI_Comm
551: Input Parameters:
552: + comm - the MPI communicator
553: . fd - the file
554: . n - the number of items to write
555: . p - the buffer
556: . istemp - the buffer may be changed
557: - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
559: Level: developer
561: Notes:
562: Process 0 does a PetscBinaryWrite()
564: PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
565: Integers are stored on the file as 32 long, regardless of whether
566: they are stored in the machine as 32 or 64, this means the same
567: binary file may be read on any machine.
569: Notes: because byte-swapping may be done on the values in data it cannot be declared const
571: WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
572: while PetscSynchronizedFPrintf() has all processes print their strings in order.
574: Concepts: files^synchronized writing of binary files
575: Concepts: binary files^reading, synchronized
577: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
578: PetscBinarySynchronizedSeek()
579: @*/
580: PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
581: {
583: PetscMPIInt rank;
586: MPI_Comm_rank(comm,&rank);
587: if (!rank) {
588: PetscBinaryWrite(fd,p,n,type,istemp);
589: }
590: return(0);
591: }
595: /*@C
596: PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
599: Input Parameters:
600: + fd - the file
601: . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
602: if PETSC_BINARY_SEEK_CUR then size is offset from current location
603: if PETSC_BINARY_SEEK_END then size is offset from end of file
604: - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
605: etc. in your calculation rather than sizeof() to compute byte lengths.
607: Output Parameter:
608: . offset - new offset in file
610: Level: developer
612: Notes:
613: Integers are stored on the file as 32 long, regardless of whether
614: they are stored in the machine as 32 or 64, this means the same
615: binary file may be read on any machine. Hence you CANNOT use sizeof()
616: to determine the offset or location.
618: Concepts: binary files^seeking
619: Concepts: files^seeking in binary
621: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
622: PetscBinarySynchronizedSeek()
623: @*/
624: PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
625: {
627: PetscMPIInt rank;
630: MPI_Comm_rank(comm,&rank);
631: if (!rank) {
632: PetscBinarySeek(fd,off,whence,offset);
633: }
634: return(0);
635: }
637: #if defined(PETSC_HAVE_MPIIO)
638: #if !defined(PETSC_WORDS_BIGENDIAN)
640: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
642: /*
643: MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
644: These are set into MPI in PetscInitialize() via MPI_Register_datarep()
646: Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
648: The next three routines are not used because MPICH does not support their use
650: */
651: PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
652: {
653: MPI_Aint ub;
654: PetscMPIInt ierr;
655:
656: MPI_Type_get_extent(datatype,&ub,file_extent);
657: return ierr;
658: }
660: PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
661: {
662: PetscDataType pdtype;
663: PetscMPIInt ierr;
664: size_t dsize;
665:
666: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
667: PetscDataTypeGetSize(pdtype,&dsize);
669: /* offset is given in units of MPI_Datatype */
670: userbuf = ((char *)userbuf) + dsize*position;
672: PetscMemcpy(userbuf,filebuf,count*dsize);
673: PetscByteSwap(userbuf,pdtype,count);
674: return ierr;
675: }
677: PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
678: {
679: PetscDataType pdtype;
680: PetscMPIInt ierr;
681: size_t dsize;
682:
683: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
684: PetscDataTypeGetSize(pdtype,&dsize);
686: /* offset is given in units of MPI_Datatype */
687: userbuf = ((char *)userbuf) + dsize*position;
689: PetscMemcpy(filebuf,userbuf,count*dsize);
690: PetscByteSwap(filebuf,pdtype,count);
691: return ierr;
692: }
694: #endif
696: PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
697: {
699: PetscDataType pdtype;
702: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
703: PetscByteSwap(data,pdtype,cnt);
704: MPI_File_write_all(fd,data,cnt,dtype,status);
705: PetscByteSwap(data,pdtype,cnt);
706: return(0);
707: }
709: PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
710: {
712: PetscDataType pdtype;
715: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
716: MPI_File_read_all(fd,data,cnt,dtype,status);
717: PetscByteSwap(data,pdtype,cnt);
718: return(0);
719: }
720: #endif
721: #endif