问题
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
}
}
I am getting this error:
[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’
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?
回答1:
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;
}
}
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
}
}
来源:https://stackoverflow.com/questions/44993310/c-armadillo-and-openmp-parallelization-of-summation-of-outer-products-defin