Я хочу использовать собственные матрицы в сочетании с сокращением OpenMP.
Ниже приведен небольшой пример того, как я это делаю (и это работает).Объект myclass
имеет три атрибута (собственная матрица, два целых числа, соответствующих его размеру) и функцию-член do_something
, которая использует уменьшение omp на сумму, которую я определяю, потому что собственные матрицы не являются стандартными типами.
#include "Eigen/Core"
class myclass {
public:
Eigen::MatrixXd m_mat;
int m_n; // number of rows in m_mat
int m_p; // number of cols in m_mat
myclass(int n, int p); // constructor
void do_something(); // omp reduction on `m_mat`
}
myclass::myclass(int n, int p) {
m_n = n;
m_p = p;
m_mat = Eigen::MatrixXd::Zero(m_n,m_p); // init m_mat with null values
}
#pragma omp declare reduction (+: Eigen::MatrixXd: omp_out=omp_out+omp_in)\
initializer(omp_priv=MatrixXd::Zero(omp_orig.rows(), omp_orig.cols()))
void myclass::do_something() {
Eigen::MatrixXd tmp = Eigen::MatrixXd::Zero(m_n, m_p); // temporary matrix
#pragma omp parallel for reduction(+:tmp)
for(int i=0; i<m_n;i++) {
for(int l=0; l<m_n; l++) {
for(int j=0; j<m_p; j++) {
tmp(l,j) += 10;
}
}
}
m_mat = tmp;
}
Проблема: OpenMP не позволяет (или, по крайней мере, не всем реализациям) использовать сокращение для членов класса, но только для переменных.Таким образом, я делаю сокращение для временной матрицы, и у меня есть эта копия в конце m_mat = tmp
, которую я хотел бы избежать (поскольку m_mat
может быть большой матрицей, и я часто использую это сокращение в своем коде).
Неправильное исправление: Я пытался использовать Eigen Map так, чтобы tmp
соответствовал данным, хранящимся в m_mat
.Таким образом, я заменил объявление сокращения omp и определение функции-члена do_something
в предыдущем коде на:
#pragma omp declare reduction (+: Eigen::Map<Eigen::MatrixXd>: omp_out=omp_out+omp_in)\
initializer(omp_priv=MatrixXd::Zero(omp_orig.rows(), omp_orig.cols()))
void myclass::do_something() {
Eigen::Map<Eigen::MatrixXd> tmp = Eigen::Map<Eigen::MatrixXd>(m_mat.data(), m_n, m_p);
#pragma omp parallel for reduction(+:tmp)
for(int i=0; i<m_n;i++) {
for(int l=0; l<m_n; l++) {
for(int j=0; j<m_p; j++) {
tmp(l,j) += 10;
}
}
}
}
Однако оно больше не работает, и я получаю следующую ошибку при компиляции:
ошибка: преобразование из 'const ConstantReturnType {aka const Eigen :: CwiseNullaryOp, Eigen :: Matrix>}' в нескалярный тип 'Eigen :: Map, 0, Eigen :: Stride <0, 0>> 'запрошенный инициализатор (omp_priv = Eigen :: MatrixXd :: Zero (omp_orig.rows (), omp_orig.cols ()))
Я получаю, что неявное преобразование из Eigen::MatrixXd
в Eigen::Map<Eigen::MatrixXd>
не работает в уменьшении omp, но я не знаю, как заставить это работать.
Заранее спасибо
Редактировать 1: Я забыл упомянуть, что яиспользуйте gcc v5.4 на машине с Ubuntu (пробовал и 16.04, и 18.04)
Edit 2: Я изменил свой пример, так как в первом не было никакого сокращения.Этот пример не совсем то, что я делаю в своем коде, это просто минимальный «тупой» пример.