From 310f0ea48d18866b773136aed11200b6eda6378b Mon Sep 17 00:00:00 2001 From: eschnett <> Date: Thu, 1 Mar 2001 11:40:00 +0000 Subject: Initial revision darcs-hash:20010301114010-f6438-12fb8a9ffcc80e86c0a97e37b5b0dae0dbc59b79.gz --- Carpet/CarpetSlab/src/slab.cc | 880 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 880 insertions(+) create mode 100644 Carpet/CarpetSlab/src/slab.cc (limited to 'Carpet/CarpetSlab/src/slab.cc') diff --git a/Carpet/CarpetSlab/src/slab.cc b/Carpet/CarpetSlab/src/slab.cc new file mode 100644 index 000000000..f734aafb9 --- /dev/null +++ b/Carpet/CarpetSlab/src/slab.cc @@ -0,0 +1,880 @@ +// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetSlab/src/slab.cc,v 1.20 2004/08/19 06:35:36 schnetter Exp $ + +#include +#include +#include + +#include + +#include "cctk.h" + +#include "util_Table.h" + +#include "bbox.hh" +#include "bboxset.hh" +#include "dh.hh" +#include "gdata.hh" +#include "gh.hh" +#include "ggf.hh" +#include "vect.hh" + +#include "carpet.hh" + +#include "slab.hh" + +extern "C" { + static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetSlab/src/slab.cc,v 1.20 2004/08/19 06:35:36 schnetter Exp $"; + CCTK_FILEVERSION(Carpet_CarpetSlab_slab_cc); +} + + + +namespace CarpetSlab { + + using namespace Carpet; + + + + // Mapping object + // (just store the mapping) + struct mapping { + int vindex; + int hdim; + vector origin; // [vdim] + vector dirs; // [hdim] + vector stride; // [hdim] + vector length; // [hdim] + }; + + + + int + StoreMapping (mapping * const mp) + { + int const table = Util_TableCreate (UTIL_TABLE_FLAGS_DEFAULT); + assert (table>=0); + int const ierr = Util_TableSetPointer (table, mp, "mapping"); + assert (ierr>=0); + return table; + } + + mapping * + RetrieveMapping (int const table) + { + CCTK_POINTER mp; + int const ierr = Util_TableGetPointer (table, &mp, "mapping"); + assert (ierr>=0); + return (mapping *)mp; + } + + void + DeleteMapping (int const table) + { + int const ierr = Util_TableDestroy (table); + assert (ierr>=0); + } + + + + void + FillSlab (const cGH* const cgh, + const int dest_proc, + const int n, + const int ti, + const int hdim, + const int origin[/*vdim*/], + const int dirs[/*hdim*/], + const int stride[/*hdim*/], + const int length[/*hdim*/], + void* const hdata) + { + int ierr; + + // Check Cactus grid hierarchy + assert (cgh); + + // Check destination processor + assert (dest_proc>=-1 && dest_proc=0 && n=0); + const int n0 = CCTK_FirstVarIndexI(group); + assert (n0>=0); + const int var = n - n0; + assert (var>=0); + + // Get info about group + cGroup gp; + ierr = CCTK_GroupData (group, &gp); + assert (! ierr); + assert (gp.dim<=dim); + assert (CCTK_QueryGroupStorageI(cgh, group)); + const int typesize = CCTK_VarTypeSize(gp.vartype); + assert (typesize>0); + + if (gp.grouptype==CCTK_GF && reflevel==-1) { + CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in meta mode or global mode (use singlemap mode instead)"); + } + const int rl = gp.grouptype==CCTK_GF ? reflevel : 0; + + if (gp.grouptype==CCTK_GF && Carpet::map==-1 && maps>1) { + CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in level mode when there are multiple maps (use singlemap mode instead, or make sure that there is only one map)"); + } + const int m = gp.grouptype==CCTK_GF ? Carpet::map : 0; + const int oldmap = Carpet::map; + if (gp.grouptype==CCTK_GF && oldmap==-1) { + enter_singlemap_mode(const_cast(cgh), m); + } + + // Check dimension + assert (hdim>=0 && hdim<=gp.dim); + + // Get more info about group + cGroupDynamicData gd; + ierr = CCTK_GroupDynamicData (cgh, group, &gd); + assert (! ierr); + const vect sizes = vect::ref(gd.gsh); + for (int d=0; d= 0); + } + + // Check timelevel + const int num_tl = gp.numtimelevels; + assert (ti>=0 && ti=0 && origin[d]<=sizes[d]); + } + + // Check directions + for (int dd=0; dd=1 && dirs[dd]<=dim); + } + + // Check stride + for (int dd=0; dd0); + } + + // Check length + for (int dd=0; dd=0); + } + + // Check extent + for (int dd=0; dd* myhh; + const dh* mydd; + const ggf* myff; + assert (group < (int)arrdata.size()); + myhh = arrdata.at(group).at(m).hh; + assert (myhh); + mydd = arrdata.at(group).at(m).dd; + assert (mydd); + assert (var < (int)arrdata.at(group).at(m).data.size()); + myff = arrdata.at(group).at(m).data.at(var); + assert (myff); + + // Detemine collecting processor + const int collect_proc = dest_proc<0 ? 0 : dest_proc; + + // Determine own rank + const int rank = CCTK_MyProc(cgh); + + // Calculate global size + int totalsize = 1; + for (int dd=0; dd* mydata; + mydata = (*myff)(tl, rl, 0, 0); + + // Stride of data in memory + const vect str = mydata->extent().stride(); + + // Stride of collected data + vect hstr = str; + for (int dd=0; dd hlb(0); + for (int d=0; d hub = hlb; + for (int dd=0; dd hextent (hlb, hub, hstr); + assert (hextent.size() == totalsize); + + // Create collector data object + void* myhdata = rank==collect_proc ? hdata : 0; + gdata* const alldata = mydata->make_typed(-1); + alldata->allocate (hextent, collect_proc, myhdata); + + // Done with the temporary stuff + mydata = 0; + + for (comm_state state; !state.done(); state.step()) { + + // Loop over all components, copying data from them + BEGIN_LOCAL_COMPONENT_LOOP (cgh, gp.grouptype) { + + // Get data object + mydata = (*myff)(tl, rl, component, mglevel); + + // Calculate overlapping extents + const bboxset myextents + = ((mydd->boxes.at(rl).at(component).at(mglevel).sync_not + | mydd->boxes.at(rl).at(component).at(mglevel).interior) + & hextent); + + // Loop over overlapping extents + for (bboxset::const_iterator ext_iter = myextents.begin(); + ext_iter != myextents.end(); + ++ext_iter) { + + // Copy data + alldata->copy_from (state, mydata, *ext_iter); + + } + + } END_LOCAL_COMPONENT_LOOP; + + } // for step + + // Copy result to all processors + if (dest_proc == -1) { + vector*> tmpdata(CCTK_nProcs(cgh)); + vector > state; + + for (int proc=0; procmake_typed(-1); + tmpdata.at(proc)->allocate (alldata->extent(), proc, myhdata); + tmpdata.at(proc)->copy_from (state.at(proc), alldata, alldata->extent()); + } + } + + for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); + } + } + + for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); + delete tmpdata.at(proc); + } + } + + } // Copy result + + if (gp.grouptype==CCTK_GF && oldmap==-1) { + leave_singlemap_mode(const_cast(cgh)); + } + + delete alldata; + } + + + + void * + GetSlab (const cGH* const cgh, + const int dest_proc, + const int n, + const int ti, + const int hdim, + const int origin[/*vdim*/], + const int dirs[/*hdim*/], + const int stride[/*hdim*/], + const int length[/*hdim*/]) + { + // Check Cactus grid hierarchy + assert (cgh); + + // Check destination processor + assert (dest_proc>=-1 && dest_proc=0 && n=0); + const int n0 = CCTK_FirstVarIndexI(group); + assert (n0>=0); + const int var = n - n0; + assert (var>=0); + + // Get info about group + cGroup gp; + CCTK_GroupData (group, &gp); + assert (gp.dim<=dim); + assert (CCTK_QueryGroupStorageI(cgh, group)); + const int typesize = CCTK_VarTypeSize(gp.vartype); + assert (typesize>0); + + if (gp.grouptype==CCTK_GF && reflevel==-1) { + CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in global mode (use singlemap mode instead)"); + } + const int rl = gp.grouptype==CCTK_GF ? reflevel : 0; + + if (gp.grouptype==CCTK_GF && Carpet::map==-1) { + CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in level mode (use singlemap mode instead)"); + } + const int m = gp.grouptype==CCTK_GF ? Carpet::map : 0; + + // Check dimension + assert (hdim>=0 && hdim<=gp.dim); + + // Check timelevel + const int num_tl = gp.numtimelevels; + assert (ti>=0 && ti=0 && origin[d]<=sizes[d]); +// } + + // Check directions + for (int dd=0; dd=1 && dirs[dd]<=dim); + } + + // Check stride + for (int dd=0; dd0); + } + + // Check length + for (int dd=0; dd=0); + } + + // Check extent +// for (int dd=0; dd* myhh; + const dh* mydd; + const ggf* myff; + assert (group < (int)arrdata.size()); + myhh = arrdata.at(group).at(m).hh; + assert (myhh); + mydd = arrdata.at(group).at(m).dd; + assert (mydd); + assert (var < (int)arrdata.at(group).at(m).data.size()); + myff = arrdata.at(group).at(m).data.at(var); + assert (myff); + + // Detemine collecting processor + const int collect_proc = dest_proc<0 ? 0 : dest_proc; + + // Determine own rank + const int rank = CCTK_MyProc(cgh); + + // Calculate global size + int totalsize = 1; + for (int dd=0; dd* mydata; + mydata = (*myff)(tl, rl, 0, 0); + + // Stride of data in memory + const vect str = mydata->extent().stride(); + + // Stride of collected data + vect hstr = str; + for (int dd=0; dd hlb(0); + for (int d=0; d hub = hlb; + for (int dd=0; dd hextent (hlb, hub, hstr); + assert (hextent.size() == totalsize); + + // Create collector data object + void* myhdata = rank==collect_proc ? hdata : 0; + gdata* const alldata = mydata->make_typed(-1); + alldata->allocate (hextent, collect_proc, myhdata); + + // Done with the temporary stuff + mydata = 0; + + for (comm_state state; !state.done(); state.step()) { + + // Loop over all components, copying data from them + BEGIN_LOCAL_COMPONENT_LOOP (cgh, gp.grouptype) { + + // Get data object + mydata = (*myff)(tl, rl, component, mglevel); + + // Calculate overlapping extents + const bboxset myextents + = ((mydd->boxes.at(rl).at(component).at(mglevel).sync_not + | mydd->boxes.at(rl).at(component).at(mglevel).interior) + & hextent); + + // Loop over overlapping extents + for (bboxset::const_iterator ext_iter = myextents.begin(); + ext_iter != myextents.end(); + ++ext_iter) { + + // Copy data + alldata->copy_from (state, mydata, *ext_iter); + + } + + } END_LOCAL_COMPONENT_LOOP; + + } // for step + + // Copy result to all processors + if (dest_proc == -1) { + vector*> tmpdata(CCTK_nProcs(cgh)); + vector > state; + + for (int proc=0; procmake_typed(-1); + tmpdata.at(proc)->allocate (alldata->extent(), proc, myhdata); + tmpdata.at(proc)->copy_from (state.at(proc), alldata, alldata->extent()); + } + } + + for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); + } + } + + for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); + delete tmpdata.at(proc); + } + } + + } // Copy result + + delete alldata; + + // Success + return hdata; + } + + + + CCTK_INT + CarpetSlab_Get (CCTK_POINTER_TO_CONST const cctkGH_, + CCTK_INT const mapping_handle, + CCTK_INT const proc, + CCTK_INT const vindex, + CCTK_INT const timelevel, + CCTK_INT const hdatatype, + CCTK_POINTER const hdata) + { + cGH const * const cctkGH = (cGH const *) cctkGH_; + + // Check arguments + assert (cctkGH); + assert (mapping_handle>=0); + assert (proc==-1 || proc>=0 && proc=0 && vindex=0); + assert (hdatatype>=0); + assert (hdata); + + // Get mapping + const mapping * const mp = RetrieveMapping (mapping_handle); + assert (mp); + + // Calculate total size + size_t size = 1; + for (size_t d=0; d<(size_t)mp->hdim; ++d) { + size *= mp->length[d]; + } + + // Get type size + size_t const sz = CCTK_VarTypeSize (hdatatype); + assert (sz>0); + + // Forward call + FillSlab (cctkGH, proc, vindex, timelevel, + mp->hdim, + &mp->origin[0], &mp->dirs[0], &mp->stride[0], &mp->length[0], + hdata); + + return 0; + } + + + + CCTK_INT + CarpetSlab_GetList (CCTK_POINTER_TO_CONST const cctkGH_, + CCTK_INT const mapping_handle, + CCTK_INT const num_arrays, + CCTK_INT const * const procs, + CCTK_INT const * const vindices, + CCTK_INT const * const timelevels, + CCTK_INT const * const hdatatypes, + CCTK_POINTER const * const hdata, + CCTK_INT * const retvals) + { + cGH const * const cctkGH = (cGH const *) cctkGH_; + + // Check arguments + assert (cctkGH); + assert (mapping_handle>=0); + assert (num_arrays>=0); + assert (procs); + assert (vindices); + assert (timelevels); + assert (hdatatypes); + assert (hdata); + assert (retvals); + + // Remember whether there were errors + bool everyting_okay = true; + + // Loop over all slabs + for (int n=0; n=0 && vindex=0 && hdim<=dim); + assert (direction); + assert (origin); + assert (extent); + // assert (downsample); + // assert (table_handle>=0); + assert (hsize); + + // Get more information + int const vdim = CCTK_GroupDimFromVarI (vindex); + assert (vdim>=0 && vdim<=dim); + assert (hdim<=vdim); + + // Not implemented + assert (! conversion_fn); + + // Allocate memory + mapping * mp = new mapping; + + // Calculate more convenient representation of the direction + vector dirs(hdim); + for (int d=0; d downsample(hdim); + for (int dd=0; dd=0); + // Partial argument check + assert (origin[dirs[dd]-1]>=0); + assert (origin[dirs[dd]-1]<=totlen); + assert (downsample[dd]>0); + hsize[dd] = (totlen - origin[dirs[dd]-1]) / downsample[dd]; + } else { + hsize[dd] = extent[dd]; + } + assert (hsize[dd]>=0); + } + + // Store information + mp->vindex = vindex; + mp->hdim = hdim; + mp->origin.resize(vdim); + mp->dirs .resize(hdim); + mp->stride.resize(hdim); + mp->length.resize(hdim); + for (size_t d=0; d<(size_t)vdim; ++d) { + mp->origin[d] = origin[d]; + } + for (size_t d=0; d<(size_t)hdim; ++d) { + mp->dirs[d] = dirs[d]; + mp->stride[d] = downsample[d]; + mp->length[d] = hsize[d]; + } + + return StoreMapping (mp); + } + + + + CCTK_INT + CarpetSlab_FreeMapping (CCTK_INT const mapping_handle) + { + // Check arguments + assert (mapping_handle>=0); + + // Get mapping + mapping * mp = RetrieveMapping (mapping_handle); + assert (mp); + + // Delete storage + DeleteMapping (mapping_handle); + + delete mp; + + return 0; + } + + + + int + Hyperslab_GetHyperslab (const cGH* const GH, + const int target_proc, + const int vindex, + const int vtimelvl, + const int hdim, + const int global_startpoint [/*vdim*/], + const int directions [/*vdim*/], + const int lengths [/*hdim*/], + const int downsample_ [/*hdim*/], + void** const hdata, + int hsize [/*hdim*/]) + { + const int vdim = CCTK_GroupDimFromVarI(vindex); + assert (vdim>=1 && vdim<=dim); + + // Check some arguments + assert (hdim>=0 && hdim<=dim); + + // Check output arguments + assert (hdata); + assert (hsize); + + // Calculate more convenient representation of the direction + int dirs[dim]; // should really be dirs[hdim] + // The following if statement is written according to the + // definition of "dir". + if (hdim==1) { + // 1-dimensional hyperslab + int mydir = 0; + for (int d=0; d0); + for (int d=0; d0); + for (int d=0; d downsample(hdim); + for (int dd=0; dd=0); + // Partial argument check + assert (global_startpoint[dirs[dd]-1]>=0); + assert (global_startpoint[dirs[dd]-1]<=totlen); + downsample[dd] = downsample_ ? downsample_[dd] : 1; + assert (downsample[dd]>0); + hsize[dd] = (totlen - global_startpoint[dirs[dd]-1]) / downsample[dd]; + } else { + hsize[dd] = lengths[dd]; + } + assert (hsize[dd]>=0); + } + + // Get the slab + *hdata = GetSlab (GH, + target_proc, + vindex, + vtimelvl, + hdim, + global_startpoint, + dirs, + &downsample[0], + hsize); + + // Return with success + return 1; + } + + + +} // namespace CarpetSlab -- cgit v1.2.3