xref: /petsc/src/sys/fileio/sysio.c (revision 9e3e4c223eaa531534b9009c0faf32256b3cea04)
1e5c89e4eSSatish Balay 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay    This file contains simple binary read/write routines.
4e5c89e4eSSatish Balay  */
5e5c89e4eSSatish Balay 
6c6db04a5SJed Brown #include <petscsys.h>
7e5c89e4eSSatish Balay #include <errno.h>
8e5c89e4eSSatish Balay #include <fcntl.h>
9e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H)
10e5c89e4eSSatish Balay #include <unistd.h>
11e5c89e4eSSatish Balay #endif
12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_IO_H)
13e5c89e4eSSatish Balay #include <io.h>
14e5c89e4eSSatish Balay #endif
15c6db04a5SJed Brown #include <petscbt.h>
16e5c89e4eSSatish Balay 
17d6a4318aSJed Brown const char *const PetscFileModes[] = {"READ","WRITE","APPEND","UPDATE","APPEND_UPDATE","PetscFileMode","PETSC_FILE_",0};
18d6a4318aSJed Brown 
196de02169SBarry Smith /* --------------------------------------------------------- */
20e5c89e4eSSatish Balay /*
216de02169SBarry Smith   PetscByteSwapEnum - Swap bytes in a  PETSc Enum
22e5c89e4eSSatish Balay 
23e5c89e4eSSatish Balay */
247087cfbeSBarry Smith PetscErrorCode  PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
25e5c89e4eSSatish Balay {
266de02169SBarry Smith   PetscInt  i,j;
270b20345dSBarry Smith   PetscEnum tmp = ENUM_DUMMY;
28e0890e22SSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
29e5c89e4eSSatish Balay 
30e5c89e4eSSatish Balay   PetscFunctionBegin;
31e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
32e5c89e4eSSatish Balay     ptr1 = (char*)(buff + j);
33a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
34a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) ptr1[i] = ptr2[i];
35e5c89e4eSSatish Balay   }
36e5c89e4eSSatish Balay   PetscFunctionReturn(0);
37e5c89e4eSSatish Balay }
386de02169SBarry Smith 
396de02169SBarry Smith /*
40acfcf0e5SJed Brown   PetscByteSwapBool - Swap bytes in a  PETSc Bool
416de02169SBarry Smith 
426de02169SBarry Smith */
437087cfbeSBarry Smith PetscErrorCode  PetscByteSwapBool(PetscBool *buff,PetscInt n)
446de02169SBarry Smith {
456de02169SBarry Smith   PetscInt  i,j;
46ace3abfcSBarry Smith   PetscBool tmp = PETSC_FALSE;
47e0890e22SSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
486de02169SBarry Smith 
496de02169SBarry Smith   PetscFunctionBegin;
506de02169SBarry Smith   for (j=0; j<n; j++) {
516de02169SBarry Smith     ptr1 = (char*)(buff + j);
52a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscBool); i++) ptr2[i] = ptr1[sizeof(PetscBool)-1-i];
53a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscBool); i++) ptr1[i] = ptr2[i];
546de02169SBarry Smith   }
556de02169SBarry Smith   PetscFunctionReturn(0);
566de02169SBarry Smith }
576de02169SBarry Smith 
58bd1d2e58SBarry Smith /*
596de02169SBarry Smith   PetscByteSwapInt - Swap bytes in a  PETSc integer (which may be 32 or 64 bits)
60bd1d2e58SBarry Smith 
61bd1d2e58SBarry Smith */
627087cfbeSBarry Smith PetscErrorCode  PetscByteSwapInt(PetscInt *buff,PetscInt n)
63bd1d2e58SBarry Smith {
64bd1d2e58SBarry Smith   PetscInt i,j,tmp = 0;
65e0890e22SSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
66bd1d2e58SBarry Smith 
67bd1d2e58SBarry Smith   PetscFunctionBegin;
68bd1d2e58SBarry Smith   for (j=0; j<n; j++) {
69bd1d2e58SBarry Smith     ptr1 = (char*)(buff + j);
70a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscInt); i++) ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
71a297a907SKarl Rupp     for (i=0; i<(PetscInt)sizeof(PetscInt); i++) ptr1[i] = ptr2[i];
72bd1d2e58SBarry Smith   }
73bd1d2e58SBarry Smith   PetscFunctionReturn(0);
74bd1d2e58SBarry Smith }
75*9e3e4c22SLisandro Dalcin 
76*9e3e4c22SLisandro Dalcin /*
77*9e3e4c22SLisandro Dalcin   PetscByteSwapInt64 - Swap bytes in a  PETSc integer (64 bits)
78*9e3e4c22SLisandro Dalcin 
79*9e3e4c22SLisandro Dalcin */
80*9e3e4c22SLisandro Dalcin PetscErrorCode  PetscByteSwapInt64(PetscInt64 *buff,PetscInt n)
81*9e3e4c22SLisandro Dalcin {
82*9e3e4c22SLisandro Dalcin   PetscInt   i,j;
83*9e3e4c22SLisandro Dalcin   PetscInt64 tmp = 0;
84*9e3e4c22SLisandro Dalcin   char       *ptr1,*ptr2 = (char*)&tmp;
85*9e3e4c22SLisandro Dalcin 
86*9e3e4c22SLisandro Dalcin   PetscFunctionBegin;
87*9e3e4c22SLisandro Dalcin   for (j=0; j<n; j++) {
88*9e3e4c22SLisandro Dalcin     ptr1 = (char*)(buff + j);
89*9e3e4c22SLisandro Dalcin     for (i=0; i<(PetscInt)sizeof(PetscInt64); i++) ptr2[i] = ptr1[sizeof(PetscInt64)-1-i];
90*9e3e4c22SLisandro Dalcin     for (i=0; i<(PetscInt)sizeof(PetscInt64); i++) ptr1[i] = ptr2[i];
91*9e3e4c22SLisandro Dalcin   }
92*9e3e4c22SLisandro Dalcin   PetscFunctionReturn(0);
93*9e3e4c22SLisandro Dalcin }
94*9e3e4c22SLisandro Dalcin 
95bd1d2e58SBarry Smith /* --------------------------------------------------------- */
96e5c89e4eSSatish Balay /*
97e5c89e4eSSatish Balay   PetscByteSwapShort - Swap bytes in a short
98e5c89e4eSSatish Balay */
997087cfbeSBarry Smith PetscErrorCode  PetscByteSwapShort(short *buff,PetscInt n)
100e5c89e4eSSatish Balay {
101e5c89e4eSSatish Balay   PetscInt i,j;
102e5c89e4eSSatish Balay   short    tmp;
103e5c89e4eSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
104e5c89e4eSSatish Balay 
105e5c89e4eSSatish Balay   PetscFunctionBegin;
106e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
107e5c89e4eSSatish Balay     ptr1 = (char*)(buff + j);
108a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(short); i++) ptr2[i] = ptr1[sizeof(short)-1-i];
109a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(short); i++) ptr1[i] = ptr2[i];
110e5c89e4eSSatish Balay   }
111e5c89e4eSSatish Balay   PetscFunctionReturn(0);
112e5c89e4eSSatish Balay }
113972064b6SLisandro Dalcin /*
114972064b6SLisandro Dalcin   PetscByteSwapLong - Swap bytes in a long
115972064b6SLisandro Dalcin */
116972064b6SLisandro Dalcin PetscErrorCode  PetscByteSwapLong(long *buff,PetscInt n)
117972064b6SLisandro Dalcin {
118972064b6SLisandro Dalcin   PetscInt i,j;
119972064b6SLisandro Dalcin   long     tmp;
120972064b6SLisandro Dalcin   char     *ptr1,*ptr2 = (char*)&tmp;
121972064b6SLisandro Dalcin 
122972064b6SLisandro Dalcin   PetscFunctionBegin;
123972064b6SLisandro Dalcin   for (j=0; j<n; j++) {
124972064b6SLisandro Dalcin     ptr1 = (char*)(buff + j);
125972064b6SLisandro Dalcin     for (i=0; i<(PetscInt) sizeof(long); i++) ptr2[i] = ptr1[sizeof(long)-1-i];
126972064b6SLisandro Dalcin     for (i=0; i<(PetscInt) sizeof(long); i++) ptr1[i] = ptr2[i];
127972064b6SLisandro Dalcin   }
128972064b6SLisandro Dalcin   PetscFunctionReturn(0);
129972064b6SLisandro Dalcin }
130e5c89e4eSSatish Balay /* --------------------------------------------------------- */
131e5c89e4eSSatish Balay /*
1324caf0332SSatish Balay   PetscByteSwapReal - Swap bytes in a PetscReal
1334caf0332SSatish Balay */
1344caf0332SSatish Balay PetscErrorCode  PetscByteSwapReal(PetscReal *buff,PetscInt n)
1354caf0332SSatish Balay {
1364caf0332SSatish Balay   PetscInt  i,j;
1374caf0332SSatish Balay   PetscReal tmp,*buff1 = (PetscReal*)buff;
1384caf0332SSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
1394caf0332SSatish Balay 
1404caf0332SSatish Balay   PetscFunctionBegin;
1414caf0332SSatish Balay   for (j=0; j<n; j++) {
1424caf0332SSatish Balay     ptr1 = (char*)(buff1 + j);
1434caf0332SSatish Balay     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
1444caf0332SSatish Balay     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i];
1454caf0332SSatish Balay   }
1464caf0332SSatish Balay   PetscFunctionReturn(0);
1474caf0332SSatish Balay }
1484caf0332SSatish Balay /* --------------------------------------------------------- */
1494caf0332SSatish Balay /*
15041f502e3SPatrick Sanan   PetscByteSwapScalar - Swap bytes in a PetscScalar
15141f502e3SPatrick Sanan   The complex case is dealt with with an array of PetscReal, twice as long.
152e5c89e4eSSatish Balay */
1537087cfbeSBarry Smith PetscErrorCode  PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
154e5c89e4eSSatish Balay {
155e5c89e4eSSatish Balay   PetscInt  i,j;
156e5c89e4eSSatish Balay   PetscReal tmp,*buff1 = (PetscReal*)buff;
157e5c89e4eSSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay   PetscFunctionBegin;
160e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
161e5c89e4eSSatish Balay   n *= 2;
162e5c89e4eSSatish Balay #endif
163e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
164e5c89e4eSSatish Balay     ptr1 = (char*)(buff1 + j);
165a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
166a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i];
167e5c89e4eSSatish Balay   }
168e5c89e4eSSatish Balay   PetscFunctionReturn(0);
169e5c89e4eSSatish Balay }
170e5c89e4eSSatish Balay /* --------------------------------------------------------- */
171e5c89e4eSSatish Balay /*
172e5c89e4eSSatish Balay   PetscByteSwapDouble - Swap bytes in a double
173e5c89e4eSSatish Balay */
1747087cfbeSBarry Smith PetscErrorCode  PetscByteSwapDouble(double *buff,PetscInt n)
175e5c89e4eSSatish Balay {
176e5c89e4eSSatish Balay   PetscInt i,j;
177e5c89e4eSSatish Balay   double   tmp,*buff1 = (double*)buff;
178e5c89e4eSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
179e5c89e4eSSatish Balay 
180e5c89e4eSSatish Balay   PetscFunctionBegin;
181e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
182e5c89e4eSSatish Balay     ptr1 = (char*)(buff1 + j);
183a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i];
184a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(double); i++) ptr1[i] = ptr2[i];
185e5c89e4eSSatish Balay   }
186e5c89e4eSSatish Balay   PetscFunctionReturn(0);
187e5c89e4eSSatish Balay }
188e39fd77fSBarry Smith 
189e95bf02fSSatish Balay /*
190e95bf02fSSatish Balay   PetscByteSwapFloat - Swap bytes in a float
191e95bf02fSSatish Balay */
192e95bf02fSSatish Balay PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n)
193e95bf02fSSatish Balay {
194e95bf02fSSatish Balay   PetscInt i,j;
195e95bf02fSSatish Balay   float    tmp,*buff1 = (float*)buff;
196e95bf02fSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
197e95bf02fSSatish Balay 
198e95bf02fSSatish Balay   PetscFunctionBegin;
199e95bf02fSSatish Balay   for (j=0; j<n; j++) {
200e95bf02fSSatish Balay     ptr1 = (char*)(buff1 + j);
201a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(float); i++) ptr2[i] = ptr1[sizeof(float)-1-i];
202a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(float); i++) ptr1[i] = ptr2[i];
203e95bf02fSSatish Balay   }
204e95bf02fSSatish Balay   PetscFunctionReturn(0);
205e95bf02fSSatish Balay }
206e95bf02fSSatish Balay 
207e39fd77fSBarry Smith PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
208e39fd77fSBarry Smith {
209e39fd77fSBarry Smith   PetscErrorCode ierr;
210e39fd77fSBarry Smith 
211e39fd77fSBarry Smith   PetscFunctionBegin;
212e39fd77fSBarry Smith   if      (pdtype == PETSC_INT)    {ierr = PetscByteSwapInt((PetscInt*)data,count);CHKERRQ(ierr);}
213e39fd77fSBarry Smith   else if (pdtype == PETSC_ENUM)   {ierr = PetscByteSwapEnum((PetscEnum*)data,count);CHKERRQ(ierr);}
214acfcf0e5SJed Brown   else if (pdtype == PETSC_BOOL)   {ierr = PetscByteSwapBool((PetscBool*)data,count);CHKERRQ(ierr);}
215e39fd77fSBarry Smith   else if (pdtype == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)data,count);CHKERRQ(ierr);}
2164caf0332SSatish Balay   else if (pdtype == PETSC_REAL)   {ierr = PetscByteSwapReal((PetscReal*)data,count);CHKERRQ(ierr);}
217*9e3e4c22SLisandro Dalcin   else if (pdtype == PETSC_INT64)  {ierr = PetscByteSwapInt64((PetscInt64*)data,count);CHKERRQ(ierr);}
218e39fd77fSBarry Smith   else if (pdtype == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)data,count);CHKERRQ(ierr);}
219e95bf02fSSatish Balay   else if (pdtype == PETSC_FLOAT)  {ierr = PetscByteSwapFloat((float*)data,count);CHKERRQ(ierr);}
220e39fd77fSBarry Smith   else if (pdtype == PETSC_SHORT)  {ierr = PetscByteSwapShort((short*)data,count);CHKERRQ(ierr);}
221972064b6SLisandro Dalcin   else if (pdtype == PETSC_LONG)   {ierr = PetscByteSwapLong((long*)data,count);CHKERRQ(ierr);}
222e39fd77fSBarry Smith   PetscFunctionReturn(0);
223e39fd77fSBarry Smith }
224e39fd77fSBarry Smith 
225e5c89e4eSSatish Balay /* --------------------------------------------------------- */
226e30d2299SSatish Balay /*@
227e5c89e4eSSatish Balay    PetscBinaryRead - Reads from a binary file.
228e5c89e4eSSatish Balay 
229e5c89e4eSSatish Balay    Not Collective
230e5c89e4eSSatish Balay 
231e5c89e4eSSatish Balay    Input Parameters:
232e5c89e4eSSatish Balay +  fd - the file
233e5c89e4eSSatish Balay .  n  - the number of items to read
234e5c89e4eSSatish Balay -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
235e5c89e4eSSatish Balay 
236e5c89e4eSSatish Balay    Output Parameters:
237e5c89e4eSSatish Balay .  p - the buffer
238e5c89e4eSSatish Balay 
239e5c89e4eSSatish Balay 
240e5c89e4eSSatish Balay 
241e5c89e4eSSatish Balay    Level: developer
242e5c89e4eSSatish Balay 
243e5c89e4eSSatish Balay    Notes:
244e5c89e4eSSatish Balay    PetscBinaryRead() uses byte swapping to work on all machines; the files
245e5c89e4eSSatish Balay    are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
246e5c89e4eSSatish Balay    are converted to the small-endian format when they are read in from the file.
247e2e64c6bSBarry Smith    When PETSc is ./configure with --with-64bit-indices the integers are written to the
24854f21887SBarry Smith    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
24954f21887SBarry Smith    is used.
250e5c89e4eSSatish Balay 
251e5c89e4eSSatish Balay    Concepts: files^reading binary
252e5c89e4eSSatish Balay    Concepts: binary files^reading
253e5c89e4eSSatish Balay 
2544ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
2554ebed01fSBarry Smith           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
256e5c89e4eSSatish Balay @*/
2577087cfbeSBarry Smith PetscErrorCode  PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
258e5c89e4eSSatish Balay {
259e5c89e4eSSatish Balay   int               wsize,err;
260e5c89e4eSSatish Balay   size_t            m = (size_t) n,maxblock = 65536;
261e5c89e4eSSatish Balay   char              *pp = (char*)p;
2627a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
263cba51d77SBarry Smith   PetscBool         readdouble = PETSC_FALSE;
2647a881295SBarry Smith   double            *ppp;
2657a881295SBarry Smith #endif
2667a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) || defined(PETSC_USE_REAL___FLOAT128)
2676de02169SBarry Smith   PetscErrorCode    ierr;
2687a881295SBarry Smith #endif
2697a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
270e5c89e4eSSatish Balay   void              *ptmp = p;
271e5c89e4eSSatish Balay #endif
27205acbc63SBarry Smith   char              *fname = NULL;
273e5c89e4eSSatish Balay 
274e5c89e4eSSatish Balay   PetscFunctionBegin;
2752d53ad75SBarry Smith   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
276e5c89e4eSSatish Balay   if (!n) PetscFunctionReturn(0);
277e5c89e4eSSatish Balay 
2782d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
2792d53ad75SBarry Smith     m            = 64;
2802d53ad75SBarry Smith     type         = PETSC_CHAR;
28105acbc63SBarry Smith     fname        = (char*) malloc(m*sizeof(char));
28205acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
2832d53ad75SBarry Smith     pp           = (char*)fname;
2842d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
2852d53ad75SBarry Smith     ptmp         = (void*)fname;
2862d53ad75SBarry Smith #endif
2872d53ad75SBarry Smith   }
2882d53ad75SBarry Smith 
2896de02169SBarry Smith   if (type == PETSC_INT)          m *= sizeof(PetscInt);
290e5c89e4eSSatish Balay   else if (type == PETSC_SCALAR)  m *= sizeof(PetscScalar);
2914caf0332SSatish Balay   else if (type == PETSC_REAL)    m *= sizeof(PetscReal);
292e5c89e4eSSatish Balay   else if (type == PETSC_DOUBLE)  m *= sizeof(double);
293e95bf02fSSatish Balay   else if (type == PETSC_FLOAT)   m *= sizeof(float);
294e5c89e4eSSatish Balay   else if (type == PETSC_SHORT)   m *= sizeof(short);
295972064b6SLisandro Dalcin   else if (type == PETSC_LONG)    m *= sizeof(long);
296e5c89e4eSSatish Balay   else if (type == PETSC_CHAR)    m *= sizeof(char);
297e5c89e4eSSatish Balay   else if (type == PETSC_ENUM)    m *= sizeof(PetscEnum);
298ace3abfcSBarry Smith   else if (type == PETSC_BOOL)    m *= sizeof(PetscBool);
299*9e3e4c22SLisandro Dalcin   else if (type == PETSC_INT64)   m *= sizeof(PetscInt64);
3009f7b6320SBarry Smith   else if (type == PETSC_BIT_LOGICAL) m  = PetscBTLength(m)*sizeof(char);
301e32f2f54SBarry Smith   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
302e5c89e4eSSatish Balay 
3037a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
304c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr);
3057a881295SBarry Smith   /* If using __float128 precision we still read in doubles from file */
3064caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) {
3077a881295SBarry Smith     m    = m/2;
308785e854fSJed Brown     ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr);
3097a881295SBarry Smith     pp   = (char*)ppp;
3107a881295SBarry Smith   }
3117a881295SBarry Smith #endif
3127a881295SBarry Smith 
313e5c89e4eSSatish Balay   while (m) {
314e5c89e4eSSatish Balay     wsize = (m < maxblock) ? m : maxblock;
315e5c89e4eSSatish Balay     err   = read(fd,pp,wsize);
316e5c89e4eSSatish Balay     if (err < 0 && errno == EINTR) continue;
317e32f2f54SBarry Smith     if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file");
318e32f2f54SBarry Smith     if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
319e5c89e4eSSatish Balay     m  -= err;
320e5c89e4eSSatish Balay     pp += err;
321e5c89e4eSSatish Balay   }
3227a881295SBarry Smith 
3237a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
3244caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) {
3257a881295SBarry Smith     PetscScalar *pv = (PetscScalar*) p;
3267a881295SBarry Smith     PetscInt    i;
3277a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
3287a881295SBarry Smith     ierr = PetscByteSwapDouble(ppp,n);CHKERRQ(ierr);
3297a881295SBarry Smith #endif
330a297a907SKarl Rupp     for (i=0; i<n; i++) pv[i] = ppp[i];
3317a881295SBarry Smith     ierr = PetscFree(ppp);CHKERRQ(ierr);
3327a881295SBarry Smith     PetscFunctionReturn(0);
3337a881295SBarry Smith   }
3347a881295SBarry Smith #endif
3357a881295SBarry Smith 
336e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
337e39fd77fSBarry Smith   ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr);
338e5c89e4eSSatish Balay #endif
339e5c89e4eSSatish Balay 
34005acbc63SBarry Smith   if (type == PETSC_FUNCTION) {
3412d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3420298fd71SBarry Smith     ierr = PetscDLSym(NULL,fname,(void**)p);CHKERRQ(ierr);
3432d53ad75SBarry Smith #else
3440298fd71SBarry Smith     *(void**)p = NULL;
3452d53ad75SBarry Smith #endif
34605acbc63SBarry Smith     free(fname);
3472d53ad75SBarry Smith   }
348e5c89e4eSSatish Balay   PetscFunctionReturn(0);
349e5c89e4eSSatish Balay }
350e5c89e4eSSatish Balay /* --------------------------------------------------------- */
351e30d2299SSatish Balay /*@
352e5c89e4eSSatish Balay    PetscBinaryWrite - Writes to a binary file.
353e5c89e4eSSatish Balay 
354e5c89e4eSSatish Balay    Not Collective
355e5c89e4eSSatish Balay 
356e5c89e4eSSatish Balay    Input Parameters:
357e5c89e4eSSatish Balay +  fd     - the file
358e5c89e4eSSatish Balay .  p      - the buffer
359e5c89e4eSSatish Balay .  n      - the number of items to write
360e5c89e4eSSatish Balay .  type   - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
361e5c89e4eSSatish Balay -  istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
362e5c89e4eSSatish Balay 
363e5c89e4eSSatish Balay    Level: advanced
364e5c89e4eSSatish Balay 
365e5c89e4eSSatish Balay    Notes:
366e5c89e4eSSatish Balay    PetscBinaryWrite() uses byte swapping to work on all machines; the files
367e5c89e4eSSatish Balay    are written using big-endian ordering to the file. On small-endian machines the numbers
368e5c89e4eSSatish Balay    are converted to the big-endian format when they are written to disk.
369e2e64c6bSBarry Smith    When PETSc is ./configure with --with-64bit-indices the integers are written to the
37054f21887SBarry Smith    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
37154f21887SBarry Smith    is used.
372e5c89e4eSSatish Balay 
37341f502e3SPatrick Sanan    If running with __float128 precision the output is in __float128 unless one uses the -binary_write_double option
3740da86b62SBarry Smith 
375e5c89e4eSSatish Balay    The Buffer p should be read-write buffer, and not static data.
376e5c89e4eSSatish Balay    This way, byte-swapping is done in-place, and then the buffer is
377e5c89e4eSSatish Balay    written to the file.
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay    This routine restores the original contents of the buffer, after
380e5c89e4eSSatish Balay    it is written to the file. This is done by byte-swapping in-place
381e5c89e4eSSatish Balay    the second time. If the flag istemp is set to PETSC_TRUE, the second
382e5c89e4eSSatish Balay    byte-swapping operation is not done, thus saving some computation,
383e5f36e38SBarry Smith    but the buffer is left corrupted.
384e5c89e4eSSatish Balay 
385300a7f5bSBarry Smith    Because byte-swapping may be done on the values in data it cannot be declared const
386300a7f5bSBarry Smith 
387e5c89e4eSSatish Balay    Concepts: files^writing binary
388e5c89e4eSSatish Balay    Concepts: binary files^writing
389e5c89e4eSSatish Balay 
3904ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
3914ebed01fSBarry Smith           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
392e5c89e4eSSatish Balay @*/
3937087cfbeSBarry Smith PetscErrorCode  PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool  istemp)
394e5c89e4eSSatish Balay {
395e5c89e4eSSatish Balay   char           *pp = (char*)p;
396e5c89e4eSSatish Balay   int            err,wsize;
397e5c89e4eSSatish Balay   size_t         m = (size_t)n,maxblock=65536;
398e5c89e4eSSatish Balay   PetscErrorCode ierr;
399f5351476SHong Zhang #if !defined(PETSC_WORDS_BIGENDIAN)
400e5c89e4eSSatish Balay   void           *ptmp = p;
401e5c89e4eSSatish Balay #endif
40205acbc63SBarry Smith   char           *fname = NULL;
4030da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
404df40af56SBarry Smith   PetscBool      writedouble = PETSC_FALSE;
4050da86b62SBarry Smith   double         *ppp;
4060da86b62SBarry Smith   PetscReal      *pv;
4070da86b62SBarry Smith   PetscInt       i;
4080da86b62SBarry Smith #endif
40941f502e3SPatrick Sanan   PetscDataType  wtype = type;
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay   PetscFunctionBegin;
412e32f2f54SBarry Smith   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
413e5c89e4eSSatish Balay   if (!n) PetscFunctionReturn(0);
414e5c89e4eSSatish Balay 
4152d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
4162d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
4172d53ad75SBarry Smith     const char *fnametmp;
4182d53ad75SBarry Smith #endif
4192d53ad75SBarry Smith     m     = 64;
420e25ab156SSatish Balay     fname = (char*)malloc(m*sizeof(char));
42105acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
42205acbc63SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
42305acbc63SBarry Smith     if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time");
42405acbc63SBarry Smith     ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr);
42505acbc63SBarry Smith     ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr);
42605acbc63SBarry Smith #else
42705acbc63SBarry Smith     ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr);
42805acbc63SBarry Smith #endif
42901963f56SBarry Smith     wtype = PETSC_CHAR;
4302d53ad75SBarry Smith     pp    = (char*)fname;
4312d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
4322d53ad75SBarry Smith     ptmp  = (void*)fname;
4332d53ad75SBarry Smith #endif
4342d53ad75SBarry Smith   }
4352d53ad75SBarry Smith 
4360da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
4370da86b62SBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-binary_write_double",&writedouble,NULL);CHKERRQ(ierr);
4380da86b62SBarry Smith   /* If using __float128 precision we still write in doubles to file */
4394caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) {
44041f502e3SPatrick Sanan     wtype = PETSC_DOUBLE;
4410da86b62SBarry Smith     ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr);
4420da86b62SBarry Smith     pv = (PetscReal*)pp;
4430da86b62SBarry Smith     for (i=0; i<n; i++) {
4440da86b62SBarry Smith       ppp[i] = (double) pv[i];
4450da86b62SBarry Smith     }
4460da86b62SBarry Smith     pp   = (char*)ppp;
4470da86b62SBarry Smith     ptmp = (char*)ppp;
4480da86b62SBarry Smith   }
4490da86b62SBarry Smith #endif
4500da86b62SBarry Smith 
45141f502e3SPatrick Sanan   if (wtype == PETSC_INT)          m *= sizeof(PetscInt);
45241f502e3SPatrick Sanan   else if (wtype == PETSC_SCALAR)  m *= sizeof(PetscScalar);
4534caf0332SSatish Balay   else if (wtype == PETSC_REAL)    m *= sizeof(PetscReal);
45441f502e3SPatrick Sanan   else if (wtype == PETSC_DOUBLE)  m *= sizeof(double);
45541f502e3SPatrick Sanan   else if (wtype == PETSC_FLOAT)   m *= sizeof(float);
45641f502e3SPatrick Sanan   else if (wtype == PETSC_SHORT)   m *= sizeof(short);
457972064b6SLisandro Dalcin   else if (wtype == PETSC_LONG)    m *= sizeof(long);
45841f502e3SPatrick Sanan   else if (wtype == PETSC_CHAR)    m *= sizeof(char);
45941f502e3SPatrick Sanan   else if (wtype == PETSC_ENUM)    m *= sizeof(PetscEnum);
46041f502e3SPatrick Sanan   else if (wtype == PETSC_BOOL)    m *= sizeof(PetscBool);
461*9e3e4c22SLisandro Dalcin   else if (wtype == PETSC_INT64)   m *= sizeof(PetscInt64);
46241f502e3SPatrick Sanan   else if (wtype == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
463e32f2f54SBarry Smith   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
46641f502e3SPatrick Sanan   ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);
467e5c89e4eSSatish Balay #endif
468e5c89e4eSSatish Balay 
469e5c89e4eSSatish Balay   while (m) {
470e5c89e4eSSatish Balay     wsize = (m < maxblock) ? m : maxblock;
471e5c89e4eSSatish Balay     err   = write(fd,pp,wsize);
472e5c89e4eSSatish Balay     if (err < 0 && errno == EINTR) continue;
47304102261SBarry Smith     if (err != wsize) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing to file total size %d err %d wsize %d",(int)n,(int)err,(int)wsize);
474e5c89e4eSSatish Balay     m  -= wsize;
475e5c89e4eSSatish Balay     pp += wsize;
476e5c89e4eSSatish Balay   }
477e5c89e4eSSatish Balay 
478b659c0ceSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
479e5c89e4eSSatish Balay   if (!istemp) {
48041f502e3SPatrick Sanan     ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);
481e5c89e4eSSatish Balay   }
482e5c89e4eSSatish Balay #endif
48305acbc63SBarry Smith   if (type == PETSC_FUNCTION) {
48405acbc63SBarry Smith     free(fname);
48505acbc63SBarry Smith   }
4860da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
4874caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) {
4880da86b62SBarry Smith     ierr = PetscFree(ppp);CHKERRQ(ierr);
4890da86b62SBarry Smith   }
4900da86b62SBarry Smith #endif
491e5c89e4eSSatish Balay   PetscFunctionReturn(0);
492e5c89e4eSSatish Balay }
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay /*@C
495e5c89e4eSSatish Balay    PetscBinaryOpen - Opens a PETSc binary file.
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay    Not Collective
498e5c89e4eSSatish Balay 
499e5c89e4eSSatish Balay    Input Parameters:
500e5c89e4eSSatish Balay +  name - filename
50145c64e65SBarry Smith -  type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay    Output Parameter:
504e5c89e4eSSatish Balay .  fd - the file
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay    Level: advanced
507e5c89e4eSSatish Balay 
508e5c89e4eSSatish Balay   Concepts: files^opening binary
509e5c89e4eSSatish Balay   Concepts: binary files^opening
510e5c89e4eSSatish Balay 
51195452b02SPatrick Sanan    Notes:
51295452b02SPatrick Sanan     Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
513e5c89e4eSSatish Balay    big-endian format. This means the file can be accessed using PetscBinaryOpen() and
514e5c89e4eSSatish Balay    PetscBinaryRead() and PetscBinaryWrite() on any machine.
515e5c89e4eSSatish Balay 
5164ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
5174ebed01fSBarry Smith           PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
51845c64e65SBarry Smith 
519e5c89e4eSSatish Balay @*/
5207087cfbeSBarry Smith PetscErrorCode  PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
521e5c89e4eSSatish Balay {
522e5c89e4eSSatish Balay   PetscFunctionBegin;
523e5c89e4eSSatish Balay #if defined(PETSC_HAVE_O_BINARY)
52445c64e65SBarry Smith   if (mode == FILE_MODE_WRITE) {
525a297a907SKarl Rupp     if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
52645c64e65SBarry Smith   } else if (mode == FILE_MODE_READ) {
527a297a907SKarl Rupp     if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
52845c64e65SBarry Smith   } else if (mode == FILE_MODE_APPEND) {
529a297a907SKarl Rupp     if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
530e5c89e4eSSatish Balay #else
53145c64e65SBarry Smith   if (mode == FILE_MODE_WRITE) {
532a297a907SKarl Rupp     if ((*fd = creat(name,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
53345c64e65SBarry Smith   } else if (mode == FILE_MODE_READ) {
534a297a907SKarl Rupp     if ((*fd = open(name,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
535e5c89e4eSSatish Balay   }
53645c64e65SBarry Smith   else if (mode == FILE_MODE_APPEND) {
537a297a907SKarl Rupp     if ((*fd = open(name,O_WRONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
538e5c89e4eSSatish Balay #endif
539e32f2f54SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
540e5c89e4eSSatish Balay   PetscFunctionReturn(0);
541e5c89e4eSSatish Balay }
542e5c89e4eSSatish Balay 
543e30d2299SSatish Balay /*@
544e5c89e4eSSatish Balay    PetscBinaryClose - Closes a PETSc binary file.
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay    Not Collective
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay    Output Parameter:
549e5c89e4eSSatish Balay .  fd - the file
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay    Level: advanced
552e5c89e4eSSatish Balay 
5534ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
5544ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
555e5c89e4eSSatish Balay @*/
5567087cfbeSBarry Smith PetscErrorCode  PetscBinaryClose(int fd)
557e5c89e4eSSatish Balay {
558e5c89e4eSSatish Balay   PetscFunctionBegin;
559e5c89e4eSSatish Balay   close(fd);
560e5c89e4eSSatish Balay   PetscFunctionReturn(0);
561e5c89e4eSSatish Balay }
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay 
564e8976759SBarry Smith /*@C
565e5c89e4eSSatish Balay    PetscBinarySeek - Moves the file pointer on a PETSc binary file.
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay    Not Collective
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Input Parameters:
570e5c89e4eSSatish Balay +  fd - the file
571ff553b35SMatthew Knepley .  off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
572e5c89e4eSSatish Balay             etc. in your calculation rather than sizeof() to compute byte lengths.
573ff553b35SMatthew Knepley -  whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
574ff553b35SMatthew Knepley             if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
575ff553b35SMatthew Knepley             if PETSC_BINARY_SEEK_END then off is an offset from the end of file
576e5c89e4eSSatish Balay 
577e5c89e4eSSatish Balay    Output Parameter:
578e5c89e4eSSatish Balay .   offset - new offset in file
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay    Level: developer
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay    Notes:
583e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
584e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
585e5c89e4eSSatish Balay    binary file may be read on any machine. Hence you CANNOT use sizeof()
586e5c89e4eSSatish Balay    to determine the offset or location.
587e5c89e4eSSatish Balay 
588e5c89e4eSSatish Balay    Concepts: files^binary seeking
589e5c89e4eSSatish Balay    Concepts: binary files^seeking
590e5c89e4eSSatish Balay 
5914ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
5924ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
593e5c89e4eSSatish Balay @*/
5947087cfbeSBarry Smith PetscErrorCode  PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
595e5c89e4eSSatish Balay {
596e5c89e4eSSatish Balay   int iwhence = 0;
597e5c89e4eSSatish Balay 
598e5c89e4eSSatish Balay   PetscFunctionBegin;
599a297a907SKarl Rupp   if (whence == PETSC_BINARY_SEEK_SET) iwhence = SEEK_SET;
600a297a907SKarl Rupp   else if (whence == PETSC_BINARY_SEEK_CUR) iwhence = SEEK_CUR;
601a297a907SKarl Rupp   else if (whence == PETSC_BINARY_SEEK_END) iwhence = SEEK_END;
602a297a907SKarl Rupp   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
603e5c89e4eSSatish Balay #if defined(PETSC_HAVE_LSEEK)
604e5c89e4eSSatish Balay   *offset = lseek(fd,off,iwhence);
605e5c89e4eSSatish Balay #elif defined(PETSC_HAVE__LSEEK)
606e5c89e4eSSatish Balay   *offset = _lseek(fd,(long)off,iwhence);
607e5c89e4eSSatish Balay #else
608e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
609e5c89e4eSSatish Balay #endif
610e5c89e4eSSatish Balay   PetscFunctionReturn(0);
611e5c89e4eSSatish Balay }
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay /*@C
6141d280d73SBarry Smith    PetscBinarySynchronizedRead - Reads from a binary file.
615e5c89e4eSSatish Balay 
616e5c89e4eSSatish Balay    Collective on MPI_Comm
617e5c89e4eSSatish Balay 
618e5c89e4eSSatish Balay    Input Parameters:
619e5c89e4eSSatish Balay +  comm - the MPI communicator
620e5c89e4eSSatish Balay .  fd - the file
621e5c89e4eSSatish Balay .  n  - the number of items to read
622e5c89e4eSSatish Balay -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay    Output Parameters:
625e5c89e4eSSatish Balay .  p - the buffer
626e5c89e4eSSatish Balay 
627e5c89e4eSSatish Balay    Level: developer
628e5c89e4eSSatish Balay 
629e5c89e4eSSatish Balay    Notes:
630e5c89e4eSSatish Balay    Does a PetscBinaryRead() followed by an MPI_Bcast()
631e5c89e4eSSatish Balay 
6321d280d73SBarry Smith    PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
633e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
634e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
635e5c89e4eSSatish Balay    binary file may be read on any machine.
636e5c89e4eSSatish Balay 
637e5c89e4eSSatish Balay    Concepts: files^synchronized reading of binary files
638e5c89e4eSSatish Balay    Concepts: binary files^reading, synchronized
639e5c89e4eSSatish Balay 
6404ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
6414ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
642e5c89e4eSSatish Balay @*/
6437087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
644e5c89e4eSSatish Balay {
645e1400dc0SSatish Balay   PetscErrorCode ierr,ierrp=0;
646e5c89e4eSSatish Balay   PetscMPIInt    rank;
647e5c89e4eSSatish Balay   MPI_Datatype   mtype;
64805acbc63SBarry Smith   char           *fname = NULL;
6490298fd71SBarry Smith   void           *ptmp = NULL;
650e5c89e4eSSatish Balay 
651e5c89e4eSSatish Balay   PetscFunctionBegin;
6522d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
6532d53ad75SBarry Smith     n            = 64;
6542d53ad75SBarry Smith     type         = PETSC_CHAR;
6552d53ad75SBarry Smith     ptmp         = p;
656e366c363SBarry Smith     fname        = (char*)malloc(n*sizeof(char));
65705acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
6582d53ad75SBarry Smith     p            = (void*)fname;
6592d53ad75SBarry Smith   }
6602d53ad75SBarry Smith 
661e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
662e5c89e4eSSatish Balay   if (!rank) {
6630090e2cfSJakub Kruzik     ierrp = PetscBinaryRead(fd,p,n,type);
664e5c89e4eSSatish Balay   }
66547fb9d19SJakub Kruzik   ierr = MPI_Bcast(&ierrp,1,MPI_INT,0,comm);CHKERRQ(ierr);
6660090e2cfSJakub Kruzik   CHKERRQ(ierrp);
667e5c89e4eSSatish Balay   ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr);
668e5c89e4eSSatish Balay   ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr);
6692d53ad75SBarry Smith 
670e366c363SBarry Smith   if (type == PETSC_FUNCTION) {
6712d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
6720298fd71SBarry Smith     ierr = PetscDLLibrarySym(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,NULL,fname,(void**)ptmp);CHKERRQ(ierr);
6732d53ad75SBarry Smith #else
6740298fd71SBarry Smith     *(void**)ptmp = NULL;
6752d53ad75SBarry Smith #endif
676e366c363SBarry Smith     free(fname);
6772d53ad75SBarry Smith   }
678e5c89e4eSSatish Balay   PetscFunctionReturn(0);
679e5c89e4eSSatish Balay }
680e5c89e4eSSatish Balay 
681e5c89e4eSSatish Balay /*@C
6821d280d73SBarry Smith    PetscBinarySynchronizedWrite - writes to a binary file.
683e5c89e4eSSatish Balay 
684e5c89e4eSSatish Balay    Collective on MPI_Comm
685e5c89e4eSSatish Balay 
686e5c89e4eSSatish Balay    Input Parameters:
687e5c89e4eSSatish Balay +  comm - the MPI communicator
688e5c89e4eSSatish Balay .  fd - the file
689e5c89e4eSSatish Balay .  n  - the number of items to write
690e5c89e4eSSatish Balay .  p - the buffer
691e5c89e4eSSatish Balay .  istemp - the buffer may be changed
692e5c89e4eSSatish Balay -  type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
693e5c89e4eSSatish Balay 
694e5c89e4eSSatish Balay    Level: developer
695e5c89e4eSSatish Balay 
696e5c89e4eSSatish Balay    Notes:
697e5c89e4eSSatish Balay    Process 0 does a PetscBinaryWrite()
698e5c89e4eSSatish Balay 
6991d280d73SBarry Smith    PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
700e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
701e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
702e5c89e4eSSatish Balay    binary file may be read on any machine.
703e5c89e4eSSatish Balay 
70495452b02SPatrick Sanan    Notes:
70595452b02SPatrick Sanan     because byte-swapping may be done on the values in data it cannot be declared const
706300a7f5bSBarry Smith 
7071d280d73SBarry Smith    WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
7081d280d73SBarry Smith    while PetscSynchronizedFPrintf() has all processes print their strings in order.
7091d280d73SBarry Smith 
710e5c89e4eSSatish Balay    Concepts: files^synchronized writing of binary files
711e5c89e4eSSatish Balay    Concepts: binary files^reading, synchronized
712e5c89e4eSSatish Balay 
7134ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
7144ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
715e5c89e4eSSatish Balay @*/
7167087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
717e5c89e4eSSatish Balay {
718e5c89e4eSSatish Balay   PetscErrorCode ierr;
719e5c89e4eSSatish Balay   PetscMPIInt    rank;
720e5c89e4eSSatish Balay 
721e5c89e4eSSatish Balay   PetscFunctionBegin;
722e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
723e5c89e4eSSatish Balay   if (!rank) {
724e5c89e4eSSatish Balay     ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr);
725e5c89e4eSSatish Balay   }
726e5c89e4eSSatish Balay   PetscFunctionReturn(0);
727e5c89e4eSSatish Balay }
728e5c89e4eSSatish Balay 
729e5c89e4eSSatish Balay /*@C
7301d280d73SBarry Smith    PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
731e5c89e4eSSatish Balay 
732e5c89e4eSSatish Balay 
733e5c89e4eSSatish Balay    Input Parameters:
734e5c89e4eSSatish Balay +  fd - the file
735e5c89e4eSSatish Balay .  whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
736e5c89e4eSSatish Balay             if PETSC_BINARY_SEEK_CUR then size is offset from current location
737e5c89e4eSSatish Balay             if PETSC_BINARY_SEEK_END then size is offset from end of file
738e5c89e4eSSatish Balay -  off    - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
739e5c89e4eSSatish Balay             etc. in your calculation rather than sizeof() to compute byte lengths.
740e5c89e4eSSatish Balay 
741e5c89e4eSSatish Balay    Output Parameter:
742e5c89e4eSSatish Balay .   offset - new offset in file
743e5c89e4eSSatish Balay 
744e5c89e4eSSatish Balay    Level: developer
745e5c89e4eSSatish Balay 
746e5c89e4eSSatish Balay    Notes:
747e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
748e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
749e5c89e4eSSatish Balay    binary file may be read on any machine. Hence you CANNOT use sizeof()
750e5c89e4eSSatish Balay    to determine the offset or location.
751e5c89e4eSSatish Balay 
752e5c89e4eSSatish Balay    Concepts: binary files^seeking
753e5c89e4eSSatish Balay    Concepts: files^seeking in binary
754e5c89e4eSSatish Balay 
7554ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
7564ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
757e5c89e4eSSatish Balay @*/
7587087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
759e5c89e4eSSatish Balay {
760e5c89e4eSSatish Balay   PetscErrorCode ierr;
761e5c89e4eSSatish Balay   PetscMPIInt    rank;
762e5c89e4eSSatish Balay 
763e5c89e4eSSatish Balay   PetscFunctionBegin;
764e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
765e5c89e4eSSatish Balay   if (!rank) {
766e5c89e4eSSatish Balay     ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr);
767e5c89e4eSSatish Balay   }
768e5c89e4eSSatish Balay   PetscFunctionReturn(0);
769e5c89e4eSSatish Balay }
770e5c89e4eSSatish Balay 
7710fc9d207SBarry Smith #if defined(PETSC_HAVE_MPIIO)
772e39fd77fSBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
773e39fd77fSBarry Smith 
774951e3c8eSBarry Smith #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
775e39fd77fSBarry Smith /*
776e39fd77fSBarry Smith       MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
777e39fd77fSBarry Smith     These are set into MPI in PetscInitialize() via MPI_Register_datarep()
778e39fd77fSBarry Smith 
779e39fd77fSBarry Smith     Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
780e39fd77fSBarry Smith 
781951e3c8eSBarry Smith     The next three routines are not used because MPICH does not support their use
782e39fd77fSBarry Smith 
783e39fd77fSBarry Smith */
7848cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
785e39fd77fSBarry Smith {
786e39fd77fSBarry Smith   MPI_Aint    ub;
787e39fd77fSBarry Smith   PetscMPIInt ierr;
788e39fd77fSBarry Smith 
789e39fd77fSBarry Smith   ierr = MPI_Type_get_extent(datatype,&ub,file_extent);
790e39fd77fSBarry Smith   return ierr;
791e39fd77fSBarry Smith }
792e39fd77fSBarry Smith 
7938cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
794e39fd77fSBarry Smith {
795e39fd77fSBarry Smith   PetscDataType pdtype;
796e39fd77fSBarry Smith   PetscMPIInt   ierr;
797e39fd77fSBarry Smith   size_t        dsize;
798e39fd77fSBarry Smith 
799e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr);
800e39fd77fSBarry Smith   ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr);
801e39fd77fSBarry Smith 
802e39fd77fSBarry Smith   /* offset is given in units of MPI_Datatype */
803e39fd77fSBarry Smith   userbuf = ((char*)userbuf) + dsize*position;
804e39fd77fSBarry Smith 
805e39fd77fSBarry Smith   ierr = PetscMemcpy(userbuf,filebuf,count*dsize);CHKERRQ(ierr);
806e39fd77fSBarry Smith   ierr = PetscByteSwap(userbuf,pdtype,count);CHKERRQ(ierr);
807e39fd77fSBarry Smith   return ierr;
808e39fd77fSBarry Smith }
809e39fd77fSBarry Smith 
810e39fd77fSBarry Smith PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
811e39fd77fSBarry Smith {
812e39fd77fSBarry Smith   PetscDataType pdtype;
813e39fd77fSBarry Smith   PetscMPIInt   ierr;
814e39fd77fSBarry Smith   size_t        dsize;
815e39fd77fSBarry Smith 
816e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr);
817e39fd77fSBarry Smith   ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr);
818e39fd77fSBarry Smith 
819e39fd77fSBarry Smith   /* offset is given in units of MPI_Datatype */
820e39fd77fSBarry Smith   userbuf = ((char*)userbuf) + dsize*position;
821e39fd77fSBarry Smith 
822e39fd77fSBarry Smith   ierr = PetscMemcpy(filebuf,userbuf,count*dsize);CHKERRQ(ierr);
823e39fd77fSBarry Smith   ierr = PetscByteSwap(filebuf,pdtype,count);CHKERRQ(ierr);
824e39fd77fSBarry Smith   return ierr;
825e39fd77fSBarry Smith }
826951e3c8eSBarry Smith #endif
827e39fd77fSBarry Smith 
828e39fd77fSBarry Smith PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
829e39fd77fSBarry Smith {
830e39fd77fSBarry Smith   PetscErrorCode ierr;
831e39fd77fSBarry Smith   PetscDataType  pdtype;
832e39fd77fSBarry Smith 
833e39fd77fSBarry Smith   PetscFunctionBegin;
834e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr);
835e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
836e39fd77fSBarry Smith   ierr = MPI_File_write_all(fd,data,cnt,dtype,status);CHKERRQ(ierr);
837e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
838a6796414SBarry Smith   PetscFunctionReturn(0);
839e39fd77fSBarry Smith }
840e39fd77fSBarry Smith 
841e39fd77fSBarry Smith PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
842e39fd77fSBarry Smith {
843e39fd77fSBarry Smith   PetscErrorCode ierr;
844e39fd77fSBarry Smith   PetscDataType  pdtype;
845e39fd77fSBarry Smith 
846e39fd77fSBarry Smith   PetscFunctionBegin;
847e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr);
848e39fd77fSBarry Smith   ierr = MPI_File_read_all(fd,data,cnt,dtype,status);CHKERRQ(ierr);
849e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
850a6796414SBarry Smith   PetscFunctionReturn(0);
851e39fd77fSBarry Smith }
852e39fd77fSBarry Smith #endif
853951e3c8eSBarry Smith #endif
854