diff options
author | tradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a> | 2002-04-17 18:01:50 +0000 |
---|---|---|
committer | tradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a> | 2002-04-17 18:01:50 +0000 |
commit | e7b5e1e51708eca4912aed95860f06a8b5a522f1 (patch) | |
tree | f6062873e2e0cf56b3e64fe6889fb7c9338b3fad /src/Write.c | |
parent | f7f7a801866271138a1888a493ae0c50ca372b52 (diff) |
Tidying up the code to make it consistent with the structure in IOHDF5.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGHIO/IOFlexIO/trunk@230 ebee0441-1374-4afa-a3b5-247f3ba15b9a
Diffstat (limited to 'src/Write.c')
-rw-r--r-- | src/Write.c | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/Write.c b/src/Write.c new file mode 100644 index 0000000..97213b6 --- /dev/null +++ b/src/Write.c @@ -0,0 +1,350 @@ +/*@@ + @file Write.c + @date Fri Feb 21 15:27:03 1997 + @author John Shalf, Gabrielle Allen, Tom Goodale, Thomas Radke + @desc + File handling routines for IOFlexIO. + @enddesc + @version $Id$ + @@*/ + + +#include <stdio.h> +#include <stdlib.h> + +#include "cctk.h" +#include "cctk_Parameters.h" +#include "CactusPUGH/PUGH/src/include/pugh.h" +#include "CactusBase/IOUtil/src/ioGH.h" +#include "CactusBase/IOUtil/src/ioutil_Utils.h" +#include "ioFlexGH.h" + +/* the rcs ID and its dummy funtion to use it */ +static const char *rcsid = "$Header$"; +CCTK_FILEVERSION(CactusPUGHIO_IOFlexIO_Write_c) + + +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static IEEEfile_t *OpenFile (const cGH *GH, const char *alias, int *is_new_file); + + +/*@@ + @routine IOFlexIO_Write + @author Paul Walker + @date Feb 1997 + @desc + Opens the IOFlexIO output file, calls the dump routine, + and closes it again. + @enddesc + + @calls OpenFile + IOFlexIO_DumpVar + + @var GH + @vdesc Pointer to CCTK GH + @vtype const cGH * + @vio in + @endvar + @var vindex + @vdesc index of variable + @vtype int + @vio in + @endvar + @var alias + @vdesc alias name of variable to output + @vtype const char * + @vio in + @endvar + + @returntype int + @returndesc + return code of @seeroutine IOFlexIO_DumpVar, or<BR> + -1 if no storage was assigned to variable<BR> + -2 if file couldn't be opened + @endreturndesc +@@*/ +int IOFlexIO_Write (const cGH *GH, int vindex, const char *alias) +{ + ioGH *ioUtilGH; + int len, is_new_file, retval; + char buffer[128]; + char *fullname; + IEEEfile_t *file; + DECLARE_CCTK_PARAMETERS + + + /* check if variable has storage assigned */ + if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (vindex))) + { + fullname = CCTK_FullName (vindex); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "No IOFlexIO output for '%s' (no storage)", fullname); + free (fullname); + return (-1); + } + + /* get the handle for IOUtil and IOFlexIO extensions */ + ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); + + if (verbose) + { + CCTK_VInfo (CCTK_THORNSTRING, "IOFlexIO output of variable '%s', " + "alias '%s'", CCTK_VarName (vindex), alias); + } + + /* get the filename and descriptor for output */ + file = OpenFile (GH, alias, &is_new_file); + + /* nothing to do for an already opened file which is kept open all the time */ + if (CCTK_MyProc (GH) == ioUtilGH->ioproc) + { + if (is_new_file || reuse_filehandles) + { + if (verbose) + { + CCTK_VInfo (CCTK_THORNSTRING, "%s IEEEIO output file '%s'", + is_new_file ? "Opening" : "Resuming", file->filename); + } + + /* first time through or one file per slice: open anew */ + if (is_new_file) + { + file->iofile = IEEEopen (file->filename, "w"); + if (! IOisValid (file->iofile)) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Couldn't " + "create IEEEIO output file '%s'", file->filename); + } + + /* add the parameter filename and the creation date + as file identification attributes */ + if (CCTK_Equals (out_fileinfo, "parameter filename") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + CCTK_ParameterFilename (sizeof (buffer), buffer); + FLEXIO_ERROR (IOwriteAttribute (file->iofile, "parameter file", + FLEXIO_CHAR, + strlen (buffer) + 1, buffer)); + } + if (CCTK_Equals (out_fileinfo, "creation date") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + Util_CurrentDate (sizeof (buffer), buffer); + len = strlen (buffer) + 1; + buffer[len-1] = ' '; + Util_CurrentTime (sizeof (buffer) - len, buffer + len); + FLEXIO_ERROR (IOwriteAttribute (file->iofile, "creation date", + FLEXIO_CHAR, + strlen (buffer) + 1, buffer)); + } + } + else + { + /* resume the file (reopen descriptor) + This allows descriptor reuse without requiring expensive destruction + and reallocation of the associated datastructures */ + FLEXIO_ERROR (IOresume (file->iofile)); + } + + /* Turn on buffer cache (with default size chosen by IEEEIO lib) */ + if (file->iofile) + { + IEEEbufferOn (file->iofile, 0); + } + } + if (! file->iofile) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Invalid file descriptor for IEEEIO ouput file '%s'", + file->filename); + return (-2); + } + } + else + { + file->iofile = (IOFile) 0; + } + + /* output the data */ + retval = IOFlexIO_DumpVar (GH, vindex, 0, file->iofile); + + /* output the GH extensions and parameters */ + if (file->iofile) + { + /* output parameters necessary for filereader datafiles */ + if (is_new_file) + { + IOFlexIOi_DumpGHExtensions (GH, file->iofile); + if (strcmp (out3D_parameters, "no")) + { + IOFlexIOi_DumpParameters (GH, strcmp (out3D_parameters, "all") == 0, + file->iofile); + } + } + + /* close the file */ + if (out3D_septimefiles || reuse_filehandles) + { + if (verbose) + { + CCTK_VInfo (CCTK_THORNSTRING, "%s IEEEIO output file '%s'", + out3D_septimefiles ? "Closing" : "Pausing", + file->filename); + } + + IEEEbufferOff (file->iofile); + if (out3D_septimefiles) + { + FLEXIO_ERROR (IOclose (file->iofile)); + } + else + { + FLEXIO_ERROR (IOpause (file->iofile)); + } + } + } + if (out3D_septimefiles) + { + free (file->filename); + free (file); + } + + return (retval); +} + + +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +/* generate the filename for the given alias and creates/opens the file */ +static IEEEfile_t *OpenFile (const cGH *GH, const char *alias, int *is_new_file) +{ + ioGH *ioUtilGH; + pGH *pughGH; + flexioGH *myGH; + int myproc, nprocs, result; + char extra[256], extradir[256]; + char *outputdir, *tmp; + IEEEfile_t *file; + DECLARE_CCTK_PARAMETERS + + + /* get the GH extensions for PUGH, IOUtil, and IOFlexIO */ + pughGH = PUGH_pGH (GH); + ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); + myGH = (flexioGH *) CCTK_GHExtension (GH, "IOFlexIO"); + + file = (IEEEfile_t *) GetNamedData (myGH->fileList, alias); + if (file != NULL) + { + /* set flag to indicate that file should be opened in append mode */ + *is_new_file = 0; + return (file); + } + + extra[0] = '\0'; + extradir[0] = '\0'; + + nprocs = CCTK_nProcs (GH); + myproc = CCTK_MyProc (GH); + + if (out3D_septimefiles) + { + tmp = extra; + sprintf (extra, "%s.time_%7.3f", extra, GH->cctk_time); + + /* be sure to replace any spaces in the filename with an _ */ + do + { + if (*tmp == ' ') + { + *tmp = '_'; + } + } while (*++tmp); + } + + /* OUTPUT ONE FILE FOR EACH N PROCESSORS + * ------------------------------------- + * + * If only one output file, the single file for each GF is written + * in the normal output dir (that is extradir = ""). Otherwise + * a directory is created for each output GF to hold the multiple + * file + */ + + if (ioUtilGH->ioproc_every < nprocs) + { + /* add the output processor number to the extra string */ + sprintf (extra, "%s.file_%d", extra, myproc / ioUtilGH->ioproc_every); + + /* if necessary create the output directory */ + outputdir = (char *) malloc (strlen (myGH->outdir) + strlen (alias) + 5); + sprintf (outputdir, "%s/%s_3d", myGH->outdir, alias); + + result = IOUtil_CreateDirectory (GH, outputdir, + ! CCTK_Equals (out3D_mode, "onefile"), + ioUtilGH->ioproc); + if (result < 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Problem creating IOFlexIO output directory '%s'", outputdir); + } + else if (result > 0 && CCTK_Equals (newverbose, "full")) + { + CCTK_VInfo (CCTK_THORNSTRING, + "IOFlexIO output directory '%s' already exists", outputdir); + } + + free (outputdir); + +#ifdef CCTK_MPI + /* wait for all processors to catch up */ + CCTK_Barrier (GH); +#endif + + /* extradir is the relative output directory */ + sprintf (extradir, "%s_3d/", alias); + } + + /* CREATE THE COMPLETE OUTPUT FILENAME + ----------------------------------- */ + + file = (IEEEfile_t *) malloc (sizeof (IEEEfile_t)); + + file->filename = (char *) malloc (strlen (myGH->outdir) + strlen (extradir) + + strlen (alias) + strlen (extra) + + (pughGH->identity_string ? + strlen (pughGH->identity_string) : 0) + + 10); + sprintf (file->filename, "%s/%s%s_3d%s%s.ieee", myGH->outdir, + extradir, alias, extra, (pughGH->identity_string ? + pughGH->identity_string : "")); + + /* no need to store file info if used only once */ + if (! out3D_septimefiles) + { + if (myproc == ioUtilGH->ioproc) + { + if (ioUtilGH->recovered) + { + file->iofile = IEEEopen (file->filename, "a"); + *is_new_file = ! IOisValid (file->iofile); + } + else + { + *is_new_file = 1; + } + } + StoreNamedData (&myGH->fileList, alias, file); + } + else + { + *is_new_file = 1; + } + + return (file); +} |