aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortradke <tradke@b32723a9-ab3a-4a60-88e2-2e5d99d7c17a>2002-04-26 15:40:31 +0000
committertradke <tradke@b32723a9-ab3a-4a60-88e2-2e5d99d7c17a>2002-04-26 15:40:31 +0000
commit6b661bbe7e32f6769d1fd24dc30f99e186d70f03 (patch)
tree36ae229ec7aa90db9352a0e2776664e994738422
parentafa83bcec509680969a3d2f60736d656016220cb (diff)
Moved the I/O request description and parsing routines from IOHDF5Util to IOUtil
so that they can be shared by all I/O thorns now. git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/IOUtil/trunk@158 b32723a9-ab3a-4a60-88e2-2e5d99d7c17a
-rw-r--r--src/Utils.c415
-rw-r--r--src/ioGH.h52
-rw-r--r--src/ioutil_Utils.h50
3 files changed, 468 insertions, 49 deletions
diff --git a/src/Utils.c b/src/Utils.c
index 7abec4d..c6a1c98 100644
--- a/src/Utils.c
+++ b/src/Utils.c
@@ -3,7 +3,7 @@
@date Tue 4th July 2000
@author Gabrielle Allen
@desc
- Utility routines which may be called by other IO thorns
+ Utility routines which may be called by other I/O thorns.
@enddesc
@version $Id$
@@*/
@@ -15,6 +15,9 @@
#include "cctk.h"
#include "cctk_Parameters.h"
+#include "cctk_GNU.h"
+#include "util_String.h"
+#include "ioGH.h"
#include "ioutil_Utils.h"
#include "ioutil_CheckpointRecovery.h"
@@ -23,10 +26,109 @@ static const char *rcsid = "$Header$";
CCTK_FILEVERSION(CactusBase_IOUtil_Utils_c)
+/********************************************************************
+ ******************** Macro Definitions ************************
+ ********************************************************************/
/* uncomment this if you want some debugging output */
/* #define DEBUG_IOUTIL 1 */
+/********************************************************************
+ ******************** Internal Typedefs ************************
+ ********************************************************************/
+typedef struct
+{
+ const cGH *GH;
+ ioRequest **request_list;
+} info_t;
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static void SetOutputVar (int vindex, const char *optstring, void *arg);
+
+
+/********************************************************************
+ ******************** External Routines ************************
+ ********************************************************************/
+int CCTK_RegexMatch (const char *string, const char *pattern, const int nmatch,
+ regmatch_t *pmatch);
+
+
+ /*@@
+ @routine IOUtil_ParseVarsForOutput
+ @date Fri 26 April 2002
+ @author Thomas Radke
+ @desc
+ Parses the given 'out_vars' string as a list of variable and/or
+ groupnames. If an option string is appended to a name this will
+ be parsed for I/O request options.
+ @enddesc
+
+ @calls CCTK_TraverseString
+
+ @var GH
+ @vdesc pointer to CCTK grid hierarchy
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var out_vars
+ @vdesc string with list of variables and/or group names to parse
+ @vtype const char *
+ @vio in
+ @endvar
+ @var request_list
+ @vdesc list of I/O requests to fill out
+ @vtype ioRequest *[]
+ @vio out
+ @endvar
+@@*/
+void IOUtil_ParseVarsForOutput (const cGH *GH, const char *out_vars,
+ ioRequest *request_list[])
+{
+ int i;
+ info_t info;
+
+
+ /* free current list of I/O requests */
+ for (i = CCTK_NumVars () - 1; i >= 0; i--)
+ {
+ if (request_list[i])
+ {
+ IOUtil_FreeIORequest (&request_list[i]);
+ }
+ }
+
+ /* generate new list of I/O requests */
+ info.GH = GH;
+ info.request_list = request_list;
+ CCTK_TraverseString (out_vars, SetOutputVar, &info, CCTK_GROUP_OR_VAR);
+}
+
+
+ /*@@
+ @routine IOUtil_FreeIORequest
+ @date Fri 26 April 2002
+ @author Thomas Radke
+ @desc
+ Frees an I/O request description.
+ @enddesc
+
+ @var request
+ @vdesc pointer to the I/O request structure
+ @vtype ioRequest **
+ @vio inout
+ @endvar
+@@*/
+void IOUtil_FreeIORequest (ioRequest **request)
+{
+ free ((*request)->vectors);
+ free (*request);
+ *request = NULL;
+}
+
+
/*@@
@routine IOUtil_1DLines
@date July 4 2000
@@ -474,3 +576,314 @@ int IOUtil_CreateDirectory (const cGH *GH, const char *dirname,
return (retval);
}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static void SetOutputVar (int vindex, const char *optstring, void *arg)
+{
+ info_t *info;
+ regmatch_t gmatch[6], *dmatch;
+ int i, j, bytes, matched;
+ char *token, *separator, *fullname;
+ char *substring, *parsestring, *regexstring;
+ ioRequest *request;
+ DECLARE_CCTK_PARAMETERS
+
+
+ info = (info_t *) arg;
+
+ /* allocate a new I/O request structure and initialize it with defaults */
+ request = IOUtil_DefaultIORequest (info->GH, vindex);
+
+ if (! optstring)
+ {
+ info->request_list[vindex] = request;
+ return;
+ }
+
+ fullname = CCTK_FullName (vindex);
+
+ /* parse the I/O request information */
+ matched = CCTK_RegexMatch (optstring,
+ "\\{([0-9]*)\\}" /* dimension */
+ "\\{([0-9,()]+)*\\}" /* direction */
+ "\\{([0-9,]+)*\\}" /* origin */
+ "\\{([-0-9,]+)*\\}" /* extent */
+ "\\{([0-9,]+)*\\}", /* downsample */
+ 6, gmatch);
+ if (matched <= 0)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Couldn't parse I/O request options '%s' for variable '%s'",
+ optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+
+ /* SLAB DIMENSION */
+ bytes = (int) (gmatch[1].rm_eo - gmatch[1].rm_so);
+ if (gmatch[1].rm_so != -1 && bytes > 0)
+ {
+ request->hdim = atoi (optstring + gmatch[1].rm_so);
+ if (request->hdim <= 0 || request->hdim > request->vdim)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid dimension given %d in I/O request options '%s' "
+ "for variable '%s'", request->hdim, optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+ }
+
+ /* DIRECTION */
+ bytes = (int) (gmatch[2].rm_eo - gmatch[2].rm_so);
+ if (gmatch[2].rm_so != -1 && bytes > 0)
+ {
+ substring = strdup (optstring + gmatch[2].rm_so);
+ substring[bytes] = 0;
+
+ dmatch = (regmatch_t *) malloc ((request->hdim + 1) *
+ sizeof (regmatch_t));
+ regexstring = (char *) malloc (request->hdim * sizeof ("\\(([0-9,]+)\\)"));
+ regexstring[0] = 0;
+ for (i = 0; i < request->hdim; i++)
+ {
+ strcat (regexstring, "\\(([0-9,]+)\\)");
+ }
+ matched = CCTK_RegexMatch (substring, regexstring, request->hdim + 1,
+ dmatch);
+ free (regexstring);
+ if (matched <= 0)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Couldn't parse direction vectors in I/O request options '%s' "
+ "for variable '%s'.", optstring, fullname);
+ free (fullname); free (dmatch); free (request);
+ return;
+ }
+
+ for (j = 0; j < request->hdim; j++)
+ {
+ i = 0;
+ bytes = (int) (dmatch[j + 1].rm_eo - dmatch[j + 1].rm_so);
+ if (dmatch[j + 1].rm_so != -1 && bytes > 0)
+ {
+ parsestring = strdup (substring + dmatch[j + 1].rm_so);
+ parsestring[bytes] = 0;
+
+ token = parsestring;
+ while ((separator = strchr (token, ',')) != NULL)
+ {
+ *separator = 0;
+ request->direction[j * request->vdim + i] = atoi (token);
+ if (++i >= request->vdim)
+ {
+ break;
+ }
+ token = separator + 1;
+ }
+ request->direction[j * request->vdim + i++] = atoi (token);
+ free (parsestring);
+ }
+ free (substring);
+ if (i < request->vdim)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Direction vectors are incomplete or missing in I/O request "
+ "options '%s' for variable '%s'.", optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+ }
+ }
+
+ /* ORIGIN */
+ bytes = (int) (gmatch[3].rm_eo - gmatch[3].rm_so);
+ if (gmatch[3].rm_so != -1 && bytes > 0)
+ {
+ substring = strdup (optstring + gmatch[3].rm_so);
+ substring[bytes] = 0;
+
+ i = 0;
+ token = substring;
+ while ((separator = strchr (token, ',')) != NULL)
+ {
+ *separator = 0;
+ request->origin[i] = atoi (token);
+ if (++i >= request->vdim)
+ {
+ break;
+ }
+ token = separator + 1;
+ }
+ request->origin[i++] = atoi (token);
+ free (substring);
+
+ if (i < request->vdim)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Origin vector is incomplete or missing in I/O request "
+ "options '%s' for variable '%s'.", optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+ }
+
+ /* LENGTH */
+ bytes = (int) (gmatch[4].rm_eo - gmatch[4].rm_so);
+ if(gmatch[4].rm_so != -1 && bytes > 0)
+ {
+ substring = strdup (optstring + gmatch[4].rm_so);
+ substring[bytes] = 0;
+
+ i = 0;
+ token = substring;
+ while ((separator = strchr (token, ',')) != NULL)
+ {
+ *separator = 0;
+ request->extent[i] = atoi (token);
+ if (++i >= request->hdim)
+ {
+ break;
+ }
+ token = separator + 1;
+ }
+ request->extent[i++] = atoi (token);
+ free (substring);
+
+ if (i < request->hdim)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Length vector is incomplete or missing in I/O request "
+ "options '%s' for variable '%s'.", optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+ }
+
+ /* DOWNSAMPLING */
+ bytes = (int) (gmatch[5].rm_eo - gmatch[5].rm_so);
+ if(gmatch[5].rm_so != -1 && bytes > 0)
+ {
+ substring = strdup (optstring + gmatch[5].rm_so);
+ substring[bytes] = 0;
+
+ i = 0;
+ token = substring;
+ while ((separator = strchr (token, ',')) != NULL)
+ {
+ *separator = 0;
+ request->downsample[i] = atoi (token);
+ if (++i >= request->hdim)
+ {
+ break;
+ }
+ token = separator + 1;
+ }
+ request->downsample[i++] = atoi (token);
+ free (substring);
+
+ if (i < request->hdim)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Downsampling vector is incomplete or missing in I/O request "
+ "options '%s' for variable '%s'.", optstring, fullname);
+ free (fullname); free (request);
+ return;
+ }
+ }
+
+ /* assign the new I/O request */
+ info->request_list[vindex] = request;
+
+ /* clean up */
+ free (fullname);
+}
+
+
+ioRequest *IOUtil_DefaultIORequest (const cGH *GH, int vindex)
+{
+ ioRequest *request;
+ int *extent_int;
+ const ioGH *myGH;
+ DECLARE_CCTK_PARAMETERS
+
+
+ myGH = (const ioGH *) CCTK_GHExtension (GH, "IO");
+
+ /* allocate a new I/O request structure */
+ request = (ioRequest *) malloc (sizeof (ioRequest));
+
+ /* fill out the basics */
+ request->vindex = vindex;
+ request->timelevel = 0;
+ request->check_exist = myGH->recovered;
+
+ /* get the I/O request datatype (will be single-precision if requested) */
+ request->hdatatype = CCTK_VarTypeI (vindex);
+ if (myGH->out_single)
+ {
+ if (request->hdatatype == CCTK_VARIABLE_REAL)
+ {
+ request->hdatatype = CCTK_VARIABLE_REAL4;
+ }
+ else if (request->hdatatype == CCTK_VARIABLE_COMPLEX)
+ {
+ request->hdatatype = CCTK_VARIABLE_COMPLEX8;
+ }
+#ifdef CCTK_INT2
+ else if (request->hdatatype == CCTK_VARIABLE_INT)
+ {
+ request->hdatatype = CCTK_VARIABLE_INT2;
+ }
+#endif
+ }
+
+ /* get the variable's dimension and extents */
+ request->vdim = CCTK_GroupDimFromVarI (vindex);
+ extent_int = (int *) malloc (request->vdim * sizeof (int));
+ CCTK_GroupgshVI (GH, request->vdim, extent_int, vindex);
+
+ /* allocate the arrays all in one go
+ only initialize those which are mandatory for the Hyperslab API */
+ request->vectors = (CCTK_INT *) calloc ((request->vdim + 6) * request->vdim + 1,
+ sizeof (CCTK_INT));
+ request->hoffset = request->vectors + 0*request->vdim;
+ request->hsize = request->vectors + 1*request->vdim;
+ request->hsize_chunk = request->vectors + 2*request->vdim;
+ request->origin = request->vectors + 3*request->vdim + 1;
+ request->extent = request->vectors + 4*request->vdim + 1;
+ request->downsample = request->vectors + 5*request->vdim + 1;
+ request->direction = request->vectors + 6*request->vdim + 1;
+
+ for (request->hdim = 0; request->hdim < request->vdim; request->hdim++)
+ {
+ request->extent[request->hdim] = extent_int[request->hdim];
+ request->direction[request->hdim * (request->vdim + 1)] = 1;
+
+ /* take the downsampling parameters from IOUtil */
+ if (request->hdim == 0)
+ {
+ request->downsample[request->hdim] = out3D_downsample_x;
+ }
+ else if (request->hdim == 1)
+ {
+ request->downsample[request->hdim] = out3D_downsample_y;
+ }
+ else if (request->hdim == 2)
+ {
+ request->downsample[request->hdim] = out3D_downsample_z;
+ }
+ else
+ {
+ request->downsample[request->hdim] = 1;
+ }
+ }
+
+ /* clean up */
+ free (extent_int);
+
+ return (request);
+}
diff --git a/src/ioGH.h b/src/ioGH.h
index c77c7b9..150e4da 100644
--- a/src/ioGH.h
+++ b/src/ioGH.h
@@ -2,22 +2,14 @@
@header ioGH.h
@date Tue 9th Jan 1999
@author Gabrielle Allen
- @desc
- The extensions to the GH structure from IOUtil.
- @history
- @hauthor Thomas Radke @hdate 16 Mar 1999
- @hdesc Added parameters for 2D and 3D output
- @hauthor Thomas Radke @hdate 17 Mar 1999
- @hdesc Changed naming: IEEEIO -> FlexIO
- @hauthor Thomas Radke @hdate 30 Mar 1999
- @hdesc Undefined DI macro
- @endhistory
- @version $Header$
+ @desc
+ The extensions to the GH structure from IOUtil.
+ @enddesc
+ @version $Header$
@@*/
-#ifndef _IOGH_H_
-#define _IOGH_H_ 1
-
+#ifndef _IOUTIL_IOGH_H_
+#define _IOUTIL_IOGH_H_ 1
#ifdef __cplusplus
extern "C"
@@ -26,34 +18,11 @@ extern "C"
/* IOUtil's GH extension structure */
-typedef struct IOGH
+typedef struct
{
-
-#if 0
- /* TR: commented these things out because they were moved into the other
- IO thorns' GH extensions
- But maybe someday we want them back here, eg. if the user
- wants to say how often to do 3D output in general for all IO thorns
- that can produce 3D output; of course they should still be able
- override this with their own parameters.
- */
- /* How often to output */
- int infoevery;
- int IO_0Devery;
- int IO_1Devery;
- int IO_2Devery;
- int IO_3Devery;
-
- /* Directory in which to output */
- char *outpfx_0D;
- char *outpfx_1D;
- char *outpfx_2D;
- char *outpfx_3D;
-#endif
-
/* for 3D output */
- int ioproc; /* the IO processor each proc belongs to */
- int nioprocs; /* total number of IO processors */
+ int ioproc; /* the I/O processor each proc belongs to */
+ int nioprocs; /* total number of I/O processors */
int ioproc_every; /* output by every N'th processor */
int unchunked; /* if true generate unchunked output file */
int *downsample; /* downsampling parameters array of size cctk_maxdim */
@@ -72,5 +41,4 @@ typedef struct IOGH
}
#endif
-#endif /* _IOGH_H_ */
-
+#endif /* _IOUTIL_IOGH_H_ */
diff --git a/src/ioutil_Utils.h b/src/ioutil_Utils.h
index 519f6ee..83831dc 100644
--- a/src/ioutil_Utils.h
+++ b/src/ioutil_Utils.h
@@ -4,13 +4,12 @@
@author Thomas Radke
@desc
Function prototypes for setting up slice centers.
- @history
- @endhistory
- @version $Header$
+ @enddesc
+ @version $Header$
@@*/
-#ifndef _IOUTIL_UTILS_H_
-#define _IOUTIL_UTILS_H_
+#ifndef _IOUTIL_IOUTIL_UTILS_H_
+#define _IOUTIL_IOUTIL_UTILS_H_ 1
#ifdef __cplusplus
extern "C"
@@ -18,6 +17,44 @@ extern "C"
#endif
+/* structure describing an I/O request (including hyperslab parameters) */
+typedef struct
+{
+ /* index and timelevel of the variable */
+ int vindex, timelevel;
+
+ /* dimensionality of the variable and the hyperslab */
+ int vdim, hdim;
+
+ /* CCTK datatype for the hyperslab */
+ int hdatatype;
+
+ /* flag indicating wheter check whether an object to be written already
+ exists (and remove it in that case) */
+ int check_exist;
+
+ /* pointer to allocated buffers */
+ CCTK_INT *vectors;
+
+ /* hyperslab mapping parameters */
+ CCTK_INT *origin, *direction, *extent, *downsample;
+
+ /* offset and sizes of hyperslab into the variable's dataspace */
+ CCTK_INT *hoffset, *hsize, *hsize_chunk;
+
+} ioRequest;
+
+
+/* parse a given 'out_vars' parameter string */
+void IOUtil_ParseVarsForOutput (const cGH *GH, const char *out_vars,
+ ioRequest *request_list[]);
+
+/* return the default I/O request description structure for a variable */
+ioRequest *IOUtil_DefaultIORequest (const cGH *GH, int vindex);
+
+/* free an I/O request description */
+void IOUtil_FreeIORequest (ioRequest **request);
+
/* set the slice center for 1D lines */
int IOUtil_1DLines (const cGH *GH,
int num_dims,
@@ -32,6 +69,7 @@ int IOUtil_2DPlanes (const cGH *GH,
const CCTK_REAL *origin_phys,
int *slice_center);
+/* create an output directory on all I/O processors */
int IOUtil_CreateDirectory (const cGH *GH,
const char *dirname,
int multiple_io_procs,
@@ -41,4 +79,4 @@ int IOUtil_CreateDirectory (const cGH *GH,
}
#endif
-#endif /* _IOUTIL_UTILS_H_ */
+#endif /* _IOUTIL_IOUTIL_UTILS_H_ */