使用 OpenMP 进行的阵列缩减导致“未找到用户定义的缩减" [英] Array reduction with OpenMP leads to "user defined reduction not found for"

查看:53
本文介绍了使用 OpenMP 进行的阵列缩减导致“未找到用户定义的缩减"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一项学术工作,我必须从图像中获取直方图.

I'm doing a scholar work and I have to obtain the histogram from a IMAGE.

一切顺利,但是当我尝试使代码与 OpenMP 并行时,编译器返回此错误:找不到用于 'histog' 的用户定义的减少

All is going well, but when I tried to make the code parallel with the OpenMP, the compiler returns me this error: user defined reduction not found for 'histog'

我使用的代码是这样的:

The code that I used is this:

void HistogramaParaleloRed(int *histog)
{

    #pragma omp parallel
    {
        #pragma omp for
        for (int i = 0; i < NG; i++)
        {
            histog[i] = 0;
        }

        #pragma omp for reduction(+ : histog)
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                histog[IMAGEN[i][j]]++;
            }
        }
    }
}

而对Main中函数的调用是:HistogramaParaleloRed(histog_pal_red);

And the call to the function in Main is: HistogramaParaleloRed(histog_pal_red);

推荐答案

出现错误

user defined reduction not found for

因为代码是用不支持 OpenMP 4.5 阵列缩减功能或配置错误.

because either the code was compiled with a compiler that does not support the OpenMP 4.5 array reduction feature or it is misconfigured.

因此,您要么使用支持 OpenMP 4.5 的编译器,正确配置编译器,要么自己实现缩减.

So either you use a compiler that supports OpenMP 4.5, configure your compiler correctly, or alternatively, implement the reduction yourself.

手动实施归约

一种方法是在线程之间创建一个共享结构( thread_histog),然后每个线程更新自己的位置,然后线程减少共享的值结构到原始 histog 数组中.

One approach is to create a shared structure among threads (i.e., thread_histog), then each thread updates its position, and afterward, threads reduce the values of the shared structure into the original histog array.

void HistogramaParaleloRed(int *histog, int number_threads)
{
    int thread_histog[number_threads][NG] = {{0}};
    #pragma omp parallel
    {
        int thread_id = omp_get_thread_num();
        #pragma omp for 
        for (int i = 0; i < N; i++)
          for (int j = 0; j < N; j++)
                thread_histog[thread_id][IMAGEN[i][j]]++;

       #pragma omp for no_wait
       for (int i = 0; i < NG; i++)
           for(int j = 0; j < number_threads; j++)
              histog[i] += thread_histog[j][i]
    }
}

另一种方法是创建一个锁数组,histog 数组的每个元素一个.每当一个线程更新给定的 histog 位置时,首先获取与该位置对应的锁,以便没有其他线程同时更新相同的数组位置.

Another approach is to create an array of locks, one for each element of the histog array. Whenever a thread updates a given histog position, first acquires the lock corresponded to that position so that no other thread will be updating concurrently the same array position.

void HistogramaParaleloRed(int *histog)
{
    omp_lock_t locks[NG];
    #pragma omp parallel
    {
       #pragma omp for
       for (int i = 0; i < NG; i++)
            omp_init_lock(&locks[i]);

        int thread_id = omp_get_thread_num();
        #pragma omp for 
        for (int i = 0; i < N; i++)
          for (int j = 0; j < N; j++){
              int pos = IMAGEN[i][j]
              omp_set_lock(&locks[pos]);
              thread_histog[thread_id][pos]++; 
              omp_unset_lock(&locks[pos]);
          }

       #pragma omp for no_wait
       for (int i = 0; i < NG; i++)
            omp_destroy_lock(&locks[i]);
    }
}

这篇关于使用 OpenMP 进行的阵列缩减导致“未找到用户定义的缩减"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆