Я использую OpenMP для распараллеливания всех oop суммирования собственных массивов. Компиляция кода с помощью G CC и Clang работает, но Clang выдает мне SIGSEGV
с ошибкой:
double free or corruption (!prev)
Segmentation fault (core dumped)
при запуске.
Я использую Ubuntu 19.10 с версией Clang 9.0.0-2 и G CC 9.2.1.
Я извлек минимальный пример:
#include <cmath>
#include <iostream>
#define EIGEN_DONT_PARALLELIZE
#include <Eigen/Dense>
const int rows = 3;
const int cols = 4;
Eigen::ArrayXXd get_array() {
return Eigen::MatrixXd::Identity(rows, cols).array();
}
struct Result {
Result() : data(Eigen::ArrayXXd::Zero(rows, cols)) {}
Eigen::ArrayXXd data;
};
void f1() {
Result result;
Eigen::ArrayXXd temp(result.data);
#pragma omp parallel for
for(int n=0; n<10; ++n){
temp += get_array();
}
result.data += temp;
std::cout << result.data << std::endl;
}
void f2() {
Result result;
#pragma omp parallel
{
Eigen::ArrayXXd temp = Eigen::ArrayXXd::Zero(rows, cols);
#pragma omp for nowait
for(int n=0; n<10; ++n){
temp += get_array();
}
#pragma omp critical
{
result.data += temp;
}
}
std::cout << result.data << std::endl;
}
void f3() {
Result result;
Eigen::ArrayXXd temp(result.data);
#pragma omp declare reduction(+:Eigen::ArrayXXd:omp_out+=omp_in) \
initializer(omp_priv=Eigen::ArrayXXd::Zero(omp_orig.rows(), omp_orig.cols()))
#pragma omp parallel for reduction(+:temp)
for(int n=0; n<10; ++n){
temp += get_array();
}
result.data += temp;
std::cout << result.data << std::endl;
}
int main() {
std::cout << "f1 works, but is not safe\n";
f1();
std::cout << "f2 works and should be safe, different structure\n";
f2();
std::cout << "f3 does not work in Clang, works in GCC\n";
f3();
}
Выход (с G CC) равен
f1 works, but is not safe
10 0 0 0
0 10 0 0
0 0 10 0
f2 works and should be safe, different structure
10 0 0 0
0 10 0 0
0 0 10 0
f3 does not work in Clang, works in GCC
10 0 0 0
0 10 0 0
0 0 10 0
, как я и ожидал, суммируя 10 матриц. Clang segfaults в функции f3
, которая использует сокращение для суммирования массивов. Мне интересно, почему он не работает в Clang.