armadillosolve()スレッドは安全ですか?


86

私のコードには、線形システムを構築して過剰決定し、それを解こうとするループがあります。

#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を再現できましたが、ハングは再現できませんでした。

どちらの場合も、ompクリティカルで囲んsolve()#pragmaも問題はありません。


1
/usr/lib64/libblas.so.3はアトラスの一部ですか?/ usr / lib64 / atlasにないのはなぜですか?
ウラジミールF

1
いいえ、opensuseではパッケージliblas3の一部であり、redhatではパッケージblasの一部です。
maxdebayser 2015

2
その場合、デフォルトのBLASを使用する場合、ATLASの保証を使用することはできません。
ウラジミールF

2
これを解決しましたか?そうでない場合は、どのパッケージがインストールされていますか。プログラムのコンパイルに使用したコマンドを投稿してください。
vindvaki 2015

3
Atlasの代わりにOpenBLASを使用することもできます。
mtall 2015

回答:


2

システムが過剰決定されていると確信していますか?solve_udスタックトレースで別の言い方をします。あなたも持っていますがsolve_od、おそらくそれは問題とは何の関係もありません。しかし、なぜそれが起こっているのかを見つけて、システムが異常であると思われる場合はそれを修正することは害にはなりません。

armadillosolve()スレッドは安全ですか?

私はあなたのlapackバージョンに依存すると思います、これも見てください。アクセスされたすべての変数のコードを見ると、solve_odローカルのようです。コード内の警告に注意してください。

注:ATLAS 3.6が提供するlapackライブラリのdgels()関数には問題があるようです

したがって、それはlapack::gelsあなたに問題を引き起こすだけのようです。lapackを修正できない場合の回避策は、システムをスタックして1つの大きなシステムを解決することです。個々のシステムが小さい場合、それはおそらくさらに効率的です。


1

Armadilloのsolve()関数のスレッドセーフは、使用するBLASライブラリに(のみ)依存します。LAPACKの実装は、BLASがスレッドセーフである場合にスレッドセーフです。参照BLASライブラリにリンクする場合、Armadillosolve()関数はスレッドセーフではありません。ただし、OpenBLASを使用する場合はスレッドセーフです。さらに、ATLASはスレッドセーフであると述べているBLAS実装を提供し、Intel MKLもスレッドセーフですが、これらのライブラリにリンクされたArmadilloの経験はありません。

もちろん、これは、solve()異なるデータを持つ複数のスレッドから実行する場合にのみ適用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.