0
我有一个问题,通过eig_sym犰狳中的本征分解。当我试图计算出多组特征向量的并行,不时的特征向量是犰狳的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有一些线程安全问题)?我真的不知道,从哪里开始寻找。
另外,您应该记住像LAPACK这样的库并不是在考虑并行计算的情况下开发的。一些例程从上次调用它们的状态时开始跟踪它们的状态,当由不同的线程访问时导致问题。 – Hannebambel
感谢您的建议。我现在正在使用OpenBLAS。它确实更安全,也更快。 – okruz