Apakah benang armadillo memecahkan () aman?

86

Dalam kode saya, saya memiliki loop di mana saya membangun dan melewati sistem linier yang ditentukan dan mencoba menyelesaikannya:

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

Kadang-kadang, program hang secara acak atau hasil dalam vektor solusi adalah NaN. Dan jika saya melakukan ini:

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

maka masalah ini sepertinya tidak terjadi lagi.

Saat hang, ia melakukannya karena beberapa utas menunggu di penghalang 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

Dan utas lainnya terjebak di dalam Armadillo:

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

Seperti yang Anda lihat dari stacktrace, versi Armadillo saya menggunakan atlas. Dan menurut atlas dokumentasi ini tampaknya thread safe: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

Perbarui 9/11/2015

Saya akhirnya punya waktu untuk menjalankan lebih banyak tes, berdasarkan saran dari Vladimir F.

Ketika saya mengkompilasi armadillo dengan ATLAS BLAS, saya masih bisa mereproduksi kemudian hang dan NaN. Saat hang, satu-satunya hal yang berubah di stacktrace adalah panggilan ke 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

Mengompilasi tanpa ATLAS, hanya dengan netlib BLAS dan LAPACK, saya dapat mereproduksi NaN tetapi tidak hang.

Dalam kedua kasus tersebut, sekitar solve()dengan #pragmaomp critical saya tidak memiliki masalah sama sekali

maxdebayser
sumber
1
Apakah /usr/lib64/libblas.so.3 bagian dari atlas? Mengapa tidak ada di / usr / lib64 / atlas?
Vladimir F
1
Tidak, di opensuse itu bagian dari paket liblas3 dan di redhat itu bagian dari paket blas.
maxdebayser
2
Maka Anda tidak dapat menggunakan jaminan ATLAS saat Anda menggunakan BLAS default.
Vladimir F
2
Sudahkah Anda memecahkan ini? Jika tidak, paket mana yang diinstal, dan dapatkah Anda memposting perintah yang Anda gunakan untuk mengkompilasi program?
vindvaki
3
Anda juga dapat mencoba menggunakan OpenBLAS sebagai ganti Atlas.
mtall

Jawaban:

2

Apakah Anda yakin sistem Anda terlalu ditentukan? solve_uddi pelacakan tumpukan Anda mengatakan sebaliknya. Meskipun solve_odbegitu, dan mungkin itu tidak ada hubungannya dengan masalah. Tetapi tidak ada salahnya untuk menemukan mengapa hal itu terjadi dan memperbaikinya jika menurut Anda sistemnya harus od.

Apakah benang armadillo memecahkan () aman?

Yang menurut saya tergantung pada versi lapack Anda, lihat juga ini . Melihat kode dari solve_odsemua variabel yang diakses sepertinya lokal. Perhatikan peringatan di kode:

CATATAN: fungsi dgels () di perpustakaan lapack yang disediakan oleh ATLAS 3.6 tampaknya mengalami masalah

Dengan demikian tampaknya hanya lapack::gelsdapat menimbulkan masalah bagi Anda. Jika memperbaiki lapack tidak memungkinkan, solusinya adalah menumpuk sistem Anda dan menyelesaikan satu sistem besar. Itu mungkin akan lebih efisien jika sistem individual Anda kecil.

semut Api
sumber
1

Keamanan utas solve()fungsi Armadillo bergantung (hanya) pada perpustakaan BLAS yang Anda gunakan. Implementasi LAPACK aman untuk thread saat BLAS berada. The Armadillo solve()fungsi tidak thread aman saat menghubungkan ke perpustakaan BLAS referensi . Namun, thread ini aman untuk thread saat menggunakan OpenBLAS . Selain itu, ATLAS menyediakan implementasi BLAS yang juga menyebutkan bahwa thread safe , dan Intel MKL juga aman untuk thread , tetapi saya tidak memiliki pengalaman dengan Armadillo yang ditautkan ke perpustakaan tersebut.

Tentu saja, ini hanya berlaku jika Anda menjalankan solve()dari beberapa utas dengan data berbeda.

André Offringa
sumber