В этом потоке было объяснено двумя способами, как передавать сообщения с использованием MPI с объявленными типами данных. У меня есть структура данных с помощью allocatables
type t_example
real, allocatable :: x(:), y(:), z(:)
end type
. Для обеспечения работоспособности кода проще всего было бы не использовать MPI_TYPE_CONTIGUOUS
следующим образом
! -- declare
type(t_example) :: p1
type(MPI_DATATYPE) :: mpi_dtexample
(...)
call MPI_TYPE_CONTIGUOUS(sizeof(p1), MPI_BYTE, mpi_dtexample, ierr);
call MPI_TYPE_COMMIT(mpi_dtexample, ierr)
. После этого я могу просто использоватьотправить / recv с mpi_dtexample
в качестве типа данных.
Я не могу прийти в голову, когда становится более разумным использовать mpi_type_create_struct, так как это потребует от вас явного указания последовательности объявленного типа с типом данных и их соответствующими размерами.
ДА, подход MPI_TYPE_CONTIGUOUS
предполагает, что объявленный тип является смежным, и я не смог бы использовать этот подход, если бы я хотел пропустить определенные пошаговые элементы объявленного типа.
Есть ли еще что-то, что я должен поднять, когда буду звонить в тревогу, используя MPI_TYPE_CONTIGUOUS
ПОЛНЫЙ ПРИМЕР
Бег с двумя рядамитолько.
module md_
use mpi_f08
integer numtasks, rank, tag, i, ierr
type(mpi_status) stat
type T_PART
real, allocatable :: x(:), y(:), z(:)
end type
contains
end module
program struct
use md_
implicit none
type(t_part) :: test_
type(mpi_datatype) :: mpidt
integer :: sz, szz
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr)
tag = 1
szz= 10
allocate(test_% x(szz),test_% y(szz), test_% z(szz) )
sz = sizeof(test_)
call MPI_Type_contiguous(sz, MPI_BYTE ,mpidt, ierr)
call MPI_TYPE_COMMIT(mpidt, ierr)
if (rank .eq. 0) then
do i=1,szz
test_%x(i) = i*1+mod(i,3)
test_%y(i) = i*2+mod(i,3)
test_%z(i) = i*3+mod(i,3)
end do
call MPI_SEND(test_, 1, mpidt, 1, tag, &
MPI_COMM_WORLD, ierr)
else
call MPI_RECV(test_, 1, mpidt, 0, tag, &
MPI_COMM_WORLD, stat, ierr)
endif
print *, 'rank= ',rank,' test_% x= ', test_%z(1) ! seg faults for rank 2
call mpi_barrier(MPI_COMM_WORLD, ierr)
! free datatype when done using it
call MPI_TYPE_FREE(mpidt, ierr)
call MPI_FINALIZE(ierr)
end