아르마딜로 solve () 스레드 안전합니까?


86

내 코드에는 선형 시스템을 구성하고 과도하게 결정하고 해결하려고하는 루프가 있습니다.

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

때로는 프로그램이 무작위로 중단되거나 솔루션 벡터의 결과가 NaN입니다. 그리고 이렇게하면 :

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

그러면 이러한 문제는 더 이상 발생하지 않는 것 같습니다.

중단되면 일부 스레드가 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

그리고 다른 스레드는 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

stacktrace에서 알 수 있듯이 Armadillo의 내 버전은 아틀라스를 사용합니다. 그리고이 문서에 따르면 atlas는 스레드로부터 안전한 것처럼 보입니다 : ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

2015 년 9 월 11 일 업데이트

마침내 Vladimir F의 제안에 따라 더 많은 테스트를 실행할 시간이 생겼습니다.

ATLAS의 BLAS로 아르마딜로를 컴파일 할 때, 나는 여전히 멈춤과 NaN을 재현 할 수 있습니다. 중단되면 stacktrace에서 변경되는 유일한 것은 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

ATLAS없이 컴파일하고 netlib BLAS 및 LAPACK으로 만 NaN을 재현 할 수 있었지만 중단되지 않았습니다.

두 경우 모두, 주변 solve()#pragmaOMP 것이 중요 나는 전혀 문제가 없다


1
/usr/lib64/libblas.so.3은 아틀라스의 일부입니까? / usr / lib64 / atlas에없는 이유는 무엇입니까?
Vladimir F

1
아니요, opensuse에서는 liblas3 패키지의 일부이고 redhat에서는 패키지 blas의 일부입니다.
maxdebayser

2
그러면 기본 BLAS를 사용할 때 ATLAS 보증을 사용할 수 없습니다.
Vladimir F

2
이 문제를 해결 했습니까? 그렇지 않은 경우 어떤 패키지가 설치되어 있으며 프로그램을 컴파일하는 데 사용한 명령을 게시 해 주시겠습니까?
vindvaki

3
Atlas 대신 OpenBLAS 를 사용해 볼 수도 있습니다 .
mtall

답변:


2

시스템이 과도하게 결정 되었습니까? solve_ud스택 추적에서 그렇지 않다고 말합니다. 당신 solve_od도 있지만 아마도 그것은 문제와 관련이 없습니다. 그러나 왜 그런 일이 발생하는지 찾아 내고 시스템이 이상하다고 생각되면 고치는 것은 아프지 않습니다.

아르마딜로 solve () 스레드 안전합니까?

나는 당신의 lapack 버전에 달려 있다고 생각 합니다 . 액세스 된 모든 변수 의 코드 를 보면 solve_od로컬 인 것 같습니다. 코드의 경고에 유의하십시오.

참고 : ATLAS 3.6에서 제공하는 lapack 라이브러리의 dgels () 함수에 문제가있는 것 같습니다.

따라서 그것은 lapack::gels당신에게 문제를 일으킬 수 있습니다. lapack을 고칠 수없는 경우 해결 방법은 시스템을 쌓고 단일 대형 시스템을 해결하는 것입니다. 개별 시스템이 작 으면 훨씬 더 효율적일 것입니다.


1

Armadillo solve()기능 의 스레드 안전성은 사용하는 BLAS 라이브러리에 따라 다릅니다. LAPACK 구현은 BLAS가있을 때 스레드로부터 안전합니다. Armadillo solve()함수는 참조 BLAS 라이브러리에 연결할 때 스레드로부터 안전 하지 않습니다 . 그러나 OpenBLAS를 사용할 때는 스레드로부터 안전 합니다. 또한 ATLAS 는 스레드로부터 안전하다고 언급 하는 BLAS 구현을 제공하며 인텔 MKL 도 스레드로부터 안전 하지만 해당 라이브러리에 연결된 Armadillo에 대한 경험이 없습니다.

물론 이것은 solve()데이터가 다른 여러 스레드에서 실행할 때만 적용됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.