Ошибка сегментации в MPI_Send для производных типов данных

В приведенном ниже коде, если MPI_Get_address(&member, &offset[0]); заменяется на offset[0] = 0; код работает, как и ожидалось, в противном случае он дает вывод ниже Насколько мне известно, для использования MPI_BOTTOM необходимы абсолютные адреса памяти, и именно поэтому MPI_Get_address() используется. В то время как структура Member не имеет проблем с MPI_Get_address()структура Family не работал с этим. В чем проблема?

Команда:

mpirun -n 2 ./out

Выход:

Signal: Segmentation fault (11)
Signal code:  (128)
Failing at address: (nil)
mpirun noticed that process rank 0...

Код:

#include <mpi.h>

struct Member
{
double height;
MPI_Datatype mpi_dtype;
Member() { make_layout(); }
void make_layout()
{
int nblock = 1;
int block_count[nblock] = {1};
MPI_Aint offset[nblock];
MPI_Get_address(&height, &offset[0]);
MPI_Datatype block_type[nblock] = {MPI_DOUBLE};
MPI_Type_create_struct(nblock, block_count, offset, block_type, &mpi_dtype);
MPI_Type_commit(&mpi_dtype);
}
};

struct Family
{
Member member;
MPI_Datatype mpi_dtype;
Family() { make_layout(); }
void make_layout()
{
int nblock = 1;
int block_count[nblock] = {1};
MPI_Aint offset[nblock];
MPI_Get_address(&member, &offset[0]);
//offset[0] = 0; <-- HERE!!!!!!!
MPI_Datatype block_type[nblock] = {member.mpi_dtype};
MPI_Type_create_struct(nblock, block_count, offset, block_type, &mpi_dtype);
MPI_Type_commit(&mpi_dtype);
}
};

int main()
{
int rank;

MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank == 0)
{
Family f;
MPI_Send(MPI_BOTTOM, 1, f.mpi_dtype, 1, 0, MPI_COMM_WORLD);
}
else if (rank == 1)
{
Family f;
MPI_Recv(MPI_BOTTOM, 1, f.mpi_dtype, 0, 0, MPI_COMM_WORLD, NULL);
}

MPI_Finalize();

return 0;
}

0

Решение

member.mpi_dtype уже несет абсолютный адрес Member::height как смещение в его карте типов. Когда в Family::make_layout() вы указываете offset[0] равно адресу memberоба смещения суммируются, что приводит к очень неправильному смещению. По этой самой причине типы данных MPI с абсолютными адресами не должны использоваться при создании других типов данных.

Там нет абсолютно никаких оснований для использования MPI_BOTTOM в этом случае — ваши структуры не имеют динамически распределенных полей, и, таким образом, типов данных MPI с относительными смещениями должно быть достаточно.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector