xref: /petsc/src/sys/fileio/sysio.c (revision 972064b65a4dc64f53e590d2cefc17fe4e1ae983)
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 }
75bd1d2e58SBarry Smith /* --------------------------------------------------------- */
76e5c89e4eSSatish Balay /*
77e5c89e4eSSatish Balay   PetscByteSwapShort - Swap bytes in a short
78e5c89e4eSSatish Balay */
797087cfbeSBarry Smith PetscErrorCode  PetscByteSwapShort(short *buff,PetscInt n)
80e5c89e4eSSatish Balay {
81e5c89e4eSSatish Balay   PetscInt i,j;
82e5c89e4eSSatish Balay   short    tmp;
83e5c89e4eSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
84e5c89e4eSSatish Balay 
85e5c89e4eSSatish Balay   PetscFunctionBegin;
86e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
87e5c89e4eSSatish Balay     ptr1 = (char*)(buff + j);
88a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(short); i++) ptr2[i] = ptr1[sizeof(short)-1-i];
89a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(short); i++) ptr1[i] = ptr2[i];
90e5c89e4eSSatish Balay   }
91e5c89e4eSSatish Balay   PetscFunctionReturn(0);
92e5c89e4eSSatish Balay }
93*972064b6SLisandro Dalcin /*
94*972064b6SLisandro Dalcin   PetscByteSwapLong - Swap bytes in a long
95*972064b6SLisandro Dalcin */
96*972064b6SLisandro Dalcin PetscErrorCode  PetscByteSwapLong(long *buff,PetscInt n)
97*972064b6SLisandro Dalcin {
98*972064b6SLisandro Dalcin   PetscInt i,j;
99*972064b6SLisandro Dalcin   long     tmp;
100*972064b6SLisandro Dalcin   char     *ptr1,*ptr2 = (char*)&tmp;
101*972064b6SLisandro Dalcin 
102*972064b6SLisandro Dalcin   PetscFunctionBegin;
103*972064b6SLisandro Dalcin   for (j=0; j<n; j++) {
104*972064b6SLisandro Dalcin     ptr1 = (char*)(buff + j);
105*972064b6SLisandro Dalcin     for (i=0; i<(PetscInt) sizeof(long); i++) ptr2[i] = ptr1[sizeof(long)-1-i];
106*972064b6SLisandro Dalcin     for (i=0; i<(PetscInt) sizeof(long); i++) ptr1[i] = ptr2[i];
107*972064b6SLisandro Dalcin   }
108*972064b6SLisandro Dalcin   PetscFunctionReturn(0);
109*972064b6SLisandro Dalcin }
110e5c89e4eSSatish Balay /* --------------------------------------------------------- */
111e5c89e4eSSatish Balay /*
1124caf0332SSatish Balay   PetscByteSwapReal - Swap bytes in a PetscReal
1134caf0332SSatish Balay */
1144caf0332SSatish Balay PetscErrorCode  PetscByteSwapReal(PetscReal *buff,PetscInt n)
1154caf0332SSatish Balay {
1164caf0332SSatish Balay   PetscInt  i,j;
1174caf0332SSatish Balay   PetscReal tmp,*buff1 = (PetscReal*)buff;
1184caf0332SSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
1194caf0332SSatish Balay 
1204caf0332SSatish Balay   PetscFunctionBegin;
1214caf0332SSatish Balay   for (j=0; j<n; j++) {
1224caf0332SSatish Balay     ptr1 = (char*)(buff1 + j);
1234caf0332SSatish Balay     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
1244caf0332SSatish Balay     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i];
1254caf0332SSatish Balay   }
1264caf0332SSatish Balay   PetscFunctionReturn(0);
1274caf0332SSatish Balay }
1284caf0332SSatish Balay /* --------------------------------------------------------- */
1294caf0332SSatish Balay /*
13041f502e3SPatrick Sanan   PetscByteSwapScalar - Swap bytes in a PetscScalar
13141f502e3SPatrick Sanan   The complex case is dealt with with an array of PetscReal, twice as long.
132e5c89e4eSSatish Balay */
1337087cfbeSBarry Smith PetscErrorCode  PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
134e5c89e4eSSatish Balay {
135e5c89e4eSSatish Balay   PetscInt  i,j;
136e5c89e4eSSatish Balay   PetscReal tmp,*buff1 = (PetscReal*)buff;
137e5c89e4eSSatish Balay   char      *ptr1,*ptr2 = (char*)&tmp;
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay   PetscFunctionBegin;
140e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
141e5c89e4eSSatish Balay   n *= 2;
142e5c89e4eSSatish Balay #endif
143e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
144e5c89e4eSSatish Balay     ptr1 = (char*)(buff1 + j);
145a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
146a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i];
147e5c89e4eSSatish Balay   }
148e5c89e4eSSatish Balay   PetscFunctionReturn(0);
149e5c89e4eSSatish Balay }
150e5c89e4eSSatish Balay /* --------------------------------------------------------- */
151e5c89e4eSSatish Balay /*
152e5c89e4eSSatish Balay   PetscByteSwapDouble - Swap bytes in a double
153e5c89e4eSSatish Balay */
1547087cfbeSBarry Smith PetscErrorCode  PetscByteSwapDouble(double *buff,PetscInt n)
155e5c89e4eSSatish Balay {
156e5c89e4eSSatish Balay   PetscInt i,j;
157e5c89e4eSSatish Balay   double   tmp,*buff1 = (double*)buff;
158e5c89e4eSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay   PetscFunctionBegin;
161e5c89e4eSSatish Balay   for (j=0; j<n; j++) {
162e5c89e4eSSatish Balay     ptr1 = (char*)(buff1 + j);
163a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i];
164a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(double); i++) ptr1[i] = ptr2[i];
165e5c89e4eSSatish Balay   }
166e5c89e4eSSatish Balay   PetscFunctionReturn(0);
167e5c89e4eSSatish Balay }
168e39fd77fSBarry Smith 
169e95bf02fSSatish Balay /*
170e95bf02fSSatish Balay   PetscByteSwapFloat - Swap bytes in a float
171e95bf02fSSatish Balay */
172e95bf02fSSatish Balay PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n)
173e95bf02fSSatish Balay {
174e95bf02fSSatish Balay   PetscInt i,j;
175e95bf02fSSatish Balay   float    tmp,*buff1 = (float*)buff;
176e95bf02fSSatish Balay   char     *ptr1,*ptr2 = (char*)&tmp;
177e95bf02fSSatish Balay 
178e95bf02fSSatish Balay   PetscFunctionBegin;
179e95bf02fSSatish Balay   for (j=0; j<n; j++) {
180e95bf02fSSatish Balay     ptr1 = (char*)(buff1 + j);
181a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(float); i++) ptr2[i] = ptr1[sizeof(float)-1-i];
182a297a907SKarl Rupp     for (i=0; i<(PetscInt) sizeof(float); i++) ptr1[i] = ptr2[i];
183e95bf02fSSatish Balay   }
184e95bf02fSSatish Balay   PetscFunctionReturn(0);
185e95bf02fSSatish Balay }
186e95bf02fSSatish Balay 
187e39fd77fSBarry Smith PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
188e39fd77fSBarry Smith {
189e39fd77fSBarry Smith   PetscErrorCode ierr;
190e39fd77fSBarry Smith 
191e39fd77fSBarry Smith   PetscFunctionBegin;
192e39fd77fSBarry Smith   if      (pdtype == PETSC_INT)    {ierr = PetscByteSwapInt((PetscInt*)data,count);CHKERRQ(ierr);}
193e39fd77fSBarry Smith   else if (pdtype == PETSC_ENUM)   {ierr = PetscByteSwapEnum((PetscEnum*)data,count);CHKERRQ(ierr);}
194acfcf0e5SJed Brown   else if (pdtype == PETSC_BOOL)   {ierr = PetscByteSwapBool((PetscBool*)data,count);CHKERRQ(ierr);}
195e39fd77fSBarry Smith   else if (pdtype == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)data,count);CHKERRQ(ierr);}
1964caf0332SSatish Balay   else if (pdtype == PETSC_REAL)   {ierr = PetscByteSwapReal((PetscReal*)data,count);CHKERRQ(ierr);}
197e39fd77fSBarry Smith   else if (pdtype == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)data,count);CHKERRQ(ierr);}
198e95bf02fSSatish Balay   else if (pdtype == PETSC_FLOAT)  {ierr = PetscByteSwapFloat((float*)data,count);CHKERRQ(ierr);}
199e39fd77fSBarry Smith   else if (pdtype == PETSC_SHORT)  {ierr = PetscByteSwapShort((short*)data,count);CHKERRQ(ierr);}
200*972064b6SLisandro Dalcin   else if (pdtype == PETSC_LONG)   {ierr = PetscByteSwapLong((long*)data,count);CHKERRQ(ierr);}
201e39fd77fSBarry Smith   PetscFunctionReturn(0);
202e39fd77fSBarry Smith }
203e39fd77fSBarry Smith 
204e5c89e4eSSatish Balay /* --------------------------------------------------------- */
205e30d2299SSatish Balay /*@
206e5c89e4eSSatish Balay    PetscBinaryRead - Reads from a binary file.
207e5c89e4eSSatish Balay 
208e5c89e4eSSatish Balay    Not Collective
209e5c89e4eSSatish Balay 
210e5c89e4eSSatish Balay    Input Parameters:
211e5c89e4eSSatish Balay +  fd - the file
212e5c89e4eSSatish Balay .  n  - the number of items to read
213e5c89e4eSSatish Balay -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
214e5c89e4eSSatish Balay 
215e5c89e4eSSatish Balay    Output Parameters:
216e5c89e4eSSatish Balay .  p - the buffer
217e5c89e4eSSatish Balay 
218e5c89e4eSSatish Balay 
219e5c89e4eSSatish Balay 
220e5c89e4eSSatish Balay    Level: developer
221e5c89e4eSSatish Balay 
222e5c89e4eSSatish Balay    Notes:
223e5c89e4eSSatish Balay    PetscBinaryRead() uses byte swapping to work on all machines; the files
224e5c89e4eSSatish Balay    are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
225e5c89e4eSSatish Balay    are converted to the small-endian format when they are read in from the file.
226e2e64c6bSBarry Smith    When PETSc is ./configure with --with-64bit-indices the integers are written to the
22754f21887SBarry Smith    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
22854f21887SBarry Smith    is used.
229e5c89e4eSSatish Balay 
230e5c89e4eSSatish Balay    Concepts: files^reading binary
231e5c89e4eSSatish Balay    Concepts: binary files^reading
232e5c89e4eSSatish Balay 
2334ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
2344ebed01fSBarry Smith           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
235e5c89e4eSSatish Balay @*/
2367087cfbeSBarry Smith PetscErrorCode  PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
237e5c89e4eSSatish Balay {
238e5c89e4eSSatish Balay   int               wsize,err;
239e5c89e4eSSatish Balay   size_t            m = (size_t) n,maxblock = 65536;
240e5c89e4eSSatish Balay   char              *pp = (char*)p;
2417a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
242cba51d77SBarry Smith   PetscBool         readdouble = PETSC_FALSE;
2437a881295SBarry Smith   double            *ppp;
2447a881295SBarry Smith #endif
2457a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) || defined(PETSC_USE_REAL___FLOAT128)
2466de02169SBarry Smith   PetscErrorCode    ierr;
2477a881295SBarry Smith #endif
2487a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
249e5c89e4eSSatish Balay   void              *ptmp = p;
250e5c89e4eSSatish Balay #endif
25105acbc63SBarry Smith   char              *fname = NULL;
252e5c89e4eSSatish Balay 
253e5c89e4eSSatish Balay   PetscFunctionBegin;
2542d53ad75SBarry Smith   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
255e5c89e4eSSatish Balay   if (!n) PetscFunctionReturn(0);
256e5c89e4eSSatish Balay 
2572d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
2582d53ad75SBarry Smith     m            = 64;
2592d53ad75SBarry Smith     type         = PETSC_CHAR;
26005acbc63SBarry Smith     fname        = (char*) malloc(m*sizeof(char));
26105acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
2622d53ad75SBarry Smith     pp           = (char*)fname;
2632d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
2642d53ad75SBarry Smith     ptmp         = (void*)fname;
2652d53ad75SBarry Smith #endif
2662d53ad75SBarry Smith   }
2672d53ad75SBarry Smith 
2686de02169SBarry Smith   if (type == PETSC_INT)          m *= sizeof(PetscInt);
269e5c89e4eSSatish Balay   else if (type == PETSC_SCALAR)  m *= sizeof(PetscScalar);
2704caf0332SSatish Balay   else if (type == PETSC_REAL)    m *= sizeof(PetscReal);
271e5c89e4eSSatish Balay   else if (type == PETSC_DOUBLE)  m *= sizeof(double);
272e95bf02fSSatish Balay   else if (type == PETSC_FLOAT)   m *= sizeof(float);
273e5c89e4eSSatish Balay   else if (type == PETSC_SHORT)   m *= sizeof(short);
274*972064b6SLisandro Dalcin   else if (type == PETSC_LONG)    m *= sizeof(long);
275e5c89e4eSSatish Balay   else if (type == PETSC_CHAR)    m *= sizeof(char);
276e5c89e4eSSatish Balay   else if (type == PETSC_ENUM)    m *= sizeof(PetscEnum);
277ace3abfcSBarry Smith   else if (type == PETSC_BOOL)    m *= sizeof(PetscBool);
2789f7b6320SBarry Smith   else if (type == PETSC_BIT_LOGICAL) m  = PetscBTLength(m)*sizeof(char);
279e32f2f54SBarry Smith   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
280e5c89e4eSSatish Balay 
2817a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
282c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr);
2837a881295SBarry Smith   /* If using __float128 precision we still read in doubles from file */
2844caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) {
2857a881295SBarry Smith     m    = m/2;
286785e854fSJed Brown     ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr);
2877a881295SBarry Smith     pp   = (char*)ppp;
2887a881295SBarry Smith   }
2897a881295SBarry Smith #endif
2907a881295SBarry Smith 
291e5c89e4eSSatish Balay   while (m) {
292e5c89e4eSSatish Balay     wsize = (m < maxblock) ? m : maxblock;
293e5c89e4eSSatish Balay     err   = read(fd,pp,wsize);
294e5c89e4eSSatish Balay     if (err < 0 && errno == EINTR) continue;
295e32f2f54SBarry Smith     if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file");
296e32f2f54SBarry Smith     if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
297e5c89e4eSSatish Balay     m  -= err;
298e5c89e4eSSatish Balay     pp += err;
299e5c89e4eSSatish Balay   }
3007a881295SBarry Smith 
3017a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
3024caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) {
3037a881295SBarry Smith     PetscScalar *pv = (PetscScalar*) p;
3047a881295SBarry Smith     PetscInt    i;
3057a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
3067a881295SBarry Smith     ierr = PetscByteSwapDouble(ppp,n);CHKERRQ(ierr);
3077a881295SBarry Smith #endif
308a297a907SKarl Rupp     for (i=0; i<n; i++) pv[i] = ppp[i];
3097a881295SBarry Smith     ierr = PetscFree(ppp);CHKERRQ(ierr);
3107a881295SBarry Smith     PetscFunctionReturn(0);
3117a881295SBarry Smith   }
3127a881295SBarry Smith #endif
3137a881295SBarry Smith 
314e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
315e39fd77fSBarry Smith   ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr);
316e5c89e4eSSatish Balay #endif
317e5c89e4eSSatish Balay 
31805acbc63SBarry Smith   if (type == PETSC_FUNCTION) {
3192d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3200298fd71SBarry Smith     ierr = PetscDLSym(NULL,fname,(void**)p);CHKERRQ(ierr);
3212d53ad75SBarry Smith #else
3220298fd71SBarry Smith     *(void**)p = NULL;
3232d53ad75SBarry Smith #endif
32405acbc63SBarry Smith     free(fname);
3252d53ad75SBarry Smith   }
326e5c89e4eSSatish Balay   PetscFunctionReturn(0);
327e5c89e4eSSatish Balay }
328e5c89e4eSSatish Balay /* --------------------------------------------------------- */
329e30d2299SSatish Balay /*@
330e5c89e4eSSatish Balay    PetscBinaryWrite - Writes to a binary file.
331e5c89e4eSSatish Balay 
332e5c89e4eSSatish Balay    Not Collective
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay    Input Parameters:
335e5c89e4eSSatish Balay +  fd     - the file
336e5c89e4eSSatish Balay .  p      - the buffer
337e5c89e4eSSatish Balay .  n      - the number of items to write
338e5c89e4eSSatish Balay .  type   - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
339e5c89e4eSSatish Balay -  istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay    Level: advanced
342e5c89e4eSSatish Balay 
343e5c89e4eSSatish Balay    Notes:
344e5c89e4eSSatish Balay    PetscBinaryWrite() uses byte swapping to work on all machines; the files
345e5c89e4eSSatish Balay    are written using big-endian ordering to the file. On small-endian machines the numbers
346e5c89e4eSSatish Balay    are converted to the big-endian format when they are written to disk.
347e2e64c6bSBarry Smith    When PETSc is ./configure with --with-64bit-indices the integers are written to the
34854f21887SBarry Smith    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
34954f21887SBarry Smith    is used.
350e5c89e4eSSatish Balay 
35141f502e3SPatrick Sanan    If running with __float128 precision the output is in __float128 unless one uses the -binary_write_double option
3520da86b62SBarry Smith 
353e5c89e4eSSatish Balay    The Buffer p should be read-write buffer, and not static data.
354e5c89e4eSSatish Balay    This way, byte-swapping is done in-place, and then the buffer is
355e5c89e4eSSatish Balay    written to the file.
356e5c89e4eSSatish Balay 
357e5c89e4eSSatish Balay    This routine restores the original contents of the buffer, after
358e5c89e4eSSatish Balay    it is written to the file. This is done by byte-swapping in-place
359e5c89e4eSSatish Balay    the second time. If the flag istemp is set to PETSC_TRUE, the second
360e5c89e4eSSatish Balay    byte-swapping operation is not done, thus saving some computation,
361e5f36e38SBarry Smith    but the buffer is left corrupted.
362e5c89e4eSSatish Balay 
363300a7f5bSBarry Smith    Because byte-swapping may be done on the values in data it cannot be declared const
364300a7f5bSBarry Smith 
365e5c89e4eSSatish Balay    Concepts: files^writing binary
366e5c89e4eSSatish Balay    Concepts: binary files^writing
367e5c89e4eSSatish Balay 
3684ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
3694ebed01fSBarry Smith           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
370e5c89e4eSSatish Balay @*/
3717087cfbeSBarry Smith PetscErrorCode  PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool  istemp)
372e5c89e4eSSatish Balay {
373e5c89e4eSSatish Balay   char           *pp = (char*)p;
374e5c89e4eSSatish Balay   int            err,wsize;
375e5c89e4eSSatish Balay   size_t         m = (size_t)n,maxblock=65536;
376e5c89e4eSSatish Balay   PetscErrorCode ierr;
377f5351476SHong Zhang #if !defined(PETSC_WORDS_BIGENDIAN)
378e5c89e4eSSatish Balay   void           *ptmp = p;
379e5c89e4eSSatish Balay #endif
38005acbc63SBarry Smith   char           *fname = NULL;
3810da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
382df40af56SBarry Smith   PetscBool      writedouble = PETSC_FALSE;
3830da86b62SBarry Smith   double         *ppp;
3840da86b62SBarry Smith   PetscReal      *pv;
3850da86b62SBarry Smith   PetscInt       i;
3860da86b62SBarry Smith #endif
38741f502e3SPatrick Sanan   PetscDataType  wtype = type;
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay   PetscFunctionBegin;
390e32f2f54SBarry Smith   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
391e5c89e4eSSatish Balay   if (!n) PetscFunctionReturn(0);
392e5c89e4eSSatish Balay 
3932d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
3942d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3952d53ad75SBarry Smith     const char *fnametmp;
3962d53ad75SBarry Smith #endif
3972d53ad75SBarry Smith     m     = 64;
398e25ab156SSatish Balay     fname = (char*)malloc(m*sizeof(char));
39905acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
40005acbc63SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
40105acbc63SBarry Smith     if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time");
40205acbc63SBarry Smith     ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr);
40305acbc63SBarry Smith     ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr);
40405acbc63SBarry Smith #else
40505acbc63SBarry Smith     ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr);
40605acbc63SBarry Smith #endif
40701963f56SBarry Smith     wtype = PETSC_CHAR;
4082d53ad75SBarry Smith     pp    = (char*)fname;
4092d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
4102d53ad75SBarry Smith     ptmp  = (void*)fname;
4112d53ad75SBarry Smith #endif
4122d53ad75SBarry Smith   }
4132d53ad75SBarry Smith 
4140da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
4150da86b62SBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-binary_write_double",&writedouble,NULL);CHKERRQ(ierr);
4160da86b62SBarry Smith   /* If using __float128 precision we still write in doubles to file */
4174caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) {
41841f502e3SPatrick Sanan     wtype = PETSC_DOUBLE;
4190da86b62SBarry Smith     ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr);
4200da86b62SBarry Smith     pv = (PetscReal*)pp;
4210da86b62SBarry Smith     for (i=0; i<n; i++) {
4220da86b62SBarry Smith       ppp[i] = (double) pv[i];
4230da86b62SBarry Smith     }
4240da86b62SBarry Smith     pp   = (char*)ppp;
4250da86b62SBarry Smith     ptmp = (char*)ppp;
4260da86b62SBarry Smith   }
4270da86b62SBarry Smith #endif
4280da86b62SBarry Smith 
42941f502e3SPatrick Sanan   if (wtype == PETSC_INT)          m *= sizeof(PetscInt);
43041f502e3SPatrick Sanan   else if (wtype == PETSC_SCALAR)  m *= sizeof(PetscScalar);
4314caf0332SSatish Balay   else if (wtype == PETSC_REAL)    m *= sizeof(PetscReal);
43241f502e3SPatrick Sanan   else if (wtype == PETSC_DOUBLE)  m *= sizeof(double);
43341f502e3SPatrick Sanan   else if (wtype == PETSC_FLOAT)   m *= sizeof(float);
43441f502e3SPatrick Sanan   else if (wtype == PETSC_SHORT)   m *= sizeof(short);
435*972064b6SLisandro Dalcin   else if (wtype == PETSC_LONG)    m *= sizeof(long);
43641f502e3SPatrick Sanan   else if (wtype == PETSC_CHAR)    m *= sizeof(char);
43741f502e3SPatrick Sanan   else if (wtype == PETSC_ENUM)    m *= sizeof(PetscEnum);
43841f502e3SPatrick Sanan   else if (wtype == PETSC_BOOL)    m *= sizeof(PetscBool);
43941f502e3SPatrick Sanan   else if (wtype == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
440e32f2f54SBarry Smith   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
44341f502e3SPatrick Sanan   ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);
444e5c89e4eSSatish Balay #endif
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay   while (m) {
447e5c89e4eSSatish Balay     wsize = (m < maxblock) ? m : maxblock;
448e5c89e4eSSatish Balay     err   = write(fd,pp,wsize);
449e5c89e4eSSatish Balay     if (err < 0 && errno == EINTR) continue;
45004102261SBarry 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);
451e5c89e4eSSatish Balay     m  -= wsize;
452e5c89e4eSSatish Balay     pp += wsize;
453e5c89e4eSSatish Balay   }
454e5c89e4eSSatish Balay 
455b659c0ceSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN)
456e5c89e4eSSatish Balay   if (!istemp) {
45741f502e3SPatrick Sanan     ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);
458e5c89e4eSSatish Balay   }
459e5c89e4eSSatish Balay #endif
46005acbc63SBarry Smith   if (type == PETSC_FUNCTION) {
46105acbc63SBarry Smith     free(fname);
46205acbc63SBarry Smith   }
4630da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128)
4644caf0332SSatish Balay   if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) {
4650da86b62SBarry Smith     ierr = PetscFree(ppp);CHKERRQ(ierr);
4660da86b62SBarry Smith   }
4670da86b62SBarry Smith #endif
468e5c89e4eSSatish Balay   PetscFunctionReturn(0);
469e5c89e4eSSatish Balay }
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay /*@C
472e5c89e4eSSatish Balay    PetscBinaryOpen - Opens a PETSc binary file.
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay    Not Collective
475e5c89e4eSSatish Balay 
476e5c89e4eSSatish Balay    Input Parameters:
477e5c89e4eSSatish Balay +  name - filename
47845c64e65SBarry Smith -  type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
479e5c89e4eSSatish Balay 
480e5c89e4eSSatish Balay    Output Parameter:
481e5c89e4eSSatish Balay .  fd - the file
482e5c89e4eSSatish Balay 
483e5c89e4eSSatish Balay    Level: advanced
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay   Concepts: files^opening binary
486e5c89e4eSSatish Balay   Concepts: binary files^opening
487e5c89e4eSSatish Balay 
48895452b02SPatrick Sanan    Notes:
48995452b02SPatrick Sanan     Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
490e5c89e4eSSatish Balay    big-endian format. This means the file can be accessed using PetscBinaryOpen() and
491e5c89e4eSSatish Balay    PetscBinaryRead() and PetscBinaryWrite() on any machine.
492e5c89e4eSSatish Balay 
4934ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
4944ebed01fSBarry Smith           PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
49545c64e65SBarry Smith 
496e5c89e4eSSatish Balay @*/
4977087cfbeSBarry Smith PetscErrorCode  PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
498e5c89e4eSSatish Balay {
499e5c89e4eSSatish Balay   PetscFunctionBegin;
500e5c89e4eSSatish Balay #if defined(PETSC_HAVE_O_BINARY)
50145c64e65SBarry Smith   if (mode == FILE_MODE_WRITE) {
502a297a907SKarl 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);
50345c64e65SBarry Smith   } else if (mode == FILE_MODE_READ) {
504a297a907SKarl 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);
50545c64e65SBarry Smith   } else if (mode == FILE_MODE_APPEND) {
506a297a907SKarl 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);
507e5c89e4eSSatish Balay #else
50845c64e65SBarry Smith   if (mode == FILE_MODE_WRITE) {
509a297a907SKarl Rupp     if ((*fd = creat(name,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
51045c64e65SBarry Smith   } else if (mode == FILE_MODE_READ) {
511a297a907SKarl Rupp     if ((*fd = open(name,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
512e5c89e4eSSatish Balay   }
51345c64e65SBarry Smith   else if (mode == FILE_MODE_APPEND) {
514a297a907SKarl Rupp     if ((*fd = open(name,O_WRONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
515e5c89e4eSSatish Balay #endif
516e32f2f54SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
517e5c89e4eSSatish Balay   PetscFunctionReturn(0);
518e5c89e4eSSatish Balay }
519e5c89e4eSSatish Balay 
520e30d2299SSatish Balay /*@
521e5c89e4eSSatish Balay    PetscBinaryClose - Closes a PETSc binary file.
522e5c89e4eSSatish Balay 
523e5c89e4eSSatish Balay    Not Collective
524e5c89e4eSSatish Balay 
525e5c89e4eSSatish Balay    Output Parameter:
526e5c89e4eSSatish Balay .  fd - the file
527e5c89e4eSSatish Balay 
528e5c89e4eSSatish Balay    Level: advanced
529e5c89e4eSSatish Balay 
5304ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
5314ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
532e5c89e4eSSatish Balay @*/
5337087cfbeSBarry Smith PetscErrorCode  PetscBinaryClose(int fd)
534e5c89e4eSSatish Balay {
535e5c89e4eSSatish Balay   PetscFunctionBegin;
536e5c89e4eSSatish Balay   close(fd);
537e5c89e4eSSatish Balay   PetscFunctionReturn(0);
538e5c89e4eSSatish Balay }
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay 
541e8976759SBarry Smith /*@C
542e5c89e4eSSatish Balay    PetscBinarySeek - Moves the file pointer on a PETSc binary file.
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay    Not Collective
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay    Input Parameters:
547e5c89e4eSSatish Balay +  fd - the file
548ff553b35SMatthew Knepley .  off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
549e5c89e4eSSatish Balay             etc. in your calculation rather than sizeof() to compute byte lengths.
550ff553b35SMatthew Knepley -  whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
551ff553b35SMatthew Knepley             if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
552ff553b35SMatthew Knepley             if PETSC_BINARY_SEEK_END then off is an offset from the end of file
553e5c89e4eSSatish Balay 
554e5c89e4eSSatish Balay    Output Parameter:
555e5c89e4eSSatish Balay .   offset - new offset in file
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay    Level: developer
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay    Notes:
560e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
561e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
562e5c89e4eSSatish Balay    binary file may be read on any machine. Hence you CANNOT use sizeof()
563e5c89e4eSSatish Balay    to determine the offset or location.
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay    Concepts: files^binary seeking
566e5c89e4eSSatish Balay    Concepts: binary files^seeking
567e5c89e4eSSatish Balay 
5684ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
5694ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
570e5c89e4eSSatish Balay @*/
5717087cfbeSBarry Smith PetscErrorCode  PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
572e5c89e4eSSatish Balay {
573e5c89e4eSSatish Balay   int iwhence = 0;
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay   PetscFunctionBegin;
576a297a907SKarl Rupp   if (whence == PETSC_BINARY_SEEK_SET) iwhence = SEEK_SET;
577a297a907SKarl Rupp   else if (whence == PETSC_BINARY_SEEK_CUR) iwhence = SEEK_CUR;
578a297a907SKarl Rupp   else if (whence == PETSC_BINARY_SEEK_END) iwhence = SEEK_END;
579a297a907SKarl Rupp   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
580e5c89e4eSSatish Balay #if defined(PETSC_HAVE_LSEEK)
581e5c89e4eSSatish Balay   *offset = lseek(fd,off,iwhence);
582e5c89e4eSSatish Balay #elif defined(PETSC_HAVE__LSEEK)
583e5c89e4eSSatish Balay   *offset = _lseek(fd,(long)off,iwhence);
584e5c89e4eSSatish Balay #else
585e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
586e5c89e4eSSatish Balay #endif
587e5c89e4eSSatish Balay   PetscFunctionReturn(0);
588e5c89e4eSSatish Balay }
589e5c89e4eSSatish Balay 
590e5c89e4eSSatish Balay /*@C
5911d280d73SBarry Smith    PetscBinarySynchronizedRead - Reads from a binary file.
592e5c89e4eSSatish Balay 
593e5c89e4eSSatish Balay    Collective on MPI_Comm
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay    Input Parameters:
596e5c89e4eSSatish Balay +  comm - the MPI communicator
597e5c89e4eSSatish Balay .  fd - the file
598e5c89e4eSSatish Balay .  n  - the number of items to read
599e5c89e4eSSatish Balay -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
600e5c89e4eSSatish Balay 
601e5c89e4eSSatish Balay    Output Parameters:
602e5c89e4eSSatish Balay .  p - the buffer
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay    Level: developer
605e5c89e4eSSatish Balay 
606e5c89e4eSSatish Balay    Notes:
607e5c89e4eSSatish Balay    Does a PetscBinaryRead() followed by an MPI_Bcast()
608e5c89e4eSSatish Balay 
6091d280d73SBarry Smith    PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
610e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
611e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
612e5c89e4eSSatish Balay    binary file may be read on any machine.
613e5c89e4eSSatish Balay 
614e5c89e4eSSatish Balay    Concepts: files^synchronized reading of binary files
615e5c89e4eSSatish Balay    Concepts: binary files^reading, synchronized
616e5c89e4eSSatish Balay 
6174ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
6184ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
619e5c89e4eSSatish Balay @*/
6207087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
621e5c89e4eSSatish Balay {
622e1400dc0SSatish Balay   PetscErrorCode ierr,ierrp=0;
623e5c89e4eSSatish Balay   PetscMPIInt    rank;
624e5c89e4eSSatish Balay   MPI_Datatype   mtype;
62505acbc63SBarry Smith   char           *fname = NULL;
6260298fd71SBarry Smith   void           *ptmp = NULL;
627e5c89e4eSSatish Balay 
628e5c89e4eSSatish Balay   PetscFunctionBegin;
6292d53ad75SBarry Smith   if (type == PETSC_FUNCTION) {
6302d53ad75SBarry Smith     n            = 64;
6312d53ad75SBarry Smith     type         = PETSC_CHAR;
6322d53ad75SBarry Smith     ptmp         = p;
633e366c363SBarry Smith     fname        = (char*)malloc(n*sizeof(char));
63405acbc63SBarry Smith     if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name");
6352d53ad75SBarry Smith     p            = (void*)fname;
6362d53ad75SBarry Smith   }
6372d53ad75SBarry Smith 
638e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
639e5c89e4eSSatish Balay   if (!rank) {
6400090e2cfSJakub Kruzik     ierrp = PetscBinaryRead(fd,p,n,type);
641e5c89e4eSSatish Balay   }
64247fb9d19SJakub Kruzik   ierr = MPI_Bcast(&ierrp,1,MPI_INT,0,comm);CHKERRQ(ierr);
6430090e2cfSJakub Kruzik   CHKERRQ(ierrp);
644e5c89e4eSSatish Balay   ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr);
645e5c89e4eSSatish Balay   ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr);
6462d53ad75SBarry Smith 
647e366c363SBarry Smith   if (type == PETSC_FUNCTION) {
6482d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
6490298fd71SBarry Smith     ierr = PetscDLLibrarySym(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,NULL,fname,(void**)ptmp);CHKERRQ(ierr);
6502d53ad75SBarry Smith #else
6510298fd71SBarry Smith     *(void**)ptmp = NULL;
6522d53ad75SBarry Smith #endif
653e366c363SBarry Smith     free(fname);
6542d53ad75SBarry Smith   }
655e5c89e4eSSatish Balay   PetscFunctionReturn(0);
656e5c89e4eSSatish Balay }
657e5c89e4eSSatish Balay 
658e5c89e4eSSatish Balay /*@C
6591d280d73SBarry Smith    PetscBinarySynchronizedWrite - writes to a binary file.
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay    Collective on MPI_Comm
662e5c89e4eSSatish Balay 
663e5c89e4eSSatish Balay    Input Parameters:
664e5c89e4eSSatish Balay +  comm - the MPI communicator
665e5c89e4eSSatish Balay .  fd - the file
666e5c89e4eSSatish Balay .  n  - the number of items to write
667e5c89e4eSSatish Balay .  p - the buffer
668e5c89e4eSSatish Balay .  istemp - the buffer may be changed
669e5c89e4eSSatish Balay -  type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay    Level: developer
672e5c89e4eSSatish Balay 
673e5c89e4eSSatish Balay    Notes:
674e5c89e4eSSatish Balay    Process 0 does a PetscBinaryWrite()
675e5c89e4eSSatish Balay 
6761d280d73SBarry Smith    PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
677e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
678e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
679e5c89e4eSSatish Balay    binary file may be read on any machine.
680e5c89e4eSSatish Balay 
68195452b02SPatrick Sanan    Notes:
68295452b02SPatrick Sanan     because byte-swapping may be done on the values in data it cannot be declared const
683300a7f5bSBarry Smith 
6841d280d73SBarry Smith    WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
6851d280d73SBarry Smith    while PetscSynchronizedFPrintf() has all processes print their strings in order.
6861d280d73SBarry Smith 
687e5c89e4eSSatish Balay    Concepts: files^synchronized writing of binary files
688e5c89e4eSSatish Balay    Concepts: binary files^reading, synchronized
689e5c89e4eSSatish Balay 
6904ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
6914ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
692e5c89e4eSSatish Balay @*/
6937087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
694e5c89e4eSSatish Balay {
695e5c89e4eSSatish Balay   PetscErrorCode ierr;
696e5c89e4eSSatish Balay   PetscMPIInt    rank;
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay   PetscFunctionBegin;
699e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
700e5c89e4eSSatish Balay   if (!rank) {
701e5c89e4eSSatish Balay     ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr);
702e5c89e4eSSatish Balay   }
703e5c89e4eSSatish Balay   PetscFunctionReturn(0);
704e5c89e4eSSatish Balay }
705e5c89e4eSSatish Balay 
706e5c89e4eSSatish Balay /*@C
7071d280d73SBarry Smith    PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
708e5c89e4eSSatish Balay 
709e5c89e4eSSatish Balay 
710e5c89e4eSSatish Balay    Input Parameters:
711e5c89e4eSSatish Balay +  fd - the file
712e5c89e4eSSatish Balay .  whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
713e5c89e4eSSatish Balay             if PETSC_BINARY_SEEK_CUR then size is offset from current location
714e5c89e4eSSatish Balay             if PETSC_BINARY_SEEK_END then size is offset from end of file
715e5c89e4eSSatish Balay -  off    - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
716e5c89e4eSSatish Balay             etc. in your calculation rather than sizeof() to compute byte lengths.
717e5c89e4eSSatish Balay 
718e5c89e4eSSatish Balay    Output Parameter:
719e5c89e4eSSatish Balay .   offset - new offset in file
720e5c89e4eSSatish Balay 
721e5c89e4eSSatish Balay    Level: developer
722e5c89e4eSSatish Balay 
723e5c89e4eSSatish Balay    Notes:
724e5c89e4eSSatish Balay    Integers are stored on the file as 32 long, regardless of whether
725e5c89e4eSSatish Balay    they are stored in the machine as 32 or 64, this means the same
726e5c89e4eSSatish Balay    binary file may be read on any machine. Hence you CANNOT use sizeof()
727e5c89e4eSSatish Balay    to determine the offset or location.
728e5c89e4eSSatish Balay 
729e5c89e4eSSatish Balay    Concepts: binary files^seeking
730e5c89e4eSSatish Balay    Concepts: files^seeking in binary
731e5c89e4eSSatish Balay 
7324ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
7334ebed01fSBarry Smith           PetscBinarySynchronizedSeek()
734e5c89e4eSSatish Balay @*/
7357087cfbeSBarry Smith PetscErrorCode  PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
736e5c89e4eSSatish Balay {
737e5c89e4eSSatish Balay   PetscErrorCode ierr;
738e5c89e4eSSatish Balay   PetscMPIInt    rank;
739e5c89e4eSSatish Balay 
740e5c89e4eSSatish Balay   PetscFunctionBegin;
741e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
742e5c89e4eSSatish Balay   if (!rank) {
743e5c89e4eSSatish Balay     ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr);
744e5c89e4eSSatish Balay   }
745e5c89e4eSSatish Balay   PetscFunctionReturn(0);
746e5c89e4eSSatish Balay }
747e5c89e4eSSatish Balay 
7480fc9d207SBarry Smith #if defined(PETSC_HAVE_MPIIO)
749e39fd77fSBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN)
750e39fd77fSBarry Smith 
751951e3c8eSBarry Smith #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
752e39fd77fSBarry Smith /*
753e39fd77fSBarry Smith       MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
754e39fd77fSBarry Smith     These are set into MPI in PetscInitialize() via MPI_Register_datarep()
755e39fd77fSBarry Smith 
756e39fd77fSBarry Smith     Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
757e39fd77fSBarry Smith 
758951e3c8eSBarry Smith     The next three routines are not used because MPICH does not support their use
759e39fd77fSBarry Smith 
760e39fd77fSBarry Smith */
7618cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
762e39fd77fSBarry Smith {
763e39fd77fSBarry Smith   MPI_Aint    ub;
764e39fd77fSBarry Smith   PetscMPIInt ierr;
765e39fd77fSBarry Smith 
766e39fd77fSBarry Smith   ierr = MPI_Type_get_extent(datatype,&ub,file_extent);
767e39fd77fSBarry Smith   return ierr;
768e39fd77fSBarry Smith }
769e39fd77fSBarry Smith 
7708cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
771e39fd77fSBarry Smith {
772e39fd77fSBarry Smith   PetscDataType pdtype;
773e39fd77fSBarry Smith   PetscMPIInt   ierr;
774e39fd77fSBarry Smith   size_t        dsize;
775e39fd77fSBarry Smith 
776e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr);
777e39fd77fSBarry Smith   ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr);
778e39fd77fSBarry Smith 
779e39fd77fSBarry Smith   /* offset is given in units of MPI_Datatype */
780e39fd77fSBarry Smith   userbuf = ((char*)userbuf) + dsize*position;
781e39fd77fSBarry Smith 
782e39fd77fSBarry Smith   ierr = PetscMemcpy(userbuf,filebuf,count*dsize);CHKERRQ(ierr);
783e39fd77fSBarry Smith   ierr = PetscByteSwap(userbuf,pdtype,count);CHKERRQ(ierr);
784e39fd77fSBarry Smith   return ierr;
785e39fd77fSBarry Smith }
786e39fd77fSBarry Smith 
787e39fd77fSBarry Smith PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
788e39fd77fSBarry Smith {
789e39fd77fSBarry Smith   PetscDataType pdtype;
790e39fd77fSBarry Smith   PetscMPIInt   ierr;
791e39fd77fSBarry Smith   size_t        dsize;
792e39fd77fSBarry Smith 
793e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr);
794e39fd77fSBarry Smith   ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr);
795e39fd77fSBarry Smith 
796e39fd77fSBarry Smith   /* offset is given in units of MPI_Datatype */
797e39fd77fSBarry Smith   userbuf = ((char*)userbuf) + dsize*position;
798e39fd77fSBarry Smith 
799e39fd77fSBarry Smith   ierr = PetscMemcpy(filebuf,userbuf,count*dsize);CHKERRQ(ierr);
800e39fd77fSBarry Smith   ierr = PetscByteSwap(filebuf,pdtype,count);CHKERRQ(ierr);
801e39fd77fSBarry Smith   return ierr;
802e39fd77fSBarry Smith }
803951e3c8eSBarry Smith #endif
804e39fd77fSBarry Smith 
805e39fd77fSBarry Smith PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
806e39fd77fSBarry Smith {
807e39fd77fSBarry Smith   PetscErrorCode ierr;
808e39fd77fSBarry Smith   PetscDataType  pdtype;
809e39fd77fSBarry Smith 
810e39fd77fSBarry Smith   PetscFunctionBegin;
811e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr);
812e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
813e39fd77fSBarry Smith   ierr = MPI_File_write_all(fd,data,cnt,dtype,status);CHKERRQ(ierr);
814e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
815a6796414SBarry Smith   PetscFunctionReturn(0);
816e39fd77fSBarry Smith }
817e39fd77fSBarry Smith 
818e39fd77fSBarry Smith PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
819e39fd77fSBarry Smith {
820e39fd77fSBarry Smith   PetscErrorCode ierr;
821e39fd77fSBarry Smith   PetscDataType  pdtype;
822e39fd77fSBarry Smith 
823e39fd77fSBarry Smith   PetscFunctionBegin;
824e39fd77fSBarry Smith   ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr);
825e39fd77fSBarry Smith   ierr = MPI_File_read_all(fd,data,cnt,dtype,status);CHKERRQ(ierr);
826e39fd77fSBarry Smith   ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);
827a6796414SBarry Smith   PetscFunctionReturn(0);
828e39fd77fSBarry Smith }
829e39fd77fSBarry Smith #endif
830951e3c8eSBarry Smith #endif
831