Nel mio codice che ho ciclo in cui costruisco e più determinato sistema lineare e cercare di risolverlo:Il thread armadillo solve() è sicuro?
#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);
}
}
}
A volte, del tutto casualmente il programma si blocca oi risultati nel vettore soluzione sono NaN. E se metto in questo modo:
arma::vec solution;
#pragma omp critical
{
solution = solve(weights*A,weights*y);
}
quindi questi problemi non sembrano più accadere.
Quando si blocca, lo fa perché alcuni thread sono in attesa alla barriera 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
E gli altri thread sono bloccati all'interno 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
Come si può vedere dalla stacktrace la mia versione di Armadillo usa l'atlante. E secondo questa documentazione atlante sembra essere thread-safe: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe
aggiornamento 9/11/2015
Finalmente ho avuto un po 'di tempo per eseguire altri test, sulla base dei suggerimenti di Vladimir F.
Quando compilo armadillo con BLAS di ATLAS, sono ancora in grado di riprodurre quindi hang e NaN. Quando si blocca, l'unica cosa che cambia nel StackTrace è la chiamata alla BLAS:
#0 0x0000003fa8054718 in [email protected]() 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
compilazione senza ATLAS, solo con netlib BLAS e LAPACK, sono stato in grado di riprodurre le NaNs ma non si blocca.
In entrambi i casi, che circonda solve()
con #pragma
OMP critica non ho problemi a tutti
È /usr/lib64/libblas.so.3 parte dell'atlante? Perché non si trova in/usr/lib64/atlas? –
No, in opensuse fa parte del pacchetto liblas3 e in redhat fa parte del pacchetto blas. – maxdebayser
Quindi non è possibile utilizzare alcuna garanzia di ATLAS quando si utilizza il BLAS predefinito. –