2017-01-06 3 views
3

Я читал, что рекомендуется использовать модуль MPI, а не включать файл mpif.h. Тем не менее, я получаю следующее сообщение об ошибкеКаков правильный способ работы с MPI-коммуникаторами в Fortran?

Error: There is no specific subroutine for the generic ‘mpi_comm_split’

когда я запускаю эту программу

program hello_world 
    use mpi_f08 
    implicit none 
    ! include 'mpif.h' 
    integer :: ierr, num_procs, my_id,newcomm 
    integer :: color,key 

    call MPI_INIT (ierr) 
    color =1; key=0 
    call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr) 
    call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr) 

    call MPI_Comm_split(MPI_COMM_WORLD, color,key,newcomm, ierr) 

    call MPI_FINALIZE (ierr) 

end 

ошибка исчезает, если я включаю «mpif.h» вместо того, чтобы использовать модуль MPI. Почему это?

+3

Никогда не пробовал, но похоже, что тип, используемый для интерфейса f08, использует 'type (MPI_comm)' for 'newcomm' ... – Gilles

+0

В связи с тем, что Жиль сказал, что произойдет, если вы просто« используете mpi »? Какой компилятор и версия, а также то, что mpi и версия могут быть полезны. –

+2

* Ошибка исчезнет, ​​если я включил 'mpif.h' вместо использования модуля MPI. Почему это? * Потому что, используя модуль mpi, вы позволяете компилятору проверять соответствие стандартных формальных и фактических аргументов во время компиляции. Подход 'include' позволяет использовать всевозможные глупости во время выполнения. –

ответ

3

Интерфейс use mpi_f08 вводит различные типы оберток для различных объектов ручки MPI. В то время как в интерфейсах mpif.h и use mpi все ручки - это просто INTEGER s, в интерфейсе use mpi_f08 есть TYPE(MPI_Comm), и т. Д. Это позволяет компилятору выполнять проверки на такие вещи, как передача дескриптора коммуникатора, где ожидается дескриптор файла.

Это критическое изменение на уровне исходного кода, как код должен быть переписан, например,

INTEGER :: newcomm 

становится

TYPE(MPI_Comm) :: newcomm 

На двоичном уровне нет никаких изменений, так как все эти MPI_Xyz типы просто INTEGER, завернутый в спецификатор TYPE, что делает их совместимыми с макетами. Старый код Fortran по-прежнему может обменивать ручки MPI с современным кодом Fortran и наоборот - значение дескриптора INTEGER может быть установлено или извлечено через newcomm%MPI_VAL.

+0

Спасибо! Я получаю еще одну ошибку при использовании MPI_types в функции уменьшения, например 'call MPI_Allreduce (x, y, N, MPI_DOUBLE, MPI_SUM, newcomm, ierr)', что символ «mpi_double» в (1) не имеет типа IMPLICIT. Как это изменить? использование 'type (MPI_DOUBLE)' не помогает. – Tarek

+3

'MPI_DOUBLE' соответствует типу C/C++' double'. Он не должен использоваться в коде Fortran. Используйте 'MPI_REAL' или что бы то ни было типа' x' и 'y' (' MPI_DOUBLE_PRECISION' и т. Д.) –

+0

Однако, если у меня есть реальный (c_double), я бы надеюсь, что соответствующий тип MPI доступен ... –

Смежные вопросы