Сокращение OMP с массивом Eigen выполняется в G CC, но не в Clang - PullRequest
0 голосов
/ 15 января 2020

Я использую 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.

...