aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortradke <tradke@38c3d835-c875-442e-b0fe-21c19ce1d001>2002-04-26 15:57:40 +0000
committertradke <tradke@38c3d835-c875-442e-b0fe-21c19ce1d001>2002-04-26 15:57:40 +0000
commit57daa72811142a5f0377bfd2cdba07eebb73e977 (patch)
treefb8d9b2a81b23464c03a9b60383c2e0de3a8e2fa
parentafcb56a4505cf6f99888590d49ce1998a61a4a3a (diff)
Switched IOPanda to use the new Hyperslabbing API for outputting arbitrary
hyperslabs. You must update thorn CactusBase/IOUtil now. git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGHIO/IOPanda/trunk@31 38c3d835-c875-442e-b0fe-21c19ce1d001
-rw-r--r--interface.ccl4
-rw-r--r--src/Output.c606
-rw-r--r--src/Startup.c3
-rw-r--r--src/ioPandaGH.h17
4 files changed, 347 insertions, 283 deletions
diff --git a/interface.ccl b/interface.ccl
index 015da7f..12dca79 100644
--- a/interface.ccl
+++ b/interface.ccl
@@ -2,4 +2,6 @@
# $Header$
implements: IOPanda
-inherits: Hyperslab FlexIO
+inherits: IO Hyperslab FlexIO
+
+USES INCLUDE HEADER: Hyperslab.h
diff --git a/src/Output.c b/src/Output.c
index 4bb6a86..467fd22 100644
--- a/src/Output.c
+++ b/src/Output.c
@@ -14,6 +14,7 @@
#include "cctk.h"
#include "cctk_Parameters.h"
+#include "Hyperslab.h"
#include "CactusBase/IOUtil/src/ioGH.h"
#include "CactusPUGH/PUGH/src/include/pugh.h"
@@ -28,13 +29,13 @@ CCTK_FILEVERSION(BetaThorns_IOPanda_Output_c)
/********************************************************************
******************** Internal Routines ************************
********************************************************************/
-static int CheckOutputVar (int vindex);
-static void CheckSteerableParameters (pandaGH *myGH);
-static void SetOutputFlag (int vindex, const char *optstring, void *arg);
-static int IOPanda_Timestep (const cGH *GH, int vindex, const char *alias);
-static void IOPanda_IEEEIOStructDump (const cGH *GH, const char *fname);
-static void IOPanda_AddCommonAttributes (const cGH *GH, int vindex, int timelevel, int global_size[3], char *fname);
-static void IOPanda_AddChunkAttributes (const cGH *GH, int vindex, CCTK_INT4 *geom, char *fname);
+static void CheckSteerableParameters (const cGH *GH);
+static int DumpVar (const cGH *GH, const ioRequest *request, const char *alias);
+static void IEEEIOStructDump (const cGH *GH, const char *fname);
+static void AddCommonAttributes (const cGH *GH, const ioRequest *request,
+ const char *fname);
+static void AddChunkAttributes (const cGH *GH, const ioRequest *request,
+ const char *fname);
/*@@
@@ -45,11 +46,12 @@ static void IOPanda_AddChunkAttributes (const cGH *GH, int vindex, CCTK_INT4 *ge
Loops over all variables and outputs them if necessary
@enddesc
- @calls IOPanda_TimeFor
- IOPanda_Timestep
+ @calls CheckSteerableParameters
+ IOPanda_TimeFor
+ IOPanda_OutputVarAs
@var GH
- @vdesc Pointer to CCTK GH
+ @vdesc pointer to CCTK GH
@vtype const cGH *
@vio in
@endvar
@@ -69,38 +71,36 @@ int IOPanda_OutputGH (const cGH *GH)
DECLARE_CCTK_PARAMETERS
- /* Get the GH extension for IOPanda */
- myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
-
- CheckSteerableParameters (myGH);
+ CheckSteerableParameters (GH);
+ myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
if (myGH->out_every <= 0)
{
return (0);
}
- /* Loop over all variables */
+ /* loop over all variables */
for (vindex = retval = 0; vindex < CCTK_NumVars (); vindex++)
{
if (IOPanda_TimeFor (GH, vindex))
{
name = CCTK_VarName (vindex);
+ fullname = CCTK_FullName (vindex);
if (verbose)
{
- fullname = CCTK_FullName (vindex);
CCTK_VInfo (CCTK_THORNSTRING, "IOPanda_OutputGH: "
"(fullname, name) = (%s, %s)", fullname, name);
- free (fullname);
}
- /* Do the output */
- if (IOPanda_Timestep (GH, vindex, name) == 0)
+ if (IOPanda_OutputVarAs (GH, fullname, name) == 0)
{
- /* Register variable as having output this iteration */
- myGH->out_last [vindex] = GH->cctk_iteration;
+ /* register variable as having output this iteration */
+ myGH->out_last[vindex] = GH->cctk_iteration;
retval++;
}
+
+ free (fullname);
}
}
@@ -116,10 +116,12 @@ int IOPanda_OutputGH (const cGH *GH)
Unconditional output of a variable using the IOPanda I/O method
@enddesc
- @calls IOPanda_Timestep
+ @calls IOUtil_ParseVarsForOutput
+ DumpVar
+ IOUtil_FreeIORequest
@var GH
- @vdesc Pointer to CCTK GH
+ @vdesc pointer to CCTK GH
@vtype const cGH *
@vio in
@endvar
@@ -137,25 +139,38 @@ int IOPanda_OutputGH (const cGH *GH)
@returntype int
@returndesc
- return code of @seeroutine IOPanda_Timestep
+ return code of @seeroutine DumpVar
@endreturndesc
@@*/
int IOPanda_OutputVarAs (const cGH *GH, const char *fullname, const char *alias)
{
- int vindex, retval;
+ int vindex, oneshot, retval;
+ const pandaGH *myGH;
DECLARE_CCTK_PARAMETERS
vindex = CCTK_VarIndex (fullname);
if (verbose)
{
- CCTK_VInfo (CCTK_THORNSTRING, "IOPanda_OutputVarAs: "
- "(fullname, alias, index) = (%s, %s, %d)",
- fullname, alias, vindex);
+ CCTK_VInfo (CCTK_THORNSTRING, "IOPanda_OutputVarAs: (fullname, alias, "
+ "index) = (%s, %s, %d)", fullname, alias, vindex);
+ }
+
+ /* check whether the variable already has an I/O request entry */
+ myGH = (const pandaGH *) CCTK_GHExtension (GH, "IOPanda");
+ oneshot = myGH->requests[vindex] == NULL;
+ if (oneshot)
+ {
+ IOUtil_ParseVarsForOutput (GH, fullname, myGH->requests);
}
- /* Do the output */
- retval = IOPanda_Timestep (GH, vindex, alias);
+ /* do the output */
+ retval = DumpVar (GH, myGH->requests[vindex], alias);
+
+ if (oneshot && myGH->requests[vindex])
+ {
+ IOUtil_FreeIORequest (&myGH->requests[vindex]);
+ }
return (retval);
}
@@ -173,7 +188,7 @@ int IOPanda_OutputVarAs (const cGH *GH, const char *fullname, const char *alias)
@calls CheckSteerableParameters
@var GH
- @vdesc Pointer to CCTK GH
+ @vdesc pointer to CCTK GH
@vtype const cGH *
@vio in
@endvar
@@ -191,39 +206,32 @@ int IOPanda_OutputVarAs (const cGH *GH, const char *fullname, const char *alias)
@@*/
int IOPanda_TimeFor (const cGH *GH, int vindex)
{
- pandaGH *myGH;
+ int retval;
+ const pandaGH *myGH;
char *fullname;
- /* Get the GH extension for IOPanda */
- myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
-
- CheckSteerableParameters (myGH);
-
- /* Check if any output was requested */
- if (myGH->out_every <= 0)
- {
- return (0);
- }
-
- /* Check this variable should be output */
- if (! (myGH->do_out[vindex] && GH->cctk_iteration % myGH->out_every == 0))
- {
- return (0);
- }
+ CheckSteerableParameters (GH);
- /* Check variable not already output this iteration */
- if (myGH->out_last [vindex] == GH->cctk_iteration)
+ /* check if this variable should be output */
+ myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
+ retval = myGH->out_every > 0 && myGH->requests[vindex] &&
+ GH->cctk_iteration % myGH->out_every == 0;
+ if (retval)
{
- fullname = CCTK_FullName (vindex);
- CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Already done IOPanda output for variable '%s' in current "
- "iteration (probably via triggers)", fullname);
- free (fullname);
- return (0);
+ /* check if variable was not already output this iteration */
+ if (myGH->out_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (6, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOPanda output for variable '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
}
- return (1);
+ return (retval);
}
@@ -235,10 +243,10 @@ int IOPanda_TimeFor (const cGH *GH, int vindex)
Triggers the output a variable using the IOPanda output method
@enddesc
- @calls IOPanda_Timestep
+ @calls DumpVar
@var GH
- @vdesc Pointer to CCTK GH
+ @vdesc pointer to CCTK GH
@vtype const cGH *
@vio in
@endvar
@@ -250,35 +258,32 @@ int IOPanda_TimeFor (const cGH *GH, int vindex)
@returntype int
@returndesc
- return code of @seeroutine IOPanda_Timestep
+ return code of @seeroutine DumpVar
@endreturndesc
@@*/
int IOPanda_TriggerOutput (const cGH *GH, int vindex)
{
int retval;
- pandaGH *myGH;
+ const pandaGH *myGH;
const char *varname;
DECLARE_CCTK_PARAMETERS
varname = CCTK_VarName (vindex);
-
- /* Get the GH extension for IOPanda */
- myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
-
if (verbose)
{
CCTK_VInfo (CCTK_THORNSTRING, "TriggerOutput: "
"name, index = %s, %d", varname, vindex);
}
- /* Do the output */
- retval = IOPanda_Timestep (GH, vindex, varname);
+ /* do the output */
+ myGH = (const pandaGH *) CCTK_GHExtension (GH, "IOPanda");
+ retval = DumpVar (GH, myGH->requests[vindex], varname);
if (retval == 0)
{
- /* Register variable as having output this iteration */
- myGH->out_last [vindex] = GH->cctk_iteration;
+ /* register variable as having output this iteration */
+ myGH->out_last[vindex] = GH->cctk_iteration;
}
return (retval);
@@ -297,22 +302,25 @@ int IOPanda_TriggerOutput (const cGH *GH, int vindex)
and does appropriate re-evaluation.
@enddesc
- @calls CCTK_TraverseString
+ @calls IOUtil_ParseVarsForOutput
- @var myGH
- @vdesc Pointer to IOPanda GH
- @vtype pandaGH *
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
@vio in
@endvar
@@*/
-static void CheckSteerableParameters (pandaGH *myGH)
+static void CheckSteerableParameters (const cGH *GH)
{
- int times_set;
+ int vindex, times_set;
+ pandaGH *myGH;
+ char *fullname;
static int out_vars_lastset = -1;
DECLARE_CCTK_PARAMETERS
/* how often to output */
+ myGH = (pandaGH *) CCTK_GHExtension (GH, "IOPanda");
myGH->out_every = out_every;
if (myGH->out_every < 0)
{
@@ -325,77 +333,57 @@ static void CheckSteerableParameters (pandaGH *myGH)
times_set = CCTK_ParameterQueryTimesSet ("out_vars", CCTK_THORNSTRING);
if (times_set != out_vars_lastset)
{
- memset (myGH->do_out, 0, CCTK_NumVars ());
- CCTK_TraverseString (out_vars, SetOutputFlag, myGH->do_out,
- CCTK_GROUP_OR_VAR);
-
- /* Save the last setting of 'out_vars' parameter */
- out_vars_lastset = times_set;
- }
-}
-
-
-/* check if this variable can be output (static conditions) */
-static int CheckOutputVar (int vindex)
-{
- char *errormsg, *fullname;
-
-
- errormsg = NULL;
-
-/*** FIXME: IEEEIO doesn't provide a COMPLEX datatype
- so somehow CCTK_COMPLEX has to be mapped onto REALs or so.
- We have to check this already here because if an IEEEIO file
- is created and nothing is written to, it crashes at re-opening. ***/
- if (CCTK_VarTypeI (vindex) == CCTK_VARIABLE_COMPLEX)
- {
- errormsg = "IOPanda output for complex variable '%s' not yet supported";
- }
- else if (CCTK_GroupTypeFromVarI (vindex) == CCTK_SCALAR)
- {
- errormsg = "IOPanda output for scalar variable '%s' not supported";
- }
-
- if (errormsg)
- {
- fullname = CCTK_FullName (vindex);
- CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- errormsg, fullname);
- free (fullname);
- }
-
- return (errormsg != NULL);
-}
-
-
-/* callback for CCTK_TraverseString() to set the output flag
- for the given variable */
-static void SetOutputFlag (int vindex, const char *optstring, void *arg)
-{
- char *flags = (char *) arg;
-
+ IOUtil_ParseVarsForOutput (GH, out_vars, myGH->requests);
+
+ /*** FIXME: IEEEIO doesn't provide a COMPLEX datatype
+ so we should map CCTK_COMPLEX to two REALs here.
+ We have to check for this already here because if an IEEEIO file
+ is created and nothing is written to it, it will crash
+ at re-opening. ***/
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (! myGH->requests[vindex])
+ {
+ continue;
+ }
- /* Check the variable type */
- flags[vindex] = CheckOutputVar (vindex) == 0;
+ if (strncmp (CCTK_VarTypeName (vindex), "CCTK_VARIABLE_COMPLEX", 21))
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOPanda output for complex variable '%s' not yet "
+ "supported", fullname);
+ free (fullname);
+ IOUtil_FreeIORequest (&myGH->requests[vindex]);
+ }
+ else if (CCTK_GroupTypeFromVarI (vindex) == CCTK_SCALAR ||
+ CCTK_GroupDimFromVarI (vindex) != 3)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOPanda output for variable '%s' not supported (can only "
+ "do 3D grid arrays)", fullname);
+ free (fullname);
+ IOUtil_FreeIORequest (&myGH->requests[vindex]);
+ }
+ }
- if (optstring)
- {
- CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Optional string '%s' in variable name ignored", optstring);
+ /* save the last setting of 'out_vars' parameter */
+ out_vars_lastset = times_set;
}
}
-static int IOPanda_Timestep (const cGH *GH, int vindex, const char *alias)
+static int DumpVar (const cGH *GH, const ioRequest *request, const char *alias)
{
- void *data;
- int tmp[1], tmp1[3], tmp2[3];
+ void *hdata;
+ int tmp[1], tmp2[3];
Distribution dist1[3], dist2[3];
- CCTK_INT4 bnd[9];
- int free_flag, timelevel;
+ int i, hdatasize, retval;
+ CCTK_INT mapping;
ArrayInfo ainfo;
- ioGH *ioUtilGH;
- pGH *pughGH;
+ const ioGH *ioUtilGH;
+ const pGH *pughGH;
char *fullname;
union
{
@@ -406,197 +394,262 @@ static int IOPanda_Timestep (const cGH *GH, int vindex, const char *alias)
/* check if variable has storage assigned */
- if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (vindex)))
+ if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (request->vindex)))
{
- fullname = CCTK_FullName (vindex);
+ fullname = CCTK_FullName (request->vindex);
CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
"No IOPanda output for '%s' (no storage)", fullname);
free (fullname);
return (-1);
}
- /* get the handles for PUGH and IOUtil GH extensions */
- pughGH = PUGH_pGH (GH);
- ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO");
+ /* define the hyperslab mapping */
+ mapping = Hyperslab_DefineLocalMappingByIndex (GH, request->vindex,
+ request->hdim,
+ request->direction,
+ request->origin,
+ request->extent,
+ request->downsample,
+ -1, NULL,
+ request->hsize_chunk,
+ request->hsize,
+ request->hoffset);
+ if (mapping < 0)
+ {
+ fullname = CCTK_FullName (request->vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Failed to define hyperslab mapping for variable '%s'",
+ fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* calculate the size of the hyperslab */
+ request->hsize_chunk[request->hdim] = 1;
+ for (i = 0; i < request->hdim; i++)
+ {
+ request->hsize_chunk[request->hdim] *= request->hsize_chunk[i];
+ }
+
+ /* get the hyperslab */
+ hdatasize = CCTK_VarTypeSize (request->hdatatype);
+ hdata = request->hsize_chunk[request->hdim] > 0 ?
+ malloc (request->hsize_chunk[request->hdim] * hdatasize) : NULL;
+ retval = Hyperslab_Get (GH, mapping, -1, request->vindex, request->timelevel,
+ request->hdatatype, hdata);
+
+ /* release the mapping structure */
+ Hyperslab_FreeMapping (mapping);
+
+ if (retval)
+ {
+ fullname = CCTK_FullName (request->vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Failed to extract hyperslab for variable '%s'", fullname);
+ free (fullname);
+ if (hdata)
+ {
+ free (hdata);
+ }
+ return (-2);
+ }
/* prevent compiler warning "cast discards `const' from pointer target type"*/
cast_to_const.const_char = alias;
ainfo.name_ = cast_to_const.non_const_char;
- ainfo.rank_ = 3;
- tmp1[0] = GH->cctk_gsh[2];
- tmp1[1] = GH->cctk_gsh[1];
- tmp1[2] = GH->cctk_gsh[0];
- ainfo.size_ = tmp1;
+ /* copy from CCTK_INT[] to int[] */
+ ainfo.size_ = (int *) malloc (request->hdim * sizeof (int));
+ for (ainfo.rank_ = 0; ainfo.rank_ < request->hdim; ainfo.rank_++)
+ {
+ ainfo.size_[ainfo.rank_] = request->hsize[i];
+ }
- switch (CCTK_VarTypeI (vindex))
+ switch (request->hdatatype)
{
- case CCTK_VARIABLE_CHAR:
- ainfo.esize_ = CHAR;
- break;
+ case CCTK_VARIABLE_CHAR: ainfo.esize_ = CHAR; break;
case CCTK_VARIABLE_INT:
#ifdef CCTK_INTEGER_PRECISION_8
- ainfo.esize_ = INT64;
+ ainfo.esize_ = INT64; break;
#elif CCTK_INTEGER_PRECISION_4
- ainfo.esize_ = INT32;
+ ainfo.esize_ = INT32; break;
#elif CCTK_INTEGER_PRECISION_2
- ainfo.esize_ = INT16;
+ ainfo.esize_ = INT16; break;
#endif
- break;
case CCTK_VARIABLE_REAL:
- if (ioUtilGH->out_single)
- {
- ainfo.esize_ = FLOAT32;
- }
- else
- {
-#ifdef CCTK_REAL_PRECISION_8
- ainfo.esize_ = FLOAT64;
-#elif CCTK_REAL_PRECISION_4
- ainfo.esize_ = FLOAT32;
+#ifdef CCTK_REAL_PRECISION_4
+ ainfo.esize_ = FLOAT32; break;
+#elif CCTK_REAL_PRECISION_8
+ ainfo.esize_ = FLOAT64; break;
#endif
- }
+
+#ifdef CCTK_INT2
+ case CCTK_VARIABLE_INT2: ainfo.esize_ = INT16; break;
+#endif
+#ifdef CCTK_INT4
+ case CCTK_VARIABLE_INT4: ainfo.esize_ = INT32; break;
+#endif
+#ifdef CCTK_INT8
+ case CCTK_VARIABLE_INT8: ainfo.esize_ = INT64; break;
+#endif
+#ifdef CCTK_REAL4
+ case CCTK_VARIABLE_REAL4: ainfo.esize_ = FLOAT32; break;
+#endif
+#ifdef CCTK_REAL8
+ case CCTK_VARIABLE_REAL8: ainfo.esize_ = FLOAT64; break;
+#endif
+
+ default: CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Unsupported "
+ "CCTK variable datatype %d", request->hdatatype);
+ break;
}
/* FIXME: rank */
ainfo.mem_rank_ = 3;
- tmp2[0] = pughGH->Connectivity [2]->nprocs [2];
- tmp2[1] = pughGH->Connectivity [2]->nprocs [1];
- tmp2[2] = pughGH->Connectivity [2]->nprocs [0];
+ pughGH = PUGH_pGH (GH);
+ tmp2[0] = pughGH->Connectivity[2]->nprocs[2];
+ tmp2[1] = pughGH->Connectivity[2]->nprocs[1];
+ tmp2[2] = pughGH->Connectivity[2]->nprocs[0];
ainfo.mem_layout_ = tmp2;
dist1[0] = dist1[1] = dist1[2] = BLOCK;
ainfo.mem_dist_ = dist1;
ainfo.disk_rank_ = 1;
dist2[0] = BLOCK; dist2[1] = dist2[2] = NONE;
+ ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO");
tmp[0]= ((CCTK_nProcs(GH) - 1) / ioUtilGH->ioproc_every + 1);
ainfo.disk_layout_ = tmp;
ainfo.disk_dist_ = dist2;
- timelevel = 0;
-
- IOPanda_getDumpData(GH, vindex, timelevel, &data, &free_flag, bnd, ainfo.esize_);
- ainfo.data_ = (char *)data;
-
/*** FIXME: asymmetric ghostzones */
- ainfo.stencil_width_ = GH->cctk_nghostzones [0];
+ ainfo.stencil_width_ = GH->cctk_nghostzones[0];
+
+ ainfo.data_ = (char *) hdata;
PandaTimestep(&ainfo);
- if (free_flag)
+ if (hdata)
{
- free (data);
+ free (hdata);
}
- IOPanda_AddCommonAttributes(GH, vindex, timelevel, ainfo.size_, ainfo.name_);
+ AddCommonAttributes(GH, request, ainfo.name_);
if (! ioUtilGH->unchunked)
{
- /* Write chunk attributes */
- IOPanda_AddChunkAttributes (GH, vindex, bnd, ainfo.name_);
+ /* write chunk attributes */
+ AddChunkAttributes (GH, request, ainfo.name_);
}
if (PandaIsNewFile(ainfo.name_))
{
- IOPanda_IEEEIOStructDump(GH, ainfo.name_);
+ IEEEIOStructDump(GH, ainfo.name_);
}
- return (0);
+ return (retval);
}
-static void IOPanda_AddCommonAttributes (const cGH *GH,
- int vindex,
- int timelevel,
- int global_size[3],
- char *fname)
+static void AddCommonAttributes (const cGH *GH, const ioRequest *request,
+ const char *fname)
{
- DECLARE_CCTK_PARAMETERS
- CCTK_REAL d3_to_IO [6]; /* buffer for writing doubles to IEEEIO */
- CCTK_INT4 i_to_IO; /* buffer for writing an int to IEEEIO */
- CCTK_INT4 i3_to_IO[3]; /* buffer for writing ints to IEEEIO */
- CCTK_REAL dummy;
- char *name, *gname;
- ioGH *ioUtilGH;
+ int i;
+ char *name;
+ CCTK_INT4 *itmp;
+ CCTK_REAL *dtmp;
+ const ioGH *ioUtilGH;
+ char coord_system_name[20];
- /* Get the handle for IO extensions */
- ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO");
+ itmp = (CCTK_INT4 *) malloc (request->hdim * sizeof (CCTK_INT4));
- name = CCTK_FullName (vindex);
+ name = CCTK_FullName (request->vindex);
Panda_WriteAttribute (fname, "name", BYTE, strlen (name) + 1, name);
free (name);
- gname = CCTK_GroupNameFromVarI (vindex);
- Panda_WriteAttribute (fname, "groupname", BYTE, strlen (gname) + 1, gname);
- free (gname);
+ name = CCTK_GroupNameFromVarI (request->vindex);
+ Panda_WriteAttribute (fname, "groupname", BYTE, strlen (name) + 1, name);
+ free (name);
- i_to_IO = CCTK_GroupTypeFromVarI (vindex);
- Panda_WriteAttribute (fname, "grouptype", INT32, 1, &i_to_IO);
+ itmp[0] = CCTK_GroupTypeFromVarI (request->vindex);
+ Panda_WriteAttribute (fname, "grouptype", INT32, 1, itmp);
- i_to_IO = CCTK_NumTimeLevelsFromVarI (vindex);
- Panda_WriteAttribute (fname, "ntimelevels", INT32, 1, &i_to_IO);
+ itmp[0] = CCTK_NumTimeLevelsFromVarI (request->vindex);
+ Panda_WriteAttribute (fname, "ntimelevels", INT32, 1, itmp);
- i_to_IO = timelevel;
- Panda_WriteAttribute (fname, "timelevel", INT32, 1, &i_to_IO);
+ itmp[0] = request->timelevel;
+ Panda_WriteAttribute (fname, "timelevel", INT32, 1, itmp);
- Panda_WriteAttribute (fname, "time", FLOAT64, 1,&GH->cctk_time);
+ Panda_WriteAttribute (fname, "time", FLOAT64, 1, &GH->cctk_time);
- d3_to_IO [0] = CCTK_CoordRange (GH, &d3_to_IO [0], &dummy, -1, "x", "cart3d");
- d3_to_IO [1] = CCTK_CoordRange (GH, &d3_to_IO [1], &dummy, -1, "y", "cart3d");
- d3_to_IO [2] = CCTK_CoordRange (GH, &d3_to_IO [2], &dummy, -1, "z", "cart3d");
- Panda_WriteAttribute (fname, "origin", FLOAT64,3,d3_to_IO);
- CCTK_CoordRange (GH, &d3_to_IO [0], &d3_to_IO [3], -1, "x", "cart3d");
- CCTK_CoordRange (GH, &d3_to_IO [1], &d3_to_IO [4], -1, "y", "cart3d");
- CCTK_CoordRange (GH, &d3_to_IO [2], &d3_to_IO [5], -1, "z", "cart3d");
- Panda_WriteAttribute (fname, "min_ext", FLOAT64, 3, d3_to_IO);
- Panda_WriteAttribute (fname, "max_ext", FLOAT64, 3, d3_to_IO+3);
+ /* attributes describing the underlying grid
+ These are only stored for CCTK_GF variables if they are associated
+ with coordinates. */
+ /* FIXME: This is hardcoded for cartesian coordinate systems.
+ A better solution would be to be able to query the coordinate
+ system which is associated with the variable. */
+ ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO");
+ sprintf (coord_system_name, "cart%dd", request->hdim);
+ if (CCTK_GroupTypeFromVarI (request->vindex) == CCTK_GF &&
+ CCTK_CoordSystemHandle (coord_system_name) >= 0)
+ {
+ dtmp = (CCTK_REAL *) malloc (3 * request->hdim * sizeof (CCTK_REAL));
+ for (i = 0; i < request->hdim; i++)
+ {
+ CCTK_CoordRange (GH, &dtmp[i], &dtmp[i + request->hdim], i + 1,
+ NULL, coord_system_name);
+ dtmp[i + 2*request->hdim] = GH->cctk_delta_space[i] *
+ ioUtilGH->downsample[i];
+ }
- /* FIXME: dimension */
- d3_to_IO [0] = GH->cctk_delta_space [0] * ioUtilGH->downsample[0];
- d3_to_IO [1] = GH->cctk_delta_space [1] * ioUtilGH->downsample[1];
- d3_to_IO [2] = GH->cctk_delta_space [2] * ioUtilGH->downsample[2];
- Panda_WriteAttribute (fname, "delta", FLOAT64, 3, d3_to_IO);
+ Panda_WriteAttribute (fname, "origin", FLOAT64, request->hdim, dtmp);
+ Panda_WriteAttribute (fname, "min_ext", FLOAT64, request->hdim, dtmp);
+ Panda_WriteAttribute (fname, "max_ext", FLOAT64, request->hdim,
+ dtmp + 1*request->hdim);
+ Panda_WriteAttribute (fname, "delta", FLOAT64, request->hdim,
+ dtmp + 2*request->hdim);
- if (ioUtilGH->downsample[0] > 1 ||
- ioUtilGH->downsample[1] > 1 ||
- ioUtilGH->downsample[2] > 1)
+ if (ioUtilGH->downsample[0] > 1 ||
+ ioUtilGH->downsample[1] > 1 ||
+ ioUtilGH->downsample[2] > 1)
+ {
+ Panda_WriteAttribute (fname, "evolution_delta", FLOAT64, request->hdim,
+ GH->cctk_delta_space);
+ }
+
+ free (dtmp);
+ }
+
+ for (i = 0; i < request->hdim; i++)
{
- d3_to_IO [0] = GH->cctk_delta_space [0];
- d3_to_IO [1] = GH->cctk_delta_space [1];
- d3_to_IO [2] = GH->cctk_delta_space [2];
- Panda_WriteAttribute (fname, "evolution_delta", FLOAT64, 3, d3_to_IO);
+ itmp[i] = request->hsize[i];
}
+ Panda_WriteAttribute (fname, "global_size", INT32, 3, itmp);
- i3_to_IO[0] = global_size[0];
- i3_to_IO[1] = global_size[1];
- i3_to_IO[2] = global_size[2];
- Panda_WriteAttribute (fname, "global_size", INT32, 3, i3_to_IO);
+ itmp[0] = CCTK_nProcs (GH);
+ Panda_WriteAttribute (fname, "nprocs", INT32, 1, itmp);
- i_to_IO = CCTK_nProcs (GH);
- Panda_WriteAttribute (fname, "nprocs", INT32, 1, &i_to_IO);
+ itmp[0] = ioUtilGH->ioproc_every;
+ Panda_WriteAttribute (fname, "ioproc_every", INT32, 1, itmp);
- i_to_IO = ioUtilGH->ioproc_every;
- Panda_WriteAttribute (fname, "ioproc_every", INT32, 1, &i_to_IO);
+ itmp[0] = ioUtilGH->unchunked;
+ Panda_WriteAttribute (fname, "unchunked", INT32, 1, itmp);
- i_to_IO = ioUtilGH->unchunked;
- Panda_WriteAttribute (fname, "unchunked", INT32, 1, &i_to_IO);
+ itmp[0] = GH->cctk_iteration;
+ Panda_WriteAttribute (fname, "iteration", INT32, 1, itmp);
- i_to_IO = GH->cctk_iteration;
- Panda_WriteAttribute (fname, "iteration", INT32, 1, &i_to_IO);
+ free (itmp);
}
-static void IOPanda_AddChunkAttributes (const cGH *GH,
- int vindex,
- CCTK_INT4 *geom,
- char *fname)
+static void AddChunkAttributes (const cGH *GH, const ioRequest *request,
+ const char *fname)
{
- int dim;
- char *name;
- CCTK_INT4 i_to_IO;
+ int i;
+ char *fullname;
+ CCTK_INT4 *itmp;
/* there is nothing to do for a serial run */
@@ -605,46 +658,53 @@ static void IOPanda_AddChunkAttributes (const cGH *GH,
return;
}
- /* get the dimension of the variable */
- dim = CCTK_GroupDimI (CCTK_GroupIndexFromVarI (vindex));
+ itmp = (CCTK_INT4 *) malloc (2 * request->hdim * sizeof (CCTK_INT4));
- Panda_WriteAttribute (fname, "chunk_origin", INT32, dim, &geom[0]);
- Panda_WriteAttribute (fname, "subchunk_lb", INT32, dim, &geom[0]);
- Panda_WriteAttribute (fname, "global_size", INT32, dim, &geom[2*dim]);
+ /* copy from CCTK_INT[] to CCTK_INT4[] */
+ for (i = 0; i < request->hdim; i++)
+ {
+ itmp[0*request->hdim + i] = request->hoffset[i];
+ itmp[1*request->hdim + i] = request->hsize[i];
+ }
- i_to_IO = GH->cctk_iteration;
- Panda_WriteAttribute (fname, "chunk_dataset", INT32, 1, &i_to_IO);
+ Panda_WriteAttribute (fname, "chunk_origin", INT32, request->hdim, &itmp[0]);
+ Panda_WriteAttribute (fname, "subchunk_lb", INT32, request->hdim, &itmp[0]);
+ Panda_WriteAttribute (fname, "global_size", INT32, request->hdim,
+ &itmp[request->hdim]);
- name = CCTK_FullName (vindex);
- Panda_WriteAttribute (fname, "name", CHAR, strlen (name)+1, name);
- free (name);
+ itmp[0] = GH->cctk_iteration;
+ Panda_WriteAttribute (fname, "chunk_dataset", INT32, 1, itmp);
+
+ fullname = CCTK_FullName (request->vindex);
+ Panda_WriteAttribute (fname, "name", CHAR, strlen (fullname)+1, fullname);
+
+ free (fullname);
+ free (itmp);
}
-static void IOPanda_IEEEIOStructDump (const cGH *GH,
- const char *fname)
+static void IEEEIOStructDump (const cGH *GH, const char *fname)
{
- DECLARE_CCTK_PARAMETERS
int len;
- CCTK_INT4 i_temp;
- CCTK_REAL d_temp;
- ioGH *ioUtilGH;
+ CCTK_INT4 itmp;
+ CCTK_REAL dtmp;
+ const ioGH *ioUtilGH;
char buffer[128];
+ DECLARE_CCTK_PARAMETERS
- ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO");
-
- i_temp = GH->cctk_iteration;
- Panda_WriteAttribute (fname, "GH$iteration", INT32, 1, &i_temp);
+ itmp = GH->cctk_iteration;
+ Panda_WriteAttribute (fname, "GH$iteration", INT32, 1, &itmp);
- i_temp = ioUtilGH->ioproc_every;
- Panda_WriteAttribute (fname, "GH$ioproc_every", INT32, 1, &i_temp);
+ ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO");
+ itmp = ioUtilGH->ioproc_every;
+ Panda_WriteAttribute (fname, "GH$ioproc_every", INT32, 1, &itmp);
- i_temp = CCTK_nProcs (GH);
- Panda_WriteAttribute (fname, "GH$nprocs", INT32, 1, &i_temp);
+ itmp = CCTK_nProcs (GH);
+ Panda_WriteAttribute (fname, "GH$nprocs", INT32, 1, &itmp);
- d_temp = GH->cctk_time;
- Panda_WriteAttribute (fname, "GH$time", FLOAT64, 1, &d_temp);
+ dtmp = GH->cctk_time;
+ Panda_WriteAttribute (fname, "GH$time", FLOAT64, 1, &dtmp);
/* add the parameter filename and the creation date
as file identification attributes */
diff --git a/src/Startup.c b/src/Startup.c
index 04a5fe6..d5f59c1 100644
--- a/src/Startup.c
+++ b/src/Startup.c
@@ -18,6 +18,7 @@
#include "CactusBase/IOUtil/src/ioGH.h"
#include "CactusBase/IOUtil/src/ioutil_Utils.h"
#include "ioPandaGH.h"
+#include "Panda/c_interface.h"
/* the rcs ID and its dummy function to use it */
static const char *rcsid = "$Id$";
@@ -143,7 +144,7 @@ static void *SetupGH (tFleshConfig *config, int convergence_level, cGH *GH)
/* allocate a new GH extension structure */
myGH = (pandaGH *) malloc (sizeof (pandaGH));
numvars = CCTK_NumVars ();
- myGH->do_out = (char *) malloc (numvars * sizeof (char));
+ myGH->requests = (ioRequest **) calloc (numvars, sizeof (ioRequest *));
myGH->out_last = (int *) malloc (numvars * sizeof (int));
for (i = 0; i < numvars; i++)
diff --git a/src/ioPandaGH.h b/src/ioPandaGH.h
index d066d37..7434e1f 100644
--- a/src/ioPandaGH.h
+++ b/src/ioPandaGH.h
@@ -12,15 +12,21 @@
#define _IOPANDA_IOPANDAGH_H_ 1
#include "StoreNamedData.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
-typedef struct IOPandaGH
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct
{
/* the number of times to output */
int out_every;
- /* flags indicating output for variable[i] */
- char *do_out;
+ /* I/O request descriptions for all CCTK variables */
+ ioRequest **requests;
/* directory in which to output */
char *outdir;
@@ -30,11 +36,6 @@ typedef struct IOPandaGH
} pandaGH;
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
/* prototypes of functions to be registered as IOPanda's IO method */
int IOPanda_OutputGH (const cGH *GH);
int IOPanda_TriggerOutput (const cGH *GH, int);