Почему этот пример кода (f90, MPI, производные типы) вызывает недопустимое чтение/запись (valgrind или dmalloc)?

Это инкриминируемый код (он связан с другим вопросом, который я задал, здесь):

program foo

  use mpi

  implicit none

  type double_st
     sequence
     real(kind(0.d0)) :: x,y,z
     integer :: acc
  end type double_st

  integer, parameter :: n=8

  INTEGER :: MPI_CADNA_DST

  integer :: nproc, iprank
  INTEGER :: IERR, STAT(MPI_STATUS_SIZE)
  INTEGER :: MPI_CADNA_DST_TMP
  INTEGER ::&
       COUNT=4,&
       BLOCKLENGTHS(4)=(/1,1,1,1/),&
       TYPES(4)=(/MPI_DOUBLE_PRECISION,&
       MPI_DOUBLE_PRECISION,&
       MPI_DOUBLE_PRECISION,&
       MPI_INTEGER/)
  INTEGER(KIND=MPI_ADDRESS_KIND) :: DISPLS(4), LB, EXTENT
  TYPE(DOUBLE_ST) :: DST
  INTEGER :: I

  type(double_st), allocatable :: bufs(:), bufr(:)

  allocate(bufs(n), bufr(n))

  CALL MPI_INIT(IERR)
  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, NPROC, IERR)
  CALL MPI_COMM_RANK(MPI_COMM_WORLD, IPRANK, IERR)

  CALL MPI_GET_ADDRESS(DST%X,   DISPLS(1))
  CALL MPI_GET_ADDRESS(DST%Y,   DISPLS(2))
  CALL MPI_GET_ADDRESS(DST%Z,   DISPLS(3))
  CALL MPI_GET_ADDRESS(DST%ACC, DISPLS(4))
  DO I=4,1,-1
     DISPLS(I)=DISPLS(I)-DISPLS(1)
  ENDDO
  CALL MPI_TYPE_CREATE_STRUCT(4,BLOCKLENGTHS,DISPLS,TYPES, MPI_CADNA_DST_TMP,IERR)
  CALL MPI_TYPE_COMMIT(MPI_CADNA_DST_TMP,IERR)

  CALL MPI_TYPE_GET_EXTENT(MPI_CADNA_DST_TMP, LB, EXTENT, IERR)
  CALL MPI_TYPE_CREATE_RESIZED(MPI_CADNA_DST_TMP, LB, EXTENT, MPI_CADNA_DST, IERR)
  CALL MPI_TYPE_COMMIT(MPI_CADNA_DST,IERR)

  bufs(:)%x=iprank
  bufs(:)%y=iprank
  bufs(:)%z=iprank
  bufs(:)%acc=iprank
  call mpi_send(bufs(1), n, mpi_cadna_dst, 1-iprank, 0, mpi_comm_world, ierr)
  call mpi_recv(bufr(1), n, mpi_cadna_dst, 1-iprank, 0, mpi_comm_world, stat, ierr)


  deallocate(bufs, bufr)

end program foo

При компиляции с помощью intelMPI версии 4.0 или 5.0 я получаю недопустимые ошибки чтения/записи с помощью valgrind или dmalloc при отправке. С openMPI не все так ясно с этим минимальным примером, но у меня были похожие проблемы с этим общением в большом коде, из которого оно извлечено.

Спасибо за помощь!


person janou195    schedule 01.09.2015    source источник


Ответы (2)


Похоже, здесь виновато использование sequence. Поскольку ваши данные не выровнены одинаково, принудительная линейная упаковка с ключевым словом sequence приводит к некоторым невыровненным обращениям, возможно, при записи одного из массивов. Удаление делает свое дело.

person Gilles    schedule 02.09.2015
comment
Итак, проблема исходит от sequence. Но тогда моя проблема в том, что производный тип double_st, который я использую, происходит из библиотеки, которая не была разработана мной, поэтому я не могу удалить sequence (который должен быть там по какой-то причине...). У меня есть способ отправить/получить производный тип последовательности с помощью MPI - person janou195; 03.09.2015
comment
Я предполагаю, что вы можете просто вычислить размер типа, используя sizeof или даже MPI_Get_address() на buf(2) минус размер bufs(1), а затем использовать MPI_Type_contiguous(size, MPI_BYTE, mytype, ierr). Таким образом, у вас не будет проблем с внутренним выравниванием. Тем не менее, я не совсем уверен, возникает ли проблема с выравниванием из-за передачи MPI или из-за чтения/записи фактических данных, как в bufs(:)%x=iprank, поскольку там bufs(2)%x смещено. - person Gilles; 03.09.2015

Я думаю, что он использовал определение производного типа с последовательностью (парень, который написал код). ПОСЛЕДОВАТЕЛЬНОСТЬ заставляет компоненты производного типа храниться в той же последовательности, в которой они перечислены в определении типа. Если указан SEQUENCE, все производные типы, указанные в определениях компонентов, должны быть типами последовательности. Вы должны рассказать нам больше о компиляции, работаете ли вы также в Linux или Windows.

person Richard Rublev    schedule 02.09.2015
comment
Я на Linux и компилирую с помощью mpiifort. Я не понимаю, что вы имеете в виду под If SEQUENCE is specified, all derived types specified in component definitions must be sequence types? - person janou195; 03.09.2015
comment
Дополнительную информацию можно найти здесь: h21007. www2.hp.com/portal/download/files/unprot/fortran/docs/ - person Richard Rublev; 03.09.2015
comment
Но в этом случае все компоненты являются внутренними не производными типами, не так ли? - person janou195; 03.09.2015