aboutsummaryrefslogtreecommitdiff
path: root/src/GetHyperslab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/GetHyperslab.c')
-rw-r--r--src/GetHyperslab.c198
1 files changed, 164 insertions, 34 deletions
diff --git a/src/GetHyperslab.c b/src/GetHyperslab.c
index b6e0af0..b1206e2 100644
--- a/src/GetHyperslab.c
+++ b/src/GetHyperslab.c
@@ -39,19 +39,12 @@ static int GetLocalHyperslab (const cGH *GH,
int timelevel,
int hdatatype,
void *hdata);
-/********************************************************************
- ******************** External Routines ************************
- ********************************************************************/
-/* Gerd's routine to get 1D lines from a 3D array */
-int Hyperslab_CollectData1D (const cGH *GH, int vindex, int vtimelvl,
- const int *origin,
- const int *directions,
- int downsampling,
- int length,
- void **hdata,
- int *hsize,
- int proc);
-
+static int GetDiagonalFromFrom3D (const cGH *GH,
+ const hslab_mapping_t *mapping,
+ int vindex,
+ int timelevel,
+ int hdatatype,
+ void *hdata);
CCTK_INT Hyperslab_Get (const cGH *GH,
@@ -274,27 +267,11 @@ static int GetLocalHyperslab (const cGH *GH,
return (0);
}
- /* FIXME: hack for getting diagonals from 3D variables
- This is calling Gerd's CollectData1D() routine which can
- extract non-axis-parallel lines too but is fixed to 3D data. */
+ /* diagonals from 3D variables are treated special */
if (mapping->is_diagonal_in_3D)
{
- const int origin[] = {0, 0, 0};
- const int directions[] = {1, 1, 1};
- int dummy_hsize;
- void *dummy_hdata;
-
-
- retval = Hyperslab_CollectData1D (GH, vindex, timelevel, origin, directions,
- 1, -1, &dummy_hdata, &dummy_hsize,
- mapping->target_proc);
- if (! retval)
- {
- memcpy (hdata, dummy_hdata,
- mapping->totals * CCTK_VarTypeSize (vinfo.vartype));
- free (dummy_hdata);
- }
-
+ retval = GetDiagonalFromFrom3D (GH, mapping, vindex, timelevel, hdatatype,
+ hdata);
return (retval);
}
@@ -427,7 +404,7 @@ static int GetLocalHyperslab (const cGH *GH,
/* get the byte pointer into the source array */
typed_vdata = (const char *) vdata + point[0];
-#if 1
+#if 0
fprintf (stderr, "***** base vdata %p offset %d '%s'\n", vdata, point[0], CCTK_FullName (vindex));
#endif
for (i = 1; i < vinfo.dim; i++)
@@ -445,7 +422,7 @@ fprintf (stderr, "***** base vdata %p offset %d '%s'\n", vdata, point[0], CCTK_F
}
else
{
-#if 1
+#if 0
fprintf (stderr, "***** copying %d bytes from %p tp %p\n", dim0_hsize, typed_vdata, typed_hdata);
#endif
memcpy (typed_hdata, typed_vdata, dim0_hsize);
@@ -489,3 +466,156 @@ fprintf (stderr, "***** copying %d bytes from %p tp %p\n", dim0_hsize, typed_vda
return (0);
}
+
+
+static int GetDiagonalFromFrom3D (const cGH *GH,
+ const hslab_mapping_t *mapping,
+ int vindex,
+ int timelevel,
+ int hdatatype,
+ void *hdata)
+{
+ int i, j, k, myproc, nprocs, linear_idx;
+ CCTK_INT local_npoints, npoints;
+ int vdatatype, htypesize, vtypesize;
+ const char *vdata;
+ char *local_hdata;
+ const pGH *pughGH;
+ const pGExtras *extras;
+#ifdef CCTK_MPI
+ CCTK_INT *global_npoints;
+ int *recvcnts, *displs;
+ MPI_Datatype mpidatatype;
+#endif
+
+
+
+ /* get the pGH pointer and the variable's GA structure */
+ pughGH = PUGH_pGH (GH);
+ extras = ((const pGA *) pughGH->variables[vindex][timelevel])->extras;
+
+ vdatatype = CCTK_VarTypeI (vindex);
+ if (hdatatype < 0)
+ {
+ hdatatype = vdatatype;
+ }
+ htypesize = CCTK_VarTypeSize (hdatatype);
+ vtypesize = CCTK_VarTypeSize (vdatatype);
+ vdata = (const char *) CCTK_VarDataPtrI (GH, timelevel, vindex);
+
+ myproc = CCTK_MyProc (GH);
+ nprocs = CCTK_nProcs (GH);
+ if (nprocs == 1)
+ {
+ local_hdata = (char *) hdata;
+ }
+ else
+ {
+ local_hdata = (char *) malloc (mapping->global_hsize[0] * htypesize);
+ }
+
+ i = mapping->global_startpoint[0] - extras->lb[myproc][0];
+ j = mapping->global_startpoint[1] - extras->lb[myproc][1];
+ k = mapping->global_startpoint[2] - extras->lb[myproc][2];
+ local_npoints = 0;
+ for (npoints = 0; npoints < mapping->global_hsize[0]; npoints++)
+ {
+ if (i >= extras->ownership[0][0][0] && i < extras->ownership[0][1][0] &&
+ j >= extras->ownership[0][0][1] && j < extras->ownership[0][1][1] &&
+ k >= extras->ownership[0][0][2] && k < extras->ownership[0][1][2])
+ {
+ linear_idx = i + j*extras->hyper_volume[1] + k*extras->hyper_volume[2];
+ if (vdatatype != hdatatype)
+ {
+ mapping->conversion_fn (vdata + linear_idx*vtypesize, local_hdata,
+ 1, 1, 1);
+ }
+ else
+ {
+ memcpy (local_hdata, vdata + linear_idx*vtypesize, htypesize);
+ }
+ local_hdata += htypesize;
+ local_npoints++;
+ }
+ i += mapping->downsample[0];
+ j += mapping->downsample[1];
+ k += mapping->downsample[2];
+ }
+ local_hdata -= local_npoints * htypesize;
+
+#ifdef CCTK_MPI
+ if (nprocs > 1)
+ {
+ /* allocate communication buffers */
+ myproc = CCTK_MyProc (GH);
+ if (mapping->target_proc < 0 || mapping->target_proc == myproc)
+ {
+ global_npoints = (CCTK_INT *) malloc (nprocs * sizeof (CCTK_INT));
+ recvcnts = (int *) malloc (2 * nprocs * sizeof (int));
+ displs = recvcnts + nprocs;
+ }
+ else
+ {
+ global_npoints = NULL; recvcnts = displs = NULL; hdata = NULL;
+ }
+
+ /* gather the number of local points on each processor */
+ if (mapping->target_proc < 0)
+ {
+ CACTUS_MPI_ERROR (MPI_Allgather (&local_npoints, 1, PUGH_MPI_INT,
+ global_npoints, 1, PUGH_MPI_INT,
+ pughGH->PUGH_COMM_WORLD));
+ }
+ else
+ {
+ CACTUS_MPI_ERROR (MPI_Gather (&local_npoints, 1, PUGH_MPI_INT,
+ global_npoints, 1, PUGH_MPI_INT,
+ mapping->target_proc,
+ pughGH->PUGH_COMM_WORLD));
+ }
+
+ /* compute the receive count and displacement vectors */
+ if (mapping->target_proc < 0 || mapping->target_proc == myproc)
+ {
+ for (i = 0; i < nprocs; i++)
+ {
+ recvcnts[i] = (int) global_npoints[i];
+ displs[i] = i == 0 ? 0 : displs[i-1] + recvcnts[i-1];
+ }
+ }
+
+ /* get the MPI datatype for the hyperslab data */
+ mpidatatype = PUGH_MPIDataType (pughGH, hdatatype);
+
+ /* gather the local hyperslab data from each processor */
+ if (mapping->target_proc < 0)
+ {
+ CACTUS_MPI_ERROR (MPI_Allgatherv (local_hdata, local_npoints,
+ mpidatatype, hdata, recvcnts, displs,
+ mpidatatype, pughGH->PUGH_COMM_WORLD));
+ }
+ else
+ {
+ CACTUS_MPI_ERROR (MPI_Gatherv (local_hdata, local_npoints,
+ mpidatatype, hdata, recvcnts, displs,
+ mpidatatype, mapping->target_proc,
+ pughGH->PUGH_COMM_WORLD));
+ }
+
+ /* free communication buffers */
+ if (mapping->target_proc < 0 || mapping->target_proc == myproc)
+ {
+ free (global_npoints);
+ free (recvcnts);
+ }
+ }
+#endif /* CCTK_MPI */
+
+ /* free allocated resources */
+ if (nprocs > 1)
+ {
+ free (local_hdata);
+ }
+
+ return (0);
+}