aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortradke <tradke@10716dce-81a3-4424-a2c8-48026a0d3035>2000-11-23 09:28:15 +0000
committertradke <tradke@10716dce-81a3-4424-a2c8-48026a0d3035>2000-11-23 09:28:15 +0000
commite05d659b4d6dbbab4a201e37d5cb634c1322e5e7 (patch)
tree252db94e48109148a7f86567de29084bbb4752d6
parent6e18d9894709ffedb3f15e5054678a273ca65f92 (diff)
Optimized hyperslab extraction for downsampled cases.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGH/PUGHSlab/trunk@38 10716dce-81a3-4424-a2c8-48026a0d3035
-rw-r--r--src/Hyperslab.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/Hyperslab.c b/src/Hyperslab.c
index b9fd31e..dba8d8a 100644
--- a/src/Hyperslab.c
+++ b/src/Hyperslab.c
@@ -38,7 +38,7 @@
#define PICKUP_HYPERSLAB_DATA(cctk_type, vdim, vdata, hdata, point, \
startpoint, endpoint, downsample,points_per_dim)\
{ \
- int i, dim, vindex; \
+ int i, dim, vindex, dim0_elements; \
cctk_type *typed_vdata = (cctk_type *) vdata; \
cctk_type *typed_hdata = (cctk_type *) hdata; \
\
@@ -46,12 +46,14 @@
/* set point to local startpoint */ \
memcpy (point, startpoint, vdim * sizeof (point[0])); \
\
+ dim0_elements = endpoint[0] - startpoint[0]; \
+ \
/* do the nested loops starting with the innermost */ \
- dim = 0; \
+ dim = 1; \
while (1) \
{ \
/* check for end of current loop */ \
- if (point[dim] >= endpoint[dim]) \
+ if (vdim > 1 && point[dim] >= endpoint[dim]) \
{ \
/* increment outermost loopers */ \
for (dim++; dim < vdim; dim++) \
@@ -70,23 +72,47 @@
} \
\
/* reset innermost loopers */ \
- for (dim--; dim >= 0; dim--) \
+ for (dim--; dim > 0; dim--) \
{ \
point[dim] = startpoint[dim]; \
} \
- dim = 0; \
+ dim = 1; \
} \
\
- /* copy the data point */ \
+ /* get the linear offset */ \
vindex = point[0]; \
for (i = 1; i < vdim; i++) \
{ \
vindex += point[i] * points_per_dim[i]; \
} \
- *typed_hdata++ = typed_vdata[vindex]; \
\
- /* increment current looper */ \
- point[dim] += downsample[dim]; \
+ /* copy the data in lowest dimension */ \
+ /* if possible (no downsampling was requested) use plain memcpy() \
+ otherwise copy element-wise in a loop */ \
+ if (downsample[0] == 1) \
+ { \
+ memcpy (typed_hdata, typed_vdata, \
+ dim0_elements * sizeof (*typed_hdata)); \
+ typed_hdata += dim0_elements; \
+ } \
+ else \
+ { \
+ for (i = 0; i < dim0_elements; i += downsample[0]) \
+ { \
+ *typed_hdata++ = typed_vdata[vindex + i]; \
+ } \
+ } \
+ \
+ if (vdim > 1) \
+ { \
+ /* increment current looper */ \
+ point[dim] += downsample[dim]; \
+ } \
+ else \
+ { \
+ /* exit loop if hyperslab dim is only 1D */ \
+ break; \
+ } \
\
} /* end of nested loops over all dimensions */ \
}
@@ -451,7 +477,7 @@ int Hyperslab_GetLocalHyperslab (cGH *GH, int vindex, int vtimelvl,
for (vdim = 1; vdim < vinfo.dim; vdim++)
{
points_per_dim[vdim] = points_per_dim[vdim-1] *
- GA->extras->lnsize[vdim-1];
+ GA->extras->lnsize[vdim-1];
}
/* now get the hyperslab data points using that wonderful macro... */