aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README9
-rw-r--r--interface.ccl5
-rw-r--r--param.ccl51
-rw-r--r--schedule.ccl15
-rw-r--r--src/DumpVar.c363
-rw-r--r--src/GHExtension.c83
-rw-r--r--src/Output.c270
-rw-r--r--src/Startup.c208
-rw-r--r--src/StreamedHDF5GH.h147
-rw-r--r--src/Write.c139
-rw-r--r--src/make.code.defn5
-rw-r--r--src/make.configuration.defn12
12 files changed, 1307 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..77a7152
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+Cactus Code Thorn IOFiberHDF5
+Authors : Thomas Radke (tradke@aei-potsdam.mpg.de)
+CVS info : $Header$
+--------------------------------------------------------------------------
+
+Purpose of the thorn:
+
+This thorn uses the HDF5 Stream Virtual File Driver to stream HDF5 files
+via live sockets to any connected clients.
diff --git a/interface.ccl b/interface.ccl
new file mode 100644
index 0000000..f09038a
--- /dev/null
+++ b/interface.ccl
@@ -0,0 +1,5 @@
+# Interface definition for thorn StreamedHDF5
+# $Header$
+
+implements: StreamedHDF5
+inherits: Hyperslab
diff --git a/param.ccl b/param.ccl
new file mode 100644
index 0000000..8ce6399
--- /dev/null
+++ b/param.ccl
@@ -0,0 +1,51 @@
+# Parameter definitions for thorn StreamedHDF5
+# $Header$
+
+#############################################################################
+### declare StreamedHDF5 parameters
+#############################################################################
+private:
+
+########################
+# How often to do output
+########################
+INT outHDF5_every "How often to do HDF5 streaming, overrides IO::out_every" STEERABLE = ALWAYS
+{
+ -1:* ::
+} -1
+
+
+#####################
+# Variables to output
+#####################
+STRING out_vars "Variables to stream in HDF5 file format" STEERABLE = ALWAYS
+{
+ .* :: A regex which matches everything
+} ""
+
+
+INT port "Port to stream the HDF5 file out" STEERABLE = ALWAYS
+{
+ 1000:16000 :: "Valid ranges are above 1000, ports below that value would require root access"
+} 8000
+
+
+#############################################################################
+### import IOUtil parameters
+#############################################################################
+shares: IO
+
+########################
+# How often to do output
+########################
+USES INT out_every ""
+{
+ : ::
+}
+
+################
+# various things
+################
+USES BOOLEAN verbose ""
+{
+}
diff --git a/schedule.ccl b/schedule.ccl
new file mode 100644
index 0000000..0287c01
--- /dev/null
+++ b/schedule.ccl
@@ -0,0 +1,15 @@
+# Schedule definitions for thorn StreamedHDF5
+# $Header$
+
+########################################################################
+### register StreamedHDF5 routines
+########################################################################
+schedule StreamedHDF5_Startup at STARTUP after IOUtil_Startup
+{
+ LANG:C
+} "StreamedHDF5 startup routine"
+
+schedule StreamedHDF5_Terminate at TERMINATE
+{
+ LANG:C
+} "StreamedHDF5 termination routine"
diff --git a/src/DumpVar.c b/src/DumpVar.c
new file mode 100644
index 0000000..2cf03d0
--- /dev/null
+++ b/src/DumpVar.c
@@ -0,0 +1,363 @@
+/*@@
+ @file DumpVar.c
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ Do the actual writing of a variable.
+ @enddesc
+ @history
+ @hauthor Thomas Radke @hdate May 21 1999
+ @hdesc Just copied from thorn FlexIO.
+ @hendhistory
+ @@*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusPUGH/Hyperslab/src/Hyperslab.h"
+#include "StreamedHDF5GH.h"
+
+
+/*#define StreamedHDF5_DEBUG 1 */
+
+/* local function prototypes */
+static void StreamedHDF5_Dump (cGH *GH, int index, int timelevel, void *outme,
+ int *hsizes, int hdf5_type, hid_t fid);
+static void StreamedHDF5_AddCommonAttributes (cGH *GH, int index, int timelevel,
+ hid_t dataset);
+static int GetHDF5type (StreamedHDF5GH *myGH, int vtype, hid_t *hdf5_type);
+
+/*@@
+ @routine StreamedHDF5_DumpVar
+ @date 16 Apr 1999
+ @author Thomas Radke
+ @desc
+ Generic dump routine, just calls the appropriate dump routine
+ @enddesc
+ @calledby StreamedHDF5_DumpGH IOHDF5_Write3D
+ @history
+ @endhistory
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH
+ @vio in
+ @endvar
+ @var index
+ @vdesc global index of the variable to be dumped
+ @vtype int
+ @vio in
+ @endvar
+ @var timelevel
+ @vdesc the timelevel to store
+ @vtype int
+ @vio in
+ @endvar
+ @var fid
+ @vdesc the HDF5 file handle
+ @vtype hid_t
+ @vio in
+ @endvar
+@@*/
+int StreamedHDF5_DumpVar (cGH *GH, int index, int timelevel, hid_t fid)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i, vdim;
+ void *data;
+ int *origin, *directions, *lengths, *downsamples, *hsizes;
+ hid_t hdf5_type;
+ StreamedHDF5GH *myGH;
+ int vtype;
+
+
+ /* Get the handle for StreamedHDF5 extensions */
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ vtype = CCTK_VarTypeI (index);
+ if (GetHDF5type (myGH, vtype, &hdf5_type) < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Unsupported variable type %d", vtype);
+ return (-1);
+ }
+
+ /* get the dimension of the variable */
+ vdim = CCTK_GroupDimI (CCTK_GroupIndexFromVarI (index));
+
+ origin = (int *) malloc (5 * vdim * sizeof (int));
+ directions = origin + 1*vdim;
+ lengths = origin + 2*vdim;
+ downsamples = origin + 3*vdim;
+ hsizes = origin + 4*vdim;
+
+ for (i = 0; i < vdim; i++)
+ {
+ origin [i] = 0;
+ lengths [i] = -1;
+ downsamples [i] = 1;
+ }
+
+ data = NULL;
+ if (Hyperslab_GetHyperslab (GH, 0, index, timelevel, vdim, origin,
+ directions, lengths, downsamples,
+ &data, hsizes) < 0)
+ {
+ char *fullname = CCTK_FullName (index);
+
+
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Failed to extract hyperslab for variable '%s'", fullname);
+ free (fullname);
+ free (origin);
+ return (-1);
+ }
+
+ if (fid >= 0)
+ {
+ StreamedHDF5_Dump (GH, index, timelevel, data, hsizes, hdf5_type, fid);
+ }
+
+ if (data)
+ free (data);
+ free (origin);
+
+ return (0);
+}
+
+
+/***************************** local functions ****************************/
+
+static int GetHDF5type (StreamedHDF5GH *myGH, int vtype, hid_t *hdf5_type)
+{
+ int retval = 0;
+
+
+ switch (vtype)
+ {
+ case CCTK_VARIABLE_CHAR:
+ *hdf5_type = IOHDF5_CHAR;
+ break;
+ case CCTK_VARIABLE_INT:
+ *hdf5_type = IOHDF5_INT;
+ break;
+ case CCTK_VARIABLE_REAL:
+ *hdf5_type = IOHDF5_REAL;
+ break;
+ case CCTK_VARIABLE_COMPLEX:
+ *hdf5_type = myGH->IOHDF5_COMPLEX;
+ break;
+ default:
+ retval = -1;
+ break;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine StreamedHDF5_AddCommonAttributes
+ @date May 21 1999
+ @author Thomas Radke
+ @desc
+ Add "Common" attributes, these are:
+ <ul>
+ <li> the variable's groupname
+ <li> the grouptype
+ <li> number of timelevels
+ <li> the current date
+ Note that the datestamp should be turned of if you are byte
+ comparing two output files.
+ <li> simulation time
+ <li> origin
+ <li> bounding box
+ <li> gridspacings (both downsampled and evolution)
+ <li> global grid size
+ </ul>
+ @enddesc
+ @calledby StreamedHDF5_DumpGS, IOHDF5_collectiveDump, IOHDF5_procDump
+ @history
+ @endhistory
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH
+ @vio in
+ @endvar
+ @var index
+ @vdesc global index of the variable to be dumped
+ @vtype int
+ @vio in
+ @endvar
+ @var timelevel
+ @vdesc the timelevel to store
+ @vtype int
+ @vio in
+ @endvar
+ @var dataset
+ @vdesc the dataset handle where the attributes should be attached to
+ @vtype hid_t
+ @vio in
+ @endvar
+@@*/
+static void StreamedHDF5_AddCommonAttributes (cGH *GH, int index, int timelevel,
+ hid_t dataset)
+{
+ DECLARE_CCTK_PARAMETERS
+#if 0
+ int dim;
+ CCTK_INT intAttr;
+ char *groupname;
+#endif
+ CCTK_REAL realAttr [6];
+ ioGH *ioUtilGH;
+ StreamedHDF5GH *myGH;
+
+
+ /* Get the handles for IOUtil and StreamedHDF5 extensions */
+ ioUtilGH = (ioGH *) GH->extensions [CCTK_GHExtensionHandle ("IO")];
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+#if 0
+ /* get the dimension of the variable */
+ dim = CCTK_GroupDimI (CCTK_GroupIndexFromVarI (index));
+
+ groupname = CCTK_GroupNameFromVarI (index);
+ WRITE_ATTRIBUTE ("groupname", groupname,
+ dataset, myGH->scalarDataspace, 0, myGH->IOHDF5_STRING);
+ free (groupname);
+ intAttr = CCTK_GroupTypeFromVarI (index);
+ WRITE_ATTRIBUTE ("grouptype", &intAttr, dataset, myGH->scalarDataspace, 0,
+ IOHDF5_INT);
+ intAttr = CCTK_NumTimeLevelsFromVarI (index);
+ WRITE_ATTRIBUTE ("ntimelevels", &intAttr, dataset, myGH->scalarDataspace, 0,
+ IOHDF5_INT);
+#endif
+
+ WRITE_ATTRIBUTE ("time", &GH->cctk_time, dataset, myGH->scalarDataspace, 0,
+ IOHDF5_REAL);
+
+ /* NOTE: the attributes "origin", "min_ext", "max_ext", and "delta"
+ are always stored as 3-dimensional points */
+ realAttr [0] = CCTK_CoordOrigin ("x");
+ realAttr [1] = CCTK_CoordOrigin ("y");
+ realAttr [2] = CCTK_CoordOrigin ("z");
+ WRITE_ATTRIBUTE ("origin", realAttr, dataset, myGH->arrayDataspace, 3,
+ IOHDF5_REAL);
+
+ CCTK_CoordRange (GH, &realAttr [0], &realAttr [3], "x");
+ CCTK_CoordRange (GH, &realAttr [1], &realAttr [4], "y");
+ CCTK_CoordRange (GH, &realAttr [2], &realAttr [5], "z");
+ WRITE_ATTRIBUTE ("min_ext", realAttr, dataset, myGH->arrayDataspace, 3,
+ IOHDF5_REAL);
+ WRITE_ATTRIBUTE ("max_ext", realAttr + 3, dataset, myGH->arrayDataspace, 3,
+ IOHDF5_REAL);
+
+ WRITE_ATTRIBUTE ("delta", GH->cctk_delta_space, dataset, myGH->arrayDataspace,
+ 3, IOHDF5_REAL);
+}
+
+
+/*@@
+ @routine StreamedHDF5_procDump
+ @author Thomas Radke
+ @date May 21 1999
+ @desc All IO processors dump the data of their group into the file,
+ either as one chunk per processor or unchunked
+ (depending on parameter "unchunked").
+ @enddesc
+ @calledby StreamedHDF5_DumpGA
+ @history
+ @endhistory
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH
+ @vio in
+ @endvar
+ @var index
+ @vdesc global index of the variable to be dumped
+ @vtype int
+ @vio in
+ @endvar
+ @var timelevel
+ @vdesc the timelevel to store
+ @vtype int
+ @vio in
+ @endvar
+ @var outme
+ @vdesc pointer to the chunk to dump
+ @vtype void *
+ @vio in
+ @endvar
+ @var geom
+ @vdesc bounds and sizes of the output
+ @vtype CCTK_INT [3*dim]
+ @vio in
+ @vcomment geom [0*dim..1*dim-1]: lower bounds
+ geom [1*dim..2*dim-1]: (local) data sizes
+ geom [2*dim..3*dim-1]: global space
+ @endvar
+ @var proc
+ @vdesc the processor which's chunk is to be dumped
+ @vtype int
+ @vio in
+ @endvar
+ @var hdf5io_type
+ @vdesc the HDF5 datatype identifier
+ @vtype int
+ @vio in
+ @endvar
+ @var fid
+ @vdesc the HDF5 file handle
+ @vtype hid_t
+ @vio in
+ @endvar
+@@*/
+static void StreamedHDF5_Dump (cGH *GH, int index, int timelevel, void *outme,
+ int *hsizes, int hdf5_type, hid_t fid)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i, dim;
+ hid_t dataset, memspace;
+ char *name, *datasetname;
+ hsize_t *dims;
+
+
+ /* get the dimension of the variable */
+ dim = CCTK_GroupDimI (CCTK_GroupIndexFromVarI (index));
+
+ dims = (hsize_t *) malloc (dim * sizeof (hsize_t));
+
+ /* HDF5 needs it in reverse order */
+ for (i = 0; i < dim; i++)
+ {
+ dims [i] = hsizes [dim - 1 - i];
+ }
+
+ /* build the unique dataset name */
+ name = CCTK_FullName (index);
+ datasetname = (char *) malloc (strlen (name) + 3);
+ sprintf (datasetname, "%s@%d@%d", name, GH->cctk_iteration, timelevel);
+ free (name);
+
+ /* create the memspace according to chunk dims */
+ CACTUS_IOHDF5_ERROR (memspace = H5Screate_simple (dim, dims, NULL));
+
+ /* create the dataset */
+ CACTUS_IOHDF5_ERROR (dataset = H5Dcreate (fid, datasetname, hdf5_type,
+ memspace, H5P_DEFAULT));
+ /* write the data */
+ CACTUS_IOHDF5_ERROR (H5Dwrite (dataset, hdf5_type, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, outme));
+
+ StreamedHDF5_AddCommonAttributes (GH, index, timelevel, dataset);
+
+ /* close the dataset and the memspace */
+ CACTUS_IOHDF5_ERROR (H5Dclose (dataset));
+ CACTUS_IOHDF5_ERROR (H5Sclose (memspace));
+
+ free (datasetname);
+ free (dims);
+}
diff --git a/src/GHExtension.c b/src/GHExtension.c
new file mode 100644
index 0000000..aa5abd9
--- /dev/null
+++ b/src/GHExtension.c
@@ -0,0 +1,83 @@
+ /*@@
+ @file GHExtension.c
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ StreamedHDF5 GH extension stuff.
+ @enddesc
+ @history
+ @hauthor Thomas Radke @hdate May 21 1999
+ @hdesc Just copied from thorn FlexIO.
+ @endhistory
+ @@*/
+
+
+/*#define DEBUG_IO*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "StreamedHDF5GH.h"
+
+
+void *StreamedHDF5_SetupGH (tFleshConfig *config, int convergence_level, cGH *GH)
+{
+ int numvars;
+ StreamedHDF5GH *newGH;
+
+
+ numvars = CCTK_NumVars ();
+
+ newGH = (StreamedHDF5GH *) malloc (sizeof (StreamedHDF5GH));
+ newGH->do_output = (char *) malloc (numvars * sizeof (char));
+ newGH->out_last = (int *) malloc (numvars * sizeof (int));
+
+ /* save the original error printing routine and its argument */
+ CACTUS_IOHDF5_ERROR (H5Eget_auto (&newGH->printErrorFn,
+ &newGH->printErrorFnArg));
+
+ /* predefine dataspaces for writing scalar and array attributes */
+ /* the dimension of the array dataspace is set when used */
+ CACTUS_IOHDF5_ERROR (newGH->scalarDataspace = H5Screate (H5S_SCALAR));
+ CACTUS_IOHDF5_ERROR (newGH->arrayDataspace = H5Screate (H5S_SIMPLE));
+
+ /* predefine a IOHDF5_COMPLEX datatype */
+ CACTUS_IOHDF5_ERROR (newGH->IOHDF5_COMPLEX =
+ H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX)));
+ CACTUS_IOHDF5_ERROR (H5Tinsert (newGH->IOHDF5_COMPLEX, "real",
+ offsetof (CCTK_COMPLEX, Re), IOHDF5_REAL));
+ CACTUS_IOHDF5_ERROR (H5Tinsert (newGH->IOHDF5_COMPLEX, "imag",
+ offsetof (CCTK_COMPLEX, Im), IOHDF5_REAL));
+
+ /* predefine a C string datatype */
+ CACTUS_IOHDF5_ERROR (newGH->IOHDF5_STRING = H5Tcopy (H5T_C_S1));
+
+ return (newGH);
+}
+
+
+int StreamedHDF5_InitGH (cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i;
+ StreamedHDF5GH *myGH;
+ const cParamData *paramdata;
+
+
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ /* How often to output */
+ myGH->out_every = out_every > 0 ? out_every : -1;
+ if (outHDF5_every > 0)
+ myGH->out_every = outHDF5_every;
+ ParseVarsForOutput (out_vars, myGH->do_output);
+
+ for (i = 0; i < CCTK_NumVars (); i++)
+ myGH->out_last [i] = -1;
+
+ return (0);
+}
diff --git a/src/Output.c b/src/Output.c
new file mode 100644
index 0000000..cfb0a97
--- /dev/null
+++ b/src/Output.c
@@ -0,0 +1,270 @@
+ /*@@
+ @file Output.c
+ @date Tue Jan 9 1999
+ @author Gabrielle Allen
+ @desc
+ Functions to deal with output of variables in HDF5 FiberBundle format
+ @enddesc
+ @history
+ @hauthor Thomas Radke @hdate 16 Mar 1999
+ @hdesc Converted to Cactus 4.0
+ @hendhistory
+ @@*/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "StreamedHDF5GH.h"
+
+
+/* function prototypes */
+int StreamedHDF5_TimeFor (cGH *GH, int index);
+int StreamedHDF5_OutputVarAs (cGH *GH, const char *var, const char *alias);
+static void CheckSteerableParameters (StreamedHDF5GH *myGH);
+
+
+/*@@
+ @routine StreamedHDF5_OutputGH
+ @date Sat March 6 1999
+ @author Gabrielle Allen
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calledby CCTK_OutputGH ("StreamedHDF5")
+ @history
+
+ @endhistory
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype cGH
+ @vio in
+ @endvar
+@@*/
+
+int StreamedHDF5_OutputGH (cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i;
+ StreamedHDF5GH *myGH;
+ const char *name;
+ char *fullname;
+
+
+ /* Get the GH extension for StreamedHDF5 */
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ CheckSteerableParameters (myGH);
+
+ if (myGH->out_every <= 0)
+ return (0);
+
+ /* Loop over all variables */
+ for (i = 0; i < CCTK_NumVars (); i++)
+ {
+
+ if (StreamedHDF5_TimeFor (GH, i))
+ {
+
+ name = CCTK_VarName (i);
+ fullname = CCTK_FullName (i);
+
+ if (verbose)
+ CCTK_VInfo (CCTK_THORNSTRING, "StreamedHDF5_OutputGH: fullname / name = "
+ "%s / %s", fullname, name);
+
+ StreamedHDF5_OutputVarAs (GH, fullname, name);
+
+ free (fullname);
+
+ /* Register variable as having output this iteration */
+ myGH->out_last [i] = GH->cctk_iteration;
+ }
+ }
+
+ return (0);
+}
+
+
+/*@@
+ @routine StreamedHDF5_OutputVarAs
+ @date Sat March 6 1999
+ @author Gabrielle Allen
+ @desc
+ unconditional output of a variable using the StreamedHDF5 output method
+ @enddesc
+ @calledby StreamedHDF5_OutputGH, CCTK_OutputVarAsByMethod ("StreamedHDF5")
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype cGH
+ @vio in
+ @vcomment
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @vcomment
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @vcomment
+ @endvar
+@@*/
+
+int StreamedHDF5_OutputVarAs (cGH *GH, const char *fullname, const char *alias)
+{
+ DECLARE_CCTK_PARAMETERS
+ int index;
+
+
+ index = CCTK_VarIndex (fullname);
+
+ if (verbose)
+ CCTK_VInfo (CCTK_THORNSTRING, "StreamedHDF5_OutputVarAs: fullname, alias, "
+ "index = (%s, %s, %d)", fullname, alias, index);
+
+ /* Do the output */
+ StreamedHDF5_Write (GH, index, alias);
+
+ return (0);
+}
+
+
+/*@@
+ @routine StreamedHDF5_TimeFor
+ @date Sat March 6 1999
+ @author Gabrielle Allen
+ @desc
+ Decides if it is time to output a variable using the StreamedHDF5 output
+ method
+ @enddesc
+ @calledby StreamedHDF5_OutputGH
+ @history
+
+ @endhistory
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype cGH
+ @vio in
+ @vcomment
+ @endvar
+ @var index
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @vcomment
+ @endvar
+@@*/
+
+int StreamedHDF5_TimeFor (cGH *GH, int index)
+{
+ StreamedHDF5GH *myGH;
+
+
+ /* Get the GH extension for StreamedHDF5 */
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ CheckSteerableParameters (myGH);
+
+ /* Check if any output was requested */
+ if(myGH->out_every <= 0)
+ return (0);
+
+ /* Check this variable should be output */
+ if (! (myGH->do_output [index] && GH->cctk_iteration % myGH->out_every == 0))
+ return (0);
+
+ /* Check variable not already output this iteration */
+ if (myGH->out_last [index] == GH->cctk_iteration) {
+ CCTK_WARN (2, "Already done output in StreamedHDF5");
+ return (0);
+ }
+
+ return (1);
+}
+
+
+/*@@
+ @routine StreamedHDF5_TriggerOutput
+ @date Sat March 6 1999
+ @author Gabrielle Allen
+ @desc
+ Triggers the output a variable using the StreamedHDF5 output
+ method
+ @enddesc
+ @calledby CCTK scheduler
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype cGH
+ @vio in
+ @vcomment
+ @endvar
+ @var index
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @vcomment
+ @endvar
+@@*/
+
+int StreamedHDF5_TriggerOutput (cGH *GH, int index)
+{
+ DECLARE_CCTK_PARAMETERS
+ StreamedHDF5GH *myGH;
+ const char *varname;
+
+ varname = CCTK_VarName (index);
+
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ if (verbose)
+ CCTK_VInfo (CCTK_THORNSTRING, "StreamedHDF5_TriggerOutput: varname, index = "
+ "(%s, %d)", varname, index);
+
+ /* Do the output */
+ StreamedHDF5_Write (GH, index, varname);
+
+ /* Register variable as having output this iteration */
+ myGH->out_last [index] = GH->cctk_iteration;
+
+ return (0);
+}
+
+
+/**************************** local functions ******************************/
+static void CheckSteerableParameters (StreamedHDF5GH *myGH)
+{
+ DECLARE_CCTK_PARAMETERS
+ const cParamData *paramdata;
+ static int out_vars_lastset = 0;
+
+
+ /* How often to output */
+ myGH->out_every = out_every > 0 ? out_every : -1;
+ if (out_every > 0)
+ myGH->out_every = out_every;
+
+ /* Check the 'out_vars' parameter */
+ paramdata = CCTK_ParameterData ("out_vars", CCTK_THORNSTRING);
+ if (! paramdata) {
+ CCTK_WARN (1, "Couldn't get info on parameter 'out_vars'");
+ return;
+ }
+
+ /* re-parse the 'out_vars' parameter if it was changed */
+ if (paramdata->n_set != out_vars_lastset) {
+ ParseVarsForOutput (out_vars, myGH->do_output);
+
+ /* Save the last setting of 'out_vars' parameter */
+ out_vars_lastset = paramdata->n_set;
+ }
+
+}
diff --git a/src/Startup.c b/src/Startup.c
new file mode 100644
index 0000000..bfae509
--- /dev/null
+++ b/src/Startup.c
@@ -0,0 +1,208 @@
+ /*@@
+ @file Startup.c
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ Startup routines for StreamedHDF5.
+ @enddesc
+ @history
+ @hauthor Thomas Radke @hdate May 21 1999
+ @hdesc Just copied from thorn FlexIO.
+ @endhistory
+ @@*/
+
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "Development/Socket/src/SocketUtils.h"
+#include "StreamedHDF5GH.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+/* prototypes of functions to be registered */
+int StreamedHDF5_OutputGH(cGH *GH);
+int StreamedHDF5_TriggerOutput(cGH *GH, int);
+int StreamedHDF5_TimeFor(cGH *GH, int);
+int StreamedHDF5_OutputVarAs(cGH *GH, const char *var, const char *alias);
+
+/* local function prototypes */
+static void *StreamedHDF5_SetupGH (tFleshConfig *config, int convergence_level, cGH *GH);
+static int StreamedHDF5_InitGH (cGH *GH);
+
+
+ /*@@
+ @routine StreamedHDF5_Startup
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ The startup registration routine for StreamedHDF5.
+ Registers the GH extensions needed for StreamedHDF5 and
+ the registerable routines used for each method of StreamedHDF5.
+ StreamedHDF5 does not overload any functions.
+ @enddesc
+ @calls
+ @calledby CCTK scheduler at STARTUP
+ @history
+
+ @endhistory
+@@*/
+void StreamedHDF5_Startup (void)
+{
+ int IO_GHExtension;
+
+
+ if (CCTK_GHExtensionHandle ("IO") < 0)
+ {
+ CCTK_WARN (1, "Thorn IOUtil was not activated. "
+ "No StreamedHDF5 IO methods will be enabled.");
+ return;
+ }
+
+ /* this check can go as soon as the Stream VFD
+ comes with the default HDF5 installation */
+#ifndef H5FDstream_H
+ CCTK_WARN (1, "The Stream VFD is not included in the configured HDF5 "
+ "installation. No HDF5 stream output will be available !");
+#else
+ IO_GHExtension = CCTK_RegisterGHExtension ("StreamedHDF5");
+ CCTK_RegisterGHExtensionSetupGH (IO_GHExtension, StreamedHDF5_SetupGH);
+ CCTK_RegisterGHExtensionInitGH (IO_GHExtension, StreamedHDF5_InitGH);
+#endif
+}
+
+
+ /*@@
+ @routine StreamedHDF5_Terminate
+ @date Mon Jun 19 2000
+ @author Thomas Radke
+ @desc
+ StreamedHDF5's termination routine
+ Closes the socket if it was opened before.
+ @enddesc
+ @calls
+ @calledby CCTK scheduler at TERMINATE
+ @history
+
+ @endhistory
+@@*/
+void StreamedHDF5_Terminate (cGH *GH)
+{
+ int handle;
+ StreamedHDF5GH *myGH;
+
+
+ handle = CCTK_GHExtensionHandle ("StreamedHDF5");
+ myGH = handle >= 0 ? (StreamedHDF5GH *) GH->extensions [handle] : NULL;
+ if (myGH)
+ {
+ if (myGH->socket >= 0)
+ {
+ close (myGH->socket);
+ }
+ }
+}
+
+
+/*************************** local routines *********************************/
+static void *StreamedHDF5_SetupGH (tFleshConfig *config, int convergence_level, cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int IOMethod;
+ int numvars, socket;
+ StreamedHDF5GH *newGH;
+
+
+ if (CCTK_MyProc (GH) == 0)
+ {
+ socket = Socket_TCPOpenServerSock (port);
+ if (socket < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Couldn't open TCP server socket on port %d. No HDF5 stream "
+ "output available !", port);
+ return (NULL);
+ }
+
+ if (Socket_SetNonBlocking (socket) < 0)
+ {
+ CCTK_WARN (1, "Couldn't set socket into non-blocking mode. No HDF5 "
+ "stream output available !");
+ close (socket);
+ return (NULL);
+ }
+ }
+ else
+ {
+ socket = -1;
+ }
+
+ /* Register StreamedHDF5 routines as output methods */
+ IOMethod = CCTK_RegisterIOMethod ("StreamedHDF5");
+ CCTK_RegisterIOMethodOutputGH (IOMethod, StreamedHDF5_OutputGH);
+ CCTK_RegisterIOMethodOutputVarAs (IOMethod, StreamedHDF5_OutputVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (IOMethod, StreamedHDF5_TimeFor);
+ CCTK_RegisterIOMethodTriggerOutput (IOMethod, StreamedHDF5_TriggerOutput);
+
+ numvars = CCTK_NumVars ();
+
+ newGH = (StreamedHDF5GH *) malloc (sizeof (StreamedHDF5GH));
+ newGH->do_output = (char *) malloc (numvars * sizeof (char));
+ newGH->out_last = (int *) malloc (numvars * sizeof (int));
+ newGH->socket = socket;
+
+ /* save the original error printing routine and its argument */
+ CACTUS_IOHDF5_ERROR (H5Eget_auto (&newGH->printErrorFn,
+ &newGH->printErrorFnArg));
+
+ /* predefine dataspaces for writing scalar and array attributes */
+ /* the dimension of the array dataspace is set when used */
+ CACTUS_IOHDF5_ERROR (newGH->scalarDataspace = H5Screate (H5S_SCALAR));
+ CACTUS_IOHDF5_ERROR (newGH->arrayDataspace = H5Screate (H5S_SIMPLE));
+
+ /* predefine a IOHDF5_COMPLEX datatype */
+ CACTUS_IOHDF5_ERROR (newGH->IOHDF5_COMPLEX =
+ H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX)));
+ CACTUS_IOHDF5_ERROR (H5Tinsert (newGH->IOHDF5_COMPLEX, "real",
+ offsetof (CCTK_COMPLEX, Re), IOHDF5_REAL));
+ CACTUS_IOHDF5_ERROR (H5Tinsert (newGH->IOHDF5_COMPLEX, "imag",
+ offsetof (CCTK_COMPLEX, Im), IOHDF5_REAL));
+
+ /* predefine a C string datatype */
+ CACTUS_IOHDF5_ERROR (newGH->IOHDF5_STRING = H5Tcopy (H5T_C_S1));
+
+ return (newGH);
+}
+
+
+static int StreamedHDF5_InitGH (cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i, handle;
+ StreamedHDF5GH *myGH;
+
+
+ handle = CCTK_GHExtensionHandle ("StreamedHDF5");
+ myGH = handle >= 0 ? (StreamedHDF5GH *) GH->extensions [handle] : NULL;
+ if (handle < 0 || myGH == NULL)
+ {
+ return (-1);
+ }
+
+ /* How often to output */
+ myGH->out_every = out_every > 0 ? out_every : -1;
+ if (outHDF5_every > 0)
+ myGH->out_every = outHDF5_every;
+ ParseVarsForOutput (out_vars, myGH->do_output);
+
+ for (i = 0; i < CCTK_NumVars (); i++)
+ myGH->out_last [i] = -1;
+
+ return (0);
+}
+
+
diff --git a/src/StreamedHDF5GH.h b/src/StreamedHDF5GH.h
new file mode 100644
index 0000000..f0433a7
--- /dev/null
+++ b/src/StreamedHDF5GH.h
@@ -0,0 +1,147 @@
+ /*@@
+ @header StreamedHDF5GH.h
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ The extensions to the GH structure from StreamedHDF5.
+ @history
+ @hauthor Thomas Radke @hdate May 21 1999
+ @hdesc Just copied from thorn FlexIO.
+ @endhistory
+ @@*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <hdf5.h>
+
+#include "StoreNamedData.h"
+
+
+/* names of the (empty) groups that hold GH extensions or global parameters */
+#define GHEXTENSIONS_GROUP "GHextensions_group"
+#define GLOBAL_PARAMETERS_GROUP "global_parameters_group"
+#define GLOBAL_PARAMETERS "global_parameters"
+
+/*****************************************************************************/
+/* some useful macros */
+/*****************************************************************************/
+/* Check error flags from HDF5 calls */
+#define CACTUS_IOHDF5_ERROR(fn_call) \
+ do { \
+ size_t strlen(const char *str); \
+ \
+ int error_code = fn_call; \
+ \
+ if (error_code < 0) \
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \
+ "HDF5 call '%s' returned error code %d\n", \
+ #fn_call, error_code); \
+ } while (0)
+
+/* macro for writing an attribute */
+#define WRITE_ATTRIBUTE(name, value, dataset, dataspace, dim, datatype) \
+ do { \
+ hid_t attr; \
+ void *val = value; \
+ hsize_t arrayDim = dim; \
+ \
+ if (H5Tget_class (datatype) == H5T_STRING) { \
+ int len = strlen ((char *) val); \
+ \
+ if (len == 0) /* HDF5 doesn't like zero-len strings */ \
+ len++; \
+ CACTUS_IOHDF5_ERROR (H5Tset_size (datatype, len)); \
+ } \
+ if (arrayDim > 0) \
+ CACTUS_IOHDF5_ERROR (H5Sset_extent_simple (dataspace, 1, \
+ &arrayDim, NULL)); \
+ CACTUS_IOHDF5_ERROR (attr = H5Acreate (dataset, name, datatype, \
+ dataspace, H5P_DEFAULT)); \
+ CACTUS_IOHDF5_ERROR (H5Awrite (attr, datatype, val)); \
+ CACTUS_IOHDF5_ERROR (H5Aclose (attr)); \
+ } while (0);
+
+/* macro for reading an attribute */
+#define READ_ATTRIBUTE(dataset, attrname, requested_type, buffer) \
+ { hid_t attr, attrtype; \
+ hsize_t asize = 0; \
+ \
+ if ((attr = H5Aopen_name (dataset, attrname)) < 0) \
+ CCTK_WARN (1, "Can't find " attrname " attribute"); \
+ if (requested_type == H5T_C_S1) { \
+ CACTUS_IOHDF5_ERROR (attrtype = H5Aget_type (attr)); \
+ CACTUS_IOHDF5_ERROR (asize = H5Tget_size (attrtype)); \
+ if (asize + 1 >= sizeof (buffer)) \
+ CCTK_WARN (1, "Can't read " attrname " attribute (too long)");\
+ } else \
+ attrtype = requested_type; \
+ if (H5Aread (attr, attrtype, buffer) < 0) \
+ CCTK_WARN (1, "Can't read " attrname " attribute"); \
+ if (requested_type == H5T_C_S1) { \
+ ((char *) buffer) [asize] = 0; \
+ CACTUS_IOHDF5_ERROR (H5Tclose (attrtype)); \
+ } \
+ CACTUS_IOHDF5_ERROR (H5Aclose (attr)); \
+ }
+
+
+/* define the HDF5 datatypes according to CCTK_??? datatypes */
+#define IOHDF5_REAL4 H5T_NATIVE_FLOAT
+
+#ifdef CCTK_REAL_PRECISION_16
+#define IOHDF5_REAL H5T_NATIVE_LDOUBLE
+#elif CCTK_REAL_PRECISION_8
+#define IOHDF5_REAL H5T_NATIVE_DOUBLE
+#elif CCTK_REAL_PRECISION_4
+#define IOHDF5_REAL H5T_NATIVE_FLOAT
+#endif
+
+#define IOHDF5_INT (sizeof (CCTK_INT) == sizeof (int) ? \
+ H5T_NATIVE_INT : H5T_NATIVE_SHORT)
+#define IOHDF5_INT4 (sizeof (int) == 4 ? \
+ H5T_NATIVE_INT : H5T_NATIVE_SHORT)
+#define IOHDF5_CHAR H5T_NATIVE_CHAR
+
+
+/* StreamedHDF5 GH extension structure */
+typedef struct StreamedHDF5GH
+{
+ /* how often to output */
+ int out_every;
+
+ /* flags indicating output for var [i] */
+ char *do_output;
+
+ /* the last iteration output */
+ int *out_last;
+
+ /* variables holding the original error printing routine and its argument */
+ H5E_auto_t printErrorFn;
+ void *printErrorFnArg;
+
+ /* predefined dataspaces for writing scalar and array attributes */
+ hid_t scalarDataspace, arrayDataspace;
+
+ /* predefined datatype for writing CCTK_COMPLEX types */
+ hid_t IOHDF5_COMPLEX;
+
+ /* predefined datatype for writing C string string attributes */
+ hid_t IOHDF5_STRING;
+
+ /* the socket to pass to the Stream VFD */
+ int socket;
+
+} StreamedHDF5GH;
+
+/* function prototypes */
+void StreamedHDF5_Write (cGH *GH, int index, const char *alias);
+void StreamedHDF5_DumpParams (cGH *GH, hid_t group);
+void StreamedHDF5_DumpGHExtensions (cGH *GH, hid_t group);
+int StreamedHDF5_DumpVar (cGH *GH, int index, int timelevel, hid_t iof);
+
+#ifdef __cplusplus
+} // extern "C" {
+#endif
diff --git a/src/Write.c b/src/Write.c
new file mode 100644
index 0000000..0c0b373
--- /dev/null
+++ b/src/Write.c
@@ -0,0 +1,139 @@
+/*@@
+ @file Write.c
+ @date Fri May 21 1999
+ @author Thomas Radke
+ @desc
+ Output and trigger routines for FiberBundle output into HDF5 files
+ @enddesc
+ @history
+ @hauthor Thomas Radke @hdate May 21 1999
+ @hdesc Just copied from thorn FlexIO.
+ @hendhistory
+ @@*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "StoreNamedData.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "StreamedHDF5GH.h"
+
+
+/* local function prototypes */
+void StreamedHDF5i_DumpParameters (cGH *GH, hid_t group);
+void StreamedHDF5i_DumpGHExtensions (cGH *GH, hid_t group);
+
+
+/*@@
+ @routine Write
+ @author Paul Walker
+ @date Feb 1997
+ @calledby StreamedHDF5_OutputVarAs, StreamedHDF5_TriggerOutput
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype cGH
+ @vio in
+ @vcomment
+ @endvar
+ @var index
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @vcomment
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ @vtype const char *
+ @vio in
+ @vcomment
+ @endvar
+@@*/
+void StreamedHDF5_Write (cGH *GH, int index, const char *alias)
+{
+ DECLARE_CCTK_PARAMETERS
+ int vtype;
+ int timelevel;
+ ioGH *ioUtilGH;
+ StreamedHDF5GH *myGH;
+ hid_t fid, plist;
+#if 0
+ hid_t group;
+#endif
+
+
+ /* first, check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (index)))
+ {
+ char *fullname = CCTK_FullName (index);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No StreamedHDF5 output for '%s' (no storage)", fullname);
+ free (fullname);
+ return;
+ }
+
+ /* check if variable is of type GF or ARRAY */
+ vtype = CCTK_GroupTypeFromVarI (index);
+ if (vtype != CCTK_GF && vtype != CCTK_ARRAY)
+ {
+ char *fullname = CCTK_FullName (index);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No StreamedHDF5 output for '%s' (not an array type)", fullname);
+ free (fullname);
+ return;
+ }
+
+ /* Get the handles for IO and StreamedHDF5 extensions */
+ ioUtilGH = (ioGH *) GH->extensions [CCTK_GHExtensionHandle ("IO")];
+ myGH = (StreamedHDF5GH *) GH->extensions [CCTK_GHExtensionHandle ("StreamedHDF5")];
+
+ fid = -1;
+ if (CCTK_MyProc (GH) == 0)
+ {
+ /* filename is not used if we pass a socket descriptor
+ but it must not be NULL or an empty string */
+ static const char *filename = "bla";
+
+
+ if (verbose)
+ CCTK_VInfo (CCTK_THORNSTRING, "Opening HDF5 output file on port %d",
+ port);
+
+ /* set VFD to stream and open the file */
+ CACTUS_IOHDF5_ERROR (plist = H5Pcreate (H5P_FILE_ACCESS));
+ CACTUS_IOHDF5_ERROR (H5Pset_fapl_stream (plist, 0, myGH->socket));
+ CACTUS_IOHDF5_ERROR (fid = H5Fcreate (filename, H5F_ACC_TRUNC,
+ H5P_DEFAULT, plist));
+ CACTUS_IOHDF5_ERROR (H5Pclose (plist));
+
+#if 0
+ /* output global attributes */
+ if (verbose)
+ CCTK_INFO ("Dumping GH extensions ...");
+
+ CACTUS_IOHDF5_ERROR (group = H5Gcreate (fid, GHEXTENSIONS_GROUP, 0));
+ StreamedHDF5i_DumpGHExtensions (GH, group);
+ CACTUS_IOHDF5_ERROR (H5Gclose (group));
+#endif
+
+ }
+
+ /* get the current timelevel */
+ timelevel = CCTK_NumTimeLevelsFromVarI (index) - 1;
+ if (timelevel > 0)
+ timelevel--;
+
+ /* output the data */
+ StreamedHDF5_DumpVar (GH, index, timelevel, fid);
+
+ /* close the file */
+ if (fid >= 0)
+ {
+ if (verbose)
+ CCTK_INFO ("Closing HDF5 output file from this iteration");
+ CACTUS_IOHDF5_ERROR (H5Fclose (fid));
+ }
+
+}
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..bab18b5
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,5 @@
+# Main make.code.defn file for thorn StreamedHDF5
+# $Header$
+
+# Source files in this directory
+SRCS = Startup.c GHExtension.c Output.c Write.c DumpVar.c
diff --git a/src/make.configuration.defn b/src/make.configuration.defn
new file mode 100644
index 0000000..0eb13c8
--- /dev/null
+++ b/src/make.configuration.defn
@@ -0,0 +1,12 @@
+# make.configuration.defn for StreamedHDF5
+
+# make sure that StreamedHDF5 was configured with HDF5
+
+ifeq ($(strip $(HDF5_LIBS)), )
+$(NAME): MissingHDF5
+.pseudo: MissingHDF5
+MissingHDF5:
+ @echo "StreamedHDF5: requires HDF5"
+ @echo "StreamedHDF5: Please configure with HDF5 or remove StreamedHDF5 from Thornlist !"
+ exit 2
+endif