Czy wątek Armadillo Solve () jest bezpieczny?

86

W swoim kodzie mam pętlę, w której konstruuję i ponad wyznaczony układ liniowy i próbuję go rozwiązać:

#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, całkiem przypadkowo, program zawiesza się lub wyniki w wektorze rozwiązania to NaN. A jeśli wstawię, zrób to:

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

to wydaje się, że ten problem już się nie pojawia.

Kiedy się zawiesza, robi to, ponieważ niektóre wątki czekają na barierze 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 utknęły w 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ć ze stosu, moja wersja Armadillo używa atlasu. Zgodnie z tą dokumentacją atlas wydaje się być bezpieczny dla wątków: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

Aktualizacja 11.09.2015

W końcu dostałem trochę czasu, aby przeprowadzić więcej testów, zgodnie z sugestiami Vladimira F.

Kiedy kompiluję pancernik z BLAS-em ATLAS-a, nadal jestem w stanie odtworzyć, a następnie zawiesza się i NaNs. Kiedy się zawiesza, jedyną rzeczą, która zmienia się w stacktrace, jest wywołanie 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

Kompilując bez ATLASA, tylko z netlib BLAS i LAPACK, byłem w stanie odtworzyć NaN, ale nie zawiesiłem się.

W obu przypadkach otaczając solve()się #pragmaomp krytycznym nie mam żadnych problemów

maxdebayser
źródło
1
Czy /usr/lib64/libblas.so.3 jest częścią atlasu? Dlaczego nie znajduje się w / usr / lib64 / atlas?
Vladimir F
1
Nie, w opensuse jest częścią pakietu liblas3, aw redhat jest częścią pakietu blas.
maxdebayser
2
W takim przypadku nie możesz korzystać z żadnych gwarancji ATLAS, gdy używasz domyślnego BLAS-a.
Vladimir F,
2
Czy rozwiązałeś to? Jeśli nie, jakie pakiety są zainstalowane i czy możesz opublikować polecenie użyte do kompilacji programu?
vindvaki
3
Możesz także spróbować użyć OpenBLAS zamiast Atlas.
mtall

Odpowiedzi:

2

Czy na pewno Twoje systemy są zbyt zdeterminowane? solve_udw śladzie stosu mówi inaczej. Chociaż ty solve_odteż masz i prawdopodobnie nie ma to nic wspólnego z problemem. Ale nie zaszkodzi dowiedzieć się, dlaczego tak się dzieje i naprawić to, jeśli uważasz, że systemy powinny być złe.

Czy wątek Armadillo Solve () jest bezpieczny?

Myślę, że zależy to od twojej wersji lapack, zobacz też to . Patrząc na kod z solve_odwszystkich zmiennych dostępnych wydają się być lokalne. Zwróć uwagę na ostrzeżenie w kodzie:

UWAGA: funkcja dgels () w bibliotece lapack dostarczonej przez ATLAS 3.6 wydaje się mieć problemy

Dlatego wydaje się, że tylko lapack::gelsmoże powodować kłopoty. Jeśli naprawienie lapack nie jest możliwe, obejściem jest ułożenie systemów w stos i rozwiązanie jednego dużego systemu. Byłoby to prawdopodobnie jeszcze bardziej wydajne, gdyby poszczególne systemy były małe.

Ognista Mrówka
źródło
1

Bezpieczeństwo wątków funkcji Armadillo solve()zależy (tylko) od biblioteki BLAS, której używasz. Implementacje LAPACK są bezpieczne wątkowo, gdy BLAS jest. Funkcja Armadillo niesolve() jest bezpieczna wątkowo podczas łączenia z referencyjną biblioteką BLAS . Jednak korzystanie z OpenBLAS jest bezpieczne wątkowo . Ponadto ATLAS zapewnia implementację BLAS, która również wspomina, że ​​jest bezpieczna dla wątków , a Intel MKL również jest bezpieczny dla wątków , ale nie mam doświadczenia z Armadillo połączonym z tymi bibliotekami.

Oczywiście dotyczy to tylko sytuacji, gdy uruchamiasz solve()z wielu wątków z różnymi danymi.

André Offringa
źródło