OpenMP argmin reduction for multiple values

删除回忆录丶 提交于 2019-12-07 18:45:11

问题


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?


回答1:



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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!