diff options
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | interface.ccl | 5 | ||||
-rw-r--r-- | param.ccl | 51 | ||||
-rw-r--r-- | schedule.ccl | 15 | ||||
-rw-r--r-- | src/DumpVar.c | 363 | ||||
-rw-r--r-- | src/GHExtension.c | 83 | ||||
-rw-r--r-- | src/Output.c | 270 | ||||
-rw-r--r-- | src/Startup.c | 208 | ||||
-rw-r--r-- | src/StreamedHDF5GH.h | 147 | ||||
-rw-r--r-- | src/Write.c | 139 | ||||
-rw-r--r-- | src/make.code.defn | 5 | ||||
-rw-r--r-- | src/make.configuration.defn | 12 |
12 files changed, 1307 insertions, 0 deletions
@@ -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 |