Память кучи, выделенная, но не свободная после вызова MPI_TYPE_CREATE_STRUCT для создания структуры с возможностями размещения - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь отправить / получить производный тип данных с размещаемыми массивами. В настоящее время мне удалось следовать предложению в производном от MPI типе данных для динамически распределенных структур с динамически распределенным элементом . При этом моя информация передается правильно. Однако, когда я выполнял профилирование с помощью tau, память, выделенная в куче, не была освобождена и привела к утечке памяти.

Я проверял много раз, комментируя / отключая различные строки кода. Утечка памяти исчезает, пока я комментирую функцию MPI_TYPE_CREATE_STRUCT.

Я также вставил код из поста в свой код, но проблема все еще сохраняется.

Я попробовал компиляторы openmpi-4.0.0, 3.1.0 и impi 18.0.2, 18.0. 0

Вот простой код, который я тестировал на

Вот версия утечки памяти

Program memory_leak

  implicit none
  include "mpif.h"
  TYPE Struct    
  INTEGER :: N
  DOUBLE PRECISION :: A
  DOUBLE PRECISION ,ALLOCATABLE :: B(:)
  END TYPE Struct
  TYPE(Struct) :: Structs(2)
  integer :: i
  integer :: Types(3)
  integer :: Blocks(3)
  integer :: Elem_Type(2), TwoElem_Type,IError
  integer(kind=MPI_ADDRESS_KIND) :: POS_(3)
  integer(kind=MPI_ADDRESS_KIND) :: Offsets(3)
  ALLOCATE(Structs(1)%B(10))
  ALLOCATE(Structs(2)%B(20))
  CALL MPI_INIT(IError)

  ! (1) Create a separate structure datatype for each record
  DO i=1,2
    CALL MPI_GET_ADDRESS(Structs(i)%N,    POS_(1), IError)
    CALL MPI_GET_ADDRESS(Structs(i)%A,    POS_(2), IError)
    CALL MPI_GET_ADDRESS(Structs(i)%B(1), POS_(3), IError)
    Offsets = POS_ - POS_(1)

    Types(1) = MPI_INTEGER
    Types(2) = MPI_DOUBLE_PRECISION
    Types(3) = MPI_DOUBLE_PRECISION

    Blocks(1) = 1
    Blocks(2) = 1
    Blocks(3) = i * 10

    CALL MPI_TYPE_CREATE_STRUCT(3, Blocks, Offsets, Types, Elem_Type(i), IError)
  END DO

  ! (2) Create a structure of structures that describes the whole array
  CALL MPI_GET_ADDRESS(Structs(1)%N, POS_(1), IError)
  CALL MPI_GET_ADDRESS(Structs(2)%N, POS_(2), IError)
  Offsets = POS_ - POS_(1)

  Types(1) = Elem_Type(1)
  Types(2) = Elem_Type(2)

  Blocks(1) = 1
  Blocks(2) = 1

  CALL MPI_TYPE_CREATE_STRUCT(2, Blocks, Offsets, Types, TwoElem_Type, IError)
  CALL MPI_TYPE_COMMIT(TwoElem_Type, IError)

  ! (2.1) Free the intermediate datatypes
  DO i=1,2
    CALL MPI_TYPE_FREE(Elem_Type(i), IError)
  END DO
  CALL MPI_TYPE_FREE(TwoElem_Type, IError)
  print *, "end"
  CALL MPI_FINALIZE(IError)

end program memory_leak

Утечка памяти с использованием тау \

Вот бесплатная версия

Program memory_leak

  implicit none
  include "mpif.h"
  TYPE Struct    
  INTEGER :: N
  DOUBLE PRECISION :: A
  DOUBLE PRECISION ,ALLOCATABLE :: B(:)
  END TYPE Struct
  TYPE(Struct) :: Structs(2)
  integer :: i
  integer :: Types(3)
  integer :: Blocks(3)
  integer :: Elem_Type(2), TwoElem_Type,IError
  integer(kind=MPI_ADDRESS_KIND) :: POS_(3)
  integer(kind=MPI_ADDRESS_KIND) :: Offsets(3)
  ALLOCATE(Structs(1)%B(10))
  ALLOCATE(Structs(2)%B(20))
  CALL MPI_INIT(IError)

  ! (1) Create a separate structure datatype for each record
  DO i=1,2
    CALL MPI_GET_ADDRESS(Structs(i)%N,    POS_(1), IError)
    CALL MPI_GET_ADDRESS(Structs(i)%A,    POS_(2), IError)
    CALL MPI_GET_ADDRESS(Structs(i)%B(1), POS_(3), IError)
    Offsets = POS_ - POS_(1)

    Types(1) = MPI_INTEGER
    Types(2) = MPI_DOUBLE_PRECISION
    Types(3) = MPI_DOUBLE_PRECISION

    Blocks(1) = 1
    Blocks(2) = 1
    Blocks(3) = i * 10

   ! CALL MPI_TYPE_CREATE_STRUCT(3, Blocks, Offsets, Types, Elem_Type(i), IError)
  END DO

  ! (2) Create a structure of structures that describes the whole array
  CALL MPI_GET_ADDRESS(Structs(1)%N, POS_(1), IError)
  CALL MPI_GET_ADDRESS(Structs(2)%N, POS_(2), IError)
  Offsets = POS_ - POS_(1)

  Types(1) = Elem_Type(1)
  Types(2) = Elem_Type(2)

  Blocks(1) = 1
  Blocks(2) = 1

  ! CALL MPI_TYPE_CREATE_STRUCT(2, Blocks, Offsets, Types, TwoElem_Type, IError)
  ! CALL MPI_TYPE_COMMIT(TwoElem_Type, IError)

  ! ! (2.1) Free the intermediate datatypes
  ! DO i=1,2
  !   CALL MPI_TYPE_FREE(Elem_Type(i), IError)
  ! END DO
  !CALL MPI_TYPE_FREE(TwoElem_Type, IError)
  print *, "end"
  CALL MPI_FINALIZE(IError)

end program memory_leak
...