I have a routine that uses a loop to compute the minimum height of a particle given a surface of particles beneath. This routine tries random positions and compute the minimum height and then returns the x, y, z
values, where z
is the minimum height found.
This routine can be parallelized with omp parallel for
. But I am having problems figuring out how to get the triplet (x, y, z)
, not just the minimum z
(because the minimum z
of course corresponds to a given x, y
coordinates). I can actually get the smallest z
by using a reduction operation as follows
double x = 0, y = 0, z = 1.0e300; // initially z is large
#pragma omp parallel for reduction(min:z)
for(int trial = 0; trial < NTRIALS; ++trial) {
// long routine that, at the end, computes x, y, z
// and selects only the x, y, z corresponding to the
// smallest z
}
But I cannot get the corresponding x
and y
. At the end I just end up with a random x
and y
written by one of the threads.
Is it possible to get also those values? How? I was thinking on having an array where each thread stores their value of x, y, zmin
and then, after the reduction operation, compare each thread zmin
with the reduced global value and then get those that correspond to the choosing one. Is there a better way in the sense that OpenMP does it so I don't need to define this dynamic array and compare floats?
You can implement an argmin for multiple values using user defined reduction (available since OpenMP 4.0). For that you have to put the triple in one type. It is helpful to define a convenience function.
struct xyz {
double x; double y; double z;
}
struct xyz xyz_min2(struct xyz a, struct xyz b) {
return a.z < b.z ? a : b;
}
#pragma omp declare reduction(xyz_min: struct xyz: omp_out=xyz_min2(omp_out, omp_in))\
initializer(omp_priv={0, 0, DBL_MAX})
struct xyz value = {0, 0, DBL_MAX};
#pragma omp parallel for reduction(xyz_min:value)
for (int trial = 0; trial < NTRIALS; ++trial) {
struct xyz new_value = ...;
value = xyz_min2(value, new_value);
}
来源:https://stackoverflow.com/questions/52390526/openmp-argmin-reduction-for-multiple-values