2015-05-05 26 views
85

W moim kodu mam pętlę w której budowę i nad określonym układzie liniowym i spróbować go rozwiązać:Czy wątek armadillo solve() jest bezpieczny?

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

Czasami zupełnie losowo zawiesza program lub wyniki w wektorze roztworu NaN. A jeśli to zrobię, to:

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

to nie wydaje się już występować ten problem.

Kiedy to wisi, robi to dlatego, że niektóre wątki czekają na barierę 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 

A inne wątki tkwią wewnątrz 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 

Jak widać z stacktrace moja wersja Armadillo używa atlasu. I zgodnie z niniejszą dokumentacją atlas wydaje się być bezpieczne wątek: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

Aktualizacja 9/11/2015

I wreszcie trochę czasu, aby uruchomić więcej testów, na podstawie sugestii Vladimir F.

Kiedy kompiluję Pancernik z BLAS ATLAS, wciąż mogę odtworzyć, a następnie zawiesić się i NaN. Kiedy to wisi, jedyną rzeczą, która zmienia się w stacktrace jest wezwanie 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 

Kompilacja bez atlas, tylko z netlib BLAS i LAPACK, udało mi się odtworzyć Nans ale nie zawiesza.

W obu przypadkach, otaczających solve() z #pragma omp krytyczny mam żadnych problemów w ogóle

+1

Czy /usr/lib64/libblas.so.3 jest częścią atlasu? Dlaczego nie znajduje się w/usr/lib64/atlas? –

+1

Nie, w opensuse jest częścią pakietu liblas3 iw redhat jest częścią pakietu blas. – maxdebayser

+2

W takim przypadku nie można korzystać z gwarancji ATLAS podczas korzystania z domyślnego BLAS. –

Odpowiedz

2

Czy na pewno wasze systemy są ponad ustalona? solve_ud w twoim śladzie stosu mówi inaczej. Chociaż masz też solve_od i prawdopodobnie to nie ma nic wspólnego z problemem. Ale nie boli, aby znaleźć powód, dlaczego tak się dzieje i naprawić go, jeśli myślisz, że systemy powinny być od.

Czy wątek armadillo solve() jest bezpieczny?

To, co myślę, zależy od twojej wersji, zobacz też this. Patrząc na code z solve_od wszystkie zmienne dostępne wydają się być lokalne. Należy zwrócić uwagę na ostrzeżenia w kodzie:

UWAGA: dgels function() w bibliotece Lapack dostarczonych przez ATLAS 3,6 wydaje się mieć problemy

Wydaje się zatem tylko lapack::gels może powodować problemy dla Ciebie. Jeśli naprawianie nie jest możliwe, rozwiązaniem jest układanie systemów i rozwiązywanie pojedynczego dużego systemu. Prawdopodobnie byłoby to jeszcze bardziej wydajne, gdyby twoje pojedyncze systemy były małe.

0

Zabezpieczenie nici funkcji Armadillo za pomocą solve() zależy (tylko) od używanej biblioteki BLAS.Implementacje LAPACK są bezpieczne dla wątków w przypadku BLAS. Funkcja Pancerza solve() jest , a nie bezpieczna dla wątków po połączeniu z the reference BLAS library. Jednak jest bezpieczna dla wątków podczas używania OpenBLAS. Dodatkowo, ATLAS dostarcza implementację BLAS, która także mentions it is thread safe, i Intel MKL is thread safe as well, ale nie mam doświadczenia z Armadillo połączonym z tymi bibliotekami.

Oczywiście ma to zastosowanie tylko po uruchomieniu solve() z wielu wątków z różnymi danymi.

Powiązane problemy