Я пытаюсь отправить / получить производный тип данных с размещаемыми массивами. В настоящее время мне удалось следовать предложению в производном от 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