Armadillo resolve () потокобезопасен?

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

Как видно из трассировки стека, моя версия Armadillo использует атлас. И согласно этой документации атлас кажется потокобезопасным: ftp://lsec.cc.ac.cn/netlib/atlas/faq.html#tsafe

Обновление 11.09.2015

Наконец-то у меня появилось время провести дополнительные тесты, основанные на предложениях Владимира Ф.

Когда я компилирую броненосца с помощью 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 критическим У меня нет никаких проблем вообще

maxdebayser
источник
1
Является ли /usr/lib64/libblas.so.3 частью атласа? Почему он не находится в / usr / lib64 / atlas?
Владимир Ф
1
Нет, в opensuse это часть пакета liblas3, а в redhat - часть пакета blas.
maxdebayser
2
Тогда вы не сможете использовать какие-либо гарантии ATLAS при использовании BLAS по умолчанию.
Владимир Ф
2
Вы решили это? Если нет, то какие пакеты установлены, и не могли бы вы опубликовать команду, которую вы использовали для компиляции программы?
виндваки
3
Вы также можете попробовать использовать OpenBLAS вместо Atlas.
mtall

Ответы:

2

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

Armadillo resolve () потокобезопасен?

Это, я думаю, зависит от вашей версии Lapack, также см. Это . Глядя на код из solve_odвсех переменных , доступных кажутся локальными. Обратите внимание на предупреждение в коде:

ПРИМЕЧАНИЕ: функция dgels () в библиотеке Lapack, поставляемой с ATLAS 3.6, похоже, имеет проблемы.

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

огненный
источник
1

Потоковая безопасность функции Armadillo solve()зависит (только) от библиотеки BLAS, которую вы используете. Реализации LAPACK являются потокобезопасными, когда BLAS. Функция Armadillo неsolve() является потокобезопасной при связывании с эталонной библиотекой BLAS . Однако при использовании OpenBLAS это потокобезопасный . Кроме того, ATLAS предоставляет реализацию BLAS, в которой также упоминается, что он является потокобезопасным , и Intel MKL также является потокобезопасным , но у меня нет опыта работы с Armadillo, связанным с этими библиотеками.

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

Андре Оффринга
источник