Обзор: Я тестирую, что тип данных, созданный с использованием MPI_Type_create_struct(), является правильным и, следовательно, отправляет правильные значения. У меня возникают проблемы с получением значений, хранящихся в массивах, для передачи на другие процессоры. Я думаю, что это, вероятно, проблема с адресами памяти массивов в каждой связанной структуре и смещениями, хранящимися в индексах массива [], используемых для создания типа данных mpibound.Использование MPI_Type_create_struct() для переноса структур, содержащих динамические массивы, в C
Проблема: Я работаю над программой, использующей MPI, и моей конечной целью является использование MPI_Gatherv() для сбора значений из массива структур, называемых bound, которые описаны ниже.
struct bound {
int n;
char* name;
double* lat;
double* lon;
};
Я создал тестовую программу, чтобы убедиться, что я использовал MPI_Type_create_struct() правильно. Функция, в которой я называю MPI_Type_create_struct(), записывается ниже.
void CreateBoundType (struct bound a_bound) {
int blocklens[4]; /*Block Lengths of data in structure*/
MPI_Datatype old_types[4]; /*Data types of data in structure*/
MPI_Aint indices[4]; /*Byte displacement of each piece of data*/
MPI_Aint addr1, addr2, addr3, addr4, baseaddr;
/*Set block lengths*/
blocklens[0] = 1;
blocklens[1] = 10;
blocklens[2] = NPT_MAX;
blocklens[3] = NPT_MAX;
/*Set Data Types*/
old_types[0] = MPI_INT;
old_types[1] = MPI_CHAR;
old_types[2] = MPI_DOUBLE;
old_types[3] = MPI_DOUBLE;
/*Set byte displacement for each piece of data in structure*/
/*!!!!!I expect that the following 8 lines cause my problem!!!!!!*/
MPI_Get_address (&a_bound, &baseaddr);
MPI_Get_address (&a_bound.num_pts, &addr1);
MPI_Get_address (a_bound.label, &addr2);
MPI_Get_address (a_bound.lat, &addr3);
MPI_Get_address (a_bound.lon, &addr4);
indices[0] = addr1 - baseaddr;
indices[1] = addr2 - baseaddr;
indices[2] = addr3 - baseaddr;
indices[3] = addr4 - baseaddr;
/*Create structure type in MPI so that we can transfer boundaries between nodes*/
MPI_Type_create_struct(4,blocklens,indices,old_types,&mpibound);
MPI_Type_commit(&mpibound);
return;
}
Когда я пытаюсь использовать тип данных я создал (который является глобальной переменной, mpibound), в вызове MPI_Bcast() значения, хранящиеся в массивах, которые являются частью буферной структуры, я использую не обновляются, но целочисленное значение n (n - длина массивов) действительно изменяется на всех процессорах. Поэтому я думаю, что моя проблема имеет какое-то отношение к смещениям (индексы [4]), которые используются для определения mpibound.
Ниже я написал основную функцию, которая показывает, как я называю эту функцию и настраиваю структуры. (Я опустил звонки в MPI_Init и другие подобные функции, чтобы держать его коротким, как я могу)
int main (int argc, char **argv) {
/*Initialise MPI etc*/...
/*Create structure to broadcast*/
struct bound my_bound;
my_bound.name = strdup(string);
my_bound.lat = malloc(NPT_MAX*sizeof(double));
my_bound.lon = malloc(NPT_MAX*sizeof(double));
if(rank == 0) {
my_bound.n = 5;
my_bound.lat[0] = 2.6;
my_bound.lon[0] = 4.2;
}
/*Call the function that creates the type mpibound*/
CreateBoundType(my_bound);
/*Create buffer to be used in a Broadcast from the root processor (rank 0)*/
struct bound *buff = malloc(sizeof(struct bound));
buff->lat = malloc(NPT_MAX*sizeof(double));
buff->lon = malloc(NPT_MAX*sizeof(double));
buff = &my_bound;
/*Cast values in buffer from proc 0 to all others*/
MPI_Bcast(buff,1,mpibound,0,MPI_COMM_WORLD);
/*Print values and checks, free memory etc*/...
return(EXIT_SUCCESS);
}
Положив несколько заявлений печати после вызова MPI_Bcast показывает, что на проках с рангами> 0, то значениями n обновляется до этой трансляции с ранга 0, но первый элемент массивов lat и lon по-прежнему равен 0.
Если вы можете мне помочь, я очень благодарен за то, что он боролся с этим в течение нескольких дней! Я старался держать это как можно короче, и это лучшая версия, которую я смог создать.
Спасибо за чтение!
Ваш код имеет мало смысла. Вы выделяете две структуры и некоторую память для обоих массивов, но затем вы полностью выбрасываете память для второго, делая 'buff = & my_bound'. В любом случае, пожалуйста, подготовьте надлежащий [mcve] и более конкретный ожидаемый и фактический результат. – Zulan
Я вернулся @Zulan до его комментария. Ваш код пронизан ошибками, и я думаю, что это больше, чем проблема MPI, это фундаментальное понимание C, которое вы пропустите здесь. После того, как у вас есть основы C, вы можете начать повышаться, пытаясь решить MPI, но язык C определенно является необходимым условием, если вы хотите запрограммировать в MPI + C. – Gilles