OpenMP 在使用犰狳的代码中生成段错误

OpenMP generates segfault in a code that uses Armadillo

本文关键字:段错误 错误 代码 OpenMP      更新时间:2023-10-16

首先,我对OpenMP不是很熟悉。我想使用 OpenMP 减少我的 C++ 代码的执行时间,这涉及数百次矩阵对角化的迭代。我并没有试图平行每个对角线化(根据犰狳的文档,可以通过强迫犰狳使用 OpenBLAS 库来实现);相反,我想在 8 核机器上的线程之间分配负载。

访问内存似乎存在问题,因为我遇到"分段错误"。我想知道是我做得不对,还是问题是由于犰狳创建和操作矩阵的方式造成的。

这是一个最小的代码,它抓住了我一直遇到的问题的本质。这个想法是对角化,比如说,1000 个 100x100 矩阵,并将其特征值存储在一个文件中。

#include<iostream>
#include<armadillo>
#include <fstream>
#include<omp.h>         
int main()
{   
    std::ofstream  File;
    File.open("./RESULTS.dat");
    arma::mat M;   //THE MATRIX TO BE DIAGONALIZED
    arma::mat Eigenvecs;  //EIGENVECTORS
    arma::vec Eigenval;   //EIGENVALUES
    arma::mat RESULTS; //STORING EIGENVALUES TEMPORARILY 
    //DISTRIBUTING THE ITTERATIONS AMONG CORES USING OpenMP
    #pragma omp parallel shared(RESULTS) private(M,Eigenvecs,Eigenval)
    {
    #pragma omp parallel for ordered schedule(guided)
    for( int i = 0 ; i < 1000; i++ )
    {
        M = arma::randu<arma::mat>(200,200); //CREATING A RANDOM MATRIX
        M = 0.5*(M + M.t() );  //TO GUARANTEE THAT THE M IS NORMAL
        arma::eig_sym( Eigenval , Eigenvecs , M ); //DIAGONALIZING "M"
        RESULTS = arma::join_vert(RESULTS,Eigenval.t()); //CONCATENATING EIGENVALUES TO THE MATRIX "RESULTS" 
    }
    }
    File << RESULTS;  //WRITING "RESULTS" TO THE FILE
    File.close();
    return 0;
}

当我运行此代码时,似乎负载已正确分配(我使用 htop 来监视机器上的内核),但最后我得到"分段错误"。

我想

我想通了,尽管我不知道为什么这可以解决问题。以下是修改后的代码:

#include<iostream>
#include<ctime>
#include<armadillo>
#include <fstream>
#include<omp.h> 

int main()
{   
    std::ofstream  File;
    File.open("./RESULTS.dat");
    arma::mat M;
    arma::mat RESULTS;
    arma::mat Eigenvecs;
    arma::vec Eigenval;
    int i,tid=0;
    //DISTRIBUTING THE ITTERATIONS AMONG CORES USING OpenMP
    #pragma omp parallel for ordered schedule(guided) shared(RESULTS) private(M,Eigenvecs,Eigenval,tid)
    for(i = 0 ; i < 10; i++ )
    {
        tid = omp_get_thread_num();
        M = arma::randu<arma::mat>(400,400);
        M = 0.5*(M + M.t() );
        //std::cout << M << std::endl;
        arma::eig_sym( Eigenval , Eigenvecs , M );
        #pragma omp ordered
        RESULTS = arma::join_vert(RESULTS,Eigenval.t());
        std::cout << i << " , " << tid  << " --- " << Eigenval(0) << std::endl;
    }
    File << RESULTS;   
    File.close();
    return 0;
}