Есть простой пример для описания моего вопроса. У меня есть пользовательская структура, которая содержит динамический c массив
struct my_data_type {
int c;
int d[];
};
, а процесс root (процесс 0) имеет массив такой структуры nums[4]
.
Я хочу отправлять куски массива различным процессам (например, 2 процессам) через MPI_Scatter
. Основная проблема здесь в том, что я хочу, чтобы этот массив d[]
был динамическим c.
Основной код следующий:
int main(int argc, char* argv[]) {
MPI_Init(NULL, NULL);
int my_size; MPI_Comm_size(MPI_COMM_WORLD, &my_size);
int my_rank; MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int len = 2; //example: the dynamic array d contains len=2 elements
my_data_type *nums //nums[4]
= (my_data_type*)malloc((sizeof(my_data_type) + sizeof(int) * len) * 4);
my_data_type *sub_nums //sub_nums[2]
= (my_data_type*)malloc((sizeof(my_data_type) + sizeof(int) * len) * 2);
if (my_rank == 0) { //just some examples
nums[0].c = 0; nums[1].c = 1; nums[2].c = 2; nums[3].c = 3;
nums[0].d[0] = 10; nums[1].d[0] = 11; nums[2].d[0] = 12; nums[3].d[0] = 13;
nums[0].d[1] = 14; nums[1].d[1] = 15; nums[2].d[1] = 16; nums[3].d[1] = 17;
}
MPI_Datatype mpi_data_type; //new datatype
int blocklens[2];
MPI_Datatype old_types[2];
MPI_Aint indices[2];
blocklens[0] = 1; blocklens[1] = len;
old_types[0] = MPI_INT; old_types[1] = MPI_INT;
MPI_Address(&nums[0].c, &indices[0]);
MPI_Address(&nums[0].d[0], &indices[1]);
indices[1] = indices[1] - indices[0];
indices[0] = 0;
MPI_Type_create_struct(2, blocklens, indices, old_types, &mpi_data_type);
MPI_Type_commit(&mpi_data_type);
MPI_Scatter(nums, 2, mpi_data_type,
sub_nums, 2, mpi_data_type,
0, MPI_COMM_WORLD);
cout << "rank " << my_rank << ": " << endl;
cout << "c: " << sub_nums[0].c << ", " << sub_nums[1].c << endl;
cout << "d: " << sub_nums[0].d[0] << ", " << sub_nums[0].d[1] << ", ";
cout << sub_nums[1].d[0] << ", " << sub_nums[1].d[1] << endl;
MPI_Finalize();
return 0;
}
Если я изменю int d[];
на int d[2];
в определении struct my_data_type
, я, конечно, получу ожидаемые результаты, такие как
rank 0:
c: 0, 1
d: 10, 14, 11, 15
rank 1:
c: 2, 3
d: 12, 16, 13, 17
Но если нет, то результаты следующие:
rank 0:
c: 0, 10
d: 10, 14, 14, 15
rank 1:
c: 33, 0
d: 0, 0, 0, 1
Как вы видите, я знаю, что проблема в массиве Dynami c, но я не могу использовать STATI c в моем проекте. Итак, как я могу изменить свой код выше, чтобы получить ожидаемые результаты?