aboutsummaryrefslogtreecommitdiff
path: root/src/Write.c
diff options
context:
space:
mode:
authortradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a>2002-04-17 18:01:50 +0000
committertradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a>2002-04-17 18:01:50 +0000
commite7b5e1e51708eca4912aed95860f06a8b5a522f1 (patch)
treef6062873e2e0cf56b3e64fe6889fb7c9338b3fad /src/Write.c
parentf7f7a801866271138a1888a493ae0c50ca372b52 (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.c350
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);
+}