OpenMP: ALLOCATABLE - переменная внутри PARALLEL блока
а что за кластер, если не секрет? На каком-нибудь BG/P, например, есть «thread-safe» версии скриптов для компиляции, что может включать в себя теоретически линковку с потокобезопасной стандартной библитекой, в которой может быть реализован этот механизм ALLOCATE просто гадаю
Так, я сейчас использую mpixlf77_r для компиляции.
Если у тебя был опыт, буду благодарен, если ты им поделишься.
с фортраном — нет, к сожалению
ну попробуй просто для проверки это дело в omp critical (в терминах C++) засунуть пробовал? Я имею в виду allocate. Или весь блок между allocate и deallocate (хотя это уже жесть, похоже).
а OpenMP - это фортран что ли? синтаксис как в фортране
Например, хочется цикл for(i = 0; i < 10000000; ++i) распараллелить, пишешь (C++):
#pragma omp parallel for
for( int i = 0; i < 10000000; ++i ) {
//...
}
с фортраном — нет, к сожалениюЯ постоянно не поспеваю за его логикой
Я попробовал вместо ALLOCATABLE сделать POINTER,
теперь память выделяют все массивы, но программа падает
на попытке освободить память, то есть при вызове
DEALLOCATE.
Не очень хочется тыкаться, хочется понимать, что делаешь.
Не очень хочется тыкаться, хочется понимать, что делаешь.ну иногда это единственный способ
TMP сидит в private?
оно в отдельной функции, вызываемой из parallel-блока. Оно может быть shared по умолчанию?
Нет, TMP - локальная переменная функции TEST.
MODULE MOD_OMP
PUBLIC :: TEST
CONTAINS
SUBROUTINE TEST(M, N)
IMPLICIT NONE
INTEGER, INTENT(IN) :: M, N
INTEGER :: I, J
REAL, DIMENSION(:, ALLOCATABLE :: TMP
ALLOCATE(TMP(M,N
DO J = 1,N
DO I = 1,M
TMP(I,J) = I+J
ENDDO
ENDDO
DEALLOCATE(TMP)
END SUBROUTINE TEST
END MODULE MOD_OMP
PROGRAM MAIN
USE MOD_OMP
IMPLICIT NONE
INTEGER :: I
!$OMP PARALLEL DO &
!$OMP DEFAULT(NONE) &
!$OMP PRIVATE(I)
DO I = 1,1000
CALL TEST(1000,500)
ENDDO
!$OMP END PARALLEL DO
END PROGRAM
Может быть проблема в том, что ты пытаешься использовать MPI и OpenMP одновременно?
так и есть: вместо mpi_init надо вызывать MPI_INIT_THREAD(MPI_THREAD_FUNNELED, PROVIDED, IERROR) и по результату в PROVIDED определять, разрешено ли данному треду использовать MPI вызовы.
так и есть: вместо mpi_init надо вызывать MPI_INIT_THREAD(MPI_THREAD_FUNNELED, PROVIDED, IERROR) и по результату в PROVIDED определять, разрешено ли данному треду использовать MPI вызовы.Безусловно, так и делается.
Проблема была в компиляторе - mpixlf77_r заменил на mpixlf90_r.
Либо никто не использует mpixlf77, либо я не смогу найти информации,
что MPI+OpenMP может работать некорректно.
P.S. А у тебя в программе количество тредов задается в переменной окружения?
А у тебя в программе количество тредов задается в переменной окружения?да, через OMP_NUM_THREADS. Но я ничего не считал на BG/P и не большой эксперт по MPI.
Проблема была в компиляторе - mpixlf77_r заменил на mpixlf90_rОтлично, что нашел решение. А разве 77-й фортран поддерживает динамическое выделение памяти?
Оставить комментарий
kataich
Не могли бы вы помочь ответить вот на какой вопрос:внутри PARALLEL блока идет вызов подпрограммы, которая,
схематично, выполняет следующую последовательность действий:
Предположим, что MPI версия программы запускается на N вычислительных узлах и на
каждом узле запускаем два треда.
Тогда наблюдается такая картина, что оба треда на каждом вычислительном
узле заходят в эту функцию, но РОВНО один (тот, который пришел первым)
из этих двух успешно зовет ALLOCATE и переходит к выполнению
следующей строчки, а ДРУГОЙ застревает в вызове ALLOCATE и не переходит
к выполнению следующей за вызовом ALLOCATE строчки.
Можете ли вы предположить, почему так происходит?
Особенность компилятора? Или ошибка в программе?