OpenMP: ALLOCATABLE - переменная внутри PARALLEL блока

kataich

Не могли бы вы помочь ответить вот на какой вопрос:
внутри PARALLEL блока идет вызов подпрограммы, которая,
схематично, выполняет следующую последовательность действий:

SUBROUTINE TEST
...
INTEGER M, N
REAL,ALLOCATABLE:: TMP(:,:)
...
ALLOCATE(TMP(M,N
....
DEALLOCATE(TMP)
...
END

Предположим, что MPI версия программы запускается на N вычислительных узлах и на
каждом узле запускаем два треда.
Тогда наблюдается такая картина, что оба треда на каждом вычислительном
узле заходят в эту функцию, но РОВНО один (тот, который пришел первым)
из этих двух успешно зовет ALLOCATE и переходит к выполнению
следующей строчки, а ДРУГОЙ застревает в вызове ALLOCATE и не переходит
к выполнению следующей за вызовом ALLOCATE строчки.
Можете ли вы предположить, почему так происходит?
Особенность компилятора? Или ошибка в программе?

Serab

а что за кластер, если не секрет? На каком-нибудь BG/P, например, есть «thread-safe» версии скриптов для компиляции, что может включать в себя теоретически линковку с потокобезопасной стандартной библитекой, в которой может быть реализован этот механизм ALLOCATE :confused: просто гадаю

kataich

BG/P. Я так понимаю ты имеешь в виду скрипты вида *_r.
Так, я сейчас использую mpixlf77_r для компиляции.
Если у тебя был опыт, буду благодарен, если ты им поделишься.

Serab

с фортраном — нет, к сожалению :(

Serab

ну попробуй просто для проверки это дело в omp critical (в терминах C++) засунуть :confused: пробовал? Я имею в виду allocate. Или весь блок между allocate и deallocate (хотя это уже жесть, похоже).

onyxis

а OpenMP - это фортран что ли? синтаксис как в фортране

Serab

OpenMP — это набор расширений для компиляторов (я сейчас знаю о фортране и C/C++) для написания многопоточных приложений.
Например, хочется цикл for(i = 0; i < 10000000; ++i) распараллелить, пишешь (C++):

#pragma omp parallel for
for( int i = 0; i < 10000000; ++i ) {
//...
}

:ooo:

kataich

с фортраном — нет, к сожалению :(
Я постоянно не поспеваю за его логикой :(
Я попробовал вместо ALLOCATABLE сделать POINTER,
теперь память выделяют все массивы, но программа падает
на попытке освободить память, то есть при вызове
DEALLOCATE. :(
Не очень хочется тыкаться, хочется понимать, что делаешь.

Serab

Не очень хочется тыкаться, хочется понимать, что делаешь.
ну иногда это единственный способ :grin:

geja_03

TMP сидит в private?

Serab

оно в отдельной функции, вызываемой из parallel-блока. Оно может быть shared по умолчанию?

kataich

Нет, TMP - локальная переменная функции TEST.

NataliaS

Вот этот код компилируется и нормально работает (gfortran 4.1 - 4.4):
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 одновременно?

NataliaS

так и есть: вместо mpi_init надо вызывать MPI_INIT_THREAD(MPI_THREAD_FUNNELED, PROVIDED, IERROR) и по результату в PROVIDED определять, разрешено ли данному треду использовать MPI вызовы.

kataich

так и есть: вместо mpi_init надо вызывать MPI_INIT_THREAD(MPI_THREAD_FUNNELED, PROVIDED, IERROR) и по результату в PROVIDED определять, разрешено ли данному треду использовать MPI вызовы.
Безусловно, так и делается.
Проблема была в компиляторе - mpixlf77_r заменил на mpixlf90_r.
Либо никто не использует mpixlf77, либо я не смогу найти информации,
что MPI+OpenMP может работать некорректно.
P.S. А у тебя в программе количество тредов задается в переменной окружения?

NataliaS

А у тебя в программе количество тредов задается в переменной окружения?
да, через OMP_NUM_THREADS. Но я ничего не считал на BG/P и не большой эксперт по MPI.
Проблема была в компиляторе - mpixlf77_r заменил на mpixlf90_r
Отлично, что нашел решение. А разве 77-й фортран поддерживает динамическое выделение памяти?
Оставить комментарий
Имя или ник:
Комментарий: