2015-05-05 2 views
85

В моем коде у меня есть цикл, в котором я построить и по определенной линейной системе и пытаюсь ее решить:Является ли armadillo решающим() потоком безопасным?

#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 использует атлас. И в соответствии с этой документацией атласа, кажется поточно: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

Обновление 9/11/2015

я, наконец, получил некоторое время, чтобы запустить несколько тестов, на основе предложений Владимира Ф.

Когда я компилирую armadillo с BLAS ATLAS, я все еще могу воспроизвести тогда зависания и NaNs. Когда он висит, единственное, что изменения в StackTrace является призыв к 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 

Компиляция без ATLAS, только с Netlib BLAS и LAPACK, я был в состоянии воспроизвести, но не пренебрежимо малых зависания.

В обоих случаях, окружающих solve() с #pragma OMP критическим У меня нет проблем на всех

+1

Есть ли /usr/lib64/libblas.so.3 часть атласа? Почему он не находится в/usr/lib64/атласе? –

+1

Нет, в opensuse это часть пакета liblas3, а в redhat - часть пакета blas. – maxdebayser

+2

Тогда вы не можете использовать какие-либо гарантии ATLAS при использовании BLAS по умолчанию. –

ответ

2

не Вы уверены, что ваши системы более определяется? solve_ud в вашей трассировке стека говорит иначе. Хотя у вас тоже есть solve_od, и, вероятно, это не связано с проблемой. Но не мешает найти, почему это происходит и исправить, если вы считаете, что системы должны быть od.

Is armadillo solve() thread safe?

То, что я думаю, зависит от вашей версии в лацкане, также см. this. Глядя на code из solve_od, все доступные переменные кажутся локальными. Обратите внимание на предупреждение в коде:

Замечание: при dgels() в библиотеке LaPack поставляемой ATLAS 3.6 кажется, есть проблемы

Таким образом, кажется, только lapack::gels может вызвать проблемы для вас. Если исправление лапака невозможно, обходным путем является сбор ваших систем и решение одной большой системы. Это, вероятно, будет еще более эффективным, если ваши отдельные системы будут небольшими.

0

Функциональность функции Armadillo solve() зависит только от библиотеки BLAS, которую вы используете.Реализации LAPACK являются потокобезопасными при использовании BLAS. Функция Armadillo solve()не нить безопасна при подключении к the reference BLAS library. Однако при использовании OpenBLAS он является потокобезопасным. Кроме того, ATLAS обеспечивает реализацию BLAS, которая также mentions it is thread safe, и Intel MKL is thread safe as well, но у меня нет опыта с Armadillo, связанным с этими библиотеками.

Конечно, это применимо только при запуске solve() из нескольких потоков с разными данными.