OpenMP argmin减少多个值

时间:2018-09-18 16:00:27

标签: c openmp

我有一个例程,该例程使用循环来计算给定下方的粒子表面的粒子的最小高度。此例程尝试随机位置并计算最小高度,然后返回x, y, z值,其中z是找到的最小高度。

此例程可以与omp parallel for并行化。但是我在弄清楚如何获取三元组(x, y, z)而不仅仅是最小的z时遇到了问题(因为最小的z当然对应于给定的x, y坐标)。实际上,我可以通过如下所示的归约运算来获得最小的z

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
}

但是我无法获得相应的xy。最后,我只是以其中一个线程编写的随机xy结尾。

是否也可以获取这些值?怎么样?我在考虑使用一个数组,其中每个线程存储其值x, y, zmin,然后在归约操作之后,将每个线程zmin与已归约的全局值进行比较,然后获得与选择的线程对应的值。从某种意义上说,OpenMP是否有更好的方法,所以我不需要定义此动态数组并比较浮点数?

1 个答案:

答案 0 :(得分:5)


您可以使用用户定义的归约(自OpenMP 4.0起可用)为多个值实现 argmin 。为此,您必须将三元组放在一种类型中。定义便利功能会很有帮助。

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);
}