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 #pragma
omp critical saya tidak memiliki masalah sama sekali
Jawaban:
Apakah Anda yakin sistem Anda terlalu ditentukan?
solve_ud
di pelacakan tumpukan Anda mengatakan sebaliknya. Meskipunsolve_od
begitu, 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.Yang menurut saya tergantung pada versi lapack Anda, lihat juga ini . Melihat kode dari
solve_od
semua variabel yang diakses sepertinya lokal. Perhatikan peringatan di kode:Dengan demikian tampaknya hanya
lapack::gels
dapat 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.sumber
Keamanan utas
solve()
fungsi Armadillo bergantung (hanya) pada perpustakaan BLAS yang Anda gunakan. Implementasi LAPACK aman untuk thread saat BLAS berada. The Armadillosolve()
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.sumber