C ++ Armadillo和OpenMp:并行累加外部乘积-定义Armadillo矩阵的约简 [英] C++ Armadillo and OpenMp: Parallelization of summation of outer products - define reduction for Armadillo matrix

查看:366
本文介绍了C ++ Armadillo和OpenMp:并行累加外部乘积-定义Armadillo矩阵的约简的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OpenMP并行化for循环,该循环求和Armadillo矩阵.我有以下代码:

I am trying to parallelize a for loop using OpenMP which sums over Armadillo matrices. I have the following code:

#include <armadillo>
#include <omp.h>

int main()
{

        arma::mat A = arma::randu<arma::mat>(1000,700);
        arma::mat X = arma::zeros(700,700);
        arma::rowvec point = A.row(0);

        # pragma omp parallel for shared(A) reduction(+:X)
        for(unsigned int i = 0; i < A.n_rows; i++){
                arma::rowvec diff = point - A.row(i);
                X += diff.t() * diff; // Adding the matrices to X here
        }

}

我收到此错误:

[Legendre@localhost ~]$ g++ test2.cpp -o test2 -O2 -larmadillo -fopenmp
test2.cpp: In function ‘int main()’:
test2.cpp:11:52: error: user defined reduction not found for ‘X’

我阅读了定义归约的内容,但是还没有找到处理Armadillo矩阵的示例.在我的案例中,定义Armadillo矩阵约简的最佳方法是什么?

I read up on defining reductions, but I haven't found examples for working with Armadillo matrices. What is the best way to define a reduction for Armadillo matrices in my case?

推荐答案

这些缩减仅适用于内置类型(doubleint等).因此,您必须自己进行还原,这很简单.只需将每个线程的结果累加到线程局部变量中,然后将其添加到关键部分的全局结果中即可.

Those reductions are only available for built-in types (double, int, etc.). Thus you have to do the reduction yourself, which is simple. Just accumulate the results for each thread in a thread-local variable and add this to the global result within a critical section.

#include <armadillo>
#include <omp.h>

int main()
{

  arma::mat A = arma::randu<arma::mat>(1000,700);
  arma::mat X = arma::zeros(700,700);
  arma::rowvec point = A.row(0);

  #pragma omp parallel shared(A)
  {
    arma::mat X_local = arma::zeros(700,700);

    #pragma omp for
    for(unsigned int i = 0; i < A.n_rows; i++)
    {
      arma::rowvec diff = point - A.row(i);
      X_local += diff.t() * diff; // Adding the matrices to X here
    }

    #pragma omp critical
    X += X_local;
  }
}

使用最新的OpenMP(我认为是4.5),您还可以为您的类型声明用户定义的归约形式.

With more recent OpenMP (4.5 I think?) you can also declare a user-defined reduction for your type.

#include <armadillo>
#include <omp.h>

#pragma omp declare reduction( + : arma::mat : omp_out += omp_in ) \
  initializer( omp_priv = omp_orig )

int main()
{

  arma::mat A = arma::randu<arma::mat>(1000,700);
  arma::mat X = arma::zeros(700,700);
  arma::rowvec point = A.row(0);

  #pragma omp parallel shared(A) reduction(+:X)
  for(unsigned int i = 0; i < A.n_rows; i++)
  {
    arma::rowvec diff = point - A.row(i);
    X += diff.t() * diff; // Adding the matrices to X here
  }
}

这篇关于C ++ Armadillo和OpenMp:并行累加外部乘积-定义Armadillo矩阵的约简的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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