Trong mã của tôi, tôi có vòng lặp trong đó tôi xây dựng và trên hệ thống tuyến tính đã xác định và cố gắng giải quyết nó:
#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);
}
}
}
Đôi khi, khá ngẫu nhiên chương trình bị treo hoặc kết quả trong vectơ lời giải là NaN. Và nếu tôi đặt làm điều này:
arma::vec solution;
#pragma omp critical
{
solution = solve(weights*A,weights*y);
}
thì những vấn đề này dường như không xảy ra nữa.
Khi nó bị treo, nó hoạt động như vậy vì một số luồng đang đợi ở rào cản 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
Và các chủ đề khác bị kẹt bên trong 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
Như bạn có thể thấy từ stacktrace, phiên bản Armadillo của tôi sử dụng tập bản đồ. Và theo tài liệu này, tập bản đồ dường như là một chuỗi an toàn: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe
Cập nhật 11/9/2015
Cuối cùng tôi cũng có thời gian để chạy thử nghiệm nhiều hơn, dựa trên đề xuất của Vladimir F.
Khi tôi biên dịch armadillo với BLAS của ATLAS, tôi vẫn có thể sao chép sau đó bị treo và các NaN. Khi nó bị treo, điều duy nhất thay đổi trong stacktrace là lệnh gọi 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
Biên dịch mà không có ATLAS, chỉ với netlib BLAS và LAPACK, tôi đã có thể tái tạo các NaN nhưng không bị treo.
Trong cả hai trường hợp, xung quanh solve()
với #pragma
quan trọng của omp tôi không có vấn đề gì cả