Skip to content

Commit 692b5e2

Browse files
authored
Fix issue #100: get_val with HAVE_MPI (#112)
* Make get_val(...) work under HAVE_MPI * Exclude vscode-specific setting files from git * Move mpi_allreduce_1 calls from get_val to interp_val
1 parent 4c81a44 commit 692b5e2

2 files changed

Lines changed: 34 additions & 11 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ mpb/mpbi_mpi
6767
src/mpbi_mpi.h
6868
mpb/mu.c
6969

70+
# local editor settings
71+
.vscode
72+
7073
# test output:
7174
check-epsilon.h5
7275
check-mu.h5

mpb/fields.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,10 @@ void fix_field_phase(void)
547547
/* Functions to return epsilon, fields, energies, etcetera, at a specified
548548
point, linearly interpolating if necessary. */
549549

550+
/* get_val returns process-specific output for HAVE_MPI: if the "point" (ix, iy, iz; stride)
551+
is on the local process, the value of data at that point is returned returned; otherwise
552+
(i.e. point is not on local process) 0.0 is returned: calls to get_val should therefore
553+
be followed by sum-reduction via mpi_allreduce_1(..) in the caller (as in interp_val) */
550554
static real get_val(int ix, int iy, int iz,
551555
int nx, int ny, int nz, int last_dim_size,
552556
real *data, int stride, int conjugate)
@@ -569,20 +573,33 @@ static real get_val(int ix, int iy, int iz,
569573
#endif
570574

571575
#ifdef HAVE_MPI
572-
CHECK(0, "get-*-point not yet implemented for MPI!");
573-
#else
574-
if (conjugate)
575-
return -data[(((ix * ny) + iy) * nz + iz) * stride];
576-
else
577-
return data[(((ix * ny) + iy) * nz + iz) * stride];
576+
/* due to real-space xy=>yx transposition in MPI configuration, we need to
577+
do a little extra work here; see details e.g. in XYZ_LOOP macro */
578+
int local_ny = mdata->local_ny; /* dim of local process over y-indices */
579+
int local_y_start = mdata->local_y_start;
580+
int local_iy = iy - local_y_start;
581+
real val = 0; /* reduce local processes over this variable later */
582+
583+
/* check if local_iy is in the current process' data block */
584+
if (local_iy >= 0 && local_iy < local_ny) {
585+
val = data[(((local_iy * nx) + ix) * nz + iz) * stride]; /* note transposition in x and y indices */
586+
}
587+
588+
#else /* no MPI */
589+
real val = data[(((ix * ny) + iy) * nz + iz) * stride];
578590
#endif
591+
592+
if (conjugate)
593+
return -val;
594+
else
595+
return val;
579596
}
580597

581598
static real interp_val(vector3 p, int nx, int ny, int nz, int last_dim_size,
582599
real *data, int stride, int conjugate)
583600
{
584601
double ipart;
585-
real rx, ry, rz, dx, dy, dz;
602+
real rx, ry, rz, dx, dy, dz, v;
586603
int x, y, z, x2, y2, z2;
587604

588605
rx = modf(p.x/geometry_lattice.size.x + 0.5, &ipart); if (rx < 0) rx += 1;
@@ -611,10 +628,13 @@ static real interp_val(vector3 p, int nx, int ny, int nz, int last_dim_size,
611628

612629
#define D(x,y,z) (get_val(x,y,z,nx,ny,nz,last_dim_size, data,stride,conjugate))
613630

614-
return(((D(x,y,z)*(1.0-dx) + D(x2,y,z)*dx) * (1.0-dy) +
615-
(D(x,y2,z)*(1.0-dx) + D(x2,y2,z)*dx) * dy) * (1.0-dz) +
616-
((D(x,y,z2)*(1.0-dx) + D(x2,y,z2)*dx) * (1.0-dy) +
617-
(D(x,y2,z2)*(1.0-dx) + D(x2,y2,z2)*dx) * dy) * dz);
631+
v = (((D(x,y,z) * (1.0-dx) + D(x2,y,z) * dx) * (1.0-dy) +
632+
(D(x,y2,z) * (1.0-dx) + D(x2,y2,z) * dx) * dy ) * (1.0-dz) +
633+
((D(x,y,z2) * (1.0-dx) + D(x2,y,z2) * dx) * (1.0-dy) +
634+
(D(x,y2,z2) * (1.0-dx) + D(x2,y2,z2) * dx) * dy ) * dz);
635+
636+
mpi_allreduce_1(&v, real, SCALAR_MPI_TYPE, MPI_SUM, mpb_comm);
637+
return v;
618638

619639
#undef D
620640
}

0 commit comments

Comments
 (0)