У меня ошибка сегментации, которую я не могу понять в простом коде, который просто:
- вызывает MPI_INIT
- , дублирует глобальный коммуникатор через MPI_COMM_DUP
- создает группу с половиной процессов глобального коммуникатора через MPI_COMM_GROUP
- , наконец, из этой группы создает новый коммуникатор через MPI_COMM_CREATE_GROUP
В частности, я использую этот последний вызоввместо того, чтобы просто использовать MPI_COMM_CREATE, потому что он только коллективный по группе процессов, содержащихся в группе, в то время как MPI_COMM_CREATE является коллективным по каждому процессу в COMM.Код следующий
program mpi_comm_create_grp
use mpi
IMPLICIT NONE
INTEGER :: mpi_size, mpi_err_code
INTEGER :: my_comm_dup, mpi_new_comm, mpi_group_world, mpi_new_group
INTEGER :: rank_index
INTEGER, DIMENSION(:), ALLOCATABLE :: rank_vec
CALL mpi_init(mpi_err_code)
CALL mpi_comm_size(mpi_comm_world, mpi_size, mpi_err_code)
!! allocate and fill the vector for the new group
allocate(rank_vec(mpi_size/2))
rank_vec(:) = (/ (rank_index , rank_index=0, mpi_size/2) /)
!! create the group directly from the comm_world: this way works
! CALL mpi_comm_group(mpi_comm_world, mpi_group_world, mpi_err_code)
!! duplicating the comm_world creating the group form the dup: this ways fails
CALL mpi_comm_dup(mpi_comm_world, my_comm_dup, mpi_err_code)
!! creatig the group of all processes from the duplicated comm_world
CALL mpi_comm_group(my_comm_dup, mpi_group_world, mpi_err_code)
!! create a new group with just half of processes in comm_world
CALL mpi_group_incl(mpi_group_world, mpi_size/2, rank_vec,mpi_new_group, mpi_err_code)
!! create a new comm from the comm_world using the new group created
CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
!! deallocate and finalize mpi
if(ALLOCATED(rank_vec)) DEALLOCATE(rank_vec)
CALL mpi_finalize(mpi_err_code)
end program !mpi_comm_create_grp
Если вместо дублирования COMM_WORLD я напрямую создаю группу из глобального коммуникатора (закомментированная строка), все работает просто отлично.
Параллельный отладчик, который я использую, отслеживает ошибку seg до вызова MPI_GROUP_TRANSLATE_RANKS, но, насколько мне известно, MPI_COMM_DUP дублирует все атрибуты скопированного коммуникатора, рангинумерация включена.
Я использую версию ifort 18.0.5, но я также пробовал с 17.0.4 и 19.0.2 без лучших результатов.