From 57daa72811142a5f0377bfd2cdba07eebb73e977 Mon Sep 17 00:00:00 2001 From: tradke Date: Fri, 26 Apr 2002 15:57:40 +0000 Subject: 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 --- interface.ccl | 4 +- src/Output.c | 606 +++++++++++++++++++++++++++++++------------------------- src/Startup.c | 3 +- src/ioPandaGH.h | 17 +- 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); -- cgit v1.2.3