是犰狳解决()线程安全吗?

在我的代码中,我有一个循环,在其中我构build和确定的线性系统,并试图解决它:

#pragma omp parallel for for (int i = 0; i < n[0]+1; i++) { for (int j = 0; j < n[1]+1; j++) { for (int k = 0; k < n[2]+1; k++) { arma::mat A(max_points, 2); arma::mat y(max_points, 1); // initialize A and y arma::vec solution = solve(A,y); } } } 

有时候,程序会非常随机地挂起来,或者解决scheme向量中的结果是NaN。 如果我这样做:

 arma::vec solution; #pragma omp critical { solution = solve(weights*A,weights*y); } 

那么这些问题似乎不再发生了。

当它挂起时,它会这样做,因为一些线程正在OpenMP障碍处等待:

 Thread 2 (Thread 0x7fe4325a5700 (LWP 39839)): #0 0x00007fe44d3c2084 in gomp_team_barrier_wait_end () from /usr/lib64/gcc-4.9.2/lib64/gcc/x86_64-redhat-linux-gnu/4.9.2/libgomp.so.1 #1 0x00007fe44d3bf8c2 in gomp_thread_start () at ../.././libgomp/team.c:118 #2 0x0000003f64607851 in start_thread () from /lib64/libpthread.so.0 #3 0x0000003f642e890d in clone () from /lib64/libc.so.6 

其他的线程都卡在犰狳里面:

 Thread 1 (Thread 0x7fe44afe2e60 (LWP 39800)): #0 0x0000003ee541f748 in dscal_ () from /usr/lib64/libblas.so.3 #1 0x00007fe44c0d3666 in dlarfp_ () from /usr/lib64/atlas/liblapack.so.3 #2 0x00007fe44c058736 in dgelq2_ () from /usr/lib64/atlas/liblapack.so.3 #3 0x00007fe44c058ad9 in dgelqf_ () from /usr/lib64/atlas/liblapack.so.3 #4 0x00007fe44c059a32 in dgels_ () from /usr/lib64/atlas/liblapack.so.3 #5 0x00007fe44f09fb3d in bool arma::auxlib::solve_ud<double, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times> >(arma::Mat<double>&, arma::Mat<double>&, arma::Base<double, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times> > const&) () at /usr/include/armadillo_bits/lapack_wrapper.hpp:677 #6 0x00007fe44f0a0f87 in arma::Col<double>::Col<arma::Glue<arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times>, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times>, arma::glue_solve> >(arma::Base<double, arma::Glue<arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times>, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times>, arma::glue_solve> > const&) () at /usr/include/armadillo_bits/glue_solve_meat.hpp:39 

从堆栈跟踪中可以看到,我的版本的Armadillo使用了图集。 而根据这个文档,地图集似乎是线程安全的: ftp : //lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

更新9/11/2015

根据弗拉基米尔·F的build议,我终于有一些时间来运行更多的testing。

当我用ATLAS的BLAS编译犰狳时,我仍然能够重现然后挂起和NaNs。 当它挂起时,堆栈跟踪中唯一改变的是对BLAS的调用:

 #0 0x0000003fa8054718 in ATL_dscal_xp1yp0aXbX@plt () from /usr/lib64/atlas/libatlas.so.3 #1 0x0000003fb05e7666 in dlarfp_ () from /usr/lib64/atlas/liblapack.so.3 #2 0x0000003fb0576a61 in dgeqr2_ () from /usr/lib64/atlas/liblapack.so.3 #3 0x0000003fb0576e06 in dgeqrf_ () from /usr/lib64/atlas/liblapack.so.3 #4 0x0000003fb056d7d1 in dgels_ () from /usr/lib64/atlas/liblapack.so.3 #5 0x00007ff8f3de4c34 in void arma::lapack::gels<double>(char*, int*, int*, int*, double*, int*, double*, int*, double*, int*, int*) () at /usr/include/armadillo_bits/lapack_wrapper.hpp:677 #6 0x00007ff8f3de1787 in bool arma::auxlib::solve_od<double, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times> >(arma::Mat<double>&, arma::Mat<double>&, arma::Base<double, arma::Glue<arma::Mat<double>, arma::Mat<double>, arma::glue_times> > const&) () at /usr/include/armadillo_bits/auxlib_meat.hpp:3434 

编译没有ATLAS,只有netlib BLAS和LAPACK,我能够重现NaN而不是挂起。

在这两种情况下,周围solve()#pragma omp关键我没有任何问题

你确定你的系统已经过时吗? solve_ud在你的堆栈跟踪否则。 虽然你也有解决solve_od ,可能这跟这个问题没有关系。 但是,如果你认为系统应该是od,那么find为什么会发生并修复它并不会造成什么伤害。

是犰狳解决()线程安全吗?

我想这取决于你的lapack版本,也看到这个 。 查看solve_od的代码 ,所有访问的variables似乎都是本地的。 请注意代码中的警告:

注意:由ATLAS 3.6提供的lapack库中的dgels()函数似乎有问题

因此,似乎只有lapack::gels你带来麻烦。 如果不能修复lapack,一个解决方法是堆叠您的系统并解决一个大的系统。 如果你的个人系统很小,这可能会更有效率。