PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer) { PetscErrorCode ierr; PetscBool isascii,isbinary; PetscFunctionBegin; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); if (isascii) { #if defined(PETSC_SERIALIZE_FUNCTIONS) const char *fname; ierr = PetscFPTFind(kdm->ops->ifunction,&fname);CHKERRQ(ierr); if (fname) { ierr = PetscViewerASCIIPrintf(viewer," IFunction used by TS: %s\n",fname);CHKERRQ(ierr); } ierr = PetscFPTFind(kdm->ops->ijacobian,&fname);CHKERRQ(ierr); if (fname) { ierr = PetscViewerASCIIPrintf(viewer," IJacobian function used by TS: %s\n",fname);CHKERRQ(ierr); } #endif } else if (isbinary) { struct { TSIFunction ifunction; PetscErrorCode (*ifunctionview)(void*,PetscViewer); PetscErrorCode (*ifunctionload)(void**,PetscViewer); } funcstruct = {kdm->ops->ifunction, kdm->ops->ifunctionview, kdm->ops->ifunctionload}; struct { TSIJacobian ijacobian; PetscErrorCode (*ijacobianview)(void*,PetscViewer); PetscErrorCode (*ijacobianload)(void**,PetscViewer); } jacstruct = {kdm->ops->ijacobian, kdm->ops->ijacobianview, kdm->ops->ijacobianload}; ierr = PetscViewerBinaryWrite(viewer,&funcstruct,3,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); if (kdm->ops->ifunctionview) { ierr = (*kdm->ops->ifunctionview)(kdm->ifunctionctx,viewer);CHKERRQ(ierr); } ierr = PetscViewerBinaryWrite(viewer,&jacstruct,3,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); if (kdm->ops->ijacobianview) { ierr = (*kdm->ops->ijacobianview)(kdm->ijacobianctx,viewer);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@ PetscBinaryWrite - Writes to a binary file. Not Collective Input Parameters: + fd - the file . p - the buffer . n - the number of items to write . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. Level: advanced Notes: PetscBinaryWrite() uses byte swapping to work on all machines; the files are written using big-endian ordering to the file. On small-endian machines the numbers are converted to the big-endian format when they are written to disk. When PETSc is ./configure with --with-64bit-indices the integers are written to the file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices is used. If running with __float128 precision the output is in __float128 unless one uses the -binary_write_double option The Buffer p should be read-write buffer, and not static data. This way, byte-swapping is done in-place, and then the buffer is written to the file. This routine restores the original contents of the buffer, after it is written to the file. This is done by byte-swapping in-place the second time. If the flag istemp is set to PETSC_TRUE, the second byte-swapping operation is not done, thus saving some computation, but the buffer is left corrupted. Because byte-swapping may be done on the values in data it cannot be declared const Concepts: files^writing binary Concepts: binary files^writing .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() @*/ PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) { char *pp = (char*)p; int err,wsize; size_t m = (size_t)n,maxblock=65536; PetscErrorCode ierr; void *ptmp = p; char *fname = NULL; #if defined(PETSC_USE_REAL___FLOAT128) PetscBool writedouble = PETSC_FALSE; double *ppp; PetscReal *pv; PetscInt i; #endif PetscDataType wtype = type; PetscFunctionBegin; if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); if (!n) PetscFunctionReturn(0); if (type == PETSC_FUNCTION) { #if defined(PETSC_SERIALIZE_FUNCTIONS) const char *fnametmp; #endif m = 64; fname = (char*)malloc(m*sizeof(char)); if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); #if defined(PETSC_SERIALIZE_FUNCTIONS) if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time"); ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr); ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr); #else ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr); #endif wtype = PETSC_CHAR; pp = (char*)fname; ptmp = (void*)fname; } #if defined(PETSC_USE_REAL___FLOAT128) ierr = PetscOptionsGetBool(NULL,NULL,"-binary_write_double",&writedouble,NULL);CHKERRQ(ierr); /* If using __float128 precision we still write in doubles to file */ if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { wtype = PETSC_DOUBLE; ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr); pv = (PetscReal*)pp; for (i=0; i<n; i++) { ppp[i] = (double) pv[i]; } pp = (char*)ppp; ptmp = (char*)ppp; } #endif if (wtype == PETSC_INT) m *= sizeof(PetscInt); else if (wtype == PETSC_SCALAR) m *= sizeof(PetscScalar); else if (wtype == PETSC_REAL) m *= sizeof(PetscReal); else if (wtype == PETSC_DOUBLE) m *= sizeof(double); else if (wtype == PETSC_FLOAT) m *= sizeof(float); else if (wtype == PETSC_SHORT) m *= sizeof(short); else if (wtype == PETSC_LONG) m *= sizeof(long); else if (wtype == PETSC_CHAR) m *= sizeof(char); else if (wtype == PETSC_ENUM) m *= sizeof(PetscEnum); else if (wtype == PETSC_BOOL) m *= sizeof(PetscBool); else if (wtype == PETSC_INT64) m *= sizeof(PetscInt64); else if (wtype == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);} while (m) { wsize = (m < maxblock) ? m : maxblock; err = write(fd,pp,wsize); if (err < 0 && errno == EINTR) continue; 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); m -= wsize; pp += wsize; } if (!istemp) { if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);} } if (type == PETSC_FUNCTION) { free(fname); } #if defined(PETSC_USE_REAL___FLOAT128) if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { ierr = PetscFree(ppp);CHKERRQ(ierr); } #endif PetscFunctionReturn(0); }
/*@ PetscBinaryWrite - Writes to a binary file. Not Collective Input Parameters: + fd - the file . p - the buffer . n - the number of items to write . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. Level: advanced Notes: PetscBinaryWrite() uses byte swapping to work on all machines; the files are written using big-endian ordering to the file. On small-endian machines the numbers are converted to the big-endian format when they are written to disk. When PETSc is ./configure with --with-64bit-indices the integers are written to the file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices is used. The Buffer p should be read-write buffer, and not static data. This way, byte-swapping is done in-place, and then the buffer is written to the file. This routine restores the original contents of the buffer, after it is written to the file. This is done by byte-swapping in-place the second time. If the flag istemp is set to PETSC_TRUE, the second byte-swapping operation is not done, thus saving some computation, but the buffer is left corrupted. Because byte-swapping may be done on the values in data it cannot be declared const Concepts: files^writing binary Concepts: binary files^writing .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() @*/ PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) { char *pp = (char*)p; int err,wsize; size_t m = (size_t)n,maxblock=65536; PetscErrorCode ierr; #if !defined(PETSC_WORDS_BIGENDIAN) void *ptmp = p; #endif char *fname = NULL; PetscFunctionBegin; if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); if (!n) PetscFunctionReturn(0); if (type == PETSC_FUNCTION) { #if defined(PETSC_SERIALIZE_FUNCTIONS) const char *fnametmp; #endif m = 64; fname = (char*)malloc(m*sizeof(char)); if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); #if defined(PETSC_SERIALIZE_FUNCTIONS) if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time"); ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr); ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr); #else ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr); #endif type = PETSC_CHAR; pp = (char*)fname; #if !defined(PETSC_WORDS_BIGENDIAN) ptmp = (void*)fname; #endif } if (type == PETSC_INT) m *= sizeof(PetscInt); else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); else if (type == PETSC_DOUBLE) m *= sizeof(double); else if (type == PETSC_FLOAT) m *= sizeof(float); else if (type == PETSC_SHORT) m *= sizeof(short); else if (type == PETSC_CHAR) m *= sizeof(char); else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); else if (type == PETSC_BOOL) m *= sizeof(PetscBool); else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); #if !defined(PETSC_WORDS_BIGENDIAN) ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr); #endif while (m) { wsize = (m < maxblock) ? m : maxblock; err = write(fd,pp,wsize); if (err < 0 && errno == EINTR) continue; 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); m -= wsize; pp += wsize; } #if !defined(PETSC_WORDS_BIGENDIAN) if (!istemp) { ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr); } #endif if (type == PETSC_FUNCTION) { free(fname); } PetscFunctionReturn(0); }