簡體   English   中英

犰狳是否解決()線程安全?

[英]Is armadillo solve() thread safe?

在我的代碼中,我有循環,我構建和確定線性系統,並嘗試解決它:

#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);
        }
    }
}

有時,程序會隨機掛起,或者解決方案向量中的結果是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

2015年9月11日更新

根據弗拉基米爾·F的建議,我終於有時間進行更多的測試。

當我用ATLAS的BLAS編譯犰狳時,我仍然可以重現然后掛起和NaN。 當它掛起時,堆棧跟蹤中唯一改變的是調用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而不是掛起。

在這兩種情況下,圍繞使用#pragma omp critical的solve()我都沒有問題

你確定你的系統已經過時了嗎? 堆棧跟蹤中的solve_ud說不然。 雖然你也有solve_od ,也許這與問題無關。 但是,如果您認為系統應該是od,那么找到為什么會發生並修復它並沒有什么壞處。

犰狳是否解決()線程安全?

我認為這取決於你的lapack版本,也看到了這一點 查看solve_od代碼solve_od所有變量似乎都是本地的。 請注意代碼中的警告:

注意:ATLAS 3.6提供的lapack庫中的dgels()函數似乎有問題

因此,似乎只有lapack::gels你帶來麻煩。 如果無法修復lapack,則解決方法是堆疊系統並解決單個大型系統。 如果您的個人系統很小,這可能會更有效。

Armadillo的solve()函數的線程安全性(僅)取決於您使用的BLAS庫。 當BLAS是LAPACK實現時是線程安全的。 鏈接到引用BLAS庫時,Armadillo solve()函數不是線程安全的。 但是,使用OpenBLAS時它是線程安全的。 此外, ATLAS提供了一個BLAS實現,也提到它是線程安全的 ,而且英特爾MKL 也是線程安全的 ,但我沒有使用鏈接到這些庫的Armadillo的經驗。

當然,這僅適用於從具有不同數據的多個線程運行solve()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM