Отправка производного типа с выделяемым массивом между процессами MPI

Для контекста, в моем моделировании CFD моя вычислительная область разделена на блоки. Каждый блок имеет свое количество ячеек, каждая из которых содержит различную информацию. Блоки распределяются между процессами с помощью алгоритма декомпозиции домена для достижения сбалансированной нагрузки.

Создание сетки вычислительной области выполняется только процессом 0 (я не хочу хранить всю сетку в каждом процессе, так как это было бы катастрофой с точки зрения используемой памяти). На самом деле сетка закодирована как одномерный массив блоков, каждый из которых представляет собой сложный производный тип с размещаемым оператором других производных типов:

TYPE something
    integer :: i,j,k
END TYPE something
!------
TYPE cell
    integer :: var1
    real, dimension(3) :: var2
    type(something), dimension(:), allocatable :: var3
END TYPE
!------
TYPE block
    integer :: var4
    real    :: var5
    type(cell), dimension(:), allocatable :: var6
END TYPE block

и сетка определяется как:

TYPE(block), dimension(n) :: mesh

Затем моя идея состоит в том, чтобы использовать MPI_SCATTERV (каждый процесс обрабатывает разное количество блоков) из процесса 0 для распределения фрагментов моего массива mesh другим процессам. В конце я использую MPI_GATHERV для восстановления всего домена, если это необходимо. Проблема в том, что я должен передать сложный производный тип.

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

Как я могу определить производный тип MPI с помощью размещаемого массива? Конечно, перед отправкой данных эти массивы выделяются, но во время компиляции их нет. Мне нужно использовать MPI_GET_ADDRESS для вычисления смещений между каждыми данными, но я не знаю, как это сделать с выделяемым массивом. Нужно ли мне переключаться на массивы фиксированной длины? Нужно ли мне определять каждый из трех вышеперечисленных типов и создавать «супер» блок производного типа MPI? Я думал о цикле по каждой ячейке каждого блока и отправке данных один за другим, что не кажется правильным способом сделать это, поскольку для этого потребуется огромное количество вызовов mpi, я ищу настоящий «блок-блок». ' коммуникация.


person Coriolis    schedule 21.05.2016    source источник
comment
Вы не можете использовать один производный тип для всех переменных с выделяемым компонентом. У них будет выделяемый компонент, хранящийся по случайным адресам.   -  person Vladimir F    schedule 21.05.2016
comment
Как насчет ключевого слова sequence для принудительного хранения данных массива непрерывно в каждом типе?   -  person Coriolis    schedule 21.05.2016
comment
Это никак не влияет на выделяемые компоненты.   -  person Vladimir F    schedule 21.05.2016
comment
Значит, нет способа определить тип, производный от MPI, с выделяемыми компонентами? Как тогда я могу общаться с другими процессами?   -  person Coriolis    schedule 21.05.2016
comment
Вы упаковываете его самостоятельно или отправляете компонент отдельно.   -  person Vladimir F    schedule 21.05.2016
comment
См. также связанные stackoverflow.com/questions/10419990/, если вы немного знаете C. Распределяемый — это просто специальный расширенный тип указателя.   -  person Vladimir F    schedule 21.05.2016