【问题标题】:OpenMP argmin reduction for multiple values多个值的 OpenMP argmin 减少
【发布时间】:2018-09-18 16:00:26
【问题描述】:

我有一个例程,它使用循环来计算给定下方粒子表面的粒子的最小高度。该例程尝试随机位置并计算最小高度,然后返回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 做到这一点,所以我不需要定义这个动态数组并比较浮点数?

【问题讨论】:

  • 您的 OpenMP 一致性等级是多少?我认为,如果您有 OpenMP 4.0 或更高版本,您可以编写自定义缩减。 (显然,您需要将 xyz 组合成一个结构以传递给归约)。
  • 关于 argmin 有一些较旧的问题,但鉴于这三个值和过时的答案,我不会以重复的方式结束。 stackoverflow.com/questions/24782038/…stackoverflow.com/questions/20618258/…

标签: c openmp


【解决方案1】:

您可以使用用户定义的归约(自 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);
}

【讨论】:

  • 优秀。这就是我一直在寻找的。我不知道 omp 声明减少。我只需要修复并行,因为它应该读取减少(xyz_min:值)。另外,由于某种原因,我不得不使用 omp_priv={0, 0, DBL_MAX} (只有一个大括号)。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多