gpt4 book ai didi

c++ - Armadillo 的 eig_sym 中的线程安全问题

转载 作者:行者123 更新时间:2023-11-30 05:10:41 27 4
gpt4 key购买 nike

我对 Armadillo 中通过 eig_sym 的特征分解有疑问。当我尝试并行计算多组特征值和特征向量时,特征向量有时是

  • 不正交
  • 未规范化
  • 甚至不是相关矩阵的特征向量。

如果每次只运行一个计算,这个问题就会消失(所以这似乎是一些线程安全问题)。一旦两个计算并行运行,问题就会再次出现。奇怪的是,特征值似乎在每种情况下都是正确的。

//compile with: g++ -std=c++11 -pthread -larmadillo -o evecs armadillo_evecs.cpp
#include <iostream>
#include <armadillo>
#include <assert.h>
#include <future>
#include <vector>
using namespace std;

void testcalc() {
// set up random symmetric matrix
arma::mat r = arma::randu<arma::mat> (100, 100);
r = r.t() * r;

arma::vec eval;
arma::mat evec;
// calculate eigenvalues and -vectors
assert(arma::eig_sym(eval, evec, r));
arma::mat test = evec.t() * evec;

// Check whether eigenvectors are orthogonal, (i. e. matrix 'test' is diagonal)
assert(arma::norm(test - arma::diagmat(test)) < 1.0e-10);
}


int main() {
// start 100 eigenvalue (+vector) calculations
vector<future<void>> fus;
for (size_t i = 0; i < 100; i++) {
// try parallel evaluation ... fails sometimes
fus.push_back(async(launch::async, &testcalc));

// try sequential evaluation ... works fine
// future<void> f = async(launch::async, &testcalc);
// f.get(); // Wait until calculation has finished, before starting new one
}

// wait until calculations have finished
for(auto it = fus.begin(); it != fus.end(); it++) {
it->get();
}

return 0;
}

所以在断言上面的代码中

assert(arma::norm(test - arma::diagmat(test)) < 1.0e-10);

有时会失败。这可能是底层库的问题(我读到 lapack 有一些线程安全问题)?我真的不知道,从哪里开始寻找。

最佳答案

与其“滚动你自己的并行化”,不如使用底层库已经提供的并行化更容易和更安全。

因此,不要使用引用 BLAS 和 LAPACK,而是使用像 OpenBLAS 这样的多线程版本或 Intel MKL .见 Armadillo FAQ了解更多详情。

关于c++ - Armadillo 的 eig_sym 中的线程安全问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45549843/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com